skir-codemirror-plugin 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/dist/codemirror/create_editor_state.d.ts +4 -2
- package/dist/codemirror/create_editor_state.d.ts.map +1 -1
- package/dist/codemirror/create_editor_state.js +178 -31
- package/dist/codemirror/create_editor_state.js.map +1 -1
- package/dist/codemirror/json_linter.d.ts.map +1 -1
- package/dist/codemirror/json_linter.js +67 -3
- package/dist/codemirror/json_linter.js.map +1 -1
- package/dist/codemirror/json_state.d.ts +5 -1
- package/dist/codemirror/json_state.d.ts.map +1 -1
- package/dist/codemirror/json_state.js +26 -1
- package/dist/codemirror/json_state.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/json/json_parser.js +35 -1
- package/dist/json/json_parser.js.map +1 -1
- package/dist/json/json_parser.test.js +48 -0
- package/dist/json/json_parser.test.js.map +1 -1
- package/dist/json/schema_validator.d.ts.map +1 -1
- package/dist/json/schema_validator.js +16 -11
- package/dist/json/schema_validator.js.map +1 -1
- package/dist/json/schema_validator.test.js +71 -0
- package/dist/json/schema_validator.test.js.map +1 -1
- package/dist/json/to_json.d.ts +1 -1
- package/dist/json/to_json.d.ts.map +1 -1
- package/dist/json/to_json.js +3 -3
- package/dist/json/to_json.js.map +1 -1
- package/dist/json/types.d.ts +4 -0
- package/dist/json/types.d.ts.map +1 -1
- package/dist/json/types.js.map +1 -1
- package/package.json +2 -3
- package/src/codemirror/create_editor_state.ts +272 -31
- package/src/codemirror/json_linter.ts +89 -4
- package/src/codemirror/json_state.ts +44 -1
- package/src/index.ts +1 -0
- package/src/json/json_parser.test.ts +51 -0
- package/src/json/json_parser.ts +37 -1
- package/src/json/schema_validator.test.ts +75 -0
- package/src/json/schema_validator.ts +20 -10
- package/src/json/to_json.ts +3 -3
- package/src/json/types.ts +7 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json_linter.js","sourceRoot":"","sources":["../../src/codemirror/json_linter.ts"],"names":[],"mappings":"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","sourcesContent":["import { Diagnostic } from \"@codemirror/lint\";\nimport { EditorView } from \"@codemirror/view\";\nimport { Hint, JsonError, JsonLiteral, TypeHint } from \"../json/types\";\nimport { ensureJsonState, jsonStateField } from \"./json_state\";\n\nexport function jsonLinter(\n editable: \"editable\" | \"read-only\",\n): (view: EditorView) => Diagnostic[] {\n function lintJson(view: EditorView): Diagnostic[] {\n const jsonState = view.state.field(jsonStateField, false);\n if (!jsonState) {\n return [];\n }\n\n const parseResult = jsonState.parseResult;\n if (parseResult.errors.length) {\n return parseResult.errors.map(errorToDiagnostic);\n }\n\n if (!jsonState.validationResult) {\n return [];\n }\n\n const { errors, hints } = jsonState.validationResult;\n return errors\n .map(errorToDiagnostic)\n .concat(hints.map((hint) => hintToDiagnostic(hint, editable)));\n }\n\n return lintJson;\n}\n\nfunction errorToDiagnostic(error: JsonError): Diagnostic {\n return {\n from: error.segment.start,\n to: error.segment.end,\n message: error.message,\n severity: \"error\",\n renderMessage: (): Node => {\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"cm-diagnostic-wrapper\";\n wrapper.textContent = error.message;\n return wrapper;\n },\n };\n}\n\nfunction getStringControlRows(\n view: EditorView,\n typeHint: TypeHint,\n value: JsonLiteral,\n editable: \"editable\" | \"read-only\",\n): HTMLDivElement[] {\n const headerRow = document.createElement(\"div\");\n headerRow.textContent = typeHint.message as string;\n\n const jsonCode = value.jsonCode;\n const parsedValue = JSON.parse(jsonCode) as string;\n\n const controlsRow = document.createElement(\"div\");\n controlsRow.className = \"cm-diagnostic-controls\";\n\n const label = document.createElement(\"span\");\n // label.className = \"cm-diagnostic-label\";\n label.textContent = \"Value:\";\n\n const textarea = document.createElement(\"textarea\");\n textarea.className = \"cm-diagnostic-textarea\";\n textarea.value = parsedValue;\n textarea.rows = 1;\n const isReadOnly = editable === \"read-only\";\n textarea.readOnly = isReadOnly;\n\n textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !isReadOnly) {\n e.preventDefault();\n const newValue = textarea.value;\n const newJsonString = JSON.stringify(newValue);\n\n view.dispatch({\n changes: {\n from: typeHint.segment.start,\n to: typeHint.segment.end,\n insert: newJsonString,\n },\n });\n }\n });\n\n controlsRow.appendChild(label);\n controlsRow.appendChild(textarea);\n\n return [headerRow, controlsRow];\n}\n\nfunction getTimestampControlRows(\n view: EditorView,\n typeHint: TypeHint,\n): HTMLDivElement[] {\n const headerRow = document.createElement(\"div\");\n headerRow.textContent = typeHint.message as string;\n\n let unixMillis: number | undefined;\n {\n const value = typeHint.valueContext!.value;\n if (value.kind === \"object\") {\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (\n unixMillisKv &&\n unixMillisKv.value.kind === \"literal\" &&\n unixMillisKv.value.type === \"number\"\n ) {\n unixMillis = JSON.parse(unixMillisKv.value.jsonCode) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n unixMillis = undefined;\n }\n }\n }\n }\n\n // Row 1: unix_millis input\n const row1 = document.createElement(\"div\");\n row1.className = \"cm-diagnostic-controls\";\n\n const label1 = document.createElement(\"span\");\n label1.className = \"cm-diagnostic-label\";\n label1.textContent = \"unix_millis:\";\n\n const field1 = document.createElement(\"div\");\n field1.className = \"cm-timestamp-field\";\n\n const unixMillisInput = document.createElement(\"input\");\n unixMillisInput.type = \"text\";\n unixMillisInput.className = \"cm-diagnostic-input\";\n unixMillisInput.value = unixMillis !== undefined ? String(unixMillis) : \"\";\n\n const error1 = document.createElement(\"div\");\n error1.className = \"cm-diagnostic-error-message\";\n error1.style.display = \"none\";\n\n field1.appendChild(unixMillisInput);\n field1.appendChild(error1);\n row1.appendChild(label1);\n row1.appendChild(field1);\n\n // Row 2: ISO 8601 date string input\n const row2 = document.createElement(\"div\");\n row2.className = \"cm-diagnostic-controls\";\n\n const label2 = document.createElement(\"span\");\n label2.className = \"cm-diagnostic-label\";\n label2.textContent = \"ISO 8601:\";\n\n const field2 = document.createElement(\"div\");\n field2.className = \"cm-timestamp-field\";\n\n const isoInput = document.createElement(\"input\");\n isoInput.type = \"text\";\n isoInput.className = \"cm-diagnostic-input\";\n if (unixMillis !== undefined) {\n isoInput.value = new Date(unixMillis).toISOString();\n }\n\n const error2 = document.createElement(\"div\");\n error2.className = \"cm-diagnostic-error-message\";\n error2.style.display = \"none\";\n\n field2.appendChild(isoInput);\n field2.appendChild(error2);\n row2.appendChild(label2);\n row2.appendChild(field2);\n\n // Row 3: Now button\n const row3 = document.createElement(\"div\");\n row3.className = \"cm-diagnostic-controls\";\n\n const nowButton = document.createElement(\"button\");\n nowButton.className = \"cm-diagnostic-button\";\n nowButton.textContent = \"Now\";\n\n row3.appendChild(nowButton);\n\n // Helper function to update the editor\n const updateEditor = (millis: number, formatted: string): void => {\n const value = typeHint.valueContext!.value;\n\n // Check if both keys exist in the object\n if (value.kind === \"object\") {\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n const formattedKv = value.keyValues[\"formatted\"];\n\n if (unixMillisKv && formattedKv) {\n // Update both values individually\n view.dispatch({\n changes: [\n {\n from: unixMillisKv.value.segment.start,\n to: unixMillisKv.value.segment.end,\n insert: String(millis),\n },\n {\n from: formattedKv.value.segment.start,\n to: formattedKv.value.segment.end,\n insert: JSON.stringify(formatted),\n },\n ],\n });\n\n return;\n }\n }\n\n // Default behavior: replace the whole object\n const newJsonString = `{\"unix_millis\": ${millis}, \"formatted\": \"${formatted}\"}`;\n\n const segment = typeHint.valueContext!.value.segment;\n view.dispatch({\n changes: {\n from: segment.start,\n to: segment.end,\n insert: newJsonString,\n },\n });\n\n ensureJsonState(view, (view as any).schema);\n };\n\n // Enter key handler for unix_millis input\n unixMillisInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n const value = unixMillisInput.value.trim();\n const millis = Number(value);\n\n // Validate\n if (value === \"\" || isNaN(millis) || !Number.isInteger(millis)) {\n error1.textContent = \"Must be an integer\";\n error1.style.display = \"block\";\n return;\n }\n\n if (millis < -8640000000000000 || millis > 8640000000000000) {\n error1.textContent = \"Timestamp out of range\";\n error1.style.display = \"block\";\n return;\n }\n\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n // Update ISO field and editor\n const formatted = new Date(millis).toISOString();\n isoInput.value = formatted;\n updateEditor(millis, formatted);\n }\n });\n\n // Enter key handler for ISO 8601 input\n isoInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n const value = isoInput.value.trim();\n const millis = Date.parse(value);\n\n // Validate\n if (isNaN(millis)) {\n error2.textContent = \"Invalid ISO 8601 date string\";\n error2.style.display = \"block\";\n return;\n }\n\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n // Update unix_millis field and editor\n const formatted = new Date(millis).toISOString();\n unixMillisInput.value = String(millis);\n updateEditor(millis, formatted);\n }\n });\n\n // Now button handler\n nowButton.addEventListener(\"click\", () => {\n const now = Date.now();\n const formatted = new Date(now).toISOString();\n\n unixMillisInput.value = String(now);\n isoInput.value = formatted;\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n updateEditor(now, formatted);\n });\n\n const controlsRow = document.createElement(\"div\");\n controlsRow.appendChild(row1);\n controlsRow.appendChild(row2);\n controlsRow.appendChild(row3);\n\n return [headerRow, controlsRow];\n}\n\nfunction hintToDiagnostic(\n typeHint: Hint,\n editable: \"editable\" | \"read-only\",\n): Diagnostic {\n const { message } = typeHint;\n return {\n from: typeHint.segment.start,\n to: typeHint.segment.end,\n message: \"\",\n severity: \"info\",\n renderMessage: (view): Node => {\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"cm-diagnostic-wrapper\";\n\n let rows: HTMLDivElement[];\n if (\n (message === \"string\" || message === \"string?\") &&\n typeHint.valueContext &&\n typeHint.valueContext.value.kind === \"literal\" &&\n typeHint.valueContext.value.type === \"string\"\n ) {\n // Render a string editing control for string hints.\n rows = getStringControlRows(\n view,\n typeHint,\n typeHint.valueContext.value,\n editable,\n );\n } else if (\n (message === \"timestamp\" || message === \"timestamp?\") &&\n typeHint.valueContext &&\n typeHint.valueContext.value.kind === \"object\" &&\n editable === \"editable\"\n ) {\n // Render a timestamp editing control for timestamp hints.\n rows = getTimestampControlRows(view, typeHint);\n } else {\n // Display the message for non-string types\n const pieces = typeof message === \"string\" ? [message] : message;\n rows = pieces.map((piece) => {\n const row = document.createElement(\"div\");\n row.textContent = piece;\n return row;\n });\n }\n\n for (const row of rows) {\n row.classList.add(\"diagnostic-row\");\n wrapper.appendChild(row);\n }\n\n return wrapper;\n },\n markClass: \"\",\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json_linter.js","sourceRoot":"","sources":["../../src/codemirror/json_linter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,UAAU,CACxB,QAAkC;IAElC,SAAS,QAAQ,CAAC,IAAgB;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAC1C,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC;QACrD,OAAO,MAAM;aACV,GAAG,CAAC,iBAAiB,CAAC;aACtB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAgB;IACzC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK;QACzB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,OAAO;QACjB,aAAa,EAAE,GAAS,EAAE;YACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,GAAG,uBAAuB,CAAC;YAC5C,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;YACpC,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAgB,EAChB,QAAkB,EAClB,KAAkB,EAClB,QAAkC;IAElC,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,OAAiB,CAAC;IAEnD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAW,CAAC;IAEnD,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClD,WAAW,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAEjD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,2CAA2C;IAC3C,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC;IAE7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAC9C,QAAQ,CAAC,KAAK,GAAG,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;IAClB,MAAM,UAAU,GAAG,QAAQ,KAAK,WAAW,CAAC;IAC5C,QAAQ,CAAC,QAAQ,GAAG,UAAU,CAAC;IAE/B,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACzC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;YACpD,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;YAChC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAE/C,IAAI,CAAC,QAAQ,CAAC;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;oBAC5B,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG;oBACxB,MAAM,EAAE,aAAa;iBACtB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC/B,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAElC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAgB,EAChB,QAAkB;IAElB,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,OAAiB,CAAC;IAEnD,IAAI,UAA8B,CAAC;IACnC,CAAC;QACC,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAa,CAAC,KAAK,CAAC;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACpD,IACE,YAAY;gBACZ,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;gBACrC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EACpC,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAW,CAAC;gBAC/D,IAAI,UAAU,GAAG,CAAC,gBAAgB,IAAI,gBAAgB,GAAG,UAAU,EAAE,CAAC;oBACpE,UAAU,GAAG,SAAS,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAE1C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,SAAS,GAAG,qBAAqB,CAAC;IACzC,MAAM,CAAC,WAAW,GAAG,cAAc,CAAC;IAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,SAAS,GAAG,oBAAoB,CAAC;IAExC,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACxD,eAAe,CAAC,IAAI,GAAG,MAAM,CAAC;IAC9B,eAAe,CAAC,SAAS,GAAG,qBAAqB,CAAC;IAClD,eAAe,CAAC,KAAK,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3E,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAE9B,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IACpC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzB,oCAAoC;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAE1C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,SAAS,GAAG,qBAAqB,CAAC;IACzC,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IAEjC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,SAAS,GAAG,oBAAoB,CAAC;IAExC,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,GAAG,qBAAqB,CAAC;IAC3C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,QAAQ,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAE9B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzB,oBAAoB;IACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAE1C,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACnD,SAAS,CAAC,SAAS,GAAG,sBAAsB,CAAC;IAC7C,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC;IAE9B,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAE5B,uCAAuC;IACvC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,SAAiB,EAAQ,EAAE;QAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAa,CAAC,KAAK,CAAC;QAE3C,yCAAyC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACpD,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAEjD,IAAI,YAAY,IAAI,WAAW,EAAE,CAAC;gBAChC,kCAAkC;gBAClC,IAAI,CAAC,QAAQ,CAAC;oBACZ,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;4BACtC,EAAE,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG;4BAClC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;yBACvB;wBACD;4BACE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;4BACrC,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG;4BACjC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;yBAClC;qBACF;iBACF,CAAC,CAAC;gBAEH,OAAO;YACT,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,MAAM,aAAa,GAAG,mBAAmB,MAAM,mBAAmB,SAAS,IAAI,CAAC;QAEhF,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAa,CAAC,KAAK,CAAC,OAAO,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO,CAAC,KAAK;gBACnB,EAAE,EAAE,OAAO,CAAC,GAAG;gBACf,MAAM,EAAE,aAAa;aACtB;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,0CAA0C;IAC1C,eAAe,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QAChD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAE7B,WAAW;YACX,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/D,MAAM,CAAC,WAAW,GAAG,oBAAoB,CAAC;gBAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,IAAI,MAAM,GAAG,CAAC,gBAAgB,IAAI,MAAM,GAAG,gBAAgB,EAAE,CAAC;gBAC5D,MAAM,CAAC,WAAW,GAAG,wBAAwB,CAAC;gBAC9C,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAE9B,8BAA8B;YAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;YAC3B,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,uCAAuC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACzC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEjC,WAAW;YACX,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClB,MAAM,CAAC,WAAW,GAAG,8BAA8B,CAAC;gBACpD,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAE9B,sCAAsC;YACtC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,eAAe,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YACvC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,qBAAqB;IACrB,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,eAAe,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACpC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAE9B,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClD,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAE9B,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,eAAe,CACtB,IAAgB,EAChB,QAAkB,EAClB,cAAuD;IAEvD,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClD,WAAW,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAEjD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,CAAC,SAAS,GAAG,qBAAqB,CAAC;IACxC,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC;IAE/B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,SAAS,GAAG,qBAAqB,CAAC;IAEzC,CAAC;QACC,0BAA0B;QAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC;QACzB,MAAM,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;QAC5B,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;IAClD,IACE,YAAY;QACZ,YAAY,CAAC,IAAI,KAAK,SAAS;QAC/B,YAAY,CAAC,IAAI,KAAK,QAAQ,EAC9B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAW,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAC1C,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAC1C,CAAC;QACH,IAAI,aAAqB,CAAC;QAC1B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,gBAAgB,CAChC,OAAO,CAAC,IAAI,EACZ,SAAS,CAAC,oBAAoB,CAC/B,CAAC;YACF,aAAa,GAAG,IAAI,CAAC,SAAS,CAC5B;gBACE,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,SAAS;aACjB,EACD,IAAI,EACJ,CAAC,CACF,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC;YACZ,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;gBAC5B,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG;gBACxB,MAAM,EAAE,aAAa;aACtB;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC/B,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAc,EACd,QAAkC;IAElC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IAC7B,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;QAC5B,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG;QACxB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,MAAM;QAChB,aAAa,EAAE,CAAC,IAAI,EAAQ,EAAE;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,GAAG,uBAAuB,CAAC;YAE5C,IAAI,IAAsB,CAAC;YAC3B,IACE,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,CAAC;gBAC/C,QAAQ,CAAC,YAAY;gBACrB,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;gBAC9C,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAC7C,CAAC;gBACD,oDAAoD;gBACpD,IAAI,GAAG,oBAAoB,CACzB,IAAI,EACJ,QAAQ,EACR,QAAQ,CAAC,YAAY,CAAC,KAAK,EAC3B,QAAQ,CACT,CAAC;YACJ,CAAC;iBAAM,IACL,CAAC,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,YAAY,CAAC;gBACrD,QAAQ,CAAC,YAAY;gBACrB,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAC7C,QAAQ,KAAK,UAAU,EACvB,CAAC;gBACD,0DAA0D;gBAC1D,IAAI,GAAG,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,uBAAuB;gBACvB,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACjE,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBAC1C,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;oBACxB,OAAO,GAAG,CAAC;gBACb,CAAC,CAAC,CAAC;gBACH,IACE,QAAQ,CAAC,YAAY;oBACrB,QAAQ,CAAC,cAAc;oBACvB,QAAQ,KAAK,UAAU,EACvB,CAAC;oBACD,uDAAuD;oBACvD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBACpC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,SAAS,EAAE,EAAE;KACd,CAAC;AACJ,CAAC","sourcesContent":["import { Diagnostic } from \"@codemirror/lint\";\nimport { EditorView } from \"@codemirror/view\";\nimport { makeJsonTemplate } from \"../json/to_json\";\nimport { Hint, JsonError, JsonLiteral, TypeHint } from \"../json/types\";\nimport { jsonStateField } from \"./json_state\";\n\nexport function jsonLinter(\n editable: \"editable\" | \"read-only\",\n): (view: EditorView) => Diagnostic[] {\n function lintJson(view: EditorView): Diagnostic[] {\n const jsonState = view.state.field(jsonStateField, false);\n if (!jsonState) {\n return [];\n }\n\n const parseResult = jsonState.parseResult;\n if (parseResult.errors.length) {\n return parseResult.errors.map(errorToDiagnostic);\n }\n\n if (!jsonState.validationResult) {\n return [];\n }\n\n const { errors, hints } = jsonState.validationResult;\n return errors\n .map(errorToDiagnostic)\n .concat(hints.map((hint) => hintToDiagnostic(hint, editable)));\n }\n\n return lintJson;\n}\n\nfunction errorToDiagnostic(error: JsonError): Diagnostic {\n return {\n from: error.segment.start,\n to: error.segment.end,\n message: error.message,\n severity: \"error\",\n renderMessage: (): Node => {\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"cm-diagnostic-wrapper\";\n wrapper.textContent = error.message;\n return wrapper;\n },\n };\n}\n\nfunction getStringControlRows(\n view: EditorView,\n typeHint: TypeHint,\n value: JsonLiteral,\n editable: \"editable\" | \"read-only\",\n): HTMLDivElement[] {\n const headerRow = document.createElement(\"div\");\n headerRow.textContent = typeHint.message as string;\n\n const jsonCode = value.jsonCode;\n const parsedValue = JSON.parse(jsonCode) as string;\n\n const controlsRow = document.createElement(\"div\");\n controlsRow.className = \"cm-diagnostic-controls\";\n\n const label = document.createElement(\"span\");\n // label.className = \"cm-diagnostic-label\";\n label.textContent = \"Value:\";\n\n const textarea = document.createElement(\"textarea\");\n textarea.className = \"cm-diagnostic-textarea\";\n textarea.value = parsedValue;\n textarea.rows = 1;\n const isReadOnly = editable === \"read-only\";\n textarea.readOnly = isReadOnly;\n\n textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !isReadOnly) {\n e.preventDefault();\n const newValue = textarea.value;\n const newJsonString = JSON.stringify(newValue);\n\n view.dispatch({\n changes: {\n from: typeHint.segment.start,\n to: typeHint.segment.end,\n insert: newJsonString,\n },\n });\n }\n });\n\n controlsRow.appendChild(label);\n controlsRow.appendChild(textarea);\n\n return [headerRow, controlsRow];\n}\n\nfunction getTimestampControlRows(\n view: EditorView,\n typeHint: TypeHint,\n): HTMLDivElement[] {\n const headerRow = document.createElement(\"div\");\n headerRow.textContent = typeHint.message as string;\n\n let unixMillis: number | undefined;\n {\n const value = typeHint.valueContext!.value;\n if (value.kind === \"object\") {\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (\n unixMillisKv &&\n unixMillisKv.value.kind === \"literal\" &&\n unixMillisKv.value.type === \"number\"\n ) {\n unixMillis = JSON.parse(unixMillisKv.value.jsonCode) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n unixMillis = undefined;\n }\n }\n }\n }\n\n // Row 1: unix_millis input\n const row1 = document.createElement(\"div\");\n row1.className = \"cm-diagnostic-controls\";\n\n const label1 = document.createElement(\"span\");\n label1.className = \"cm-diagnostic-label\";\n label1.textContent = \"unix_millis:\";\n\n const field1 = document.createElement(\"div\");\n field1.className = \"cm-timestamp-field\";\n\n const unixMillisInput = document.createElement(\"input\");\n unixMillisInput.type = \"text\";\n unixMillisInput.className = \"cm-diagnostic-input\";\n unixMillisInput.value = unixMillis !== undefined ? String(unixMillis) : \"\";\n\n const error1 = document.createElement(\"div\");\n error1.className = \"cm-diagnostic-error-message\";\n error1.style.display = \"none\";\n\n field1.appendChild(unixMillisInput);\n field1.appendChild(error1);\n row1.appendChild(label1);\n row1.appendChild(field1);\n\n // Row 2: ISO 8601 date string input\n const row2 = document.createElement(\"div\");\n row2.className = \"cm-diagnostic-controls\";\n\n const label2 = document.createElement(\"span\");\n label2.className = \"cm-diagnostic-label\";\n label2.textContent = \"ISO 8601:\";\n\n const field2 = document.createElement(\"div\");\n field2.className = \"cm-timestamp-field\";\n\n const isoInput = document.createElement(\"input\");\n isoInput.type = \"text\";\n isoInput.className = \"cm-diagnostic-input\";\n if (unixMillis !== undefined) {\n isoInput.value = new Date(unixMillis).toISOString();\n }\n\n const error2 = document.createElement(\"div\");\n error2.className = \"cm-diagnostic-error-message\";\n error2.style.display = \"none\";\n\n field2.appendChild(isoInput);\n field2.appendChild(error2);\n row2.appendChild(label2);\n row2.appendChild(field2);\n\n // Row 3: Now button\n const row3 = document.createElement(\"div\");\n row3.className = \"cm-diagnostic-controls\";\n\n const nowButton = document.createElement(\"button\");\n nowButton.className = \"cm-diagnostic-button\";\n nowButton.textContent = \"Now\";\n\n row3.appendChild(nowButton);\n\n // Helper function to update the editor\n const updateEditor = (millis: number, formatted: string): void => {\n const value = typeHint.valueContext!.value;\n\n // Check if both keys exist in the object\n if (value.kind === \"object\") {\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n const formattedKv = value.keyValues[\"formatted\"];\n\n if (unixMillisKv && formattedKv) {\n // Update both values individually\n view.dispatch({\n changes: [\n {\n from: unixMillisKv.value.segment.start,\n to: unixMillisKv.value.segment.end,\n insert: String(millis),\n },\n {\n from: formattedKv.value.segment.start,\n to: formattedKv.value.segment.end,\n insert: JSON.stringify(formatted),\n },\n ],\n });\n\n return;\n }\n }\n\n // Default behavior: replace the whole object\n const newJsonString = `{\"unix_millis\": ${millis}, \"formatted\": \"${formatted}\"}`;\n\n const segment = typeHint.valueContext!.value.segment;\n view.dispatch({\n changes: {\n from: segment.start,\n to: segment.end,\n insert: newJsonString,\n },\n });\n };\n\n // Enter key handler for unix_millis input\n unixMillisInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n const value = unixMillisInput.value.trim();\n const millis = Number(value);\n\n // Validate\n if (value === \"\" || isNaN(millis) || !Number.isInteger(millis)) {\n error1.textContent = \"Must be an integer\";\n error1.style.display = \"block\";\n return;\n }\n\n if (millis < -8640000000000000 || millis > 8640000000000000) {\n error1.textContent = \"Timestamp out of range\";\n error1.style.display = \"block\";\n return;\n }\n\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n // Update ISO field and editor\n const formatted = new Date(millis).toISOString();\n isoInput.value = formatted;\n updateEditor(millis, formatted);\n }\n });\n\n // Enter key handler for ISO 8601 input\n isoInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n const value = isoInput.value.trim();\n const millis = Date.parse(value);\n\n // Validate\n if (isNaN(millis)) {\n error2.textContent = \"Invalid ISO 8601 date string\";\n error2.style.display = \"block\";\n return;\n }\n\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n // Update unix_millis field and editor\n const formatted = new Date(millis).toISOString();\n unixMillisInput.value = String(millis);\n updateEditor(millis, formatted);\n }\n });\n\n // Now button handler\n nowButton.addEventListener(\"click\", () => {\n const now = Date.now();\n const formatted = new Date(now).toISOString();\n\n unixMillisInput.value = String(now);\n isoInput.value = formatted;\n error1.style.display = \"none\";\n error2.style.display = \"none\";\n\n updateEditor(now, formatted);\n });\n\n const controlsRow = document.createElement(\"div\");\n controlsRow.appendChild(row1);\n controlsRow.appendChild(row2);\n controlsRow.appendChild(row3);\n\n return [headerRow, controlsRow];\n}\n\nfunction getEnumDropdown(\n view: EditorView,\n typeHint: TypeHint,\n enumDefinition: NonNullable<TypeHint[\"enumDefinition\"]>,\n): HTMLDivElement {\n const controlsRow = document.createElement(\"div\");\n controlsRow.className = \"cm-diagnostic-controls\";\n\n const label = document.createElement(\"span\");\n label.className = \"cm-diagnostic-label\";\n label.textContent = \"Variant:\";\n\n const select = document.createElement(\"select\");\n select.className = \"cm-diagnostic-input\";\n\n {\n // Add the UNKNOWN variant\n const option = document.createElement(\"option\");\n option.value = \"UNKNOWN\";\n option.textContent = \"UNKNOWN\";\n select.appendChild(option);\n }\n for (const variant of enumDefinition.variants) {\n const option = document.createElement(\"option\");\n option.value = variant.name;\n option.textContent = variant.name;\n select.appendChild(option);\n }\n\n const currentValue = typeHint.valueContext?.value;\n if (\n currentValue &&\n currentValue.kind === \"literal\" &&\n currentValue.type === \"string\"\n ) {\n try {\n select.value = JSON.parse(currentValue.jsonCode) as string;\n } catch {\n // Ignore invalid value and keep the default selection.\n }\n }\n\n select.addEventListener(\"change\", () => {\n const variant = enumDefinition.variants.find(\n (variant) => variant.name === select.value,\n )!;\n let newJsonString: string;\n if (variant.type) {\n const jsonState = view.state.field(jsonStateField, false)!;\n const valueJson = makeJsonTemplate(\n variant.type,\n jsonState.recordIdToDefinition,\n );\n newJsonString = JSON.stringify(\n {\n kind: variant.name,\n value: valueJson,\n },\n null,\n 2,\n ).replaceAll(\"\\n\", \"\\n\" + \" \".repeat(typeHint.valueContext.value.indent));\n } else {\n newJsonString = JSON.stringify(variant.name);\n }\n view.dispatch({\n changes: {\n from: typeHint.segment.start,\n to: typeHint.segment.end,\n insert: newJsonString,\n },\n });\n });\n\n controlsRow.appendChild(label);\n controlsRow.appendChild(select);\n return controlsRow;\n}\n\nfunction hintToDiagnostic(\n typeHint: Hint,\n editable: \"editable\" | \"read-only\",\n): Diagnostic {\n const { message } = typeHint;\n return {\n from: typeHint.segment.start,\n to: typeHint.segment.end,\n message: \"\",\n severity: \"info\",\n renderMessage: (view): Node => {\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"cm-diagnostic-wrapper\";\n\n let rows: HTMLDivElement[];\n if (\n (message === \"string\" || message === \"string?\") &&\n typeHint.valueContext &&\n typeHint.valueContext.value.kind === \"literal\" &&\n typeHint.valueContext.value.type === \"string\"\n ) {\n // Render a string editing control for string hints.\n rows = getStringControlRows(\n view,\n typeHint,\n typeHint.valueContext.value,\n editable,\n );\n } else if (\n (message === \"timestamp\" || message === \"timestamp?\") &&\n typeHint.valueContext &&\n typeHint.valueContext.value.kind === \"object\" &&\n editable === \"editable\"\n ) {\n // Render a timestamp editing control for timestamp hints.\n rows = getTimestampControlRows(view, typeHint);\n } else {\n // Display the message.\n const pieces = typeof message === \"string\" ? [message] : message;\n rows = pieces.map((piece) => {\n const row = document.createElement(\"div\");\n row.textContent = piece;\n return row;\n });\n if (\n typeHint.valueContext &&\n typeHint.enumDefinition &&\n editable === \"editable\"\n ) {\n // Render a dropdown for selecting a different variant.\n rows.push(getEnumDropdown(view, typeHint, typeHint.enumDefinition));\n }\n }\n\n for (const row of rows) {\n row.classList.add(\"diagnostic-row\");\n wrapper.appendChild(row);\n }\n\n return wrapper;\n },\n markClass: \"\",\n };\n}\n"]}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Extension, StateField } from "@codemirror/state";
|
|
2
2
|
import { EditorView } from "@codemirror/view";
|
|
3
|
-
import type { JsonParseResult, TypeDefinition, ValidationResult } from "../json/types";
|
|
3
|
+
import type { JsonParseResult, RecordDefinition, TypeDefinition, ValidationResult } from "../json/types";
|
|
4
4
|
export interface JsonState {
|
|
5
5
|
readonly parseResult: JsonParseResult;
|
|
6
6
|
readonly validationResult?: ValidationResult;
|
|
7
7
|
readonly source: string;
|
|
8
|
+
readonly schema: TypeDefinition;
|
|
9
|
+
readonly recordIdToDefinition: {
|
|
10
|
+
[id: string]: RecordDefinition;
|
|
11
|
+
};
|
|
8
12
|
}
|
|
9
13
|
export declare const jsonStateField: StateField<JsonState | null>;
|
|
10
14
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json_state.d.ts","sourceRoot":"","sources":["../../src/codemirror/json_state.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAET,UAAU,EAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AAGtE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"json_state.d.ts","sourceRoot":"","sources":["../../src/codemirror/json_state.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAET,UAAU,EAEX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AAGtE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,oBAAoB,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAAA;KAAE,CAAC;CACnE;AAID,eAAO,MAAM,cAAc,8BAYzB,CAAC;AAEH;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,cAAc,GACrB,SAAS,CAkCX;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,EAAE,CAiHvE"}
|
|
@@ -33,7 +33,14 @@ export function ensureJsonState(view, schema) {
|
|
|
33
33
|
if (parseResult.value) {
|
|
34
34
|
validationResult = validateSchema(parseResult.value, schema);
|
|
35
35
|
}
|
|
36
|
-
const
|
|
36
|
+
const recordIdToDefinition = indexRecordDefinitions(schema, currentState);
|
|
37
|
+
const newState = {
|
|
38
|
+
parseResult,
|
|
39
|
+
validationResult,
|
|
40
|
+
source,
|
|
41
|
+
schema,
|
|
42
|
+
recordIdToDefinition,
|
|
43
|
+
};
|
|
37
44
|
// Update the state if it's different
|
|
38
45
|
if (!currentState || currentState !== newState) {
|
|
39
46
|
view.dispatch({
|
|
@@ -93,22 +100,30 @@ export function debouncedJsonParser(schema) {
|
|
|
93
100
|
to: edit.segment.end,
|
|
94
101
|
insert: edit.replacement,
|
|
95
102
|
}));
|
|
103
|
+
const oldState = this.view.state.field(jsonStateField, false);
|
|
104
|
+
const recordIdToDefinition = indexRecordDefinitions(schema, oldState);
|
|
96
105
|
this.view.dispatch({
|
|
97
106
|
changes,
|
|
98
107
|
effects: updateJsonState.of({
|
|
99
108
|
parseResult,
|
|
100
109
|
validationResult,
|
|
101
110
|
source,
|
|
111
|
+
schema,
|
|
112
|
+
recordIdToDefinition,
|
|
102
113
|
}),
|
|
103
114
|
scrollIntoView: true,
|
|
104
115
|
});
|
|
105
116
|
}
|
|
106
117
|
else {
|
|
118
|
+
const oldState = this.view.state.field(jsonStateField, false);
|
|
119
|
+
const recordIdToDefinition = indexRecordDefinitions(schema, oldState);
|
|
107
120
|
this.view.dispatch({
|
|
108
121
|
effects: updateJsonState.of({
|
|
109
122
|
parseResult,
|
|
110
123
|
validationResult,
|
|
111
124
|
source,
|
|
125
|
+
schema,
|
|
126
|
+
recordIdToDefinition,
|
|
112
127
|
}),
|
|
113
128
|
});
|
|
114
129
|
}
|
|
@@ -121,4 +136,14 @@ export function debouncedJsonParser(schema) {
|
|
|
121
136
|
}),
|
|
122
137
|
];
|
|
123
138
|
}
|
|
139
|
+
function indexRecordDefinitions(schema, oldState) {
|
|
140
|
+
if (schema === oldState?.schema) {
|
|
141
|
+
return oldState.recordIdToDefinition;
|
|
142
|
+
}
|
|
143
|
+
const idToRecordDef = {};
|
|
144
|
+
for (const recordDef of schema.records) {
|
|
145
|
+
idToRecordDef[recordDef.id] = recordDef;
|
|
146
|
+
}
|
|
147
|
+
return idToRecordDef;
|
|
148
|
+
}
|
|
124
149
|
//# sourceMappingURL=json_state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json_state.js","sourceRoot":"","sources":["../../src/codemirror/json_state.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Extension,\n StateEffect,\n StateField,\n Transaction,\n} from \"@codemirror/state\";\nimport { EditorView, ViewPlugin, ViewUpdate } from \"@codemirror/view\";\nimport { parseJsonValue } from \"../json/json_parser\";\nimport { validateSchema } from \"../json/schema_validator\";\nimport type {\n JsonParseResult,\n TypeDefinition,\n ValidationResult,\n} from \"../json/types\";\n\nexport interface JsonState {\n readonly parseResult: JsonParseResult;\n readonly validationResult?: ValidationResult;\n readonly source: string;\n}\n\nconst updateJsonState = StateEffect.define<JsonState>();\n\nexport const jsonStateField = StateField.define<JsonState | null>({\n create(): JsonState | null {\n return null;\n },\n update(value, tr): JsonState | null {\n for (const effect of tr.effects) {\n if (effect.is(updateJsonState)) {\n return effect.value;\n }\n }\n return value;\n },\n});\n\n/**\n * Ensures the JSON state is up-to-date with the current document.\n * If the state is stale or missing, triggers an immediate parse and returns the updated state.\n */\nexport function ensureJsonState(\n view: EditorView,\n schema: TypeDefinition,\n): JsonState {\n const currentState = view.state.field(jsonStateField, false);\n const source = view.state.doc.toString();\n\n // If the source hasn't changed, return the current state\n if (currentState && currentState.source === source) {\n return currentState;\n }\n\n // Parse and validate immediately\n const parseResult = parseJsonValue(source);\n let validationResult: ValidationResult | undefined;\n if (parseResult.value) {\n validationResult = validateSchema(parseResult.value, schema);\n }\n\n const newState: JsonState = { parseResult, validationResult, source };\n\n // Update the state if it's different\n if (!currentState || currentState !== newState) {\n view.dispatch({\n effects: updateJsonState.of(newState),\n });\n }\n\n return newState;\n}\n\nexport function debouncedJsonParser(schema: TypeDefinition): Extension[] {\n return [\n jsonStateField,\n ViewPlugin.fromClass(\n class {\n timeout: number | null = null;\n view: EditorView;\n\n constructor(view: EditorView) {\n this.view = view;\n this.scheduleUpdate();\n }\n\n update(update: ViewUpdate): void {\n if (update.docChanged) {\n const isUndo = update.transactions.some(\n (tr) =>\n tr.annotation(Transaction.userEvent) === \"undo\" ||\n tr.annotation(Transaction.userEvent) === \"redo\",\n );\n this.scheduleUpdate(isUndo ? \"from-undo\" : undefined);\n }\n }\n\n scheduleUpdate(fromUndo?: \"from-undo\"): void {\n if (this.timeout !== null) {\n clearTimeout(this.timeout);\n }\n this.timeout = window.setTimeout(() => {\n this.parseJson(fromUndo);\n this.timeout = null;\n }, 200);\n }\n\n parseJson(fromUndo: \"from-undo\" | undefined): void {\n const source = this.view.state.doc.toString();\n const parseResult = parseJsonValue(source);\n\n let validationResult: ValidationResult | undefined;\n if (parseResult.value) {\n validationResult = validateSchema(parseResult.value, schema);\n }\n\n const cursorInsideEdit = (): boolean => {\n const cursorPos = this.view.state.selection.main.head;\n return parseResult.edits.some(\n (edit) =>\n edit.segment.start <= cursorPos &&\n cursorPos <= edit.segment.end,\n );\n };\n\n // Apply edits if all these conditions are satisfied:\n // - no error\n // - the cursor is not inside any of the edited segments, to avoid\n // disrupting the user while they're typing\n // - the update is not triggered by an undo operation\n if (\n !fromUndo &&\n parseResult.edits.length &&\n parseResult.errors.length <= 0 &&\n !cursorInsideEdit()\n ) {\n const changes = parseResult.edits.map((edit) => ({\n from: edit.segment.start,\n to: edit.segment.end,\n insert: edit.replacement,\n }));\n\n this.view.dispatch({\n changes,\n effects: updateJsonState.of({\n parseResult,\n validationResult,\n source,\n }),\n scrollIntoView: true,\n });\n } else {\n this.view.dispatch({\n effects: updateJsonState.of({\n parseResult,\n validationResult,\n source,\n }),\n });\n }\n }\n\n destroy(): void {\n if (this.timeout !== null) {\n clearTimeout(this.timeout);\n }\n }\n },\n ),\n ];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json_state.js","sourceRoot":"","sources":["../../src/codemirror/json_state.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Extension,\n StateEffect,\n StateField,\n Transaction,\n} from \"@codemirror/state\";\nimport { EditorView, ViewPlugin, ViewUpdate } from \"@codemirror/view\";\nimport { parseJsonValue } from \"../json/json_parser\";\nimport { validateSchema } from \"../json/schema_validator\";\nimport type {\n JsonParseResult,\n RecordDefinition,\n TypeDefinition,\n ValidationResult,\n} from \"../json/types\";\n\nexport interface JsonState {\n readonly parseResult: JsonParseResult;\n readonly validationResult?: ValidationResult;\n readonly source: string;\n readonly schema: TypeDefinition;\n readonly recordIdToDefinition: { [id: string]: RecordDefinition };\n}\n\nconst updateJsonState = StateEffect.define<JsonState>();\n\nexport const jsonStateField = StateField.define<JsonState | null>({\n create(): JsonState | null {\n return null;\n },\n update(value, tr): JsonState | null {\n for (const effect of tr.effects) {\n if (effect.is(updateJsonState)) {\n return effect.value;\n }\n }\n return value;\n },\n});\n\n/**\n * Ensures the JSON state is up-to-date with the current document.\n * If the state is stale or missing, triggers an immediate parse and returns the updated state.\n */\nexport function ensureJsonState(\n view: EditorView,\n schema: TypeDefinition,\n): JsonState {\n const currentState = view.state.field(jsonStateField, false);\n const source = view.state.doc.toString();\n\n // If the source hasn't changed, return the current state\n if (currentState && currentState.source === source) {\n return currentState;\n }\n\n // Parse and validate immediately\n const parseResult = parseJsonValue(source);\n let validationResult: ValidationResult | undefined;\n if (parseResult.value) {\n validationResult = validateSchema(parseResult.value, schema);\n }\n\n const recordIdToDefinition = indexRecordDefinitions(schema, currentState);\n\n const newState: JsonState = {\n parseResult,\n validationResult,\n source,\n schema,\n recordIdToDefinition,\n };\n\n // Update the state if it's different\n if (!currentState || currentState !== newState) {\n view.dispatch({\n effects: updateJsonState.of(newState),\n });\n }\n\n return newState;\n}\n\nexport function debouncedJsonParser(schema: TypeDefinition): Extension[] {\n return [\n jsonStateField,\n ViewPlugin.fromClass(\n class {\n timeout: number | null = null;\n view: EditorView;\n\n constructor(view: EditorView) {\n this.view = view;\n this.scheduleUpdate();\n }\n\n update(update: ViewUpdate): void {\n if (update.docChanged) {\n const isUndo = update.transactions.some(\n (tr) =>\n tr.annotation(Transaction.userEvent) === \"undo\" ||\n tr.annotation(Transaction.userEvent) === \"redo\",\n );\n this.scheduleUpdate(isUndo ? \"from-undo\" : undefined);\n }\n }\n\n scheduleUpdate(fromUndo?: \"from-undo\"): void {\n if (this.timeout !== null) {\n clearTimeout(this.timeout);\n }\n this.timeout = window.setTimeout(() => {\n this.parseJson(fromUndo);\n this.timeout = null;\n }, 200);\n }\n\n parseJson(fromUndo: \"from-undo\" | undefined): void {\n const source = this.view.state.doc.toString();\n const parseResult = parseJsonValue(source);\n\n let validationResult: ValidationResult | undefined;\n if (parseResult.value) {\n validationResult = validateSchema(parseResult.value, schema);\n }\n\n const cursorInsideEdit = (): boolean => {\n const cursorPos = this.view.state.selection.main.head;\n return parseResult.edits.some(\n (edit) =>\n edit.segment.start <= cursorPos &&\n cursorPos <= edit.segment.end,\n );\n };\n\n // Apply edits if all these conditions are satisfied:\n // - no error\n // - the cursor is not inside any of the edited segments, to avoid\n // disrupting the user while they're typing\n // - the update is not triggered by an undo operation\n if (\n !fromUndo &&\n parseResult.edits.length &&\n parseResult.errors.length <= 0 &&\n !cursorInsideEdit()\n ) {\n const changes = parseResult.edits.map((edit) => ({\n from: edit.segment.start,\n to: edit.segment.end,\n insert: edit.replacement,\n }));\n\n const oldState = this.view.state.field(jsonStateField, false);\n const recordIdToDefinition = indexRecordDefinitions(\n schema,\n oldState,\n );\n\n this.view.dispatch({\n changes,\n effects: updateJsonState.of({\n parseResult,\n validationResult,\n source,\n schema,\n recordIdToDefinition,\n }),\n scrollIntoView: true,\n });\n } else {\n const oldState = this.view.state.field(jsonStateField, false);\n const recordIdToDefinition = indexRecordDefinitions(\n schema,\n oldState,\n );\n\n this.view.dispatch({\n effects: updateJsonState.of({\n parseResult,\n validationResult,\n source,\n schema,\n recordIdToDefinition,\n }),\n });\n }\n }\n\n destroy(): void {\n if (this.timeout !== null) {\n clearTimeout(this.timeout);\n }\n }\n },\n ),\n ];\n}\n\nfunction indexRecordDefinitions(\n schema: TypeDefinition,\n oldState: JsonState | null | undefined,\n): {\n [id: string]: RecordDefinition;\n} {\n if (schema === oldState?.schema) {\n return oldState.recordIdToDefinition;\n }\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const recordDef of schema.records) {\n idToRecordDef[recordDef.id] = recordDef;\n }\n return idToRecordDef;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createEditorState } from "./codemirror/create_editor_state";
|
|
2
|
-
export type { CreateEditorStateParams, CustomTheme, } from "./codemirror/create_editor_state";
|
|
2
|
+
export type { BuiltinThemeName, CreateEditorStateParams, CustomTheme, } from "./codemirror/create_editor_state";
|
|
3
3
|
export { ensureJsonState } from "./codemirror/json_state";
|
|
4
4
|
export type { JsonState } from "./codemirror/json_state";
|
|
5
5
|
export { toJson } from "./json/to_json";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,YAAY,EACV,uBAAuB,EACvB,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,mBAAmB,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,WAAW,GACZ,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,mBAAmB,cAAc,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAMrE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { createEditorState } from \"./codemirror/create_editor_state\";\nexport type {\n BuiltinThemeName,\n CreateEditorStateParams,\n CustomTheme,\n} from \"./codemirror/create_editor_state\";\nexport { ensureJsonState } from \"./codemirror/json_state\";\nexport type { JsonState } from \"./codemirror/json_state\";\nexport { toJson } from \"./json/to_json\";\nexport type * from \"./json/types\";\n"]}
|
package/dist/json/json_parser.js
CHANGED
|
@@ -19,12 +19,25 @@ export function parseJsonValue(input) {
|
|
|
19
19
|
function tokenize(input) {
|
|
20
20
|
const tokens = [];
|
|
21
21
|
let pos = 0;
|
|
22
|
+
let lineIndent = 0;
|
|
23
|
+
let lineHasContent = false;
|
|
22
24
|
const whitespaceRegex = /[ \t\r\n]*/y;
|
|
23
25
|
const tokenRegex = /([[\]{}:,]|(-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)|false|true|null|("(((?=\\)\\(["\\/ bfnrt]|u[0-9a-fA-F]{4}))|[^"\\\0-\x1F\x7F]+)*")|$)/y;
|
|
24
26
|
while (true) {
|
|
27
|
+
const beforeWhitespacePos = pos;
|
|
25
28
|
whitespaceRegex.lastIndex = pos;
|
|
26
29
|
whitespaceRegex.exec(input);
|
|
27
30
|
pos = whitespaceRegex.lastIndex;
|
|
31
|
+
for (let i = beforeWhitespacePos; i < pos; ++i) {
|
|
32
|
+
const ch = input[i];
|
|
33
|
+
if (ch === "\n") {
|
|
34
|
+
lineIndent = 0;
|
|
35
|
+
lineHasContent = false;
|
|
36
|
+
}
|
|
37
|
+
else if (!lineHasContent && (ch === " " || ch === "\t")) {
|
|
38
|
+
lineIndent++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
28
41
|
tokenRegex.lastIndex = pos;
|
|
29
42
|
const tokenMatch = tokenRegex.exec(input);
|
|
30
43
|
if (tokenMatch) {
|
|
@@ -33,9 +46,16 @@ function tokenize(input) {
|
|
|
33
46
|
start: pos,
|
|
34
47
|
end: pos + tokenText.length,
|
|
35
48
|
};
|
|
36
|
-
const token = {
|
|
49
|
+
const token = {
|
|
50
|
+
segment,
|
|
51
|
+
jsonCode: tokenText,
|
|
52
|
+
indent: lineIndent,
|
|
53
|
+
};
|
|
37
54
|
pos = tokenRegex.lastIndex;
|
|
38
55
|
tokens.push(token);
|
|
56
|
+
if (tokenText !== "") {
|
|
57
|
+
lineHasContent = true;
|
|
58
|
+
}
|
|
39
59
|
if (tokenText === "") {
|
|
40
60
|
return {
|
|
41
61
|
kind: "tokens",
|
|
@@ -69,6 +89,7 @@ class JsonParser {
|
|
|
69
89
|
parseValueOrSkip() {
|
|
70
90
|
const token = this.peekToken();
|
|
71
91
|
const firstChar = token.jsonCode ? token.jsonCode[0] : "";
|
|
92
|
+
const { indent } = token;
|
|
72
93
|
switch (firstChar) {
|
|
73
94
|
case "[":
|
|
74
95
|
return this.parseArray();
|
|
@@ -82,6 +103,7 @@ class JsonParser {
|
|
|
82
103
|
segment: token.segment,
|
|
83
104
|
jsonCode: "null",
|
|
84
105
|
type: "null",
|
|
106
|
+
indent,
|
|
85
107
|
};
|
|
86
108
|
case "f":
|
|
87
109
|
this.nextToken();
|
|
@@ -91,6 +113,7 @@ class JsonParser {
|
|
|
91
113
|
segment: token.segment,
|
|
92
114
|
jsonCode: "false",
|
|
93
115
|
type: "boolean",
|
|
116
|
+
indent,
|
|
94
117
|
};
|
|
95
118
|
case "t":
|
|
96
119
|
this.nextToken();
|
|
@@ -100,6 +123,7 @@ class JsonParser {
|
|
|
100
123
|
segment: token.segment,
|
|
101
124
|
jsonCode: "true",
|
|
102
125
|
type: "boolean",
|
|
126
|
+
indent,
|
|
103
127
|
};
|
|
104
128
|
case '"':
|
|
105
129
|
this.nextToken();
|
|
@@ -109,6 +133,7 @@ class JsonParser {
|
|
|
109
133
|
segment: token.segment,
|
|
110
134
|
jsonCode: token.jsonCode,
|
|
111
135
|
type: "string",
|
|
136
|
+
indent,
|
|
112
137
|
};
|
|
113
138
|
case "0":
|
|
114
139
|
case "1":
|
|
@@ -128,6 +153,7 @@ class JsonParser {
|
|
|
128
153
|
segment: token.segment,
|
|
129
154
|
jsonCode: token.jsonCode,
|
|
130
155
|
type: "number",
|
|
156
|
+
indent,
|
|
131
157
|
};
|
|
132
158
|
}
|
|
133
159
|
this.errors.push({
|
|
@@ -140,6 +166,7 @@ class JsonParser {
|
|
|
140
166
|
}
|
|
141
167
|
parseArray() {
|
|
142
168
|
const leftBracket = this.nextToken();
|
|
169
|
+
const { indent } = leftBracket;
|
|
143
170
|
const values = [];
|
|
144
171
|
while (true) {
|
|
145
172
|
if (this.peekToken().jsonCode === "]") {
|
|
@@ -152,6 +179,7 @@ class JsonParser {
|
|
|
152
179
|
end: rightBracket.segment.end,
|
|
153
180
|
},
|
|
154
181
|
values,
|
|
182
|
+
indent,
|
|
155
183
|
};
|
|
156
184
|
}
|
|
157
185
|
if (this.peekToken().jsonCode === "}") {
|
|
@@ -169,6 +197,7 @@ class JsonParser {
|
|
|
169
197
|
end: wrongBracket.segment.end,
|
|
170
198
|
},
|
|
171
199
|
values,
|
|
200
|
+
indent,
|
|
172
201
|
};
|
|
173
202
|
}
|
|
174
203
|
if (this.peekToken().jsonCode === "") {
|
|
@@ -182,6 +211,7 @@ class JsonParser {
|
|
|
182
211
|
end: this.peekToken().segment.start,
|
|
183
212
|
},
|
|
184
213
|
values,
|
|
214
|
+
indent,
|
|
185
215
|
};
|
|
186
216
|
}
|
|
187
217
|
const value = this.parseValueOrSkip();
|
|
@@ -203,6 +233,7 @@ class JsonParser {
|
|
|
203
233
|
}
|
|
204
234
|
parseObject() {
|
|
205
235
|
const leftBracket = this.nextToken();
|
|
236
|
+
const { indent } = leftBracket;
|
|
206
237
|
const keyValues = {};
|
|
207
238
|
const allKeys = [];
|
|
208
239
|
while (true) {
|
|
@@ -217,6 +248,7 @@ class JsonParser {
|
|
|
217
248
|
},
|
|
218
249
|
keyValues,
|
|
219
250
|
allKeys,
|
|
251
|
+
indent,
|
|
220
252
|
};
|
|
221
253
|
}
|
|
222
254
|
if (this.peekToken().jsonCode === "]") {
|
|
@@ -235,6 +267,7 @@ class JsonParser {
|
|
|
235
267
|
},
|
|
236
268
|
keyValues,
|
|
237
269
|
allKeys,
|
|
270
|
+
indent,
|
|
238
271
|
};
|
|
239
272
|
}
|
|
240
273
|
if (this.peekToken().jsonCode === "") {
|
|
@@ -249,6 +282,7 @@ class JsonParser {
|
|
|
249
282
|
},
|
|
250
283
|
keyValues,
|
|
251
284
|
allKeys,
|
|
285
|
+
indent,
|
|
252
286
|
};
|
|
253
287
|
}
|
|
254
288
|
const keyToken = this.peekToken();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json_parser.js","sourceRoot":"","sources":["../../src/json/json_parser.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n JsonArray,\n JsonEdit,\n JsonError,\n JsonKey,\n JsonKeyValue,\n JsonObject,\n JsonParseResult,\n JsonValue,\n Segment,\n} from \"./types\";\n\nexport function parseJsonValue(input: string): JsonParseResult {\n const tokens = tokenize(input);\n if (tokens.kind === \"error\") {\n return {\n value: undefined,\n errors: [tokens],\n edits: [],\n };\n }\n const parser = new JsonParser(tokens.tokens, input);\n const parseResult = parser.parseValueOrSkip();\n parser.expectEnd();\n\n return {\n value: parseResult,\n errors: parser.errors,\n edits: parser.edits,\n };\n}\n\ninterface JsonToken {\n segment: Segment;\n jsonCode: string;\n}\n\ninterface JsonTokens {\n kind: \"tokens\";\n tokens: JsonToken[];\n}\n\nfunction tokenize(input: string): JsonTokens | JsonError {\n const tokens: JsonToken[] = [];\n let pos = 0;\n\n const whitespaceRegex = /[ \\t\\r\\n]*/y;\n const tokenRegex =\n /([[\\]{}:,]|(-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|false|true|null|(\"(((?=\\\\)\\\\([\"\\\\/ bfnrt]|u[0-9a-fA-F]{4}))|[^\"\\\\\\0-\\x1F\\x7F]+)*\")|$)/y;\n\n while (true) {\n whitespaceRegex.lastIndex = pos;\n whitespaceRegex.exec(input);\n pos = whitespaceRegex.lastIndex;\n\n tokenRegex.lastIndex = pos;\n const tokenMatch = tokenRegex.exec(input);\n if (tokenMatch) {\n const tokenText = tokenMatch[0];\n const segment: Segment = {\n start: pos,\n end: pos + tokenText.length,\n };\n const token: JsonToken = { segment, jsonCode: tokenText };\n pos = tokenRegex.lastIndex;\n tokens.push(token);\n if (tokenText === \"\") {\n return {\n kind: \"tokens\",\n tokens: tokens,\n };\n }\n } else {\n // Find the next word boundary using unicode support\n const wordBoundaryRegex = /\\w*/uy;\n wordBoundaryRegex.lastIndex = pos + 1;\n wordBoundaryRegex.exec(input);\n const end = wordBoundaryRegex.lastIndex || pos + 1;\n return {\n kind: \"error\",\n message: \"not a token\",\n segment: { start: pos, end: end },\n };\n }\n }\n}\n\nclass JsonParser {\n constructor(private tokens: JsonToken[], private readonly input: string) {}\n private tokenIndex = 0;\n errors: JsonError[] = [];\n edits: JsonEdit[] = [];\n private indent = \"\";\n\n parseValueOrSkip(): JsonValue | undefined {\n const token = this.peekToken();\n const firstChar = token.jsonCode ? token.jsonCode[0] : \"\";\n\n switch (firstChar) {\n case \"[\":\n return this.parseArray();\n case \"{\":\n return this.parseObject();\n case \"n\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"null\",\n type: \"null\",\n };\n case \"f\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"false\",\n type: \"boolean\",\n };\n case \"t\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"true\",\n type: \"boolean\",\n };\n case '\"':\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: token.jsonCode,\n type: \"string\",\n };\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\":\n case \"-\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: token.jsonCode,\n type: \"number\",\n };\n }\n\n this.errors.push({\n kind: \"error\",\n message: \"expected: value\",\n segment: this.peekToken().segment,\n });\n this.skip();\n return undefined;\n }\n\n private parseArray(): JsonArray {\n const leftBracket = this.nextToken();\n const values: JsonValue[] = [];\n while (true) {\n if (this.peekToken().jsonCode === \"]\") {\n const rightBracket = this.nextToken();\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: rightBracket.segment.end,\n },\n values,\n };\n }\n if (this.peekToken().jsonCode === \"}\") {\n this.errors.push({\n kind: \"error\",\n message: \"expected: ']'\",\n segment: this.peekToken().segment,\n });\n const wrongBracket = this.nextToken();\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: wrongBracket.segment.end,\n },\n values,\n };\n }\n if (this.peekToken().jsonCode === \"\") {\n // End of file\n this.expectSymbolOrSkip(\"]\");\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: this.peekToken().segment.start,\n },\n values,\n };\n }\n const value = this.parseValueOrSkip();\n if (value) {\n values.push(value);\n }\n if (this.peekToken().jsonCode === \",\") {\n const commaToken = this.nextToken();\n // Check if this is a trailing comma\n if (this.peekToken().jsonCode === \"]\") {\n // Trailing comma - add edit to remove it\n this.edits.push({\n segment: commaToken.segment,\n replacement: \"\",\n });\n }\n }\n }\n }\n\n private parseObject(): JsonObject {\n const leftBracket = this.nextToken();\n const keyValues: { [key: string]: JsonKeyValue } = {};\n const allKeys: JsonKey[] = [];\n while (true) {\n if (this.peekToken().jsonCode === \"}\") {\n const rightBracket = this.nextToken();\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: rightBracket.segment.end,\n },\n keyValues,\n allKeys,\n };\n }\n if (this.peekToken().jsonCode === \"]\") {\n this.errors.push({\n kind: \"error\",\n message: \"expected: ']'\",\n segment: this.peekToken().segment,\n });\n const wrongBracket = this.nextToken();\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: wrongBracket.segment.end,\n },\n keyValues,\n allKeys,\n };\n }\n if (this.peekToken().jsonCode === \"\") {\n // End of file\n this.expectSymbolOrSkip(\"}\");\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: this.peekToken().segment.start,\n },\n keyValues,\n allKeys,\n };\n }\n const keyToken = this.peekToken();\n if (!keyToken.jsonCode.startsWith('\"')) {\n this.errors.push({\n kind: \"error\",\n message: \"expected: string\",\n segment: keyToken.segment,\n });\n this.skip();\n // Consume comma if we're stuck at one to avoid infinite loop\n if (this.peekToken().jsonCode === \",\") {\n this.nextToken();\n }\n continue;\n }\n const key = JSON.parse(keyToken.jsonCode) as string;\n allKeys.push({\n key: key,\n keySegment: keyToken.segment,\n });\n this.nextToken();\n if (!this.expectSymbolOrSkip(\":\")) {\n continue;\n }\n if (keyValues[key]) {\n this.errors.push({\n kind: \"error\",\n message: \"duplicate key\",\n segment: keyToken.segment,\n });\n }\n const value = this.parseValueOrSkip();\n if (value) {\n keyValues[key] = {\n keySegment: keyToken.segment,\n key: key,\n value: value,\n };\n }\n if (this.peekToken().jsonCode === \",\") {\n const commaToken = this.nextToken();\n // Check if this is a trailing comma\n if (this.peekToken().jsonCode === \"}\") {\n // Trailing comma - add edit to remove it\n this.edits.push({\n segment: commaToken.segment,\n replacement: \"\",\n });\n }\n }\n }\n }\n\n expectEnd(): void {\n const token = this.nextToken();\n if (token.jsonCode) {\n this.errors.push({\n kind: \"error\",\n message: \"expected: end\",\n segment: this.peekToken().segment,\n });\n }\n }\n\n private nextToken(): JsonToken {\n const result = this.tokens[this.tokenIndex];\n\n // Check the whitespace separator before the current token.\n {\n const previous =\n this.tokenIndex <= 0 ? undefined : this.tokens[this.tokenIndex - 1];\n const separatorSegment: Segment = {\n start: previous ? previous.segment.end : 0,\n end: result.segment.start,\n };\n const actualSeparator = this.input.substring(\n separatorSegment.start,\n separatorSegment.end,\n );\n const expectedSeparator = this.inferWhitespaceSeparator(\n previous?.jsonCode ?? \"\",\n result.jsonCode,\n );\n\n if (actualSeparator !== expectedSeparator.text) {\n this.edits.push({\n segment: separatorSegment,\n replacement: expectedSeparator.text,\n });\n }\n this.indent = expectedSeparator.newIndent ?? this.indent;\n }\n\n ++this.tokenIndex;\n return result;\n }\n\n private inferWhitespaceSeparator(a: string, b: string): WhitespaceSeparator {\n const { indent } = this;\n if (a === \":\") {\n return {\n text: \" \",\n };\n } else if (a === \",\" && b !== \"]\" && b !== \"}\") {\n return {\n text: `\\n${indent}`,\n };\n } else if (/[0-9\"}\\]el]$/.test(a) && /^[0-9\"{[tfn-]/.test(b)) {\n // a is the end of a JSON value and B is the start of a JSON value\n return {\n text: `,\\n${indent}`,\n };\n } else if ((a === \"[\" && b !== \"]\") || (a === \"{\" && b !== \"}\")) {\n const newIndent = indent + INDENT_UNIT;\n return {\n text: `\\n${newIndent}`,\n newIndent: newIndent,\n };\n } else if ((a !== \"[\" && b === \"]\") || (a !== \"{\" && b === \"}\")) {\n const newIndent = indent.replace(INDENT_UNIT, \"\");\n return {\n text: `\\n${newIndent}`,\n newIndent: newIndent,\n };\n } else {\n return {\n text: \"\",\n };\n }\n }\n\n private peekToken(): JsonToken {\n return this.tokens[this.tokenIndex];\n }\n\n private expectSymbolOrSkip(symbol: string): boolean {\n if (this.peekToken().jsonCode !== symbol) {\n this.errors.push({\n kind: \"error\",\n message: `expected: '${symbol}'`,\n segment: this.peekToken().segment,\n });\n this.skip();\n return false;\n }\n this.nextToken();\n return true;\n }\n\n private skip(): void {\n while (true) {\n const tokenJson = this.peekToken().jsonCode;\n if (\n tokenJson === \"\" ||\n tokenJson === \",\" ||\n tokenJson === \"]\" ||\n tokenJson === \"}\" ||\n tokenJson.startsWith('\"')\n ) {\n return;\n } else if (tokenJson === \"[\") {\n this.parseArray();\n } else if (tokenJson === \"{\") {\n this.parseObject();\n } else {\n this.nextToken();\n }\n }\n }\n}\n\n/// Text to insert between two consecutive tokens.\ninterface WhitespaceSeparator {\n /// Matches /(,?)(\\n?)( )*/\n text: string;\n newIndent?: string;\n}\n\nconst INDENT_UNIT = \" \";\n"]}
|
|
1
|
+
{"version":3,"file":"json_parser.js","sourceRoot":"","sources":["../../src/json/json_parser.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n JsonArray,\n JsonEdit,\n JsonError,\n JsonKey,\n JsonKeyValue,\n JsonObject,\n JsonParseResult,\n JsonValue,\n Segment,\n} from \"./types\";\n\nexport function parseJsonValue(input: string): JsonParseResult {\n const tokens = tokenize(input);\n if (tokens.kind === \"error\") {\n return {\n value: undefined,\n errors: [tokens],\n edits: [],\n };\n }\n const parser = new JsonParser(tokens.tokens, input);\n const parseResult = parser.parseValueOrSkip();\n parser.expectEnd();\n\n return {\n value: parseResult,\n errors: parser.errors,\n edits: parser.edits,\n };\n}\n\ninterface JsonToken {\n segment: Segment;\n jsonCode: string;\n indent: number;\n}\n\ninterface JsonTokens {\n kind: \"tokens\";\n tokens: JsonToken[];\n}\n\nfunction tokenize(input: string): JsonTokens | JsonError {\n const tokens: JsonToken[] = [];\n let pos = 0;\n let lineIndent = 0;\n let lineHasContent = false;\n\n const whitespaceRegex = /[ \\t\\r\\n]*/y;\n const tokenRegex =\n /([[\\]{}:,]|(-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|false|true|null|(\"(((?=\\\\)\\\\([\"\\\\/ bfnrt]|u[0-9a-fA-F]{4}))|[^\"\\\\\\0-\\x1F\\x7F]+)*\")|$)/y;\n\n while (true) {\n const beforeWhitespacePos = pos;\n whitespaceRegex.lastIndex = pos;\n whitespaceRegex.exec(input);\n pos = whitespaceRegex.lastIndex;\n\n for (let i = beforeWhitespacePos; i < pos; ++i) {\n const ch = input[i];\n if (ch === \"\\n\") {\n lineIndent = 0;\n lineHasContent = false;\n } else if (!lineHasContent && (ch === \" \" || ch === \"\\t\")) {\n lineIndent++;\n }\n }\n\n tokenRegex.lastIndex = pos;\n const tokenMatch = tokenRegex.exec(input);\n if (tokenMatch) {\n const tokenText = tokenMatch[0];\n const segment: Segment = {\n start: pos,\n end: pos + tokenText.length,\n };\n const token: JsonToken = {\n segment,\n jsonCode: tokenText,\n indent: lineIndent,\n };\n pos = tokenRegex.lastIndex;\n tokens.push(token);\n if (tokenText !== \"\") {\n lineHasContent = true;\n }\n if (tokenText === \"\") {\n return {\n kind: \"tokens\",\n tokens: tokens,\n };\n }\n } else {\n // Find the next word boundary using unicode support\n const wordBoundaryRegex = /\\w*/uy;\n wordBoundaryRegex.lastIndex = pos + 1;\n wordBoundaryRegex.exec(input);\n const end = wordBoundaryRegex.lastIndex || pos + 1;\n return {\n kind: \"error\",\n message: \"not a token\",\n segment: { start: pos, end: end },\n };\n }\n }\n}\n\nclass JsonParser {\n constructor(private tokens: JsonToken[], private readonly input: string) {}\n private tokenIndex = 0;\n errors: JsonError[] = [];\n edits: JsonEdit[] = [];\n private indent = \"\";\n\n parseValueOrSkip(): JsonValue | undefined {\n const token = this.peekToken();\n const firstChar = token.jsonCode ? token.jsonCode[0] : \"\";\n\n const { indent } = token;\n\n switch (firstChar) {\n case \"[\":\n return this.parseArray();\n case \"{\":\n return this.parseObject();\n case \"n\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"null\",\n type: \"null\",\n indent,\n };\n case \"f\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"false\",\n type: \"boolean\",\n indent,\n };\n case \"t\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: \"true\",\n type: \"boolean\",\n indent,\n };\n case '\"':\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: token.jsonCode,\n type: \"string\",\n indent,\n };\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\":\n case \"-\":\n this.nextToken();\n return {\n kind: \"literal\",\n firstToken: token.segment,\n segment: token.segment,\n jsonCode: token.jsonCode,\n type: \"number\",\n indent,\n };\n }\n\n this.errors.push({\n kind: \"error\",\n message: \"expected: value\",\n segment: this.peekToken().segment,\n });\n this.skip();\n return undefined;\n }\n\n private parseArray(): JsonArray {\n const leftBracket = this.nextToken();\n const { indent } = leftBracket;\n const values: JsonValue[] = [];\n while (true) {\n if (this.peekToken().jsonCode === \"]\") {\n const rightBracket = this.nextToken();\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: rightBracket.segment.end,\n },\n values,\n indent,\n };\n }\n if (this.peekToken().jsonCode === \"}\") {\n this.errors.push({\n kind: \"error\",\n message: \"expected: ']'\",\n segment: this.peekToken().segment,\n });\n const wrongBracket = this.nextToken();\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: wrongBracket.segment.end,\n },\n values,\n indent,\n };\n }\n if (this.peekToken().jsonCode === \"\") {\n // End of file\n this.expectSymbolOrSkip(\"]\");\n return {\n kind: \"array\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: this.peekToken().segment.start,\n },\n values,\n indent,\n };\n }\n const value = this.parseValueOrSkip();\n if (value) {\n values.push(value);\n }\n if (this.peekToken().jsonCode === \",\") {\n const commaToken = this.nextToken();\n // Check if this is a trailing comma\n if (this.peekToken().jsonCode === \"]\") {\n // Trailing comma - add edit to remove it\n this.edits.push({\n segment: commaToken.segment,\n replacement: \"\",\n });\n }\n }\n }\n }\n\n private parseObject(): JsonObject {\n const leftBracket = this.nextToken();\n const { indent } = leftBracket;\n const keyValues: { [key: string]: JsonKeyValue } = {};\n const allKeys: JsonKey[] = [];\n while (true) {\n if (this.peekToken().jsonCode === \"}\") {\n const rightBracket = this.nextToken();\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: rightBracket.segment.end,\n },\n keyValues,\n allKeys,\n indent,\n };\n }\n if (this.peekToken().jsonCode === \"]\") {\n this.errors.push({\n kind: \"error\",\n message: \"expected: ']'\",\n segment: this.peekToken().segment,\n });\n const wrongBracket = this.nextToken();\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: wrongBracket.segment.end,\n },\n keyValues,\n allKeys,\n indent,\n };\n }\n if (this.peekToken().jsonCode === \"\") {\n // End of file\n this.expectSymbolOrSkip(\"}\");\n return {\n kind: \"object\",\n firstToken: leftBracket.segment,\n segment: {\n start: leftBracket.segment.start,\n end: this.peekToken().segment.start,\n },\n keyValues,\n allKeys,\n indent,\n };\n }\n const keyToken = this.peekToken();\n if (!keyToken.jsonCode.startsWith('\"')) {\n this.errors.push({\n kind: \"error\",\n message: \"expected: string\",\n segment: keyToken.segment,\n });\n this.skip();\n // Consume comma if we're stuck at one to avoid infinite loop\n if (this.peekToken().jsonCode === \",\") {\n this.nextToken();\n }\n continue;\n }\n const key = JSON.parse(keyToken.jsonCode) as string;\n allKeys.push({\n key: key,\n keySegment: keyToken.segment,\n });\n this.nextToken();\n if (!this.expectSymbolOrSkip(\":\")) {\n continue;\n }\n if (keyValues[key]) {\n this.errors.push({\n kind: \"error\",\n message: \"duplicate key\",\n segment: keyToken.segment,\n });\n }\n const value = this.parseValueOrSkip();\n if (value) {\n keyValues[key] = {\n keySegment: keyToken.segment,\n key: key,\n value: value,\n };\n }\n if (this.peekToken().jsonCode === \",\") {\n const commaToken = this.nextToken();\n // Check if this is a trailing comma\n if (this.peekToken().jsonCode === \"}\") {\n // Trailing comma - add edit to remove it\n this.edits.push({\n segment: commaToken.segment,\n replacement: \"\",\n });\n }\n }\n }\n }\n\n expectEnd(): void {\n const token = this.nextToken();\n if (token.jsonCode) {\n this.errors.push({\n kind: \"error\",\n message: \"expected: end\",\n segment: this.peekToken().segment,\n });\n }\n }\n\n private nextToken(): JsonToken {\n const result = this.tokens[this.tokenIndex];\n\n // Check the whitespace separator before the current token.\n {\n const previous =\n this.tokenIndex <= 0 ? undefined : this.tokens[this.tokenIndex - 1];\n const separatorSegment: Segment = {\n start: previous ? previous.segment.end : 0,\n end: result.segment.start,\n };\n const actualSeparator = this.input.substring(\n separatorSegment.start,\n separatorSegment.end,\n );\n const expectedSeparator = this.inferWhitespaceSeparator(\n previous?.jsonCode ?? \"\",\n result.jsonCode,\n );\n\n if (actualSeparator !== expectedSeparator.text) {\n this.edits.push({\n segment: separatorSegment,\n replacement: expectedSeparator.text,\n });\n }\n this.indent = expectedSeparator.newIndent ?? this.indent;\n }\n\n ++this.tokenIndex;\n return result;\n }\n\n private inferWhitespaceSeparator(a: string, b: string): WhitespaceSeparator {\n const { indent } = this;\n if (a === \":\") {\n return {\n text: \" \",\n };\n } else if (a === \",\" && b !== \"]\" && b !== \"}\") {\n return {\n text: `\\n${indent}`,\n };\n } else if (/[0-9\"}\\]el]$/.test(a) && /^[0-9\"{[tfn-]/.test(b)) {\n // a is the end of a JSON value and B is the start of a JSON value\n return {\n text: `,\\n${indent}`,\n };\n } else if ((a === \"[\" && b !== \"]\") || (a === \"{\" && b !== \"}\")) {\n const newIndent = indent + INDENT_UNIT;\n return {\n text: `\\n${newIndent}`,\n newIndent: newIndent,\n };\n } else if ((a !== \"[\" && b === \"]\") || (a !== \"{\" && b === \"}\")) {\n const newIndent = indent.replace(INDENT_UNIT, \"\");\n return {\n text: `\\n${newIndent}`,\n newIndent: newIndent,\n };\n } else {\n return {\n text: \"\",\n };\n }\n }\n\n private peekToken(): JsonToken {\n return this.tokens[this.tokenIndex];\n }\n\n private expectSymbolOrSkip(symbol: string): boolean {\n if (this.peekToken().jsonCode !== symbol) {\n this.errors.push({\n kind: \"error\",\n message: `expected: '${symbol}'`,\n segment: this.peekToken().segment,\n });\n this.skip();\n return false;\n }\n this.nextToken();\n return true;\n }\n\n private skip(): void {\n while (true) {\n const tokenJson = this.peekToken().jsonCode;\n if (\n tokenJson === \"\" ||\n tokenJson === \",\" ||\n tokenJson === \"]\" ||\n tokenJson === \"}\" ||\n tokenJson.startsWith('\"')\n ) {\n return;\n } else if (tokenJson === \"[\") {\n this.parseArray();\n } else if (tokenJson === \"{\") {\n this.parseObject();\n } else {\n this.nextToken();\n }\n }\n }\n}\n\n/// Text to insert between two consecutive tokens.\ninterface WhitespaceSeparator {\n /// Matches /(,?)(\\n?)( )*/\n text: string;\n newIndent?: string;\n}\n\nconst INDENT_UNIT = \" \";\n"]}
|
|
@@ -57,6 +57,17 @@ describe("json_parser", () => {
|
|
|
57
57
|
edits: [],
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
|
+
it("tracks indent for top-level literal", () => {
|
|
61
|
+
expect(parseJsonValue(" true")).toMatch({
|
|
62
|
+
value: {
|
|
63
|
+
kind: "literal",
|
|
64
|
+
jsonCode: "true",
|
|
65
|
+
type: "boolean",
|
|
66
|
+
indent: 3,
|
|
67
|
+
},
|
|
68
|
+
errors: [],
|
|
69
|
+
});
|
|
70
|
+
});
|
|
60
71
|
it("parses empty array", () => {
|
|
61
72
|
expect(parseJsonValue("[]")).toMatch({
|
|
62
73
|
value: { kind: "array", values: [] },
|
|
@@ -109,6 +120,43 @@ describe("json_parser", () => {
|
|
|
109
120
|
],
|
|
110
121
|
});
|
|
111
122
|
});
|
|
123
|
+
it("tracks indent from line leading spaces for field values", () => {
|
|
124
|
+
const result = parseJsonValue(`{
|
|
125
|
+
"a": 1,
|
|
126
|
+
"b": [
|
|
127
|
+
2
|
|
128
|
+
]
|
|
129
|
+
}`);
|
|
130
|
+
expect(result).toMatch({
|
|
131
|
+
value: {
|
|
132
|
+
kind: "object",
|
|
133
|
+
indent: 0,
|
|
134
|
+
keyValues: {
|
|
135
|
+
a: {
|
|
136
|
+
value: {
|
|
137
|
+
kind: "literal",
|
|
138
|
+
jsonCode: "1",
|
|
139
|
+
indent: 2,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
b: {
|
|
143
|
+
value: {
|
|
144
|
+
kind: "array",
|
|
145
|
+
indent: 2,
|
|
146
|
+
values: [
|
|
147
|
+
{
|
|
148
|
+
kind: "literal",
|
|
149
|
+
jsonCode: "2",
|
|
150
|
+
indent: 4,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
errors: [],
|
|
158
|
+
});
|
|
159
|
+
});
|
|
112
160
|
it("parses arrays with whitespace", () => {
|
|
113
161
|
expect(parseJsonValue(" [ 1 ] ")).toMatch({
|
|
114
162
|
value: {
|