UNPKG

codemirror-json-schema

Version:

Codemirror 6 extensions that provide full JSONSchema support for `@codemirror/lang-json` and `codemirror-json5`

88 lines (87 loc) 4.09 kB
import { COMPLEX_TYPES, TOKENS, PRIMITIVE_TYPES, MODES } from "../constants"; import { syntaxTree } from "@codemirror/language"; import { resolveTokenName } from "./json-pointers"; export const getNodeAtPosition = (state, pos, side = -1) => { return syntaxTree(state).resolveInner(pos, side); }; export const stripSurroundingQuotes = (str) => { return str.replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1"); }; export const surroundingDoubleQuotesToSingle = (str) => { return str.replace(/^"(.*)"$/, "'$1'"); }; export const getWord = (doc, node, stripQuotes = true, onlyEvenQuotes = true) => { const word = node ? doc.sliceString(node.from, node.to) : ""; if (!stripQuotes) { return word; } if (onlyEvenQuotes) { return stripSurroundingQuotes(word); } return word.replace(/(^["'])|(["']$)/g, ""); }; export const isInvalidValueNode = (node, mode) => { var _a, _b, _c, _d; return (resolveTokenName(node.name, mode) === TOKENS.INVALID && (resolveTokenName((_b = (_a = node.prevSibling) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "", mode) === TOKENS.PROPERTY_NAME || resolveTokenName((_d = (_c = node.prevSibling) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : "", mode) === TOKENS.PROPERTY_COLON)); }; export const isPrimitiveValueNode = (node, mode) => { return (PRIMITIVE_TYPES.includes(resolveTokenName(node.name, mode)) || isInvalidValueNode(node, mode)); }; export const isValueNode = (node, mode) => { return ([...PRIMITIVE_TYPES, ...COMPLEX_TYPES].includes(resolveTokenName(node.name, mode)) || isInvalidValueNode(node, mode)); }; export const isPropertyNameNode = (node, mode) => { var _a, _b, _c, _d, _e, _f; return (resolveTokenName(node.name, mode) === TOKENS.PROPERTY_NAME || (resolveTokenName(node.name, mode) === TOKENS.INVALID && (resolveTokenName((_b = (_a = node.prevSibling) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "", mode) === TOKENS.PROPERTY || resolveTokenName((_d = (_c = node.prevSibling) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : "", mode) === "{")) || // TODO: Can we make this work without checking for the mode? (mode === MODES.YAML && resolveTokenName((_f = (_e = node.parent) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : "", mode) === TOKENS.OBJECT)); }; export const getChildrenNodes = (node) => { const children = []; let child = node.firstChild; while (child) { if (child) { children.push(child); } child = child === null || child === void 0 ? void 0 : child.nextSibling; } return children; }; export const getMatchingChildrenNodes = (node, nodeName, mode) => { return getChildrenNodes(node).filter((n) => resolveTokenName(n.name, mode) === nodeName); }; export const getMatchingChildNode = (node, nodeName, mode) => { var _a; return ((_a = getChildrenNodes(node).find((n) => resolveTokenName(n.name, mode) === nodeName)) !== null && _a !== void 0 ? _a : null); }; export const getChildValueNode = (node, mode) => { return getChildrenNodes(node).find((n) => isPrimitiveValueNode(n, mode)); }; const getArrayNodeChildren = (node, mode) => { return getChildrenNodes(node).filter((n) => PRIMITIVE_TYPES.includes(resolveTokenName(n.name, mode)) || COMPLEX_TYPES.includes(resolveTokenName(n.name, mode))); }; export const findNodeIndexInArrayNode = (arrayNode, valueNode, mode) => { return getArrayNodeChildren(arrayNode, mode).findIndex((nd) => nd.from === valueNode.from && nd.to === valueNode.to); }; export const getClosestNode = (node, nodeName, mode, depth = Infinity) => { let n = node; while (n && depth > 0) { if (resolveTokenName(n.name, mode) === nodeName) { return n; } n = n.parent; depth--; } return null; };