v8r
v8r copied to clipboard
Check `$schema` key inside the document to know what schema to validate against
Sometimes there are files where multiple schemas from the catalogue might match, e.g. a manifest.json file:
ℹ Processing ./src/manifest.json
ℹ Cache hit: using cached response from https://www.schemastore.org/api/json/catalog.json
ℹ Cache hit: using cached response from https://json.schemastore.org/schema-catalog.json
ℹ Searching for schema in https://www.schemastore.org/api/json/catalog.json ...
ℹ Found multiple possible matches for ./src/manifest.json. Possible matches:
Foxx Manifest
ArangoDB Foxx service manifest file
https://json.schemastore.org/foxx-manifest.json
UI5 Manifest
UI5 Manifest (manifest.json)
https://raw.githubusercontent.com/SAP/ui5-manifest/master/schema.json
WebExtensions
WebExtension manifest files
https://json.schemastore.org/webextension.json
Web App Manifest
Web Application manifest file
https://json.schemastore.org/web-manifest-combined.json
✖ Found multiple possible schemas to validate ./src/manifest.json
As I also depend on JSON schemas when editing these type of files, I often supply a specific $schema within the file so VSCode can manage. See the following screenshots showing how VSCode is warning me about all the keys before I add $schema:
- Can v8r break ties based on the
$schemamember? - Should v8r go as far as to prefer the explicit
$schemamember over the catalogue?
In case of 2, it could save the entire round trip to schemastore.org. If all files in a repository include $schema it will not need to check a catalogue at all.
As an aside to this, it would be really nice if $schema was allowed by the v8r config schema. This would then allow the schema to be used by the code editor by doing something like the following:
{
"$schema": "./node_modules/v8r/config-schema.json",
"customCatalog": {
"schemas": [
{
"name": "JSON schema for WebExtensions manifest files",
"fileMatch": [
"manifest.json"
],
"location": "https://json.schemastore.org/webextension.json"
}
]
}
}
Currently this cannot be done as v8r (correctly) validates its config file before using it, leading to an additional properties error because of $schema:
/Users/Zegnat/path/.v8rrc.json# must NOT have additional properties
If you've got files where SchemaStore doesn't know how to validate them, you can use a custom catalog to tell v8r which schemas to use for which files. This can either be a standalone catalog https://chris48s.github.io/v8r/usage-examples/#using-a-custom-catlog or you can do it in the config file https://chris48s.github.io/v8r/configuration/ So there is a way to solve the case where there are multiple possible matches in schemastore.
This idea of files that contain a $schema key has come up once before a few years ago in https://github.com/chris48s/v8r/pull/129 I asked some follow up questions but the original poster never responded so it never went anywhere. Maybe you have some info on how widespread this is or resources I could look at.
Thanks for linking the closed PR. I had looked through the repo before, but clearly still managed to somehow miss that one.
I am not sure how wide-spread the usage is. Like I described above, I mostly do it because it makes VSCode’s linting work and delivers auto-complete. It would not surprise me if this is how most people use it, which might be hard to track.
I will do some discovery work this weekend and see if I can find any projects that explicitly use or call out the use of $schema and then report back. Probably better to have this as an issue for discussing than immediately jump to a PR.
After reading into this more, I think the use of $schema as a property on non-schema documents does not have a very clear origin. Or at least I have not been able to find one. It is definitely not something that came from the JSON Schema specifications. As such, I am now less inclined to push for v8r to make special concessions for it.
Mostly people discuss it in combination with talk of their IDEs helping through auto-complete / intellisense. And here it might have been Microsoft that has been pushing this convention the most. Back in 2014 they already added $schema for Visual Studio 2013, before Visual Studio Code (VSCode) had even launched. So it is not surprising that Microsoft also maintains the JSON language server within VSCode and the “smarts behind” it to follow the convention that they have set.
The VSCode documentation for JSON schemas and settings still recommends mapping a schema with a $schema key in the JSON. But it also offers a few other ways to configure the IDE through settings files.
As these settings files allow for schemas to be defined with a fileMatch array of globs as well as a url property, it might actually be possible to use the VSCode settings as custom catalogues after a little pre-processing. That will be my next focus. I would prefer not to have to create both a custom Schema Catalog and duplicate that data within my VSCode settings file.
Although I would personally still like to see config-schema.json expanded to explicitly allow a $schema property in the same way the schema for JSON Catalogs does. Just so it allows people who like the convention to use it.
Sharing my current solution here, to see if people have other ideas.
I have a .vscode/settings.json file that defines the schema for my WebExtensions manifest (an example JSON file where multiple schemas would otherwise match):
{
"json.schemas": [
{
"fileMatch": ["src/manifest.json"],
"url": "https://json.schemastore.org/webextension.json"
}
]
}
I also have a .v8rrc.json file that makes sure I validate all JSON files in my project that are not something I do not control:
{
"patterns": ["./!(package-lock)*.json", "./!(node_modules|.vscode)/**/*.json"]
}
My package.json includes a script to lint (validate) all my JSON files with v8r:
{
"scripts": {
"lint": "run-p --print-label --continue-on-error lint:**",
"lint:json": "bash v8r.sh"
}
}
Previously this script would just run v8r, but now I am using a bash script to make sure the schemas I define within .vscode/settings.json are picked up as an alternative catalogue:
#!/usr/bin/env bash
tempfile=$(mktemp)
jq '{
"$schema": "https://json.schemastore.org/schema-catalog.json",
"version": 1,
"schemas": [."json.schemas"[] | . + { "name": .url, "description": .url }]
}' ./.vscode/settings.json >"$tempfile"
if [ -f "$tempfile" ]; then
npm exec -- v8r -c "$tempfile"
rm "$tempfile"
else
echo "Error: Failed to create temporary file."
exit 1
fi
I am not sure if I really like going via Bash and jq. It is a very light shell script, but it does introduce some dependencies outside of the npm ecosystem and put some minor portability constraints on the repository. For now I will be using this to see how I like it, as it ticks all the boxes:
- No need for
$schemain documents that do not support it, depend on VSCode’s own settings. - Able to validate all JSON documents in the repository, based on schemas VSCode know about.
- No repitition of settings.
I was looking for this exact question myself, @Zegnat . Thank you for mentioning the custom catalog approach -- I wouldn't have thought about that.
My use-case is that I'm writing a plugin for MegaLinter and I would like to be able to validate the YAML plugin configuration file. I, too, was thinking about a $schema approach in the plugin file; as it is, I'm currently using v8r -s "https://url/to.the/JSON.schema" "./file-to-validate.yml" approach and that's working just fine.
As an alternative to the configuration / catalog approach, my other thought was to include a test file that would run the above command.
Thank you for your feedback, @chris48s . It's very helpful!
Minor update on this, which is v8r 4.3.0 no longer rejects config files containing a $schema property
Nice update, this means I can make use of the language server features of VSCode for the v8r config file! Thank you for considering this.
I am also interested using this. I have been decorating all of my yaml files for my k8s repo with the schema that I want to validate the files against.