redhat-developer / redhat-developer/yaml-language-server
Can specify static resolved value for custom tags
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 352
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 11
Description
Is your enhancement related to a problem? Please describe.
Related issue:
- https://github.com/redhat-developer/vscode-yaml/issues/680
- https://github.com/redhat-developer/yaml-language-server/issues/647
The key point of my scenario
The customized resolver I defined for such custom tag changes the data type and value dynamically at runtime.
So how could I do validation on it?
Current behavior
I can only specify the rough shape (scalar, mapping or sequence) of data with some custom tag. After that, the parser will just return the data as is with a simple shape check.
But it doesn't make sense in my scenario right? My expected resolved data is definitely not the original one, but I have to accept it when writing schema.
Describe the solution you would like
To solve it, there are several directions in theory:
- Best: Can do a validation on the final result dynamically. But it's impossible when only uses JSON schema.
- Secondary: Can do a customized schema validation on the fragments with custom tag by its tag value. But it's not supported now.
- At least: There is a way that can ignore/bypass the fragments with some custom tag during validation.
Here I propose a solution under direction 3 because it is simplest:
Allow to specify static resolved values (stubs) for custom tags
Specification
Extends the yaml.customTags setting to accept object type values with a new property resolvedValue (property name can be discussed further).
Example
{
// ......
"yaml.customTags": [
{
"tag": "!TagName",
"type": "mapping",
// new property `resolvedValue` to define a stub, can give any valid json data here
"resolvedValue": {
"anything": "you want to be"
}
}
]
}
Then every fragment with tag !TagName will be replaced by the resolvedValue before doing validation.
Use cases
1. Force to use specific custom tag
Settings:
{
// ......
"yaml.customTags": [
{
"tag": "!regex",
"type": "scalar",
"resolvedValue": "This must be a regex type value!!!"
}
]
}
Schema:
{
// ......
"properties": {
"matcher": {
"type": "string",
"const": "This must be a regex type value!!!"
}
},
"required": [ "productId" ]
// ......
}
Correct:
---
matcher: !regex '([A-Z])\w+'
Incorrect:
---
matcher: '([A-Z])\w+'
2. Ignore merging of objects with custom tag
Settings:
{
// ......
"yaml.customTags": [
{
"tag": "!include",
"type": "mapping",
"resolvedValue": {}
}
]
}
Yaml:
---
object:
<<: !include
source: './abc/xyz'
path: 'any-path'
path: 'may be seen as a duplicate key'
Result with resolvedValue setting:
{
"object": {
"path": "may be seen as a duplicate key"
}
}
Result without resolvedValue setting:
{
"object": {
"source": "./abc/xyz",
"path": "any-path",
"path": "may be seen as a duplicate key" // error!
}
}
Describe alternatives you have considered
Can also choose another solution under direction 1 which is a little more risky than above one:
Allow to specify a dynamic resolver function for custom tags
Specification
Extends yaml.customTags setting to accept object type values with new property resolver.
Settings:
{
"yaml.customTags": [
{
"tag": "!TagName",
"type": "mapping",
"resolver": "./path/to/js/file/.../resolverFunction.js"
}
]
}
resolverFunction.js: Exports a function that will be invoked to resolve the inputs tagged by such custom tag.
Note
The resolver property is better to also accept raw JavaScript code string so that extension developers can pass their functions directly without creating a temporary js file.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing how the yaml.customTags setting is parsed and how custom-tag fragments participate in schema validation. Compare the proposed resolvedValue behavior with the dynamic resolver alternative and define which option is in scope. Done means custom-tag fragments use the configured static value during validation without breaking existing tag handling, with coverage for the scalar and mapping examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, yaml
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100