yaml-language-server icon indicating copy to clipboard operation
yaml-language-server copied to clipboard

Can specify static resolved value for custom tags

Open jindong-zhang-git opened this issue 2 years ago • 3 comments

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:

  1. Best: Can do a validation on the final result dynamically. But it's impossible when only uses JSON schema.
  2. Secondary: Can do a customized schema validation on the fragments with custom tag by its tag value. But it's not supported now.
  3. 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.

jindong-zhang-git avatar Aug 20 '22 10:08 jindong-zhang-git

If this proposal is accepted, I can close that 2 related issues.

jindong-zhang-git avatar Aug 20 '22 10:08 jindong-zhang-git

Hi @gorkem @evidolob, what do you think about this proposal?

jindong-zhang-git avatar Aug 24 '22 01:08 jindong-zhang-git

Hi @msivasubramaniaan, what's your opinion about this?

jindong-zhang-git avatar Aug 31 '22 03:08 jindong-zhang-git