codemirror-json-schema
Advanced tools
Comparing version 0.7.9 to 0.8.0
# codemirror-json-schema | ||
## 0.8.0 | ||
### Minor Changes | ||
- [#138](https://github.com/jsonnext/codemirror-json-schema/pull/138) [`aa27ad7`](https://github.com/jsonnext/codemirror-json-schema/commit/aa27ad740fec447069bacd1d817e1d32fbbf8d90) Thanks [@thomasjahoda](https://github.com/thomasjahoda)! - More robust conditional types support (thanks @thomasjahoda!) | ||
## 0.7.9 | ||
@@ -4,0 +10,0 @@ |
@@ -14,4 +14,4 @@ "use strict"; | ||
PROPERTY_NAME: "PropertyName", | ||
PROPERTY_COLON: "PropertyColon", | ||
ITEM: "Item", | ||
PROPERTY_COLON: "PropertyColon", // used in json5 grammar | ||
ITEM: "Item", // used in yaml grammar | ||
JSON_TEXT: "JsonText", | ||
@@ -31,3 +31,3 @@ INVALID: "⚠", | ||
QuotedLiteral: exports.TOKENS.STRING, | ||
Literal: exports.TOKENS.STRING, | ||
Literal: exports.TOKENS.STRING, // best guess | ||
Stream: exports.TOKENS.JSON_TEXT, | ||
@@ -34,0 +34,0 @@ Document: exports.TOKENS.OBJECT, |
@@ -10,3 +10,12 @@ import { CompletionContext, CompletionResult } from "@codemirror/autocomplete"; | ||
private opts; | ||
private originalSchema; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
*/ | ||
private schema; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
* Does not contain any required properties and allows any additional properties everywhere. | ||
*/ | ||
private laxSchema; | ||
private mode; | ||
@@ -16,2 +25,3 @@ private parser; | ||
doComplete(ctx: CompletionContext): never[] | CompletionResult; | ||
private doCompleteForSchema; | ||
private applySnippetCompletion; | ||
@@ -33,4 +43,2 @@ private getPropertyCompletions; | ||
private getSchemas; | ||
private expandSchemaProperty; | ||
private getReferenceSchema; | ||
private getAppliedValue; | ||
@@ -37,0 +45,0 @@ private getValueFromLabel; |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.jsonCompletion = exports.JSONCompletion = void 0; | ||
exports.JSONCompletion = void 0; | ||
exports.jsonCompletion = jsonCompletion; | ||
const autocomplete_1 = require("@codemirror/autocomplete"); | ||
@@ -15,2 +27,3 @@ const language_1 = require("@codemirror/language"); | ||
const parsers_1 = require("../parsers"); | ||
const recordUtil_1 = require("../utils/recordUtil"); | ||
class CompletionCollector { | ||
@@ -31,7 +44,23 @@ constructor() { | ||
} | ||
function isRealSchema(subSchema) { | ||
return !(!subSchema || | ||
(0, json_schema_library_1.isJsonError)(subSchema) || | ||
subSchema.name === "UnknownPropertyError" || | ||
subSchema.type === "undefined"); | ||
} | ||
class JSONCompletion { | ||
// private lastKnownValidData: object | null = null; | ||
constructor(opts) { | ||
var _a, _b, _c; | ||
this.opts = opts; | ||
this.originalSchema = null; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
*/ | ||
this.schema = null; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
* Does not contain any required properties and allows any additional properties everywhere. | ||
*/ | ||
this.laxSchema = null; | ||
this.mode = constants_1.MODES.JSON; | ||
@@ -42,6 +71,11 @@ this.mode = (_a = opts.mode) !== null && _a !== void 0 ? _a : constants_1.MODES.JSON; | ||
doComplete(ctx) { | ||
var _a, _b, _c; | ||
const s = (0, state_1.getJSONSchema)(ctx.state); | ||
this.schema = (_a = this.expandSchemaProperty(s, s)) !== null && _a !== void 0 ? _a : s; | ||
if (!this.schema) { | ||
var _a; | ||
const schemaFromState = (0, state_1.getJSONSchema)(ctx.state); | ||
if (this.originalSchema !== schemaFromState) { | ||
// only process schema when it changed (could be huge) | ||
this.schema = | ||
(_a = expandSchemaProperty(schemaFromState, schemaFromState)) !== null && _a !== void 0 ? _a : schemaFromState; | ||
this.laxSchema = makeSchemaLax(this.schema); | ||
} | ||
if (!this.schema || !this.laxSchema) { | ||
// todo: should we even do anything without schema | ||
@@ -51,2 +85,14 @@ // without taking over the existing mode responsibilties? | ||
} | ||
// first attempt to complete with the original schema | ||
debug_1.debug.log("xxx", "trying with original schema"); | ||
const completionResultForOriginalSchema = this.doCompleteForSchema(ctx, this.schema); | ||
if (completionResultForOriginalSchema.options.length !== 0) { | ||
return completionResultForOriginalSchema; | ||
} | ||
// if there are no completions, try with the lax schema (because json-schema-library would otherwise not provide schemas if invalid properties are present) | ||
debug_1.debug.log("xxx", "no completions with original schema, trying with lax schema"); | ||
return this.doCompleteForSchema(ctx, this.laxSchema); | ||
} | ||
doCompleteForSchema(ctx, rootSchema) { | ||
var _a, _b; | ||
const result = { | ||
@@ -84,3 +130,3 @@ from: ctx.pos, | ||
result.from = | ||
node.name === constants_1.TOKENS.INVALID ? (_b = word === null || word === void 0 ? void 0 : word.from) !== null && _b !== void 0 ? _b : ctx.pos : overwriteStart; | ||
node.name === constants_1.TOKENS.INVALID ? ((_a = word === null || word === void 0 ? void 0 : word.from) !== null && _a !== void 0 ? _a : ctx.pos) : overwriteStart; | ||
result.to = ctx.pos; | ||
@@ -113,3 +159,3 @@ } | ||
// find object node | ||
node = (_c = (0, node_1.getClosestNode)(parent, constants_1.TOKENS.OBJECT, this.mode)) !== null && _c !== void 0 ? _c : null; | ||
node = (_b = (0, node_1.getClosestNode)(parent, constants_1.TOKENS.OBJECT, this.mode)) !== null && _b !== void 0 ? _b : null; | ||
} | ||
@@ -129,3 +175,3 @@ } | ||
// property proposals with schema | ||
this.getPropertyCompletions(this.schema, ctx, node, collector, addValue, rawWord); | ||
this.getPropertyCompletions(rootSchema, ctx, node, collector, addValue, rawWord); | ||
} | ||
@@ -136,3 +182,3 @@ else { | ||
// value proposals with schema | ||
const res = this.getValueCompletions(this.schema, ctx, types, collector); | ||
const res = this.getValueCompletions(rootSchema, ctx, types, collector); | ||
debug_1.debug.log("xxx", "getValueCompletions res", res); | ||
@@ -156,3 +202,3 @@ if (res) { | ||
} | ||
getPropertyCompletions(schema, ctx, node, collector, addValue, rawWord) { | ||
getPropertyCompletions(rootSchema, ctx, node, collector, addValue, rawWord) { | ||
// don't suggest properties that are already present | ||
@@ -167,3 +213,3 @@ const properties = (0, node_1.getMatchingChildrenNodes)(node, constants_1.TOKENS.PROPERTY, this.mode); | ||
// Get matching schemas | ||
const schemas = this.getSchemas(schema, ctx); | ||
const schemas = this.getSchemas(rootSchema, ctx); | ||
debug_1.debug.log("xxx", "propertyCompletion schemas", schemas); | ||
@@ -185,3 +231,3 @@ schemas.forEach((s) => { | ||
label: key, | ||
apply: this.getInsertTextForProperty(key, addValue, rawWord, value), | ||
apply: this.getInsertTextForProperty(key, addValue, rawWord, rootSchema, value), | ||
type: "property", | ||
@@ -205,3 +251,3 @@ detail: typeStr, | ||
label, | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord), | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord, rootSchema), | ||
type: "property", | ||
@@ -217,3 +263,3 @@ }; | ||
label, | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord), | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord, rootSchema), | ||
type: "property", | ||
@@ -237,6 +283,6 @@ }; | ||
// idea: https://discuss.codemirror.net/t/autocomplete-cursor-position-in-apply-function/4088/3 | ||
getInsertTextForProperty(key, addValue, rawWord, propertySchema) { | ||
getInsertTextForProperty(key, addValue, rawWord, rootSchema, propertySchema) { | ||
// expand schema property if it is a reference | ||
propertySchema = propertySchema | ||
? this.expandSchemaProperty(propertySchema, this.schema) | ||
? expandSchemaProperty(propertySchema, rootSchema) | ||
: propertySchema; | ||
@@ -392,3 +438,3 @@ let resultText = this.getInsertTextForPropertyName(key, rawWord); | ||
} | ||
getValueCompletions(schema, ctx, types, collector) { | ||
getValueCompletions(rootSchema, ctx, types, collector) { | ||
let node = (0, language_1.syntaxTree)(ctx.state).resolveInner(ctx.pos, -1); | ||
@@ -403,3 +449,3 @@ let valueNode = null; | ||
if (!node) { | ||
this.addSchemaValueCompletions(schema, types, collector); | ||
this.addSchemaValueCompletions(rootSchema, types, collector); | ||
return; | ||
@@ -419,3 +465,3 @@ } | ||
// Get matching schemas | ||
const schemas = this.getSchemas(schema, ctx); | ||
const schemas = this.getSchemas(rootSchema, ctx); | ||
for (const s of schemas) { | ||
@@ -456,2 +502,5 @@ if (typeof s !== "object") { | ||
} | ||
if (s.type == null || s.type !== "object") { | ||
this.addSchemaValueCompletions(s, types, collector); | ||
} | ||
if (parentKey !== undefined) { | ||
@@ -504,3 +553,6 @@ let propertyMatched = false; | ||
} | ||
addSchemaValueCompletions(schema, types, collector) { | ||
addSchemaValueCompletions(schema, | ||
// TODO this is buggy because it does not resolve refs, should hand down rootSchema and expand each ref | ||
// rootSchema: JSONSchema7, | ||
types, collector) { | ||
if (typeof schema === "object") { | ||
@@ -589,32 +641,62 @@ this.addEnumValueCompletions(schema, collector); | ||
} | ||
getSchemas(schema, ctx) { | ||
var _a, _b; | ||
const draft = new json_schema_library_1.Draft07(this.schema); | ||
getSchemas(rootSchema, ctx) { | ||
var _a, _b, _c; | ||
const { data: documentData } = this.parser(ctx.state); | ||
const draft = new json_schema_library_1.Draft07(rootSchema); | ||
let pointer = (0, json_pointers_1.jsonPointerForPosition)(ctx.state, ctx.pos, -1, this.mode); | ||
// Pass parsed data to getSchema to get the correct schema based on the data context | ||
const { data } = this.parser(ctx.state); | ||
// TODO make jsonPointer consistent and compatible with json-schema-library by default (root path '/' or ' ' or undefined or '#', idk) | ||
if (pointer === "") | ||
pointer = undefined; | ||
if (pointer != null && pointer.endsWith("/")) { | ||
// opening new property under pointer | ||
// the property name is empty but json-schema-library would puke itself with a trailing slash, so we shouldn't even call it with that | ||
pointer = pointer.substring(0, pointer.length - 1); | ||
// when adding a new property, we just wanna return the possible properties if possible | ||
const effectiveSchemaOfPointer = getEffectiveObjectWithPropertiesSchema(rootSchema, documentData, pointer); | ||
if (effectiveSchemaOfPointer != null) { | ||
return [effectiveSchemaOfPointer]; | ||
} | ||
} | ||
let parentPointer = pointer != null ? pointer.replace(/\/[^/]*$/, "") : undefined; | ||
if (parentPointer === "") | ||
parentPointer = undefined; | ||
// Pass parsed data to getSchema to get the correct schema based on the data context (e.g. for anyOf or if-then) | ||
const effectiveSchemaOfParent = getEffectiveObjectWithPropertiesSchema(rootSchema, documentData, parentPointer); | ||
const deepestPropertyKey = pointer === null || pointer === void 0 ? void 0 : pointer.split("/").pop(); | ||
const pointerPointsToKnownProperty = deepestPropertyKey == null || | ||
deepestPropertyKey in ((_a = effectiveSchemaOfParent === null || effectiveSchemaOfParent === void 0 ? void 0 : effectiveSchemaOfParent.properties) !== null && _a !== void 0 ? _a : {}); | ||
// TODO upgrade json-schema-library, so this actually returns undefined if data and schema are incompatible (currently it sometimes pukes itself with invalid data and imagines schemas on-the-fly) | ||
let subSchema = draft.getSchema({ | ||
pointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
data: documentData !== null && documentData !== void 0 ? documentData : undefined, | ||
}); | ||
debug_1.debug.log("xxxx", "draft.getSchema", subSchema, "data", data, "pointer", pointer); | ||
if (!pointerPointsToKnownProperty && | ||
(subSchema === null || subSchema === void 0 ? void 0 : subSchema.type) === "null" && | ||
this.mode === "yaml") { | ||
// TODO describe YAML special-case where null is given the value and json-schema-library simply makes up a new schema based on that null value for whatever reason | ||
subSchema = undefined; | ||
} | ||
debug_1.debug.log("xxxx", "draft.getSchema", subSchema, "data", documentData, "pointer", pointer, "pointerPointsToKnownProperty", pointerPointsToKnownProperty); | ||
if ((0, json_schema_library_1.isJsonError)(subSchema)) { | ||
subSchema = (_a = subSchema.data) === null || _a === void 0 ? void 0 : _a.schema; | ||
subSchema = (_b = subSchema.data) === null || _b === void 0 ? void 0 : _b.schema; | ||
} | ||
// if we don't have a schema for the current pointer, try the parent pointer | ||
if (!subSchema || | ||
subSchema.name === "UnknownPropertyError" || | ||
subSchema.enum || | ||
subSchema.type === "undefined" || | ||
subSchema.type === "null") { | ||
pointer = pointer.replace(/\/[^/]*$/, "/"); | ||
subSchema = draft.getSchema({ pointer }); | ||
// if we don't have a schema for the current pointer, try the parent pointer with data to get a list of possible properties | ||
if (!isRealSchema(subSchema)) { | ||
if (effectiveSchemaOfParent) { | ||
return [effectiveSchemaOfParent]; | ||
} | ||
} | ||
// then try the parent pointer without data | ||
if (!isRealSchema(subSchema)) { | ||
subSchema = draft.getSchema({ pointer: parentPointer }); | ||
// TODO should probably only change pointer if it actually found a schema there, but i left it as-is | ||
pointer = parentPointer; | ||
} | ||
debug_1.debug.log("xxx", "pointer..", JSON.stringify(pointer)); | ||
// For some reason, it returns undefined schema for the root pointer | ||
// We use the root schema in that case as the relevant (sub)schema | ||
if (!pointer || pointer === "/") { | ||
subSchema = (_b = this.expandSchemaProperty(schema, schema)) !== null && _b !== void 0 ? _b : schema; | ||
if (!isRealSchema(subSchema) && (!pointer || pointer === "/")) { | ||
subSchema = (_c = expandSchemaProperty(rootSchema, rootSchema)) !== null && _c !== void 0 ? _c : rootSchema; | ||
} | ||
// const subSchema = new Draft07(this.schema).getSchema(pointer); | ||
// const subSchema = new Draft07(this.dirtyCtx.rootSchema).getSchema(pointer); | ||
debug_1.debug.log("xxx", "subSchema..", subSchema); | ||
@@ -627,3 +709,3 @@ if (!subSchema) { | ||
subSchema, | ||
...subSchema.allOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.allOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -634,3 +716,3 @@ } | ||
subSchema, | ||
...subSchema.oneOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.oneOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -641,3 +723,3 @@ } | ||
subSchema, | ||
...subSchema.anyOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.anyOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -647,30 +729,2 @@ } | ||
} | ||
expandSchemaProperty(property, schema) { | ||
if (typeof property === "object" && property.$ref) { | ||
const refSchema = this.getReferenceSchema(schema, property.$ref); | ||
if (typeof refSchema === "object") { | ||
const dereferenced = Object.assign(Object.assign({}, property), refSchema); | ||
Reflect.deleteProperty(dereferenced, "$ref"); | ||
return dereferenced; | ||
} | ||
} | ||
return property; | ||
} | ||
getReferenceSchema(schema, ref) { | ||
const refPath = ref.split("/"); | ||
let curReference = schema; | ||
refPath.forEach((cur) => { | ||
if (!cur) { | ||
return; | ||
} | ||
if (cur === "#") { | ||
curReference = schema; | ||
return; | ||
} | ||
if (typeof curReference === "object") { | ||
curReference = curReference[cur]; | ||
} | ||
}); | ||
return curReference; | ||
} | ||
getAppliedValue(value) { | ||
@@ -731,2 +785,144 @@ const stripped = (0, node_1.stripSurroundingQuotes)(JSON.stringify(value)); | ||
} | ||
exports.jsonCompletion = jsonCompletion; | ||
/** | ||
* removes required properties and allows additional properties everywhere | ||
* @param schema | ||
*/ | ||
function makeSchemaLax(schema) { | ||
return (0, recordUtil_1.replacePropertiesDeeply)(schema, (key, value) => { | ||
if (key === "additionalProperties" && value === false) { | ||
return []; | ||
} | ||
if (key === "required" && Array.isArray(value)) { | ||
return []; | ||
} | ||
if (key === "unevaluatedProperties" && value === false) { | ||
return []; | ||
} | ||
if (key === "unevaluatedItems" && value === false) { | ||
return []; | ||
} | ||
// TODO remove dependencies and other restrictions | ||
// if (key === 'dependencies' && typeof value === 'object') { | ||
// return Object.keys(value).reduce((acc: any, depKey) => { | ||
// const depValue = value[depKey]; | ||
// if (Array.isArray(depValue)) { | ||
// return acc; | ||
// } | ||
// return { ...acc, [depKey]: depValue }; | ||
// }, {}); | ||
// } | ||
return [key, value]; | ||
}); | ||
} | ||
/** | ||
* determines effective object schema for given data | ||
* TODO support patternProperties, etc. | ||
* @param schema | ||
* @param data | ||
* @param pointer | ||
*/ | ||
function getEffectiveObjectWithPropertiesSchema(schema, data, pointer) { | ||
// TODO (unimportant): [performance] cache Draft07 in case it does some pre-processing? but does not seem to be significant | ||
const draft = new json_schema_library_1.Draft07(schema); | ||
const subSchema = draft.getSchema({ | ||
pointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
}); | ||
if (!isRealSchema(subSchema)) { | ||
return undefined; | ||
} | ||
const possibleDirectPropertyNames = getAllPossibleDirectStaticPropertyNames(draft, subSchema); | ||
const effectiveProperties = {}; | ||
for (let possibleDirectPropertyName of possibleDirectPropertyNames) { | ||
let propertyPointer = extendJsonPointer(pointer, possibleDirectPropertyName); | ||
const subSchemaForPropertyConsideringData = draft.getSchema({ | ||
// TODO [performance] use subSchema and only check it's sub-properties | ||
pointer: propertyPointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
// pointer: `/${possibleDirectPropertyName}`, | ||
// schema: subSchema | ||
}); | ||
if (isRealSchema(subSchemaForPropertyConsideringData)) { | ||
Object.assign(effectiveProperties, { | ||
[possibleDirectPropertyName]: subSchemaForPropertyConsideringData, | ||
}); | ||
} | ||
} | ||
if (possibleDirectPropertyNames.length === 0 || | ||
Object.keys(effectiveProperties).length === 0) { | ||
// in case json-schema-library behaves too weirdly and returns nothing, just return no schema too to let other cases handle this edge-case | ||
return undefined; | ||
} | ||
// TODO also resolve patternProperties of allOf, anyOf, oneOf | ||
const _a = subSchema, { allOf, anyOf, oneOf } = _a, subSchemaRest = __rest(_a, ["allOf", "anyOf", "oneOf"]); | ||
return Object.assign(Object.assign({}, subSchemaRest), { properties: effectiveProperties }); | ||
} | ||
/** | ||
* static means not from patternProperties | ||
* @param rootDraft | ||
* @param schema | ||
*/ | ||
function getAllPossibleDirectStaticPropertyNames(rootDraft, schema) { | ||
schema = expandSchemaProperty(schema, rootDraft.rootSchema); | ||
if (typeof schema !== "object" || schema == null) { | ||
return []; | ||
} | ||
const possiblePropertyNames = []; | ||
function addFrom(subSchema) { | ||
const possiblePropertyNamesOfSubSchema = getAllPossibleDirectStaticPropertyNames(rootDraft, subSchema); | ||
possiblePropertyNames.push(...possiblePropertyNamesOfSubSchema); | ||
} | ||
if (typeof schema.properties === "object" && schema.properties != null) { | ||
possiblePropertyNames.push(...Object.keys(schema.properties)); | ||
} | ||
if (typeof schema.then === "object" && schema.then != null) { | ||
addFrom(schema.then); | ||
} | ||
if (Array.isArray(schema.allOf)) { | ||
for (const subSchema of schema.allOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
if (Array.isArray(schema.anyOf)) { | ||
for (const subSchema of schema.anyOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
if (Array.isArray(schema.oneOf)) { | ||
for (const subSchema of schema.oneOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
return possiblePropertyNames; | ||
} | ||
function expandSchemaProperty(propertySchema, rootSchema) { | ||
if (typeof propertySchema === "object" && propertySchema.$ref) { | ||
const refSchema = getReferenceSchema(rootSchema, propertySchema.$ref); | ||
if (typeof refSchema === "object") { | ||
const dereferenced = Object.assign(Object.assign({}, propertySchema), refSchema); | ||
Reflect.deleteProperty(dereferenced, "$ref"); | ||
return dereferenced; | ||
} | ||
} | ||
return propertySchema; | ||
} | ||
function getReferenceSchema(schema, ref) { | ||
const refPath = ref.split("/"); | ||
let curReference = schema; | ||
refPath.forEach((cur) => { | ||
if (!cur) { | ||
return; | ||
} | ||
if (cur === "#") { | ||
curReference = schema; | ||
return; | ||
} | ||
if (typeof curReference === "object") { | ||
curReference = curReference[cur]; | ||
} | ||
}); | ||
return curReference; | ||
} | ||
function extendJsonPointer(pointer, key) { | ||
return pointer === undefined ? `/${key}` : `${pointer}/${key}`; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.JSONHover = exports.jsonSchemaHover = void 0; | ||
exports.JSONHover = void 0; | ||
exports.jsonSchemaHover = jsonSchemaHover; | ||
const json_schema_library_1 = require("json-schema-library"); | ||
@@ -22,3 +23,2 @@ const json_pointers_1 = require("../utils/json-pointers"); | ||
} | ||
exports.jsonSchemaHover = jsonSchemaHover; | ||
function formatType(data) { | ||
@@ -25,0 +25,0 @@ if (data.type) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.JSONValidation = exports.jsonSchemaLinter = exports.handleRefresh = void 0; | ||
exports.JSONValidation = exports.handleRefresh = void 0; | ||
exports.jsonSchemaLinter = jsonSchemaLinter; | ||
const json_schema_library_1 = require("json-schema-library"); | ||
@@ -40,3 +41,2 @@ const state_1 = require("./state"); | ||
} | ||
exports.jsonSchemaLinter = jsonSchemaLinter; | ||
// all the error types that apply to a specific key or value | ||
@@ -43,0 +43,0 @@ const positionalErrors = [ |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.jsonSchema = void 0; | ||
exports.jsonSchema = jsonSchema; | ||
const lang_json_1 = require("@codemirror/lang-json"); | ||
@@ -29,2 +29,1 @@ const view_1 = require("@codemirror/view"); | ||
} | ||
exports.jsonSchema = jsonSchema; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json5Schema = void 0; | ||
exports.json5Schema = json5Schema; | ||
const codemirror_json5_1 = require("codemirror-json5"); | ||
@@ -30,2 +30,1 @@ const view_1 = require("@codemirror/view"); | ||
} | ||
exports.json5Schema = json5Schema; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json5Completion = void 0; | ||
exports.json5Completion = json5Completion; | ||
const constants_1 = require("../constants"); | ||
@@ -16,2 +16,1 @@ const completion_1 = require("../features/completion"); | ||
} | ||
exports.json5Completion = json5Completion; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json5SchemaHover = void 0; | ||
exports.json5SchemaHover = json5SchemaHover; | ||
const hover_1 = require("../features/hover"); | ||
@@ -21,2 +21,1 @@ const json5_1 = __importDefault(require("json5")); | ||
} | ||
exports.json5SchemaHover = json5SchemaHover; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.json5SchemaLinter = void 0; | ||
exports.json5SchemaLinter = json5SchemaLinter; | ||
const validation_1 = require("../features/validation"); | ||
@@ -17,2 +17,1 @@ const constants_1 = require("../constants"); | ||
} | ||
exports.json5SchemaLinter = json5SchemaLinter; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseJSONDocument = exports.parseJSONDocumentState = void 0; | ||
exports.parseJSONDocumentState = parseJSONDocumentState; | ||
exports.parseJSONDocument = parseJSONDocument; | ||
const lang_json_1 = require("@codemirror/lang-json"); | ||
@@ -28,3 +29,2 @@ const state_1 = require("@codemirror/state"); | ||
} | ||
exports.parseJSONDocumentState = parseJSONDocumentState; | ||
/** | ||
@@ -38,2 +38,1 @@ * Mimics the behavior of `json-source-map`'s `parseJSONDocument` function using codemirror EditorState | ||
} | ||
exports.parseJSONDocument = parseJSONDocument; |
@@ -9,3 +9,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseJSON5Document = exports.parseJSON5DocumentState = void 0; | ||
exports.parseJSON5DocumentState = parseJSON5DocumentState; | ||
exports.parseJSON5Document = parseJSON5Document; | ||
const codemirror_json5_1 = require("codemirror-json5"); | ||
@@ -22,12 +23,15 @@ const json5_1 = __importDefault(require("json5")); | ||
function parseJSON5DocumentState(state) { | ||
const stateDoc = state.doc.toString(); | ||
let data = null; | ||
try { | ||
data = json5_1.default.parse(state.doc.toString()); | ||
// return pointers regardless of whether JSON.parse succeeds | ||
data = json5_1.default.parse(stateDoc); | ||
} | ||
catch (_a) { | ||
// try again with best-effort strategy | ||
try { | ||
data = (0, best_effort_json_parser_1.parse)(state.doc.toString()); | ||
data = (0, best_effort_json_parser_1.parse)(stateDoc); | ||
} | ||
catch (_b) { } | ||
catch (_b) { | ||
// return pointers regardless of whether JSON.parse succeeds | ||
} | ||
} | ||
@@ -37,3 +41,2 @@ const pointers = (0, json_pointers_1.getJsonPointers)(state, constants_1.MODES.JSON5); | ||
} | ||
exports.parseJSON5DocumentState = parseJSON5DocumentState; | ||
/** | ||
@@ -50,2 +53,1 @@ * Mimics the behavior of `json-source-map`'s `parseJSONDocument` function, for json5! | ||
} | ||
exports.parseJSON5Document = parseJSON5Document; |
@@ -9,3 +9,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseYAMLDocumentState = void 0; | ||
exports.parseYAMLDocumentState = parseYAMLDocumentState; | ||
const yaml_1 = __importDefault(require("yaml")); | ||
@@ -28,2 +28,1 @@ const json_pointers_1 = require("../utils/json-pointers"); | ||
} | ||
exports.parseYAMLDocumentState = parseYAMLDocumentState; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.el = void 0; | ||
exports.el = el; | ||
function el(tagName, attributes, children = []) { | ||
@@ -20,2 +20,1 @@ const e = document.createElement(tagName); | ||
} | ||
exports.el = el; |
@@ -1,1 +0,1 @@ | ||
export declare const joinWithOr: (arr: string[], getPath?: ((err: any) => any) | undefined) => string; | ||
export declare const joinWithOr: (arr: string[], getPath?: (err: any) => any) => string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getJsonPointers = exports.jsonPointerForPosition = exports.getJsonPointerAt = exports.resolveTokenName = void 0; | ||
exports.getJsonPointers = exports.jsonPointerForPosition = exports.resolveTokenName = void 0; | ||
exports.getJsonPointerAt = getJsonPointerAt; | ||
const language_1 = require("@codemirror/language"); | ||
@@ -28,3 +29,7 @@ const constants_1 = require("../constants"); | ||
if (name) { | ||
path.unshift((0, node_1.getWord)(docText, name).replace(/[/~]/g, (v) => v === "~" ? "~0" : "~1")); | ||
let word = (0, node_1.getWord)(docText, name).replace(/[/~]/g, (v) => v === "~" ? "~0" : "~1"); | ||
// TODO generally filter out pointers to objects being started? | ||
// if (word !== '') { | ||
path.unshift(word); | ||
// } | ||
} | ||
@@ -42,6 +47,8 @@ break; | ||
} | ||
path.unshift(""); | ||
return path.join("/"); | ||
if (path.length === 0) { | ||
// TODO json-schema-library does not seem to like / as root pointer (it probably just uses split and it will return two empty strings). So is this fine? And why is it not prefixed with #? | ||
return ""; | ||
} | ||
return "/" + path.join("/"); | ||
} | ||
exports.getJsonPointerAt = getJsonPointerAt; | ||
/** | ||
@@ -48,0 +55,0 @@ * retrieve a JSON pointer for a given position in the editor |
@@ -18,9 +18,19 @@ "use strict"; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importStar = (this && this.__importStar) || (function () { | ||
var ownKeys = function(o) { | ||
ownKeys = Object.getOwnPropertyNames || function (o) { | ||
var ar = []; | ||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; | ||
return ar; | ||
}; | ||
return ownKeys(o); | ||
}; | ||
return function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
})(); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -30,3 +40,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.renderMarkdown = void 0; | ||
exports.renderMarkdown = renderMarkdown; | ||
const markdown_it_1 = __importDefault(require("markdown-it")); | ||
@@ -79,2 +89,1 @@ const core_1 = require("@shikijs/markdown-it/core"); | ||
} | ||
exports.renderMarkdown = renderMarkdown; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.yamlSchema = void 0; | ||
exports.yamlSchema = yamlSchema; | ||
const lang_yaml_1 = require("@codemirror/lang-yaml"); | ||
@@ -29,2 +29,1 @@ const view_1 = require("@codemirror/view"); | ||
} | ||
exports.yamlSchema = yamlSchema; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.yamlCompletion = void 0; | ||
exports.yamlCompletion = yamlCompletion; | ||
const constants_1 = require("../constants"); | ||
@@ -16,2 +16,1 @@ const completion_1 = require("../features/completion"); | ||
} | ||
exports.yamlCompletion = yamlCompletion; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.yamlSchemaHover = void 0; | ||
exports.yamlSchemaHover = yamlSchemaHover; | ||
const hover_1 = require("../features/hover"); | ||
@@ -21,2 +21,1 @@ const yaml_1 = __importDefault(require("yaml")); | ||
} | ||
exports.yamlSchemaHover = yamlSchemaHover; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.yamlSchemaLinter = void 0; | ||
exports.yamlSchemaLinter = yamlSchemaLinter; | ||
const validation_1 = require("../features/validation"); | ||
@@ -17,2 +17,1 @@ const constants_1 = require("../constants"); | ||
} | ||
exports.yamlSchemaLinter = yamlSchemaLinter; |
@@ -11,4 +11,4 @@ export const TOKENS = { | ||
PROPERTY_NAME: "PropertyName", | ||
PROPERTY_COLON: "PropertyColon", | ||
ITEM: "Item", | ||
PROPERTY_COLON: "PropertyColon", // used in json5 grammar | ||
ITEM: "Item", // used in yaml grammar | ||
JSON_TEXT: "JsonText", | ||
@@ -28,3 +28,3 @@ INVALID: "⚠", | ||
QuotedLiteral: TOKENS.STRING, | ||
Literal: TOKENS.STRING, | ||
Literal: TOKENS.STRING, // best guess | ||
Stream: TOKENS.JSON_TEXT, | ||
@@ -31,0 +31,0 @@ Document: TOKENS.OBJECT, |
@@ -10,3 +10,12 @@ import { CompletionContext, CompletionResult } from "@codemirror/autocomplete"; | ||
private opts; | ||
private originalSchema; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
*/ | ||
private schema; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
* Does not contain any required properties and allows any additional properties everywhere. | ||
*/ | ||
private laxSchema; | ||
private mode; | ||
@@ -16,2 +25,3 @@ private parser; | ||
doComplete(ctx: CompletionContext): never[] | CompletionResult; | ||
private doCompleteForSchema; | ||
private applySnippetCompletion; | ||
@@ -33,4 +43,2 @@ private getPropertyCompletions; | ||
private getSchemas; | ||
private expandSchemaProperty; | ||
private getReferenceSchema; | ||
private getAppliedValue; | ||
@@ -37,0 +45,0 @@ private getValueFromLabel; |
@@ -0,5 +1,16 @@ | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
import { snippetCompletion, } from "@codemirror/autocomplete"; | ||
import { syntaxTree } from "@codemirror/language"; | ||
import { debug } from "../utils/debug"; | ||
import { findNodeIndexInArrayNode, getChildValueNode, getWord, isPropertyNameNode, isPrimitiveValueNode, stripSurroundingQuotes, getNodeAtPosition, getClosestNode, getMatchingChildrenNodes, getMatchingChildNode, getChildrenNodes, surroundingDoubleQuotesToSingle, } from "../utils/node"; | ||
import { findNodeIndexInArrayNode, getChildrenNodes, getChildValueNode, getClosestNode, getMatchingChildNode, getMatchingChildrenNodes, getNodeAtPosition, getWord, isPrimitiveValueNode, isPropertyNameNode, stripSurroundingQuotes, surroundingDoubleQuotesToSingle, } from "../utils/node"; | ||
import { getJSONSchema } from "./state"; | ||
@@ -12,2 +23,3 @@ import { Draft07, isJsonError } from "json-schema-library"; | ||
import { getDefaultParser } from "../parsers"; | ||
import { replacePropertiesDeeply } from "../utils/recordUtil"; | ||
class CompletionCollector { | ||
@@ -28,7 +40,23 @@ constructor() { | ||
} | ||
function isRealSchema(subSchema) { | ||
return !(!subSchema || | ||
isJsonError(subSchema) || | ||
subSchema.name === "UnknownPropertyError" || | ||
subSchema.type === "undefined"); | ||
} | ||
export class JSONCompletion { | ||
// private lastKnownValidData: object | null = null; | ||
constructor(opts) { | ||
var _a, _b, _c; | ||
this.opts = opts; | ||
this.originalSchema = null; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
*/ | ||
this.schema = null; | ||
/** | ||
* Inlined (expanded) top-level $ref if present. | ||
* Does not contain any required properties and allows any additional properties everywhere. | ||
*/ | ||
this.laxSchema = null; | ||
this.mode = MODES.JSON; | ||
@@ -39,6 +67,11 @@ this.mode = (_a = opts.mode) !== null && _a !== void 0 ? _a : MODES.JSON; | ||
doComplete(ctx) { | ||
var _a, _b, _c; | ||
const s = getJSONSchema(ctx.state); | ||
this.schema = (_a = this.expandSchemaProperty(s, s)) !== null && _a !== void 0 ? _a : s; | ||
if (!this.schema) { | ||
var _a; | ||
const schemaFromState = getJSONSchema(ctx.state); | ||
if (this.originalSchema !== schemaFromState) { | ||
// only process schema when it changed (could be huge) | ||
this.schema = | ||
(_a = expandSchemaProperty(schemaFromState, schemaFromState)) !== null && _a !== void 0 ? _a : schemaFromState; | ||
this.laxSchema = makeSchemaLax(this.schema); | ||
} | ||
if (!this.schema || !this.laxSchema) { | ||
// todo: should we even do anything without schema | ||
@@ -48,2 +81,14 @@ // without taking over the existing mode responsibilties? | ||
} | ||
// first attempt to complete with the original schema | ||
debug.log("xxx", "trying with original schema"); | ||
const completionResultForOriginalSchema = this.doCompleteForSchema(ctx, this.schema); | ||
if (completionResultForOriginalSchema.options.length !== 0) { | ||
return completionResultForOriginalSchema; | ||
} | ||
// if there are no completions, try with the lax schema (because json-schema-library would otherwise not provide schemas if invalid properties are present) | ||
debug.log("xxx", "no completions with original schema, trying with lax schema"); | ||
return this.doCompleteForSchema(ctx, this.laxSchema); | ||
} | ||
doCompleteForSchema(ctx, rootSchema) { | ||
var _a, _b; | ||
const result = { | ||
@@ -81,3 +126,3 @@ from: ctx.pos, | ||
result.from = | ||
node.name === TOKENS.INVALID ? (_b = word === null || word === void 0 ? void 0 : word.from) !== null && _b !== void 0 ? _b : ctx.pos : overwriteStart; | ||
node.name === TOKENS.INVALID ? ((_a = word === null || word === void 0 ? void 0 : word.from) !== null && _a !== void 0 ? _a : ctx.pos) : overwriteStart; | ||
result.to = ctx.pos; | ||
@@ -110,3 +155,3 @@ } | ||
// find object node | ||
node = (_c = getClosestNode(parent, TOKENS.OBJECT, this.mode)) !== null && _c !== void 0 ? _c : null; | ||
node = (_b = getClosestNode(parent, TOKENS.OBJECT, this.mode)) !== null && _b !== void 0 ? _b : null; | ||
} | ||
@@ -126,3 +171,3 @@ } | ||
// property proposals with schema | ||
this.getPropertyCompletions(this.schema, ctx, node, collector, addValue, rawWord); | ||
this.getPropertyCompletions(rootSchema, ctx, node, collector, addValue, rawWord); | ||
} | ||
@@ -133,3 +178,3 @@ else { | ||
// value proposals with schema | ||
const res = this.getValueCompletions(this.schema, ctx, types, collector); | ||
const res = this.getValueCompletions(rootSchema, ctx, types, collector); | ||
debug.log("xxx", "getValueCompletions res", res); | ||
@@ -153,3 +198,3 @@ if (res) { | ||
} | ||
getPropertyCompletions(schema, ctx, node, collector, addValue, rawWord) { | ||
getPropertyCompletions(rootSchema, ctx, node, collector, addValue, rawWord) { | ||
// don't suggest properties that are already present | ||
@@ -164,3 +209,3 @@ const properties = getMatchingChildrenNodes(node, TOKENS.PROPERTY, this.mode); | ||
// Get matching schemas | ||
const schemas = this.getSchemas(schema, ctx); | ||
const schemas = this.getSchemas(rootSchema, ctx); | ||
debug.log("xxx", "propertyCompletion schemas", schemas); | ||
@@ -182,3 +227,3 @@ schemas.forEach((s) => { | ||
label: key, | ||
apply: this.getInsertTextForProperty(key, addValue, rawWord, value), | ||
apply: this.getInsertTextForProperty(key, addValue, rawWord, rootSchema, value), | ||
type: "property", | ||
@@ -202,3 +247,3 @@ detail: typeStr, | ||
label, | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord), | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord, rootSchema), | ||
type: "property", | ||
@@ -214,3 +259,3 @@ }; | ||
label, | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord), | ||
apply: this.getInsertTextForProperty(label, addValue, rawWord, rootSchema), | ||
type: "property", | ||
@@ -234,6 +279,6 @@ }; | ||
// idea: https://discuss.codemirror.net/t/autocomplete-cursor-position-in-apply-function/4088/3 | ||
getInsertTextForProperty(key, addValue, rawWord, propertySchema) { | ||
getInsertTextForProperty(key, addValue, rawWord, rootSchema, propertySchema) { | ||
// expand schema property if it is a reference | ||
propertySchema = propertySchema | ||
? this.expandSchemaProperty(propertySchema, this.schema) | ||
? expandSchemaProperty(propertySchema, rootSchema) | ||
: propertySchema; | ||
@@ -389,3 +434,3 @@ let resultText = this.getInsertTextForPropertyName(key, rawWord); | ||
} | ||
getValueCompletions(schema, ctx, types, collector) { | ||
getValueCompletions(rootSchema, ctx, types, collector) { | ||
let node = syntaxTree(ctx.state).resolveInner(ctx.pos, -1); | ||
@@ -400,3 +445,3 @@ let valueNode = null; | ||
if (!node) { | ||
this.addSchemaValueCompletions(schema, types, collector); | ||
this.addSchemaValueCompletions(rootSchema, types, collector); | ||
return; | ||
@@ -416,3 +461,3 @@ } | ||
// Get matching schemas | ||
const schemas = this.getSchemas(schema, ctx); | ||
const schemas = this.getSchemas(rootSchema, ctx); | ||
for (const s of schemas) { | ||
@@ -453,2 +498,5 @@ if (typeof s !== "object") { | ||
} | ||
if (s.type == null || s.type !== "object") { | ||
this.addSchemaValueCompletions(s, types, collector); | ||
} | ||
if (parentKey !== undefined) { | ||
@@ -501,3 +549,6 @@ let propertyMatched = false; | ||
} | ||
addSchemaValueCompletions(schema, types, collector) { | ||
addSchemaValueCompletions(schema, | ||
// TODO this is buggy because it does not resolve refs, should hand down rootSchema and expand each ref | ||
// rootSchema: JSONSchema7, | ||
types, collector) { | ||
if (typeof schema === "object") { | ||
@@ -586,32 +637,62 @@ this.addEnumValueCompletions(schema, collector); | ||
} | ||
getSchemas(schema, ctx) { | ||
var _a, _b; | ||
const draft = new Draft07(this.schema); | ||
getSchemas(rootSchema, ctx) { | ||
var _a, _b, _c; | ||
const { data: documentData } = this.parser(ctx.state); | ||
const draft = new Draft07(rootSchema); | ||
let pointer = jsonPointerForPosition(ctx.state, ctx.pos, -1, this.mode); | ||
// Pass parsed data to getSchema to get the correct schema based on the data context | ||
const { data } = this.parser(ctx.state); | ||
// TODO make jsonPointer consistent and compatible with json-schema-library by default (root path '/' or ' ' or undefined or '#', idk) | ||
if (pointer === "") | ||
pointer = undefined; | ||
if (pointer != null && pointer.endsWith("/")) { | ||
// opening new property under pointer | ||
// the property name is empty but json-schema-library would puke itself with a trailing slash, so we shouldn't even call it with that | ||
pointer = pointer.substring(0, pointer.length - 1); | ||
// when adding a new property, we just wanna return the possible properties if possible | ||
const effectiveSchemaOfPointer = getEffectiveObjectWithPropertiesSchema(rootSchema, documentData, pointer); | ||
if (effectiveSchemaOfPointer != null) { | ||
return [effectiveSchemaOfPointer]; | ||
} | ||
} | ||
let parentPointer = pointer != null ? pointer.replace(/\/[^/]*$/, "") : undefined; | ||
if (parentPointer === "") | ||
parentPointer = undefined; | ||
// Pass parsed data to getSchema to get the correct schema based on the data context (e.g. for anyOf or if-then) | ||
const effectiveSchemaOfParent = getEffectiveObjectWithPropertiesSchema(rootSchema, documentData, parentPointer); | ||
const deepestPropertyKey = pointer === null || pointer === void 0 ? void 0 : pointer.split("/").pop(); | ||
const pointerPointsToKnownProperty = deepestPropertyKey == null || | ||
deepestPropertyKey in ((_a = effectiveSchemaOfParent === null || effectiveSchemaOfParent === void 0 ? void 0 : effectiveSchemaOfParent.properties) !== null && _a !== void 0 ? _a : {}); | ||
// TODO upgrade json-schema-library, so this actually returns undefined if data and schema are incompatible (currently it sometimes pukes itself with invalid data and imagines schemas on-the-fly) | ||
let subSchema = draft.getSchema({ | ||
pointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
data: documentData !== null && documentData !== void 0 ? documentData : undefined, | ||
}); | ||
debug.log("xxxx", "draft.getSchema", subSchema, "data", data, "pointer", pointer); | ||
if (!pointerPointsToKnownProperty && | ||
(subSchema === null || subSchema === void 0 ? void 0 : subSchema.type) === "null" && | ||
this.mode === "yaml") { | ||
// TODO describe YAML special-case where null is given the value and json-schema-library simply makes up a new schema based on that null value for whatever reason | ||
subSchema = undefined; | ||
} | ||
debug.log("xxxx", "draft.getSchema", subSchema, "data", documentData, "pointer", pointer, "pointerPointsToKnownProperty", pointerPointsToKnownProperty); | ||
if (isJsonError(subSchema)) { | ||
subSchema = (_a = subSchema.data) === null || _a === void 0 ? void 0 : _a.schema; | ||
subSchema = (_b = subSchema.data) === null || _b === void 0 ? void 0 : _b.schema; | ||
} | ||
// if we don't have a schema for the current pointer, try the parent pointer | ||
if (!subSchema || | ||
subSchema.name === "UnknownPropertyError" || | ||
subSchema.enum || | ||
subSchema.type === "undefined" || | ||
subSchema.type === "null") { | ||
pointer = pointer.replace(/\/[^/]*$/, "/"); | ||
subSchema = draft.getSchema({ pointer }); | ||
// if we don't have a schema for the current pointer, try the parent pointer with data to get a list of possible properties | ||
if (!isRealSchema(subSchema)) { | ||
if (effectiveSchemaOfParent) { | ||
return [effectiveSchemaOfParent]; | ||
} | ||
} | ||
// then try the parent pointer without data | ||
if (!isRealSchema(subSchema)) { | ||
subSchema = draft.getSchema({ pointer: parentPointer }); | ||
// TODO should probably only change pointer if it actually found a schema there, but i left it as-is | ||
pointer = parentPointer; | ||
} | ||
debug.log("xxx", "pointer..", JSON.stringify(pointer)); | ||
// For some reason, it returns undefined schema for the root pointer | ||
// We use the root schema in that case as the relevant (sub)schema | ||
if (!pointer || pointer === "/") { | ||
subSchema = (_b = this.expandSchemaProperty(schema, schema)) !== null && _b !== void 0 ? _b : schema; | ||
if (!isRealSchema(subSchema) && (!pointer || pointer === "/")) { | ||
subSchema = (_c = expandSchemaProperty(rootSchema, rootSchema)) !== null && _c !== void 0 ? _c : rootSchema; | ||
} | ||
// const subSchema = new Draft07(this.schema).getSchema(pointer); | ||
// const subSchema = new Draft07(this.dirtyCtx.rootSchema).getSchema(pointer); | ||
debug.log("xxx", "subSchema..", subSchema); | ||
@@ -624,3 +705,3 @@ if (!subSchema) { | ||
subSchema, | ||
...subSchema.allOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.allOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -631,3 +712,3 @@ } | ||
subSchema, | ||
...subSchema.oneOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.oneOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -638,3 +719,3 @@ } | ||
subSchema, | ||
...subSchema.anyOf.map((s) => this.expandSchemaProperty(s, schema)), | ||
...subSchema.anyOf.map((s) => expandSchemaProperty(s, rootSchema)), | ||
]; | ||
@@ -644,30 +725,2 @@ } | ||
} | ||
expandSchemaProperty(property, schema) { | ||
if (typeof property === "object" && property.$ref) { | ||
const refSchema = this.getReferenceSchema(schema, property.$ref); | ||
if (typeof refSchema === "object") { | ||
const dereferenced = Object.assign(Object.assign({}, property), refSchema); | ||
Reflect.deleteProperty(dereferenced, "$ref"); | ||
return dereferenced; | ||
} | ||
} | ||
return property; | ||
} | ||
getReferenceSchema(schema, ref) { | ||
const refPath = ref.split("/"); | ||
let curReference = schema; | ||
refPath.forEach((cur) => { | ||
if (!cur) { | ||
return; | ||
} | ||
if (cur === "#") { | ||
curReference = schema; | ||
return; | ||
} | ||
if (typeof curReference === "object") { | ||
curReference = curReference[cur]; | ||
} | ||
}); | ||
return curReference; | ||
} | ||
getAppliedValue(value) { | ||
@@ -727,1 +780,144 @@ const stripped = stripSurroundingQuotes(JSON.stringify(value)); | ||
} | ||
/** | ||
* removes required properties and allows additional properties everywhere | ||
* @param schema | ||
*/ | ||
function makeSchemaLax(schema) { | ||
return replacePropertiesDeeply(schema, (key, value) => { | ||
if (key === "additionalProperties" && value === false) { | ||
return []; | ||
} | ||
if (key === "required" && Array.isArray(value)) { | ||
return []; | ||
} | ||
if (key === "unevaluatedProperties" && value === false) { | ||
return []; | ||
} | ||
if (key === "unevaluatedItems" && value === false) { | ||
return []; | ||
} | ||
// TODO remove dependencies and other restrictions | ||
// if (key === 'dependencies' && typeof value === 'object') { | ||
// return Object.keys(value).reduce((acc: any, depKey) => { | ||
// const depValue = value[depKey]; | ||
// if (Array.isArray(depValue)) { | ||
// return acc; | ||
// } | ||
// return { ...acc, [depKey]: depValue }; | ||
// }, {}); | ||
// } | ||
return [key, value]; | ||
}); | ||
} | ||
/** | ||
* determines effective object schema for given data | ||
* TODO support patternProperties, etc. | ||
* @param schema | ||
* @param data | ||
* @param pointer | ||
*/ | ||
function getEffectiveObjectWithPropertiesSchema(schema, data, pointer) { | ||
// TODO (unimportant): [performance] cache Draft07 in case it does some pre-processing? but does not seem to be significant | ||
const draft = new Draft07(schema); | ||
const subSchema = draft.getSchema({ | ||
pointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
}); | ||
if (!isRealSchema(subSchema)) { | ||
return undefined; | ||
} | ||
const possibleDirectPropertyNames = getAllPossibleDirectStaticPropertyNames(draft, subSchema); | ||
const effectiveProperties = {}; | ||
for (let possibleDirectPropertyName of possibleDirectPropertyNames) { | ||
let propertyPointer = extendJsonPointer(pointer, possibleDirectPropertyName); | ||
const subSchemaForPropertyConsideringData = draft.getSchema({ | ||
// TODO [performance] use subSchema and only check it's sub-properties | ||
pointer: propertyPointer, | ||
data: data !== null && data !== void 0 ? data : undefined, | ||
// pointer: `/${possibleDirectPropertyName}`, | ||
// schema: subSchema | ||
}); | ||
if (isRealSchema(subSchemaForPropertyConsideringData)) { | ||
Object.assign(effectiveProperties, { | ||
[possibleDirectPropertyName]: subSchemaForPropertyConsideringData, | ||
}); | ||
} | ||
} | ||
if (possibleDirectPropertyNames.length === 0 || | ||
Object.keys(effectiveProperties).length === 0) { | ||
// in case json-schema-library behaves too weirdly and returns nothing, just return no schema too to let other cases handle this edge-case | ||
return undefined; | ||
} | ||
// TODO also resolve patternProperties of allOf, anyOf, oneOf | ||
const _a = subSchema, { allOf, anyOf, oneOf } = _a, subSchemaRest = __rest(_a, ["allOf", "anyOf", "oneOf"]); | ||
return Object.assign(Object.assign({}, subSchemaRest), { properties: effectiveProperties }); | ||
} | ||
/** | ||
* static means not from patternProperties | ||
* @param rootDraft | ||
* @param schema | ||
*/ | ||
function getAllPossibleDirectStaticPropertyNames(rootDraft, schema) { | ||
schema = expandSchemaProperty(schema, rootDraft.rootSchema); | ||
if (typeof schema !== "object" || schema == null) { | ||
return []; | ||
} | ||
const possiblePropertyNames = []; | ||
function addFrom(subSchema) { | ||
const possiblePropertyNamesOfSubSchema = getAllPossibleDirectStaticPropertyNames(rootDraft, subSchema); | ||
possiblePropertyNames.push(...possiblePropertyNamesOfSubSchema); | ||
} | ||
if (typeof schema.properties === "object" && schema.properties != null) { | ||
possiblePropertyNames.push(...Object.keys(schema.properties)); | ||
} | ||
if (typeof schema.then === "object" && schema.then != null) { | ||
addFrom(schema.then); | ||
} | ||
if (Array.isArray(schema.allOf)) { | ||
for (const subSchema of schema.allOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
if (Array.isArray(schema.anyOf)) { | ||
for (const subSchema of schema.anyOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
if (Array.isArray(schema.oneOf)) { | ||
for (const subSchema of schema.oneOf) { | ||
addFrom(subSchema); | ||
} | ||
} | ||
return possiblePropertyNames; | ||
} | ||
function expandSchemaProperty(propertySchema, rootSchema) { | ||
if (typeof propertySchema === "object" && propertySchema.$ref) { | ||
const refSchema = getReferenceSchema(rootSchema, propertySchema.$ref); | ||
if (typeof refSchema === "object") { | ||
const dereferenced = Object.assign(Object.assign({}, propertySchema), refSchema); | ||
Reflect.deleteProperty(dereferenced, "$ref"); | ||
return dereferenced; | ||
} | ||
} | ||
return propertySchema; | ||
} | ||
function getReferenceSchema(schema, ref) { | ||
const refPath = ref.split("/"); | ||
let curReference = schema; | ||
refPath.forEach((cur) => { | ||
if (!cur) { | ||
return; | ||
} | ||
if (cur === "#") { | ||
curReference = schema; | ||
return; | ||
} | ||
if (typeof curReference === "object") { | ||
curReference = curReference[cur]; | ||
} | ||
}); | ||
return curReference; | ||
} | ||
function extendJsonPointer(pointer, key) { | ||
return pointer === undefined ? `/${key}` : `${pointer}/${key}`; | ||
} |
@@ -7,3 +7,3 @@ /** | ||
import { EditorState } from "@codemirror/state"; | ||
import { parse } from "best-effort-json-parser"; | ||
import { parse as bestEffortParse } from "best-effort-json-parser"; | ||
import { getJsonPointers } from "../utils/json-pointers"; | ||
@@ -16,12 +16,15 @@ import { MODES } from "../constants"; | ||
export function parseJSON5DocumentState(state) { | ||
const stateDoc = state.doc.toString(); | ||
let data = null; | ||
try { | ||
data = json5.parse(state.doc.toString()); | ||
// return pointers regardless of whether JSON.parse succeeds | ||
data = json5.parse(stateDoc); | ||
} | ||
catch (_a) { | ||
// try again with best-effort strategy | ||
try { | ||
data = parse(state.doc.toString()); | ||
data = bestEffortParse(stateDoc); | ||
} | ||
catch (_b) { } | ||
catch (_b) { | ||
// return pointers regardless of whether JSON.parse succeeds | ||
} | ||
} | ||
@@ -28,0 +31,0 @@ const pointers = getJsonPointers(state, MODES.JSON5); |
@@ -1,1 +0,1 @@ | ||
export declare const joinWithOr: (arr: string[], getPath?: ((err: any) => any) | undefined) => string; | ||
export declare const joinWithOr: (arr: string[], getPath?: (err: any) => any) => string; |
@@ -24,3 +24,7 @@ import { syntaxTree } from "@codemirror/language"; | ||
if (name) { | ||
path.unshift(getWord(docText, name).replace(/[/~]/g, (v) => v === "~" ? "~0" : "~1")); | ||
let word = getWord(docText, name).replace(/[/~]/g, (v) => v === "~" ? "~0" : "~1"); | ||
// TODO generally filter out pointers to objects being started? | ||
// if (word !== '') { | ||
path.unshift(word); | ||
// } | ||
} | ||
@@ -38,4 +42,7 @@ break; | ||
} | ||
path.unshift(""); | ||
return path.join("/"); | ||
if (path.length === 0) { | ||
// TODO json-schema-library does not seem to like / as root pointer (it probably just uses split and it will return two empty strings). So is this fine? And why is it not prefixed with #? | ||
return ""; | ||
} | ||
return "/" + path.join("/"); | ||
} | ||
@@ -42,0 +49,0 @@ /** |
@@ -21,3 +21,3 @@ [codemirror-json-schema](../README.md) / JSONCompletion | ||
- [doComplete](JSONCompletion.md#docomplete) | ||
- [expandSchemaProperty](JSONCompletion.md#expandschemaproperty) | ||
- [doCompleteForSchema](JSONCompletion.md#docompleteforschema) | ||
- [extendedRegExp](JSONCompletion.md#extendedregexp) | ||
@@ -32,3 +32,2 @@ - [getAppliedValue](JSONCompletion.md#getappliedvalue) | ||
- [getPropertyCompletions](JSONCompletion.md#getpropertycompletions) | ||
- [getReferenceSchema](JSONCompletion.md#getreferenceschema) | ||
- [getSchemas](JSONCompletion.md#getschemas) | ||
@@ -40,4 +39,6 @@ - [getValueCompletions](JSONCompletion.md#getvaluecompletions) | ||
- [laxSchema](JSONCompletion.md#laxschema) | ||
- [mode](JSONCompletion.md#mode) | ||
- [opts](JSONCompletion.md#opts) | ||
- [originalSchema](JSONCompletion.md#originalschema) | ||
- [parser](JSONCompletion.md#parser) | ||
@@ -60,3 +61,3 @@ - [schema](JSONCompletion.md#schema) | ||
[features/completion.ts:63](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L63) | ||
[features/completion.ts:87](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L87) | ||
@@ -82,3 +83,3 @@ ## Methods | ||
[features/completion.ts:784](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L784) | ||
[features/completion.ts:856](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L856) | ||
@@ -105,3 +106,3 @@ --- | ||
[features/completion.ts:713](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L713) | ||
[features/completion.ts:785](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L785) | ||
@@ -127,3 +128,3 @@ --- | ||
[features/completion.ts:759](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L759) | ||
[features/completion.ts:831](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L831) | ||
@@ -148,3 +149,3 @@ --- | ||
[features/completion.ts:794](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L794) | ||
[features/completion.ts:866](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L866) | ||
@@ -171,3 +172,3 @@ --- | ||
[features/completion.ts:687](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L687) | ||
[features/completion.ts:756](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L756) | ||
@@ -192,3 +193,3 @@ --- | ||
[features/completion.ts:251](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L251) | ||
[features/completion.ts:301](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L301) | ||
@@ -214,3 +215,3 @@ --- | ||
[features/completion.ts:801](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L801) | ||
[features/completion.ts:873](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L873) | ||
@@ -235,30 +236,24 @@ --- | ||
[features/completion.ts:67](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L67) | ||
[features/completion.ts:92](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L92) | ||
--- | ||
### expandSchemaProperty | ||
### doCompleteForSchema | ||
▸ `Private` **expandSchemaProperty**\<`T`\>(`property`, `schema`): `T` | ||
▸ `Private` **doCompleteForSchema**(`ctx`, `rootSchema`): `CompletionResult` | ||
#### Type parameters | ||
| Name | Type | | ||
| :--- | :------------------------------ | | ||
| `T` | extends `JSONSchema7Definition` | | ||
#### Parameters | ||
| Name | Type | | ||
| :--------- | :------------ | | ||
| `property` | `T` | | ||
| `schema` | `JSONSchema7` | | ||
| Name | Type | | ||
| :----------- | :------------------ | | ||
| `ctx` | `CompletionContext` | | ||
| `rootSchema` | `JSONSchema7` | | ||
#### Returns | ||
`T` | ||
`CompletionResult` | ||
#### Defined in | ||
[features/completion.ts:887](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L887) | ||
[features/completion.ts:124](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L124) | ||
@@ -283,3 +278,3 @@ --- | ||
[features/completion.ts:950](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L950) | ||
[features/completion.ts:1038](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L1038) | ||
@@ -309,3 +304,3 @@ --- | ||
[features/completion.ts:925](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L925) | ||
[features/completion.ts:1013](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L1013) | ||
@@ -331,3 +326,3 @@ --- | ||
[features/completion.ts:506](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L506) | ||
[features/completion.ts:570](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L570) | ||
@@ -352,3 +347,3 @@ --- | ||
[features/completion.ts:528](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L528) | ||
[features/completion.ts:593](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L593) | ||
@@ -359,3 +354,3 @@ --- | ||
▸ `Private` **getInsertTextForProperty**(`key`, `addValue`, `rawWord`, `propertySchema?`): `string` | ||
▸ `Private` **getInsertTextForProperty**(`key`, `addValue`, `rawWord`, `rootSchema`, `propertySchema?`): `string` | ||
@@ -369,2 +364,3 @@ #### Parameters | ||
| `rawWord` | `string` | | ||
| `rootSchema` | `JSONSchema7` | | ||
| `propertySchema?` | `JSONSchema7Definition` | | ||
@@ -378,3 +374,3 @@ | ||
[features/completion.ts:361](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L361) | ||
[features/completion.ts:422](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L422) | ||
@@ -400,3 +396,3 @@ --- | ||
[features/completion.ts:478](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L478) | ||
[features/completion.ts:541](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L541) | ||
@@ -422,3 +418,3 @@ --- | ||
[features/completion.ts:494](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L494) | ||
[features/completion.ts:558](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L558) | ||
@@ -444,3 +440,3 @@ --- | ||
[features/completion.ts:532](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L532) | ||
[features/completion.ts:597](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L597) | ||
@@ -451,14 +447,14 @@ --- | ||
▸ `Private` **getPropertyCompletions**(`schema`, `ctx`, `node`, `collector`, `addValue`, `rawWord`): `void` | ||
▸ `Private` **getPropertyCompletions**(`rootSchema`, `ctx`, `node`, `collector`, `addValue`, `rawWord`): `void` | ||
#### Parameters | ||
| Name | Type | | ||
| :---------- | :-------------------- | | ||
| `schema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
| `node` | `SyntaxNode` | | ||
| `collector` | `CompletionCollector` | | ||
| `addValue` | `boolean` | | ||
| `rawWord` | `string` | | ||
| Name | Type | | ||
| :----------- | :-------------------- | | ||
| `rootSchema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
| `node` | `SyntaxNode` | | ||
| `collector` | `CompletionCollector` | | ||
| `addValue` | `boolean` | | ||
| `rawWord` | `string` | | ||
@@ -471,37 +467,16 @@ #### Returns | ||
[features/completion.ts:260](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L260) | ||
[features/completion.ts:310](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L310) | ||
--- | ||
### getReferenceSchema | ||
▸ `Private` **getReferenceSchema**(`schema`, `ref`): `Record`\<`string`, `any`\> | ||
#### Parameters | ||
| Name | Type | | ||
| :------- | :------------ | | ||
| `schema` | `JSONSchema7` | | ||
| `ref` | `string` | | ||
#### Returns | ||
`Record`\<`string`, `any`\> | ||
#### Defined in | ||
[features/completion.ts:906](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L906) | ||
--- | ||
### getSchemas | ||
▸ `Private` **getSchemas**(`schema`, `ctx`): `JSONSchema7Definition`[] | ||
▸ `Private` **getSchemas**(`rootSchema`, `ctx`): `JSONSchema7Definition`[] | ||
#### Parameters | ||
| Name | Type | | ||
| :------- | :------------------ | | ||
| `schema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
| Name | Type | | ||
| :----------- | :------------------ | | ||
| `rootSchema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
@@ -514,3 +489,3 @@ #### Returns | ||
[features/completion.ts:816](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L816) | ||
[features/completion.ts:888](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L888) | ||
@@ -521,12 +496,12 @@ --- | ||
▸ `Private` **getValueCompletions**(`schema`, `ctx`, `types`, `collector`): `undefined` \| \{ `valuePrefix`: `string` } | ||
▸ `Private` **getValueCompletions**(`rootSchema`, `ctx`, `types`, `collector`): `undefined` \| \{ `valuePrefix`: `string` } | ||
#### Parameters | ||
| Name | Type | | ||
| :---------- | :-------------------- | | ||
| `schema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
| `types` | `Object` | | ||
| `collector` | `CompletionCollector` | | ||
| Name | Type | | ||
| :----------- | :-------------------- | | ||
| `rootSchema` | `JSONSchema7` | | ||
| `ctx` | `CompletionContext` | | ||
| `types` | `Object` | | ||
| `collector` | `CompletionCollector` | | ||
@@ -539,3 +514,3 @@ #### Returns | ||
[features/completion.ts:542](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L542) | ||
[features/completion.ts:607](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L607) | ||
@@ -560,6 +535,19 @@ --- | ||
[features/completion.ts:946](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L946) | ||
[features/completion.ts:1034](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L1034) | ||
## Properties | ||
### laxSchema | ||
• `Private` **laxSchema**: `null` \| `JSONSchema7` = `null` | ||
Inlined (expanded) top-level $ref if present. | ||
Does not contain any required properties and allows any additional properties everywhere. | ||
#### Defined in | ||
[features/completion.ts:81](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L81) | ||
--- | ||
### mode | ||
@@ -571,3 +559,3 @@ | ||
[features/completion.ts:60](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L60) | ||
[features/completion.ts:82](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L82) | ||
@@ -582,6 +570,16 @@ --- | ||
[features/completion.ts:63](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L63) | ||
[features/completion.ts:87](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L87) | ||
--- | ||
### originalSchema | ||
• `Private` **originalSchema**: `null` \| `JSONSchema7` = `null` | ||
#### Defined in | ||
[features/completion.ts:72](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L72) | ||
--- | ||
### parser | ||
@@ -593,3 +591,3 @@ | ||
[features/completion.ts:61](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L61) | ||
[features/completion.ts:83](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L83) | ||
@@ -602,4 +600,6 @@ --- | ||
Inlined (expanded) top-level $ref if present. | ||
#### Defined in | ||
[features/completion.ts:59](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L59) | ||
[features/completion.ts:76](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L76) |
@@ -38,3 +38,3 @@ [codemirror-json-schema](../README.md) / JSONHover | ||
[features/hover.ts:88](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L88) | ||
[features/hover.ts:88](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L88) | ||
@@ -61,3 +61,3 @@ ## Methods | ||
[features/hover.ts:203](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L203) | ||
[features/hover.ts:203](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L203) | ||
@@ -82,3 +82,3 @@ --- | ||
[features/hover.ts:136](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L136) | ||
[features/hover.ts:136](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L136) | ||
@@ -105,3 +105,3 @@ --- | ||
[features/hover.ts:95](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L95) | ||
[features/hover.ts:95](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L95) | ||
@@ -127,3 +127,3 @@ --- | ||
[features/hover.ts:162](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L162) | ||
[features/hover.ts:162](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L162) | ||
@@ -138,3 +138,3 @@ ## Properties | ||
[features/hover.ts:87](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L87) | ||
[features/hover.ts:87](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L87) | ||
@@ -149,3 +149,3 @@ --- | ||
[features/hover.ts:88](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L88) | ||
[features/hover.ts:88](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L88) | ||
@@ -160,2 +160,2 @@ --- | ||
[features/hover.ts:86](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L86) | ||
[features/hover.ts:86](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L86) |
@@ -39,3 +39,3 @@ [codemirror-json-schema](../README.md) / JSONValidation | ||
[features/validation.ts:77](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L77) | ||
[features/validation.ts:77](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L77) | ||
@@ -56,3 +56,3 @@ ## Constructors | ||
[features/validation.ts:67](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L67) | ||
[features/validation.ts:67](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L67) | ||
@@ -77,3 +77,3 @@ ## Methods | ||
[features/validation.ts:108](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L108) | ||
[features/validation.ts:108](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L108) | ||
@@ -98,3 +98,3 @@ --- | ||
[features/validation.ts:82](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L82) | ||
[features/validation.ts:82](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L82) | ||
@@ -109,3 +109,3 @@ ## Properties | ||
[features/validation.ts:65](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L65) | ||
[features/validation.ts:65](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L65) | ||
@@ -120,3 +120,3 @@ --- | ||
[features/validation.ts:67](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L67) | ||
[features/validation.ts:67](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L67) | ||
@@ -131,3 +131,3 @@ --- | ||
[features/validation.ts:66](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L66) | ||
[features/validation.ts:66](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L66) | ||
@@ -142,2 +142,2 @@ --- | ||
[features/validation.ts:63](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L63) | ||
[features/validation.ts:63](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L63) |
@@ -20,3 +20,3 @@ [codemirror-json-schema](../README.md) / JSONCompletionOptions | ||
[features/completion.ts:55](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L55) | ||
[features/completion.ts:57](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L57) | ||
@@ -31,2 +31,2 @@ --- | ||
[features/completion.ts:54](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L54) | ||
[features/completion.ts:56](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L56) |
@@ -35,3 +35,3 @@ [codemirror-json-schema](../README.md) / JSONValidationOptions | ||
[features/validation.ts:30](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L30) | ||
[features/validation.ts:30](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L30) | ||
@@ -46,3 +46,3 @@ --- | ||
[features/validation.ts:31](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L31) | ||
[features/validation.ts:31](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L31) | ||
@@ -57,2 +57,2 @@ --- | ||
[features/validation.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L29) | ||
[features/validation.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L29) |
@@ -77,3 +77,3 @@ codemirror-json-schema | ||
[json/bundled.ts:15](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/json/bundled.ts#L15) | ||
[json/bundled.ts:15](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/json/bundled.ts#L15) | ||
@@ -112,3 +112,3 @@ ## Codemirror Extensions | ||
[features/completion.ts:973](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/completion.ts#L973) | ||
[features/completion.ts:1062](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/completion.ts#L1062) | ||
@@ -149,3 +149,3 @@ ___ | ||
[features/hover.ts:46](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L46) | ||
[features/hover.ts:46](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L46) | ||
@@ -184,3 +184,3 @@ ___ | ||
[features/validation.ts:46](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L46) | ||
[features/validation.ts:46](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L46) | ||
@@ -208,3 +208,3 @@ ## Utilities | ||
[utils/json-pointers.ts:85](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/utils/json-pointers.ts#L85) | ||
[utils/json-pointers.ts:89](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/utils/json-pointers.ts#L89) | ||
@@ -234,3 +234,3 @@ ___ | ||
[utils/json-pointers.ts:68](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/utils/json-pointers.ts#L68) | ||
[utils/json-pointers.ts:72](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/utils/json-pointers.ts#L72) | ||
@@ -262,3 +262,3 @@ ___ | ||
[parsers/json-parser.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/parsers/json-parser.ts#L29) | ||
[parsers/json-parser.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/parsers/json-parser.ts#L29) | ||
@@ -290,3 +290,3 @@ ___ | ||
[parsers/json-parser.ts:11](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/parsers/json-parser.ts#L11) | ||
[parsers/json-parser.ts:11](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/parsers/json-parser.ts#L11) | ||
@@ -311,3 +311,3 @@ ## Functions | ||
[features/state.ts:25](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/state.ts#L25) | ||
[features/state.ts:25](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/state.ts#L25) | ||
@@ -334,3 +334,3 @@ ___ | ||
[utils/json-pointers.ts:31](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/utils/json-pointers.ts#L31) | ||
[utils/json-pointers.ts:31](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/utils/json-pointers.ts#L31) | ||
@@ -355,3 +355,3 @@ ___ | ||
[features/validation.ts:36](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/validation.ts#L36) | ||
[features/validation.ts:36](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/validation.ts#L36) | ||
@@ -377,3 +377,3 @@ ___ | ||
[utils/json-pointers.ts:18](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/utils/json-pointers.ts#L18) | ||
[utils/json-pointers.ts:18](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/utils/json-pointers.ts#L18) | ||
@@ -398,3 +398,3 @@ ___ | ||
[features/state.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/state.ts#L29) | ||
[features/state.ts:29](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/state.ts#L29) | ||
@@ -420,3 +420,3 @@ ___ | ||
[features/state.ts:19](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/state.ts#L19) | ||
[features/state.ts:19](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/state.ts#L19) | ||
@@ -438,3 +438,3 @@ ## Type Aliases | ||
[features/hover.ts:19](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L19) | ||
[features/hover.ts:19](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L19) | ||
@@ -449,3 +449,3 @@ ___ | ||
[features/hover.ts:21](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L21) | ||
[features/hover.ts:21](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L21) | ||
@@ -469,3 +469,3 @@ ___ | ||
[features/hover.ts:25](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/hover.ts#L25) | ||
[features/hover.ts:25](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/hover.ts#L25) | ||
@@ -487,3 +487,3 @@ ___ | ||
[types.ts:6](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/types.ts#L6) | ||
[types.ts:6](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/types.ts#L6) | ||
@@ -507,3 +507,3 @@ ___ | ||
[types.ts:11](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/types.ts#L11) | ||
[types.ts:11](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/types.ts#L11) | ||
@@ -518,3 +518,3 @@ ___ | ||
[types.ts:20](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/types.ts#L20) | ||
[types.ts:20](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/types.ts#L20) | ||
@@ -529,2 +529,2 @@ ## Variables | ||
[features/state.ts:6](https://github.com/jsonnext/codemirror-json-schema/blob/ef7f336/src/features/state.ts#L6) | ||
[features/state.ts:6](https://github.com/jsonnext/codemirror-json-schema/blob/aa27ad7/src/features/state.ts#L6) |
{ | ||
"name": "codemirror-json-schema", | ||
"license": "MIT", | ||
"version": "0.7.9", | ||
"version": "0.8.0", | ||
"description": "Codemirror 6 extensions that provide full JSONSchema support for `@codemirror/lang-json` and `codemirror-json5`", | ||
@@ -98,13 +98,15 @@ "contributors": [ | ||
"@types/node": "^20.4.2", | ||
"@vitest/coverage-v8": "^0.34.6", | ||
"@vitest/coverage-v8": "^2.0.5", | ||
"codemirror-json5": "^1.0.3", | ||
"happy-dom": "^10.3.2", | ||
"jsdom": "^24.1.1", | ||
"json5": "^2.2.3", | ||
"prettier": "^3.3.3", | ||
"typedoc": "^0.24.8", | ||
"typedoc-plugin-markdown": "^3.15.3", | ||
"typescript": "^5.1.6", | ||
"vite": "^5.2.12", | ||
"vite-tsconfig-paths": "^4.3.1", | ||
"vitest": "0.34.6", | ||
"vitest-dom": "^0.1.0" | ||
"typescript": "^5.5.2", | ||
"vite": "^5.3.1", | ||
"vitest": "^1.6.0", | ||
"vitest-dom": "^0.1.1", | ||
"vite-tsconfig-paths": "^4.3.1" | ||
}, | ||
@@ -111,0 +113,0 @@ "scripts": { |
260086
127
4750
27