@std/yaml: expose/enable custom tag (!Foo / !!foo) support (I can implement)
- Dominant language
- TypeScript
- Stars
- 3.6k
- Forks
- 681
- PR merge metrics
- No merged PRs in 30d
Description
Today `@std/yaml` parses tag properties, but end users cannot register custom tags. Any unknown explicit tag (for example `!User`, `!Entity`, `!!my/tag`) fails during resolution.
This blocks some YAML patterns used in some DSLs and configuration systems.
## What I'm trying to do
Parse YAML like:
``` yaml
- !Entity
name: Workspace
- !Entity
name: User
```
And have `!Entity` resolved into a custom runtime structure (or at least a predictable representation), instead of throwing an unknown tag error.
## Current limitation
- `parse()` only accepts a schema name (`"failsafe" | "json" | "core" | "default" | "extended"`).
- There is internal schema/type machinery (type maps and tag resolution).
- However, there is no public API to register custom explicit or implicit tag handlers.
- `parse()` explicitly states that parsing untrusted data is safe. Any custom tag mechanism would need to keep this guarantee explicit and opt-in.
## Question
Are you open to adding **custom tag support** to `@std/yaml`?
If yes, I would like to implement it.
My goals would be:
1. No breaking changes.
2. Default behavior remains unchanged.
3. Custom tags are fully opt-in.
4. The "safe for untrusted input" guarantee remains explicit and documented.
5. The design fits the current internal schema + type map architecture.
## Possible API Directions
### Option A: Allow passing explicit/implicit types via `parse` options
``` ts
parse(yamlText, {
schema: "default",
types: {
explicit: [
{
tag: "!Entity",
kind: "mapping",
resolve: (data) => true,
construct: (data) => new Entity(data),
},
],
},
});
```
### Option B: Expose a public `createSchema()` or extend `getSchema()`
Allow users to build a schema with custom explicit + implicit types, and pass it to `parse()`.
This would align with the existing internal schema design.
### Option C: Minimal tag resolver map
``` ts
parse(yamlText, {
tagResolvers: {
"!Entity": (data) => new Entity(data),
},
});
```
This would be a simpler abstraction layer over the internal type system.
## I can implement
If maintainers confirm that custom tag support is something you are open to, I can:
- Propose a concrete design
- Implement the feature
- Add documentation
- Add tests
- Ensure full backward compatibility
Thank you.
Contributor guide
Assessment
This issue has not been assessed yet.