yaml-language-server
yaml-language-server copied to clipboard
Can specify static resolved value for custom tags
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.
If this proposal is accepted, I can close that 2 related issues.
Hi @gorkem @evidolob, what do you think about this proposal?
Hi @msivasubramaniaan, what's your opinion about this?