mirror of
https://github.com/danbulant/monaco-yaml
synced 2026-06-18 14:01:07 +00:00
Merge pull request #97 from remcohaszing/schemastore-example
Let demo users select a schema from schema store
This commit is contained in:
commit
b4ffefc00f
9 changed files with 159 additions and 71 deletions
|
|
@ -8,6 +8,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@schemastore/schema-catalog": "^0.0.5",
|
||||
"css-loader": "^6.2.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ nav {
|
|||
margin: 1.5rem;
|
||||
}
|
||||
|
||||
#schema-selection {
|
||||
background-color: var(--editor-background);
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--shadow-color);
|
||||
color: var(--foreground-color);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#breadcrumbs {
|
||||
border-bottom: 1px solid var(--shadow-color);
|
||||
color: var(--foreground-color);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
</div>
|
||||
</nav>
|
||||
<div class="editor-wrapper">
|
||||
<div>
|
||||
<select id="schema-selection">
|
||||
<option value="monaco-yaml.yaml">Monaco YAML example</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="breadcrumbs"></div>
|
||||
<div id="editor"></div>
|
||||
<div id="problems"></div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import './index.css';
|
||||
|
||||
import { JSONSchemaForSchemaStoreOrgCatalogFiles } from '@schemastore/schema-catalog';
|
||||
import { CancellationToken } from 'monaco-editor/esm/vs/base/common/cancellation';
|
||||
import { getDocumentSymbols } from 'monaco-editor/esm/vs/editor/contrib/documentSymbols/documentSymbols';
|
||||
import {
|
||||
|
|
@ -8,13 +9,16 @@ import {
|
|||
languages,
|
||||
Position,
|
||||
Range,
|
||||
Uri,
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { setDiagnosticsOptions } from 'monaco-yaml';
|
||||
import { SchemasSettings, setDiagnosticsOptions } from 'monaco-yaml';
|
||||
|
||||
// NOTE: This will give you all editor featues. If you would prefer to limit to only the editor
|
||||
// features you want to use, import them each individually. See this example: (https://github.com/microsoft/monaco-editor-samples/blob/main/browser-esm-webpack-small/index.js#L1-L91)
|
||||
import 'monaco-editor';
|
||||
|
||||
import defaultSchemaUri from './schema.json';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
MonacoEnvironment: Environment;
|
||||
|
|
@ -34,63 +38,18 @@ window.MonacoEnvironment = {
|
|||
},
|
||||
};
|
||||
|
||||
const defaultSchema: SchemasSettings = {
|
||||
uri: defaultSchemaUri,
|
||||
fileMatch: ['monaco-yaml.yaml'],
|
||||
};
|
||||
|
||||
setDiagnosticsOptions({
|
||||
validate: true,
|
||||
enableSchemaRequest: true,
|
||||
format: true,
|
||||
hover: true,
|
||||
completion: true,
|
||||
schemas: [
|
||||
{
|
||||
// Id of the first schema
|
||||
uri: 'https://example.com/example-schema.json',
|
||||
// Associate with our model
|
||||
fileMatch: ['*'],
|
||||
schema: {
|
||||
// Id of the first schema
|
||||
id: 'https://example.com/example-schema.json',
|
||||
type: 'object',
|
||||
properties: {
|
||||
property: {
|
||||
description: 'I have a description',
|
||||
},
|
||||
titledProperty: {
|
||||
title: 'I have a title',
|
||||
description: 'I also have a description',
|
||||
},
|
||||
markdown: {
|
||||
markdownDescription: 'Even **markdown** _descriptions_ `are` ~~not~~ supported!',
|
||||
},
|
||||
enum: {
|
||||
description: 'Pick your starter',
|
||||
enum: ['Bulbasaur', 'Squirtle', 'Charmander', 'Pikachu'],
|
||||
},
|
||||
number: {
|
||||
description: 'Numbers work!',
|
||||
minimum: 42,
|
||||
maximum: 1337,
|
||||
},
|
||||
boolean: {
|
||||
description: 'Are boolean supported?',
|
||||
type: 'boolean',
|
||||
},
|
||||
string: {
|
||||
type: 'string',
|
||||
},
|
||||
reference: {
|
||||
description: 'JSON schemas can be referenced, even recursively',
|
||||
$ref: 'https://example.com/example-schema.json',
|
||||
},
|
||||
array: {
|
||||
description: 'It also works in arrays',
|
||||
items: {
|
||||
$ref: 'https://example.com/example-schema.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
schemas: [defaultSchema],
|
||||
});
|
||||
|
||||
const value = `
|
||||
|
|
@ -152,11 +111,50 @@ formatting: Formatting is supported too! Under the hood this is powered by
|
|||
|
||||
const ed = editor.create(document.getElementById('editor'), {
|
||||
automaticLayout: true,
|
||||
value,
|
||||
language: 'yaml',
|
||||
model: editor.createModel(value, 'yaml', Uri.parse('monaco-yaml.yaml')),
|
||||
theme: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'vs-dark' : 'vs-light',
|
||||
});
|
||||
|
||||
const select = document.getElementById('schema-selection') as HTMLSelectElement;
|
||||
|
||||
fetch('https://www.schemastore.org/api/json/catalog.json').then(async (response) => {
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
const catalog: JSONSchemaForSchemaStoreOrgCatalogFiles = await response.json();
|
||||
const schemas = [defaultSchema];
|
||||
catalog.schemas.sort((a, b) => a.name.localeCompare(b.name));
|
||||
for (const { fileMatch, name, url } of catalog.schemas) {
|
||||
const match =
|
||||
typeof name === 'string' && fileMatch?.find((filename) => /\.ya?ml$/i.test(filename));
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
const option = document.createElement('option');
|
||||
option.value = match;
|
||||
|
||||
option.textContent = name;
|
||||
select.append(option);
|
||||
schemas.push({
|
||||
fileMatch: [match],
|
||||
uri: url,
|
||||
});
|
||||
}
|
||||
|
||||
setDiagnosticsOptions({
|
||||
validate: true,
|
||||
enableSchemaRequest: true,
|
||||
format: true,
|
||||
hover: true,
|
||||
completion: true,
|
||||
schemas,
|
||||
});
|
||||
});
|
||||
|
||||
select.addEventListener('change', () => {
|
||||
ed.setModel(editor.createModel(ed.getValue(), 'yaml', Uri.parse(select.value)));
|
||||
});
|
||||
|
||||
function* iterateSymbols(
|
||||
symbols: languages.DocumentSymbol[],
|
||||
position: Position,
|
||||
|
|
|
|||
41
examples/demo/src/schema.json
Normal file
41
examples/demo/src/schema.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"property": {
|
||||
"description": "I have a description"
|
||||
},
|
||||
"titledProperty": {
|
||||
"title": "I have a title",
|
||||
"description": "I also have a description"
|
||||
},
|
||||
"markdown": {
|
||||
"markdownDescription": "Even **markdown** _descriptions_ `are` ~~not~~ supported!"
|
||||
},
|
||||
"enum": {
|
||||
"description": "Pick your starter",
|
||||
"enum": ["Bulbasaur", "Squirtle", "Charmander", "Pikachu"]
|
||||
},
|
||||
"number": {
|
||||
"description": "Numbers work!",
|
||||
"minimum": 42,
|
||||
"maximum": 1337
|
||||
},
|
||||
"boolean": {
|
||||
"description": "Are boolean supported?",
|
||||
"type": "boolean"
|
||||
},
|
||||
"string": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"description": "JSON schemas can be referenced, even recursively",
|
||||
"$ref": "#"
|
||||
},
|
||||
"array": {
|
||||
"description": "It also works in arrays",
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
examples/demo/src/types.d.ts
vendored
Normal file
4
examples/demo/src/types.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
declare module '*.json' {
|
||||
declare const uri;
|
||||
export default uri;
|
||||
}
|
||||
|
|
@ -22,7 +22,11 @@ module.exports = {
|
|||
{
|
||||
// Monaco editor uses .ttf icons.
|
||||
test: /\.(svg|ttf)$/,
|
||||
type: 'asset',
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /schema\.json$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
|
|
|
|||
39
index.d.ts
vendored
39
index.d.ts
vendored
|
|
@ -1,6 +1,29 @@
|
|||
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
|
||||
import { IEvent, languages } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
|
||||
export interface SchemasSettings {
|
||||
/**
|
||||
* A `Uri` file match which will trigger the schema validation. This may be a glob or an exact
|
||||
* path.
|
||||
*
|
||||
* @example '.gitlab-ci.yml'
|
||||
* @example 'file://**\/.github/actions/*.yaml'
|
||||
*/
|
||||
fileMatch: string[];
|
||||
|
||||
/**
|
||||
* The JSON schema which will be used for validation. If not specified, it will be downloaded from
|
||||
* `uri`.
|
||||
*/
|
||||
schema?: JSONSchema4 | JSONSchema6 | JSONSchema7;
|
||||
|
||||
/**
|
||||
* The source URI of the JSON schema. The JSON schema will be downloaded from here if no schema
|
||||
* was supplied. It will also be displayed as the source in hover tooltips.
|
||||
*/
|
||||
uri: string;
|
||||
}
|
||||
|
||||
declare module 'monaco-editor/esm/vs/editor/editor.api' {
|
||||
namespace languages.yaml {
|
||||
export interface DiagnosticsOptions {
|
||||
|
|
@ -23,21 +46,7 @@ declare module 'monaco-editor/esm/vs/editor/editor.api' {
|
|||
/**
|
||||
* A list of known schemas and/or associations of schemas to file names.
|
||||
*/
|
||||
readonly schemas?: {
|
||||
/**
|
||||
* The URI of the schema, which is also the identifier of the schema.
|
||||
*/
|
||||
readonly uri: string;
|
||||
/**
|
||||
* A list of file names that are associated to the schema. The '*' wildcard can be used.
|
||||
* For example '*.schema.json', 'package.json'
|
||||
*/
|
||||
readonly fileMatch?: string[];
|
||||
/**
|
||||
* The schema for the given URI.
|
||||
*/
|
||||
readonly schema?: JSONSchema4 | JSONSchema6 | JSONSchema7;
|
||||
}[];
|
||||
readonly schemas?: SchemasSettings[];
|
||||
|
||||
/**
|
||||
* If set, the schema service would load schema content on-demand with 'fetch' if available
|
||||
|
|
|
|||
20
package-lock.json
generated
20
package-lock.json
generated
|
|
@ -42,6 +42,7 @@
|
|||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@schemastore/schema-catalog": "^0.0.5",
|
||||
"css-loader": "^6.2.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
|
|
@ -690,6 +691,11 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@schemastore/schema-catalog": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@schemastore/schema-catalog/-/schema-catalog-0.0.5.tgz",
|
||||
"integrity": "sha512-5+Xo5tNdgdQ6Q2otY3XSs1WZR8J1cYHAmGDDHbCk0C3Qx/ycD6r2Fpzz0X9UFjm/hsbZDBd9fh/xLqdIKzREew=="
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz",
|
||||
|
|
@ -11590,6 +11596,11 @@
|
|||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@schemastore/schema-catalog": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@schemastore/schema-catalog/-/schema-catalog-0.0.5.tgz",
|
||||
"integrity": "sha512-5+Xo5tNdgdQ6Q2otY3XSs1WZR8J1cYHAmGDDHbCk0C3Qx/ycD6r2Fpzz0X9UFjm/hsbZDBd9fh/xLqdIKzREew=="
|
||||
},
|
||||
"@trysound/sax": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz",
|
||||
|
|
@ -13368,6 +13379,7 @@
|
|||
"version": "file:examples/demo",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@schemastore/schema-catalog": "*",
|
||||
"css-loader": "^6.2.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
|
|
@ -16139,7 +16151,7 @@
|
|||
"monaco-editor": "^0.27.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"prettier": "2.0.5",
|
||||
"type-fest": "*",
|
||||
"type-fest": "^2.1.0",
|
||||
"typescript": "^4.3.5",
|
||||
"vscode-languageserver-textdocument": "^1.0.1",
|
||||
"vscode-languageserver-types": "^3.16.0",
|
||||
|
|
@ -16649,6 +16661,11 @@
|
|||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@schemastore/schema-catalog": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@schemastore/schema-catalog/-/schema-catalog-0.0.5.tgz",
|
||||
"integrity": "sha512-5+Xo5tNdgdQ6Q2otY3XSs1WZR8J1cYHAmGDDHbCk0C3Qx/ycD6r2Fpzz0X9UFjm/hsbZDBd9fh/xLqdIKzREew=="
|
||||
},
|
||||
"@trysound/sax": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.1.1.tgz",
|
||||
|
|
@ -18427,6 +18444,7 @@
|
|||
"version": "file:examples/demo",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@schemastore/schema-catalog": "*",
|
||||
"css-loader": "^6.2.0",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
|
|
|
|||
Loading…
Reference in a new issue