microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.7k stars 29.45k forks source link

[json] support meta-schema features #155379

Open proohit opened 2 years ago

proohit commented 2 years ago

Issue Type: Bug

So basically I have a VS Code extension that provides JSON file validation based on the built in JSON validator. The schema that I'm validating against (OpenAPI 3.1.x) uses meta-schema features, i.e. $dynamicRef, which I also need to use, since I reference the OpenAPI schema.

When defining a custom schema like the following, I get a warning stating that the validator doesn't support meta-schema features yet. Needless to say, validation does really not work. When using normal $ref, most of the schema work but not properties that use $dynamicRef. So I'm forced to reference the schema by $dynamicRef as well.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "OpenApiPathObject",
  "type": "object",
  "additionalProperties": {
    "$dynamicRef": "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/schemas/v3.1/schema.json#/$defs/path-item-or-reference"
  }
}
The schema uses meta-schema features ($dynamicRef) that are not yet supported by the validator.

I'm using VS Code 1.69.0 and changed the required engine of my extension to ^1.68.0, which should include support for schema verion Draft 2020-12 as stated in the May 2022 release notes. What are my options here and how can I come around this warning?

Here's an excerpt of the extension package.json

...
"engines": {
    "vscode": "^1.68.0"
},
...

VS Code version: Code 1.69.0 (92d25e35d9bf1a6b16f7d0758f25d48ace11e5b9, 2022-07-07T05:28:36.503Z) OS version: Windows_NT x64 10.0.22000 Restricted Mode: No Remote OS version: Linux x64 5.10.102.1-microsoft-standard-WSL2

System Info |Item|Value| |---|---| |CPUs|AMD Ryzen 5 2600X Six-Core Processor (12 x 3593)| |GPU Status|2d_canvas: enabled
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_renderer: enabled_on
video_decode: enabled
video_encode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled| |Load (avg)|undefined| |Memory (System)|15.93GB (4.25GB free)| |Process Argv|--crash-reporter-id 807faa54-048f-4bca-b099-f3700536fcc8| |Screen Reader|no| |VM|0%| |Item|Value| |---|---| |Remote|WSL: Ubuntu| |OS|Linux x64 5.10.102.1-microsoft-standard-WSL2| |CPUs|AMD Ryzen 5 2600X Six-Core Processor (12 x 3593)| |Memory (System)|7.73GB (4.17GB free)| |VM|0%|
Extensions (72) Extension|Author (truncated)|Version ---|---|--- better-comments|aar|3.0.0 project-manager|ale|12.6.0 es7-react-js-snippets|dsz|4.4.3 lex-flex-yacc-bison|fau|0.0.3 auto-rename-tag|for|0.1.10 remotehub|Git|0.36.0 better-cpp-syntax|jef|1.15.19 jupyter-keymap|ms-|1.0.0 remote-ssh-edit|ms-|0.80.0 remote-wsl|ms-|0.66.3 remote-repositories|ms-|0.14.0 vscode-openapi|42C|4.11.3 vscode-css-formatter|aes|1.0.2 turbo-console-log|Cha|2.3.2 npm-intellisense|chr|1.4.2 path-intellisense|chr|2.8.1 doxdocgen|csc|1.4.0 vscode-svgviewer|css|2.0.0 vscode-markdownlint|Dav|0.47.0 vscode-eslint|dba|2.2.6 githistory|don|0.6.19 vscode-generate-getter-setter|DSK|0.5.0 gitlens|eam|12.1.2 prettier-vscode|esb|9.5.0 shell-format|fox|7.2.2 c-cpp-runner|fra|4.0.3 copilot|Git|1.31.6194 vscode-pull-request-github|Git|0.46.0 latex-workshop|Jam|8.27.2 better-cpp-syntax|jef|1.15.19 vscode-github-actions|me-|3.0.1 vscode-todo-parser|min|1.9.1 csharp|ms-|1.25.0 python|ms-|2022.10.1 vscode-pylance|ms-|2022.7.30 jupyter|ms-|2022.6.1201981810 jupyter-keymap|ms-|1.0.0 jupyter-renderers|ms-|1.0.8 cmake-tools|ms-|1.11.26 cpptools|ms-|1.10.8 cpptools-extension-pack|ms-|1.2.0 gradle-language|nac|0.2.3 color-highlight|nau|2.5.0 vscode-jest|Ort|4.6.0 peggy-language|Peg|2.3.0 vscode-boot-dev-pack|Piv|0.1.0 vscode-spring-boot|Piv|1.36.0 openapi-snippets|pro|0.0.9 quicktype|qui|12.0.46 typescript-hero|rbb|3.0.0 java|red|1.8.0 vscode-commons|red|0.0.6 vscode-xml|red|0.21.0 vscode-yaml|red|1.9.1 vscode-gradle-extension-pack|ric|0.0.4 LiveServer|rit|5.7.5 rust-analyzer|rus|0.3.1123 sonarlint-vscode|Son|3.7.0 svelte-vscode|sve|105.18.1 cmake|twx|0.0.17 vscode-lldb|vad|1.7.1 vscode-ltex|val|13.1.0 vscodeintellicode|Vis|1.2.22 vscode-gradle|vsc|3.12.2 vscode-java-debug|vsc|0.42.0 vscode-java-dependency|vsc|0.20.0 vscode-java-pack|vsc|0.24.0 vscode-java-test|vsc|0.35.2 vscode-maven|vsc|0.36.0 vscode-spring-boot-dashboard|vsc|0.5.0 vscode-spring-initializr|vsc|0.10.0 glean|wix|5.2.2 (2 theme extensions excluded)
vscodenpa commented 2 years ago

Thanks for creating this issue! It looks like you may be using an old version of VS Code, the latest stable release is 1.69.1. Please try upgrading to the latest version and checking whether this issue remains.

Happy Coding!

aeschli commented 2 years ago

As explained in the release notes we don't yet have support for meta-schema.

proohit commented 2 years ago

Thanks for your clarification. You are absolutely right and somehow I missed that. Is this feature on the roadmap or far ahead?

aeschli commented 2 years ago

It's not on the plan for now as other work has higher priority. Please add your vote on the issue so give this more weight. Or, if you want to give it a try, PR are very welcome. The implementation is in https://github.com/microsoft/vscode-json-languageservice

flisboac commented 2 years ago

I know this is not on the roadmap, but Is there any known alternative?

Is there any way for us to use VSCode for JSON Schema authoring, with all the benefits of autocomplete, etc?

flisboac commented 2 years ago

Curiously, I just opened a folder and configured .vscode/settings.json as such, and VSCode understood that some of my .schema.json files were JSON schemas, and gave me autocompletion:

{
  "json.schemas": [
    {
      "fileMatch": ["*.schema.json"],
      "url": "https://json-schema.org/draft/2019-09/schema"
    }
  ]
}

Unfortunately, the .schema.json file MUST NOT have that very same URL, otherwise all the validation and autocompletion functionalities are lost.

Summarizing. Once you properly configure your workspace, this works:

{
  "$id": "https://REDACTED/REDACTED/core/table-migration-config/v1",
  // ...
}

But this breaks, even though it's the very same Schema URL:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "$id": "https://REDACTED/REDACTED/core/table-migration-config/v1",
  // ...
}

Whi is the behaviour different?

I imagine those default JSON-Schema URLs are ubiquitous enough to receive a special treatment, so they may be internally resolved to a dereferenced schema object/string in VSCode, somehow -- especially given that the language service has no support for meta-schemas, so it must be dealt with outside the language service itself.

Considering that, would it be possible to interpret the "$schema" in the JSON file the same way the workspace settings URL is dealt with, for this specific use-case (of schema authoring, from a default JSON-Schema URL)?

JustinGrote commented 2 years ago

I'm getting a false positive warning that I am using dynamicref when I am not on this schema, should this be a separate issue? image

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/JustinGrote/AzurePolicySchema/main/policyParameters.schema.json",
  "title": "Azure Policy Parameters",
  "description": "Azure Policy Parameters: https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure",
  "type": "object",
  "additionalProperties": {
    "type": "object",
    "description": "Input parameter definitions",
    "additionalProperties": false,
    "properties": {
      "name": {
        "type": "string",
        "description": "The name of your parameter. Used by the parameters deployment function within the policy rule. For more information, see https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure#using-a-parameter-value."
      },
      "type": {
        "type": "string",
        "description": "Type of input parameter",
        "enum": [
          "string",
          "securestring",
          "int",
          "bool",
          "object",
          "secureObject",
          "array"
        ]
      },
      "defaultValue": {
        "type": [
          "string",
          "boolean",
          "integer",
          "number",
          "object",
          "array",
          "null"
        ],
        "description": "Default value to be used if one is not provided"
      },
      "allowedValues": {
        "type": "array",
        "description": "Value can only be one of these values"
      },
      "metadata": {
        "type": "object",
        "description": "Metadata for the parameter, can be any valid JSON object but there are some well known properties that influence the Azure Portal",
        "properties": {
          "displayName": {
            "type": "string",
            "description": "The friendly name shown in the portal for the parameter."
          },
          "description": {
            "type": "string",
            "description": "The explanation of what the parameter is used for. Can be used to provide examples of acceptable values."
          },
          "strongType": {
            "type": "string",
            "description": "Used when assigning the policy definition through the portal. Provides a context aware list. For more information, see strongTy"
          },
          "assignPermissions": {
            "type": "boolean",
            "description": "Set as true to have Azure portal create role assignments during policy assignment. This property is useful in case you wish to assign permissions outside the assignment scope. There's one role assignment per role definition in the policy (or per role definition in all of the policies in the initiative). The parameter value must be a valid resource or scope."
          }
        }
      },
      "schema": {
        "type": "string",
        "description": "Provides validation of parameter inputs during assignment using a self-defined JSON schema. This property is only supported for object-type parameters and follows the Json.NET Schema 2019-09 implementation. You can learn more about using schemas at https://json-schema.org/ and test draft schemas at https://www.jsonschemavalidator.net/."
      }
    },
    "required": [
      "type"
    ]
  }
}
aeschli commented 2 years ago

The https://json-schema.org/draft/2020-12/schema schema uses $dynamicRef... :crying_cat_face:

JustinGrote commented 2 years ago

@aeschli oh, fair point, maybe filter these notices when you're referencing the actual schema spec? :)

proohit commented 2 years ago

@JustinGrote Using the spec, which uses $dynamicRef, could lead to unintended behaviour or not work at all, so suppressing the warning wouldn't be a good idea imho.

proohit commented 1 year ago

@aeschli any news on this?

mengdu commented 1 year ago

It maybe fix this

.vscode/settings.json

{
    "yaml.schemas": {
      "https://json-schema.org/draft/2020-12/schema": ["my.schema.json"]
    }
}
gcacars commented 1 year ago

I think that #98724 is related to this.

carlosalban commented 1 year ago

Would love to see this get in.

klausMistlberger commented 8 months ago

Would highly appreciate this beeing implemented.

zloveless commented 7 months ago

Would love support for newer schemas too...

brandon-austin-lark commented 7 months ago

Are we making any progress on this?

Necrelox commented 7 months ago

Hi, does anyone have more information about https://json-schema.org/draft/2020-12/schema and validation on vscode?

GabenGar commented 7 months ago

What information do you need?

Necrelox commented 6 months ago

I wanted to find out if VSCode will soon support validation for https://json-schema.org/draft/2020-12/schema, or if there is an alternative solution?

JustinGrote commented 6 months ago

@Necrelox that's tracked here: https://github.com/microsoft/vscode/issues/165219

Necrelox commented 6 months ago

Thanks you !! @JustinGrote