GithubHelp home page GithubHelp logo

microsoft / vscode-json-languageservice Goto Github PK

View Code? Open in Web Editor NEW
221.0 29.0 100.0 1.26 MB

JSON language service extracted from VSCode to be reused, e.g in the Monaco editor.

License: Other

TypeScript 99.75% JavaScript 0.25%

vscode-json-languageservice's Introduction

vscode-json-languageservice

JSON language service extracted from VSCode to be reused, e.g in the Monaco editor.

npm Package NPM Downloads Build Status License: MIT

Why?

The vscode-json-languageservice contains the language smarts behind the JSON editing experience of Visual Studio Code and the Monaco editor.

  • doValidation analyses an input string and returns syntax and lint errors.
  • doComplete provides completion proposals for a given location.
  • doResolve resolves a completion proposals.
  • doHover provides a hover text for a given location.
  • findDocumentSymbols provides all symbols in the given document.
  • findDocumentColors provides all color symbols in the given document.
  • getColorPresentations returns available color formats for a color symbol.
  • format formats the code at the given range.
  • getFoldingRanges gets folding ranges for the given document.
  • getSelectionRanges gets selection ranges for a given location.
  • getMatchingSchemas matches a document against its schema and returns all AST nodes along with the matching sub schemas.
  • parseJSONDocument creates a JSON document from source code.
  • newJSONDocument creates a JSON document from an AST.

For the complete API see jsonLanguageService.ts and jsonLanguageTypes.ts

Installation

npm install --save vscode-json-languageservice

Sample usage

See sample.ts for an example on how to use the JSON language service.

To run the sample use yarn sample

Development

git clone https://github.com/microsoft/vscode-json-languageservice
cd vscode-json-languageservice
yarn

Use yarn test to compile and run tests

How can I run and debug the service?

  • open the folder in VSCode.
  • set breakpoints, e.g. in jsonCompletion.ts
  • run the Unit tests from the run viewlet and wait until a breakpoint is hit: image

How can I run and debug the service inside an instance of VSCode?

  • run VSCode out of sources setup as described here: https://github.com/Microsoft/vscode/wiki/How-to-Contribute
  • use yarn link vscode-json-languageservice in vscode/extensions/json-language-features/server to run VSCode with the latest changes from vscode-json-languageservice
  • run VSCode out of source (vscode/scripts/code.sh|bat) and open a .json file
  • in VSCode window that is open on the vscode-json-languageservice sources, run command Debug: Attach to Node process and pick the code-oss process with the json-language-features path image
  • set breakpoints, e.g. in jsonCompletion.ts
  • in the instance run from sources, invoke code completion in the .json file

vscode-json-languageservice's People

Contributors

abc-55 avatar aeschli avatar aiday-mar avatar ananthakumaran avatar debck avatar denisw avatar dependabot[bot] avatar floedelmann avatar gjsjohnmurray avatar ianchi avatar jgraettinger avatar kapitanoczywisty avatar kosrendq avatar levertion avatar literalplus avatar lszomoru avatar mati-o avatar microsoft-github-policy-service[bot] avatar mifieldxu avatar msftgits avatar n10v avatar octogonz avatar rahulbanerjee26 avatar relequestual avatar sandersn avatar sqs avatar ssbarnea avatar stepjanssen avatar tamayika avatar zardoy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vscode-json-languageservice's Issues

Are the `filterText` and `label` accidentally swapped?

This server returns LSP completion items in the following format:

"word_wrap": $1
^^^^^^^^^^^ filterText
 ^^^^^^^^^ label

Shouldn't it be the other way around? I always assumed the filterText should ideally be a substring of the label (with some room for possible interesting exceptional completion items):

"word_wrap": $1
^^^^^^^^^^^ label
 ^^^^^^^^^ filterText

That is, the user presumably already typed the first double-quote, and the filterText should now start matching the word word_wrap.

DocumentSymbol pop-up

In my sample workspace, I often see this. Settings, launch files etc are all normal sized

Screenshot 2020-04-17 at 13 46 50

publish d.ts for /lib modules?

I'm working on a derivation of the language service.

As I started to extend the JSONValidation class, I noticed that the d.ts files for the lib directory are being .npmignore'd.

Could that be reconsidered? Would make it easier to integrate the services into higher-level services if the d.ts files were there...

Show values in document symbols

Hello.

Would displaying the primitive string values in the outline (symbols) as done in JetBrains products be relevant to this language server?

Examples Below

JetBrains

image

VSCode

image

JSON Schema fails to resolve reference to definition if the definition is a uri reference.

monaco-editor version: 0.20.0
**Browser:85.0.4183.102
**OS:MacOS
Playground code that reproduces the issue:

// The Monaco Editor can be easily created, given an
// empty container and an options literal.
// Two members of the literal are "value" and "language".
// The editor takes the full size of its container.


const actionSchema = {
    description: "feedback component",
    oneOf: [
        {
            type: "object",
            properties: {
                kind: { const: "other" }
            }
        },
        {
            type: "object",
            properties: {
                kind: {
                    const: "feedback",
                    description:"this is a feedback component"
                },
                feedback: {
                    type: "object",
                    description: "feedback",
                    properties: {
                        modalProps: {
                            type: "object",
                            description: "modalProps",
                            properties: {
                                content: {
                                    description: "This is a nested component schema",
                                    $ref: "#/definitions/B",
                                },
                                compareToThis: {
                                    description: "This is also a nested component schema",
                                    $ref: "internal://schema/b.json",
                                },
                                C: {
                                    $ref: "#/definitions/C"
                                }
                            }
                        },
                    }
                },
                then: {
                    $ref: "#/definitions/itself"
                }
            },
        }
    ],
    definitions: {
        'itself': {
            $ref: "#"
        },
        B: {
            $ref: "internal://schema/b.json",
        },
        C: {
            description: "C"
        }
    }
}

const componentSchema = {
    oneOf: [
        {
            type: "string",
        },
        {
            type: "object",
            properties: {
                props: {
                    description: "A",
                    $ref: "internal://schema/a.json"
                }
            },
            additionalProperties: false,
        }
    ],
}

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [
        {
            uri: "internal://schema/a.json",
            schema: actionSchema
        },
        {
            fileMatch: ["*"],
            uri: "internal://schema/b.json",
            schema: componentSchema
        }
    ]
})

const a = {
    props: {
        kind: "feedback",
        feedback: {
            modalProps: {
                content: {
                    //cannot get any hover information in this node!!!!!!
                    props: {
                        kind: "feedback",
                        feedback: {
                            modalProps: {
                                content: {
                                    kind: "other"
                                }
                            }
                        }
                    }
                },
                compareToThis: {
                    props: {
                        kind: "feedback",
                        feedback: {
                            modalProps: {
                                content: " 1"
                            }
                        }
                    }
                },
                C: "1"
            }
        },
        then: {
            kind: "other"
        }
    }
}


const model = monaco.editor.createModel(JSON.stringify(a, null, "\t"), "json", "internal://json/a.json");

monaco.editor.create(document.getElementById("container"), {
    model: model
});

The problem is:

At this path and its descendants: props.feedback.modalProps.content, I cannot hover and see the json-schema 'description', it just shows nothing.

As a comparison, directly refererence to schema uri works (props.feedback.modalProps.compareToThis).

Implementation of codeaction and executeCommand

Hi,
I want to implement codeaction and execute command in certain cases.
Can I add a pull request that extends the jsonworker interface to support this, to be added in the contributions parameter in the constructor?
Thanks

Configurition of severity for schema error

Hi,
Is there a possibility to add configuration to the severity of schema problems?
Perhaps with the documentSettings.
I would like to define that all schema problems have a severity of error.
Best regards,
Adam

Schema are resolved multiple times.

So while trying to solve another issue

I have noticed the current schema solver doesn't take into account that something can be solved multiple times.
When it tries to loads or retrieve another schema it tries to get only the unresolved schema and resolve it. Also with all the promises resolving all the subschemas, It brings some trouble when a schema is resolved. So I am proposing the following:

export enum ResolveState {
	unresolved,
	resolving,
	resolved
}

export interface ISchemaState {
	schema: JSONSchema;
	errors: string[];
	readonly resolved: ResolveState;
}

export class UnresolvedSchema implements ISchemaState {
	public schema: JSONSchema;
	public errors: string[];
	readonly resolved: ResolveState = ResolveState.unresolved;

	constructor(schema: JSONSchema, errors: string[] = []) {
		this.schema = schema;
		this.errors = errors;
	}
}

export class ResolvingSchema implements ISchemaState {
	public schema: JSONSchema;
	public errors: string[];
	readonly resolved: ResolveState = ResolveState.resolving;

	constructor(schema: JSONSchema, errors: string[] = []) {
		this.schema = schema;
		this.errors = errors;
	}
}

export class ResolvedSchema implements ISchemaState  {
	public schema: JSONSchema;
	public errors: string[];
	readonly resolved: ResolveState = ResolveState.resolved;

	constructor(schema: JSONSchema, errors: string[] = []) {
		this.schema = schema;
		this.errors = errors;
	}
}

So once you reach the point to solve the refs again you can check if it is already resolved, resolving or not.
And at the end of the resolving, you overwrite the existing entry with a resolved schema.

Sourcemaps broken in VSCode debugger

When I run the Tests in the VSCode debugger, any breakpoints in the TypeScript sources are disabled with the

Breakpoint ignored because generated code not found (source map problem?)

message.

Synchronous validation

In some situations it is useful to support JSON where the set of required schemas is known before the validation is run. It appears to me, from my armchair (figure of speech) postulations, that the only required promises are in fetching schemas from a filesystem as decided by SchemaRequestService. In my case, this would be a single static schema.

However, the current api still requires that such cases happen in the infectious async world, which is not always valuable. Have you got any suggestions for how I could handle this/what changes would be required to support such a use case?

If this is out of scope, I will be forced to reimplement (using the powers vested in me by ctrl-c and ctrl-v) all of the logic in this library.

Many thanks!

Further Context:
For my project https://github.com/Levertion/mcfunction-langserver, I know that the only required schema is https://github.com/Levertion/minecraft-json-schemas/blob/master/shared/minecraft_definitions.json, which doesn't reference any external files.
As this is a language server implementation requiring JSON support, I thought that vscode-json-languageservice would be a suitable, but as my core api is synchronous, I would require large changes just to avoid this issue.

Add coverage details

This is a core piece of software in VSCode and it should have code coverage information done during CI and present as a badge on the README.

I got it to output useful coverage information by adding nyc as an npm script.

date-time validation

Hi,
I'm using the coc.nvim extension with coc-json to develop jsonschema files in neovim. I stumbled upon a problem with date-time validation.
This is my schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "date": {
      "type": "string",
      "format": "date-time"
    }
  }
}

This is my JSON:

{
  "date": "020-12-23T18:25:43.511Z"
}

The year is missing the first digit and coc-json does not report any errors. Actually no errors are detected for the date-time string format, it seems the validation is completely ignored. When I set the format to email, all erroneous mail addresses are reported, so the format validation is basically working.
Here is how it should behave: https://www.jsonschemavalidator.net/s/AjNuDoH9
I first raised this issue for coc-json, but I was redirected to this JSON language server.

Is that a known issue or am I doing something wrong?

use real glob instead of simpleRegex

I'm not sure if this is documented, but I was under the impression that the syntax used when providing fileMatch-Patterns for schemas ist a "glob"-Pattern. But it appers it is a "Simpleregex" defined by replacing certain characters as defined here: https://github.com/microsoft/vscode-json-languageservice/blob/master/src/utils/strings.ts#L34-L36

The key difference i noticed is that /**/ in a glob pattern matches zero or more folders, whereas in "simpleRegex" it matches one or more nested folders.

There is a package called glob-to-regex which appears to do the conversion respecting "globstar".

I'm happy to do the pull-request if you would approve this change.

Snippet completions with a single $1 should instead use a single $0

Some snippet completions contain a single $1. For instance I type "f, and the server could insert

"foo": $1

This, however, creates a "snippet field" stack in Sublime Text. It'd be better if such completions were to complete to

"foo": $0

I'm willing to put some effort into fixing this, but I would like to know if such a change would be accepted.

[json] Encoded references in JSON schema are not decoded correctly

This JSON schema is valid but not processed correctly.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "Foo<number>": {
      "type": "object",
      "properties": {"q1": {"enum": ["x1", "x2"]}}
    }
  },
  "type": "object",
  "properties": {
    "p1": {"enum": ["v1", "v2"]},
    "p2": {"$ref": "#/definitions/Foo%3Cnumber%3E"}
  }
}
{
  "$schema": "https://gist.githubusercontent.com/domoritz/3cd0ddb8cad62ad611f301b2a8743ebf/raw/3bc4ff9350a8e9a7acb54d9683ce3a6d3c179377/schema.json",
}

Screen Shot 2020-01-29 at 13 18 08

The JSON schema standard says that references need to be valid URIs. "#/definitions/Foo<number>" contains invalid characters.

monaco-editor version: v0.19.3
Browser: Chrome
OS: MacOS

cc @kanitw

Resource apiVersion validation fails when using a nested template

Hiya Martin!

A bit of context:

I'm using an ARM template to deploy a VM and other resources (storage account/NICs/etc) and I've also added a nested template into it to be able to target a recovery vault in another RG (so backups could be setup as well).
To this end, I've used the "resourceGroup:" parameter as described on the documentation here: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-cross-resource-group-deployment

The template passes the Test-AzureRmResourceGroup validation and deploys as expected, but I've noticed that on VS Code the apiVersion for the Microsoft.Resources resource provider gets highlighted and marked as invalid, claiming 'Value is not accepted. Valid values: "2015-01-01"'.

However, the value that I'm trying to pass (2017-05-10) is definitely published on the RP schema.

VS Code version: 1.30.1 (also repros with no extensions loaded)

Condensed template (- storage/NICs/etc, stripped for simplicity):

    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "VmName": {
            "type": "string"
        },
        "vmSize": {
            "type": "string"
        }
    },
    "variables": {
    },
    "resources": [
        {
            "name": "[parameters('VmName')]",
            "type": "Microsoft.Compute/virtualMachines",
            "location": "[resourceGroup().location]",
            "apiVersion": "2017-03-30",
            "dependsOn": [ ],
            "tags": {},
            "properties": {
                "hardwareProfile": {
                    "vmSize": "[parameters('VmSize')]"
                },
                "osProfile": {
                    "computerName": "[parameters('VmName')]",
                    "adminUsername": "localadmin",
                    "adminPassword": "MyUserPwd123#",
                    "windowsConfiguration": {
                        "timeZone": "Eastern Standard Time"
                    }
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "MicrosoftWindowsServer",
                        "offer": "WindowsServer",
                        "sku": "2016-Datacenter",
                        "version": "latest"
                    },
                    "osDisk": {
                        "name": "[concat(parameters('VmName'), 'OSDisk')]",
                        "caching": "ReadWrite",
                        "createOption": "FromImage"
                    }
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('VmNicName'))]"
                        }
                    ]
                }
            }
        },
		{
			"apiVersion": "2017-05-10",
			"name": "MyNestedRecoveryVaultdeployment",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "[variables('RecoveryVaultResourceGroup')]",
			"dependsOn": [
				"[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
				],
			"properties": {
				"mode": "Incremental",
				"template": {
					"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
					"contentVersion": "1.0.0.0",
					"parameters": {},
					"variables": {},
					"resources": [
							{
							"name": "vaultname",
							"apiVersion": "2016-12-01",
							"location": "[resourceGroup().location]",
							"type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
							"properties": {
								"protectedItemType": "Microsoft.Compute/virtualMachines",
								"policyId": "policyname",
								"sourceResourceId": "[resourceId('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
								}
							}
						]
					},
				   "parameters": {},
				   "outputs": {}
			}
	}
    ],
    "outputs": {}
}```

getMatchingSchemas with unresolved schema

Great addition with getMatchingSchemas, but there is small inconsistency with how schema is handled i.e. when schema is provided as an argument, $refs are not resolved. Example bellow.

So maybe we need to expose resolver api or call resolver inside getMatchingSchemas?

const jsonSchema = {
  definitions: {
    field: {
      type: "number",
    },
  },
  type: "array",
  items: { $ref: "#/definitions/field" },
};
const jsonCode = "[1,2]";

ls.configure({
  validate: true,
  allowComments: true,
  schemas: [
    {
      uri: "test://schema.json",
      schema: jsonSchema,
      fileMatch: ["*.json"],
    },
  ],
});

const document = TextDocument.create("test://test.json", "json", 0, jsonCode);
const jsonDoc = ls.parseJSONDocument(document);

const show = (list) => {
  console.log(list.map((x) => JSON.stringify(x.schema)));
};

ls.getMatchingSchemas(document, jsonDoc, jsonSchema).then(show);
// unresolved $refs
// [
//   '{"$ref":"#/definitions/field"}',
//   '{"$ref":"#/definitions/field"}',
//   '{"definitions":{"field":{"type":"number"}},"type":"array","items":{"$ref":"#/definitions/field"}}'
// ]

ls.getMatchingSchemas(document, jsonDoc).then(show);
// resolved
// [
//   '{"type":"number"}',
//   '{"type":"number"}',
//   '{"definitions":{"field":{"type":"number"}},"type":"array","items":{"type":"number"}}'
// ]

Improve message error for "oneOf" element when several schemas are possible

Currently, if several schemas are possible a validation warning is provided:
Matches multiple schemas when only one must validate.

if (matches.length > 1 && maxOneMatch) {
validationResult.problems.push({
location: { offset: node.offset, length: 1 },
severity: DiagnosticSeverity.Warning,
message: localize('oneOfWarning', "Matches multiple schemas when only one must validate.")
});

I can be wrong but it seems a possible case. it is causing a false-positive in UI.
I think that it would be nice to validate against the various potential schemas and if one is matching, to not throw the validation.

Does it sounds reasonable?

Or it is the schema should never hit this case. In this case, how to avoid that in a clean way on schema side?

$ref should accept $id references

As part of JSONSchema Draft 6, $ref can point to a definition defined with an $id (or just id, spec seems vague if its $id or id in v6) -- it would be wonderful if we could get support for that here.

For instance, in definitions we will be able to use {"references": { "$id": "#test", ... }} and in our core properties, refer to it via {"properties": {"$ref": "#test", ...}}

Thanks!

JSON Schema “oneOf”: autocompletion of property name doesn’t insert a colon

monaco-editor version: 0.21.2
Browser: Any
OS: Windows 10

Steps reproducing the issue:

Run the following snippet within the Monaco Editor Playground:

var jsonCode = [
    '{','}'
].join('\n');
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
var model = monaco.editor.createModel(jsonCode, "json", modelUri);

// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [{
        uri: "http://myserver/foo-schema.json", // id of the first schema
        fileMatch: [modelUri.toString()], // associate with our model
        schema: {
            type: "object",
            properties: {
                enum : { enum: ["a","b"]},
                object : {
                            type: "object",
                            properties : {
                                q: {
                                    enum: ["c","d"]
                                }
                            }
                        },
                oneOf: {
                    oneOf: [
                        { enum: ["a","b"]},
                        {
                            type: "object",
                            properties : {
                                q: {
                                    enum: ["c","d"]
                                }
                            }
                        }
                    ] 
                }
            }
        }
    }
    ]
});

monaco.editor.create(document.getElementById("container"), {
    model: model
});

Typing "estrg+space tab between the curly brackets leads to:
"enum":

Typing "obstrg+space tab between the curly brackets leads to:
"object":{}

Whereas typing "onstrg+space tab between the curly brackets leads to:
"oneOf"
instead of:
"oneOf":

custom keywords

In the case of dynamic content, I'm wondering if custom keywords like ajv could be possible.

In that case, I guess a user setting for the functions as well as the target schema would be needed.

Another option is to extend the $ref with hyper schema like syntax:

"properties":{
    "type":{"type": "string"},
    "name":{
      "$ref":{
        "hrel":"http://my-host/dynamicType/{type}",
        "templatePointers":{
             "type": "/type"
        }
   }
  }
}

and input:

{"type": "user", "name": "Peter"}

with return something like this:

{
  "type": "string",
  "enum":["John","Peter"]
}

In both cases we move slightly away from json schema standard...

Let me know if this makes sense.

Monaco editor fails to offer all valid completions for a string/enum property

For a schema that uses oneOf to implement polymorphic types, Monaco sometimes fails to offer completions for all valid values of a string/enum property.

When I use the following JSON schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type",
        "prop1.2"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}

and when the contents of the editor is:

{
  "component": {
      "type": ""
  }
}

I'd expect Monaco to offer two auto-complete options for the type property: component1.1 and component1.2. However, for the above schema, only component1.1 is shown in the auto-complete box. (The full playground reproduction code is included at the bottom.)

Interestingly, when I edit the definition of component1.1 to make the prop1.1 property required, Monaco behaves correctly and offers both type values (Working definition 1 below). Also, when I make the prop1.2 property not required (Working definition 2 below), I'm also getting the correct behavior.

Is this inconsistency in auto-complete somehow justified?

Working definition 1
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type", "prop1.1"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type",
        "prop1.2"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}
Working definition 2
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "component1.1": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.1"
          ]
        },
        "prop1.1": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1.2": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "component1.2"
          ]
        },
        "prop1.2": {
          "type": "integer"
        }
      },
      "required": [
        "type"
      ]
    },
    "component1": {
      "oneOf": [
        {
          "$ref": "#/definitions/component1.1"
        },
        {
          "$ref": "#/definitions/component1.2"
        }
      ]
    }
  },
  "properties": {
    "component": {
      "$ref": "#/definitions/component1"
    }
  }
}

monaco-editor version: 0.21.2
Browser: Chrome
OS: Windows 10
Playground code that reproduces the issue:

var jsonCode = `{
  "component": {
      "type": ""
  }
}`;
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
var model = monaco.editor.createModel(jsonCode, "json", modelUri);

// configure the JSON language support with schemas and schema associations
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [{
        uri: "http://myserver/foo-schema.json", // id of the first schema
        fileMatch: [modelUri.toString()], // associate with our model
        schema: {
            "$schema": "http://json-schema.org/draft-07/schema#",
            "type": "object",
            "definitions": {
                "component1.1": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "enum": [
                                "component1.1"
                            ]
                        },
                        "prop1.1": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "type"
                    ]
                },
                "component1.2": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "enum": [
                                "component1.2"
                            ]
                        },
                        "prop1.2": {
                            "type": "integer"
                        }
                    },
                    "required": [
                        "type",
                        "prop1.2"
                    ]
                },
                "component1": {
                    "oneOf": [
                        {
                            "$ref": "#/definitions/component1.1"
                        },
                        {
                            "$ref": "#/definitions/component1.2"
                        }
                    ]
                }
            },
            "properties": {
                "component": {
                    "$ref": "#/definitions/component1"
                }
            }
        }
    }]
});

monaco.editor.create(document.getElementById("container"), {
    model: model
});

draft/2019-09: exclusiveMinimum and exclusiveMaximum must be numbers

In my workspace, if I put $schema to 2019-09, and set exclusiveMinimum and exclusiveMaximum with a boolean is not throwing any error.

Considering these two examples:

A JSON Schema based on draft-07

{
    "$id": "https://example.com/my-schema",
    "$schema": "https://json-schema.org/draft-07/schema",
    "properties": {
        "test": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "maximum": 100,
            "exclusiveMaximum": true
        }
    }
}

And a JSON Schema based on lastest version draft 2019-09

{
    "$id": "https://example.com/my-schema",
    "$schema": "https://json-schema.org/draft/2019-09/schema",
    "properties": {
        "test": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "maximum": 100,
            "exclusiveMaximum": true
        }
    }
}

The example with draft 2019-09 is going to be accepted, while the first example with draft-07 throws an error as expected:
Incorrect type. Expected "number".

As I can see in jsonParser.ts is going to accept both number and boolean on 2019-09 which is incorrect while It is showing an expected error on draft-09.
2019-09 draft specefication mention this:

6.2.3. exclusiveMaximum
The value of "exclusiveMaximum" MUST be number, representing an exclusive upper limit for a numeric instance.

6.2.5. exclusiveMinimum
The value of "exclusiveMinimum" MUST be number, representing an exclusive lower limit for a numeric instance.

Suggestion: vscode json schema meta schema

The json schema meta schema for validating json schemas located at http://json-schema.org/schema is helpful for developing schemas, however it doesn't include the vscode-json-languageservice specific json schema extensions as described in jsonSchema.ts.

It would be useful to have a published schema which includes these updates for better clarity about the supported aspects of json schemas. This could be used to generate jsonSchema.ts using a tool such as YousefED/typescript-json-schema.

Alternatively, a more general schema including any known extensions could be created.

I am unavailable to complete this myself at the moment as I am busy with other work.

Unable to refer to external schama's root definition

When a $ref points to another schema file, and refers to the root definition (referred-schema.json#/ instead of referred-schema.json#/definitions/xxx), the language service gives the error $ref '/' in referred-schema.json can not be resolved..

For a real-world example, see the AWS CloudFormation JSON schema where schema.json refers to resource.json#/

That schema works fine after moving the resource root definition under /definitions.

Allow exclusive globs in `fileMatch`

I would expect that:

"json.schemas": [
	{
		"fileMatch": [
			"/foo/*.json",
			"!/foo/*.excluded.json"
		],
		"url": "/foo.schema.json"
	}
]

would not add the foo.schema.json to any files ending with .excluded.json.

Npm release 3.8.0 is missing some type definitions

Trying to compile vscode-json-languagesserver (not "service") results in an error because npm-released version of this package is missing so type definitinions.

node_modules/vscode-json-languageservice/lib/umd/jsonLanguageService.d.ts:7:35 - error TS7016: Could not find a declaration file for module './parser/jsonParser'. '/Users/projects/vscode-json-languageserver/node_modules/vscode-json-languageservice/lib/umd/parser/jsonParser.js' implicitly has an 'any' type.

7 export { IApplicableSchema } from './parser/jsonParser';
                                    ~~~~~~~~~~~~~~~~~~~~~


Found 1 error.

There are only definitions for the files in the root of umd directory but not in ./parser and such:
Screenshot 2020-08-15 at 09 11 46

Creating .d.ts file for json parser

Hi,

we are currently using a forked version of the json parser in the YAML Language Server and we were wondering if we could create a .d.ts file for the json parser so that we can extend specific parts of it rather than having to fork it.

JSON 5 support

is it possible that monaco will support a json5 mode anytime soon? json5 is being used widely in many ecosystems, so it would be handy! https://github.com/json5/json5-vscode is in progress. Doesn't look like there is any language server implementation for JSON5 yet, hmmm...

Add tests for hover contributions

The current tests use schema contributions to test various schema features.

However there are no tests for hover contributions, which poses a problem if one wanted to write alternative hover providers.

The relevant code is here:

for (let i = this.contributions.length - 1; i >= 0; i--) {
const contribution = this.contributions[i];
const promise = contribution.getInfoContribution(document.uri, location);
if (promise) {
return promise.then(htmlContent => createHover(htmlContent));
}
}

defaultSnippets doesn't work with additionalProperties nor patternProperties

Snippets are not offered when defined inside additionalProperties or patternProperties, which is kinda big deal when you need a bit more complex structure, but still allow unlimited (just unique) parameter names.

Screenshots of current behavior:

image

image

Test schema ./simple.schema.json:

{
  "$schema": "http://json-schema.org/draft-07/schema#",

  "allowComments": true,
  "allowTrailingCommas": true,

  "definitions": {
    "element": {
      "type": "object",
      "properties": { "type": { "enum": ["image", "link"] } },
      "required": ["type"],
      "allOf": [
        {
          "if": {
            "required": ["type"],
            "properties": { "type": { "const": "input" } }
          },
          "then": {
            "properties": {
              "type": true,
              "width": { "type": "number" },
              "height": { "type": "number" }
            },
            "required": ["width", "height"]
          }
        },
        {
          "if": {
            "required": ["type"],
            "properties": { "type": { "const": "link" } }
          },
          "then": {
            "properties": {
              "type": true,
              "url": { "type": "string" }
            },
            "required": ["url"]
          }
        }
      ],

      "defaultSnippets": [
        {
          "label": "image",
          "description": "Add image",
          "body": {
            "type": "image",
            "width": "^${1:100}",
            "height": "^${2:100}"
          }
        },
        {
          "label": "link",
          "description": "Add link",
          "body": {
            "type": "link",
            "url": "${1:https://github.com}"
          }
        }
      ]
    }
  },

  "type": "object",
  "properties": {
    "$schema": { "type": "string" },
    "properties_test": {
      "description": "properties test",
      "$ref": "#/definitions/element"
    }
  },
  "patternProperties": {
    "^pattern_": {
      "description": "patternProperties test",
      "$ref": "#/definitions/element"
    }
  },
  "additionalProperties": {
    "description": "additionalProperties test",
    "$ref": "#/definitions/element"
  }
}

Update to JSON schema draft 6

It would be awesome if the JSON language service could be updated to support a newer draft of JSON schema.

See YousefED/typescript-json-schema#156 (comment)

Json-schema.org will soon be moving projects that do not support at least draft-06 to an "obsolete" or "older" implementations page. The main implementations page will promote implementations of draft06, draft-07, and future drafts.

requestService is undefined in JSONWorker

I'm trying to create two editors on same page, which uses schema validation. I have set the schemas like

monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
        validate: true,
        schemas: schemas
});

Where schemas is an array of

{
    uri: 'http://server/foo.json',
    fileMatch: ['http://server/foo.json'],
    schema: {
    }
}

Then I construct the editor by providing model

 var monacoModel = monaco.editor.getModel('http://server/foo.json');
  monacoModel = monacoModel || monaco.editor.createModel('{}', 'json', 'http://server/foo.json');

 var editor1 = monaco.editor.create(document.getElementById('editor-container-123'), {
            model: monacoModel,
            language: 'json',
}

Now when I construct second editor for a different URI, resetSchema event is fired; which internally clears schema provided through setDiagnosticsOptions for the given URI. Now as there is no unresolvedSchema for current URI, it tries to download it by calling loadSchema function. In this function this.requestService is undefined and hence I get the error No schema request service available

I didn't find anything on how can I set this.requestService. I have found that there is an import done for SchemaRequestService in jsonSchemaService.ts.

I tried to do this on playground, and it failed there also, with the same error.

If I delete following lines from clearSchema, everything works fine.

 this.resolvedSchema = null,
 this.unresolvedSchema = null

but don't know it's impact.

Thanks for the help.

Question: how to leverage JSON validation and syntax highlight

Hi, I am writing an VSCode extension for a definition language which is based on JSON format, add some grammar and the file extension is still *.json. Once I create a new language id for this new language, the existing JSON syntax highlight and basic validation disappears. Is there any way to leverage JSON syntax highlight, bracket auto-close and JSON format validation in my VSCode extension? Is there any document or example to follow?

Hover fails on json file containing only string

Steps for easiest reproduction:

  • open a new vscode editor
  • change format to JSON
  • insert ""
  • move mouse over ""
[Error - <TIME>] Error while computing hover for untitled:Untitled-1: Cannot read property 'type' of null
TypeError: Cannot read property 'type' of null
    at JSONHover.doHover (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\node_modules\vscode-json-languageservice\lib\umd\services\jsonHover.js:35:28)
    at Object.<anonymous> (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:318:55)
    at step (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:36:23)
    at Object.next (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:17:53)
    at c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:11:71
    at new Promise (<anonymous>)
    at __awaiter (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:7:12)
    at c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\jsonServerMain.js:312:55
    at Immediate._onImmediate (c:\Program Files\Microsoft VS Code Insiders\resources\app\extensions\json-language-features\server\out\utils\runner.js:28:20)
    at runCallback (timers.js:789:20)

The stack trace starts at https://github.com/Microsoft/vscode-json-languageservice/blob/99ef3f087b849f53a3d776e7701a0a10a07aa107/src/services/jsonHover.ts#L39.

A simple fix would be to change the if to:

if (parent && parent.type === 'property' && parent.keyNode === node) {...}

However, maybe it would be better to use a non-string node for properties keys anyway (I don't know this codebase, so maybe that's stupid).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.