skir-codemirror-plugin 0.9.0
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 +126 -0
- package/dist/codemirror/create_editor_state.d.ts +20 -0
- package/dist/codemirror/create_editor_state.d.ts.map +1 -0
- package/dist/codemirror/create_editor_state.js +252 -0
- package/dist/codemirror/create_editor_state.js.map +1 -0
- package/dist/codemirror/enter_key_handler.d.ts +8 -0
- package/dist/codemirror/enter_key_handler.d.ts.map +1 -0
- package/dist/codemirror/enter_key_handler.js +181 -0
- package/dist/codemirror/enter_key_handler.js.map +1 -0
- package/dist/codemirror/json_completion.d.ts +4 -0
- package/dist/codemirror/json_completion.d.ts.map +1 -0
- package/dist/codemirror/json_completion.js +150 -0
- package/dist/codemirror/json_completion.js.map +1 -0
- package/dist/codemirror/json_linter.d.ts +4 -0
- package/dist/codemirror/json_linter.d.ts.map +1 -0
- package/dist/codemirror/json_linter.js +277 -0
- package/dist/codemirror/json_linter.js.map +1 -0
- package/dist/codemirror/json_state.d.ts +16 -0
- package/dist/codemirror/json_state.d.ts.map +1 -0
- package/dist/codemirror/json_state.js +124 -0
- package/dist/codemirror/json_state.js.map +1 -0
- package/dist/codemirror/status_bar.d.ts +3 -0
- package/dist/codemirror/status_bar.d.ts.map +1 -0
- package/dist/codemirror/status_bar.js +123 -0
- package/dist/codemirror/status_bar.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/json/json_parser.d.ts +3 -0
- package/dist/json/json_parser.d.ts.map +1 -0
- package/dist/json/json_parser.js +414 -0
- package/dist/json/json_parser.js.map +1 -0
- package/dist/json/json_parser.test.d.ts +2 -0
- package/dist/json/json_parser.test.d.ts.map +1 -0
- package/dist/json/json_parser.test.js +337 -0
- package/dist/json/json_parser.test.js.map +1 -0
- package/dist/json/schema_validator.d.ts +3 -0
- package/dist/json/schema_validator.d.ts.map +1 -0
- package/dist/json/schema_validator.js +525 -0
- package/dist/json/schema_validator.js.map +1 -0
- package/dist/json/schema_validator.test.d.ts +2 -0
- package/dist/json/schema_validator.test.d.ts.map +1 -0
- package/dist/json/schema_validator.test.js +212 -0
- package/dist/json/schema_validator.test.js.map +1 -0
- package/dist/json/to_json.d.ts +6 -0
- package/dist/json/to_json.d.ts.map +1 -0
- package/dist/json/to_json.js +61 -0
- package/dist/json/to_json.js.map +1 -0
- package/dist/json/to_json.test.d.ts +2 -0
- package/dist/json/to_json.test.d.ts.map +1 -0
- package/dist/json/to_json.test.js +128 -0
- package/dist/json/to_json.test.js.map +1 -0
- package/dist/json/types.d.ts +170 -0
- package/dist/json/types.d.ts.map +1 -0
- package/dist/json/types.js +2 -0
- package/dist/json/types.js.map +1 -0
- package/package.json +85 -0
- package/src/codemirror/create_editor_state.ts +278 -0
- package/src/codemirror/enter_key_handler.ts +232 -0
- package/src/codemirror/json_completion.ts +182 -0
- package/src/codemirror/json_linter.ts +358 -0
- package/src/codemirror/json_state.ts +170 -0
- package/src/codemirror/status_bar.ts +137 -0
- package/src/index.ts +6 -0
- package/src/json/json_parser.test.ts +360 -0
- package/src/json/json_parser.ts +461 -0
- package/src/json/schema_validator.test.ts +230 -0
- package/src/json/schema_validator.ts +558 -0
- package/src/json/to_json.test.ts +150 -0
- package/src/json/to_json.ts +70 -0
- package/src/json/types.ts +254 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# skir-codemirror-plugin
|
|
2
|
+
|
|
3
|
+
This library provides a CodeMirror-based JSON editor for Skir values.
|
|
4
|
+
It helps users edit Skir request/response payloads in a human-readable JSON form while preserving schema-aware guidance and validation.
|
|
5
|
+
|
|
6
|
+
Demo: `npx skir-studio-demo`
|
|
7
|
+
|
|
8
|
+
## What It Provides
|
|
9
|
+
|
|
10
|
+
- A ready-to-use `createEditorState(...)` factory for CodeMirror.
|
|
11
|
+
- Schema-driven JSON template generation (when no JSON value is provided).
|
|
12
|
+
- JSON validation and lint diagnostics.
|
|
13
|
+
- In-editor hints and completions informed by the Skir type schema.
|
|
14
|
+
- Read-only mode support for response viewing.
|
|
15
|
+
- Built-in theme support:
|
|
16
|
+
- `tokyo-night`
|
|
17
|
+
- `tokyo-night-day`
|
|
18
|
+
- custom theme object
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm install skir-codemirror-plugin
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Public API
|
|
27
|
+
|
|
28
|
+
The package root exports:
|
|
29
|
+
|
|
30
|
+
- `createEditorState`
|
|
31
|
+
- `CreateEditorStateParams` (type)
|
|
32
|
+
- `CustomTheme` (type)
|
|
33
|
+
- `Json` (type)
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { EditorView } from "@codemirror/view";
|
|
39
|
+
import {
|
|
40
|
+
createEditorState,
|
|
41
|
+
type CreateEditorStateParams,
|
|
42
|
+
} from "skir-codemirror-plugin";
|
|
43
|
+
|
|
44
|
+
const params: CreateEditorStateParams = {
|
|
45
|
+
schema: {
|
|
46
|
+
type: { kind: "primitive", value: "string" },
|
|
47
|
+
records: [],
|
|
48
|
+
},
|
|
49
|
+
// Optional:
|
|
50
|
+
// readOnly: true,
|
|
51
|
+
// json: "hello",
|
|
52
|
+
// theme: "tokyo-night-day",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const state = createEditorState(params);
|
|
56
|
+
|
|
57
|
+
new EditorView({
|
|
58
|
+
state,
|
|
59
|
+
parent: document.getElementById("editor")!,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## createEditorState Parameters
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
{
|
|
67
|
+
schema: TypeDefinition,
|
|
68
|
+
readOnly?: true,
|
|
69
|
+
json?: Json,
|
|
70
|
+
theme?: "tokyo-night" | "tokyo-night-day" | CustomTheme,
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Behavior:
|
|
75
|
+
|
|
76
|
+
- `schema` is required and drives validation/completion.
|
|
77
|
+
- If `json` is omitted, a JSON template is generated from the schema.
|
|
78
|
+
- `readOnly: true` enables non-editable mode.
|
|
79
|
+
- `theme` defaults to `tokyo-night`.
|
|
80
|
+
|
|
81
|
+
## Local Dev Flow
|
|
82
|
+
|
|
83
|
+
This repository includes a minimal local dev page for previewing the editor state produced by `createEditorState`.
|
|
84
|
+
|
|
85
|
+
### Run It
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
npm run dev
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This does three things:
|
|
92
|
+
|
|
93
|
+
1. Builds TypeScript sources into `dist/`.
|
|
94
|
+
2. Builds the dev entry point from `dev/main.ts` into `dev-dist/main.js`.
|
|
95
|
+
3. Starts `web-dev-server` and opens `/dev/index.html`.
|
|
96
|
+
|
|
97
|
+
Dev URL:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
http://localhost:8080/dev/index.html
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Dev Files
|
|
104
|
+
|
|
105
|
+
- `dev/index.html`: minimal host page containing only `#editor` and module import.
|
|
106
|
+
- `dev/main.ts`: creates `EditorView` with `createEditorState(...)`.
|
|
107
|
+
- `dev-dist/main.js`: generated browser output from `dev/main.ts`.
|
|
108
|
+
|
|
109
|
+
To try your own schema/JSON inputs, edit `dev/main.ts` and change the `params` object.
|
|
110
|
+
|
|
111
|
+
### Auto Rebuild and Reload
|
|
112
|
+
|
|
113
|
+
`npm run dev` watches both:
|
|
114
|
+
|
|
115
|
+
- `src/**/*.ts` -> rebuilds the library into `dist/`
|
|
116
|
+
- `dev/**/*.ts` -> rebuilds the dev entry into `dev-dist/`
|
|
117
|
+
|
|
118
|
+
`web-dev-server --watch` reloads the page when served files change.
|
|
119
|
+
|
|
120
|
+
### Dev-Only Note
|
|
121
|
+
|
|
122
|
+
This flow is for local development only.
|
|
123
|
+
|
|
124
|
+
- Dev sources are in `dev/`.
|
|
125
|
+
- Dev compiled output is in `dev-dist/`.
|
|
126
|
+
- Package distribution uses `dist/` as the runtime entrypoint.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EditorState, Extension } from "@codemirror/state";
|
|
2
|
+
import type { Json, TypeDefinition } from "../json/types";
|
|
3
|
+
export type CreateEditorStateParams = {
|
|
4
|
+
schema: TypeDefinition;
|
|
5
|
+
readOnly?: true;
|
|
6
|
+
json?: Json;
|
|
7
|
+
theme?: "tokyo-night" | "tokyo-night-day" | CustomTheme;
|
|
8
|
+
};
|
|
9
|
+
export declare function createEditorState({ schema, readOnly, json, theme, }: CreateEditorStateParams): EditorState;
|
|
10
|
+
export interface CustomTheme {
|
|
11
|
+
backgroundColor: string;
|
|
12
|
+
lighterBgColor: string;
|
|
13
|
+
borderColor: string;
|
|
14
|
+
foregroundColor: string;
|
|
15
|
+
accentColor: string;
|
|
16
|
+
errorColor: string;
|
|
17
|
+
selectionColor: string;
|
|
18
|
+
themeExtension?: Extension;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=create_editor_state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_editor_state.d.ts","sourceRoot":"","sources":["../../src/codemirror/create_editor_state.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAM3D,OAAO,KAAK,EAAE,IAAI,EAAoB,cAAc,EAAE,MAAM,eAAe,CAAC;AAO5E,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,WAAW,CAAC;CACzD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,KAAK,GACN,EAAE,uBAAuB,GAAG,WAAW,CA8OvC;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { autocompletion, closeBrackets } from "@codemirror/autocomplete";
|
|
2
|
+
import { json as jsonExtension } from "@codemirror/lang-json";
|
|
3
|
+
import { linter, lintGutter } from "@codemirror/lint";
|
|
4
|
+
import { EditorState } from "@codemirror/state";
|
|
5
|
+
import { EditorView } from "@codemirror/view";
|
|
6
|
+
import { tokyoNight } from "@uiw/codemirror-theme-tokyo-night";
|
|
7
|
+
import { tokyoNightDay } from "@uiw/codemirror-theme-tokyo-night-day";
|
|
8
|
+
import { basicSetup } from "codemirror";
|
|
9
|
+
import { makeJsonTemplate } from "../json/to_json";
|
|
10
|
+
import { enterKeyHandler } from "./enter_key_handler";
|
|
11
|
+
import { jsonCompletion } from "./json_completion";
|
|
12
|
+
import { jsonLinter } from "./json_linter";
|
|
13
|
+
import { debouncedJsonParser } from "./json_state";
|
|
14
|
+
import { statusBar } from "./status_bar";
|
|
15
|
+
export function createEditorState({ schema, readOnly, json, theme, }) {
|
|
16
|
+
const idToRecordDef = {};
|
|
17
|
+
for (const record of schema.records) {
|
|
18
|
+
idToRecordDef[record.id] = record;
|
|
19
|
+
}
|
|
20
|
+
const content = json ?? makeJsonTemplate(schema.type, idToRecordDef);
|
|
21
|
+
switch (theme) {
|
|
22
|
+
case undefined:
|
|
23
|
+
case "tokyo-night": {
|
|
24
|
+
theme = {
|
|
25
|
+
backgroundColor: "#1a1b26",
|
|
26
|
+
lighterBgColor: "#1f2335",
|
|
27
|
+
borderColor: "#414868",
|
|
28
|
+
foregroundColor: "#c0caf5",
|
|
29
|
+
accentColor: "#7aa2f7",
|
|
30
|
+
errorColor: "#f7768e",
|
|
31
|
+
selectionColor: "#515c7e40",
|
|
32
|
+
themeExtension: tokyoNight,
|
|
33
|
+
};
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case "tokyo-night-day": {
|
|
37
|
+
theme = {
|
|
38
|
+
backgroundColor: "#d5d6db",
|
|
39
|
+
lighterBgColor: "#e1e2e7",
|
|
40
|
+
borderColor: "#adb0bb",
|
|
41
|
+
foregroundColor: "#3760bf",
|
|
42
|
+
accentColor: "#2e7de9",
|
|
43
|
+
errorColor: "#f52a65",
|
|
44
|
+
selectionColor: "#3760bf33",
|
|
45
|
+
themeExtension: tokyoNightDay,
|
|
46
|
+
};
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return EditorState.create({
|
|
51
|
+
doc: JSON.stringify(content, null, 2),
|
|
52
|
+
extensions: [
|
|
53
|
+
EditorState.readOnly.of(!!readOnly),
|
|
54
|
+
enterKeyHandler(schema),
|
|
55
|
+
basicSetup,
|
|
56
|
+
EditorState.languageData.of(() => [
|
|
57
|
+
{
|
|
58
|
+
closeBrackets: { before: ",]}" },
|
|
59
|
+
},
|
|
60
|
+
]),
|
|
61
|
+
closeBrackets(),
|
|
62
|
+
theme.themeExtension ?? [],
|
|
63
|
+
jsonExtension(),
|
|
64
|
+
debouncedJsonParser(schema),
|
|
65
|
+
linter(jsonLinter(readOnly ? "read-only" : "editable")),
|
|
66
|
+
autocompletion({
|
|
67
|
+
override: [jsonCompletion(schema)],
|
|
68
|
+
}),
|
|
69
|
+
lintGutter(),
|
|
70
|
+
statusBar(),
|
|
71
|
+
EditorView.theme({
|
|
72
|
+
"&": {
|
|
73
|
+
fontSize: "14px",
|
|
74
|
+
height: "100%",
|
|
75
|
+
},
|
|
76
|
+
".cm-scroller": {
|
|
77
|
+
fontFamily: "'JetBrains Mono', monospace",
|
|
78
|
+
overflow: "auto",
|
|
79
|
+
},
|
|
80
|
+
".cm-lintRange-info": {
|
|
81
|
+
backgroundImage: "none",
|
|
82
|
+
},
|
|
83
|
+
".cm-lintRange-info:hover": {
|
|
84
|
+
backgroundColor: theme.selectionColor,
|
|
85
|
+
},
|
|
86
|
+
".cm-lintRange-error": {
|
|
87
|
+
backgroundImage: "none",
|
|
88
|
+
borderBottom: `3px solid ${theme.errorColor}`,
|
|
89
|
+
},
|
|
90
|
+
".cm-tooltip-hover": {
|
|
91
|
+
backgroundColor: theme.lighterBgColor,
|
|
92
|
+
border: `1px solid ${theme.borderColor}`,
|
|
93
|
+
borderRadius: "4px",
|
|
94
|
+
padding: "8px 12px",
|
|
95
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.5)",
|
|
96
|
+
fontSize: "14px",
|
|
97
|
+
lineHeight: "1.4",
|
|
98
|
+
color: theme.foregroundColor,
|
|
99
|
+
},
|
|
100
|
+
".cm-tooltip.cm-tooltip-lint": {
|
|
101
|
+
backgroundColor: theme.lighterBgColor,
|
|
102
|
+
border: `1px solid ${theme.borderColor}`,
|
|
103
|
+
borderRadius: "4px",
|
|
104
|
+
padding: "8px 12px",
|
|
105
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.5)",
|
|
106
|
+
fontSize: "14px", // Ensure consistency
|
|
107
|
+
color: theme.foregroundColor,
|
|
108
|
+
},
|
|
109
|
+
".cm-tooltip-lint .cm-diagnostic-error": {
|
|
110
|
+
fontWeight: "bold",
|
|
111
|
+
color: theme.errorColor,
|
|
112
|
+
},
|
|
113
|
+
".cm-status-bar": {
|
|
114
|
+
backgroundColor: theme.lighterBgColor,
|
|
115
|
+
borderTopColor: theme.borderColor,
|
|
116
|
+
color: theme.accentColor,
|
|
117
|
+
},
|
|
118
|
+
".cm-diagnostic-textarea": {
|
|
119
|
+
backgroundColor: theme.lighterBgColor,
|
|
120
|
+
borderColor: theme.borderColor,
|
|
121
|
+
color: theme.foregroundColor,
|
|
122
|
+
},
|
|
123
|
+
".cm-diagnostic-textarea[readonly]": {
|
|
124
|
+
backgroundColor: theme.backgroundColor,
|
|
125
|
+
},
|
|
126
|
+
".cm-diagnostic-input": {
|
|
127
|
+
backgroundColor: theme.lighterBgColor,
|
|
128
|
+
borderColor: theme.borderColor,
|
|
129
|
+
color: theme.foregroundColor,
|
|
130
|
+
},
|
|
131
|
+
".cm-diagnostic-button": {
|
|
132
|
+
backgroundColor: theme.lighterBgColor,
|
|
133
|
+
borderColor: theme.borderColor,
|
|
134
|
+
color: theme.foregroundColor,
|
|
135
|
+
},
|
|
136
|
+
".cm-diagnostic-button:hover": {
|
|
137
|
+
backgroundColor: theme.borderColor,
|
|
138
|
+
},
|
|
139
|
+
".cm-diagnostic-error-message": {
|
|
140
|
+
color: theme.errorColor,
|
|
141
|
+
},
|
|
142
|
+
".diagnostic-row + .diagnostic-row": {
|
|
143
|
+
borderTopColor: theme.borderColor,
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
EditorView.baseTheme({
|
|
147
|
+
".cm-lint-marker-info": {
|
|
148
|
+
display: "none",
|
|
149
|
+
},
|
|
150
|
+
".cm-status-bar": {
|
|
151
|
+
display: "flex",
|
|
152
|
+
flexDirection: "row-reverse",
|
|
153
|
+
justifyContent: "flex-end",
|
|
154
|
+
padding: "4px 12px",
|
|
155
|
+
borderTop: "1px solid",
|
|
156
|
+
fontSize: "12px",
|
|
157
|
+
height: "16px",
|
|
158
|
+
},
|
|
159
|
+
".cm-status-bar-link": {
|
|
160
|
+
textDecoration: "none",
|
|
161
|
+
cursor: "pointer",
|
|
162
|
+
},
|
|
163
|
+
".cm-status-bar-link:hover": {
|
|
164
|
+
textDecoration: "underline",
|
|
165
|
+
},
|
|
166
|
+
".cm-status-bar-link:hover ~ .cm-status-bar-link": {
|
|
167
|
+
textDecoration: "underline",
|
|
168
|
+
},
|
|
169
|
+
".cm-diagnostic-wrapper": {
|
|
170
|
+
fontSize: "12px",
|
|
171
|
+
lineHeight: "1.3",
|
|
172
|
+
padding: "2px",
|
|
173
|
+
},
|
|
174
|
+
".cm-diagnostic-controls": {
|
|
175
|
+
marginTop: "4px",
|
|
176
|
+
display: "flex",
|
|
177
|
+
gap: "6px",
|
|
178
|
+
alignItems: "center",
|
|
179
|
+
},
|
|
180
|
+
".cm-diagnostic-label": {
|
|
181
|
+
whiteSpace: "nowrap",
|
|
182
|
+
fontWeight: "500",
|
|
183
|
+
minWidth: "64px",
|
|
184
|
+
},
|
|
185
|
+
".cm-diagnostic-textarea": {
|
|
186
|
+
flex: "1",
|
|
187
|
+
padding: "3px 6px",
|
|
188
|
+
border: "1px solid",
|
|
189
|
+
borderRadius: "3px",
|
|
190
|
+
fontSize: "12px",
|
|
191
|
+
fontFamily: "'JetBrains Mono', monospace",
|
|
192
|
+
resize: "none",
|
|
193
|
+
overflow: "auto",
|
|
194
|
+
boxSizing: "border-box",
|
|
195
|
+
},
|
|
196
|
+
".cm-diagnostic-textarea[readonly]": {
|
|
197
|
+
cursor: "default",
|
|
198
|
+
},
|
|
199
|
+
".cm-diagnostic-input": {
|
|
200
|
+
padding: "3px 6px",
|
|
201
|
+
border: "1px solid",
|
|
202
|
+
borderRadius: "3px",
|
|
203
|
+
fontSize: "12px",
|
|
204
|
+
fontFamily: "'JetBrains Mono', monospace",
|
|
205
|
+
boxSizing: "border-box",
|
|
206
|
+
width: "100%",
|
|
207
|
+
},
|
|
208
|
+
".cm-diagnostic-button": {
|
|
209
|
+
padding: "3px 12px",
|
|
210
|
+
border: "1px solid",
|
|
211
|
+
borderRadius: "3px",
|
|
212
|
+
fontSize: "12px",
|
|
213
|
+
fontFamily: "'JetBrains Mono', monospace",
|
|
214
|
+
cursor: "pointer",
|
|
215
|
+
boxSizing: "border-box",
|
|
216
|
+
},
|
|
217
|
+
".cm-diagnostic-button:active": {
|
|
218
|
+
transform: "translateY(1px)",
|
|
219
|
+
},
|
|
220
|
+
".cm-diagnostic-error-message": {
|
|
221
|
+
fontSize: "11px",
|
|
222
|
+
marginTop: "2px",
|
|
223
|
+
fontWeight: "500",
|
|
224
|
+
},
|
|
225
|
+
".cm-timestamp-field": {
|
|
226
|
+
display: "flex",
|
|
227
|
+
flexDirection: "column",
|
|
228
|
+
gap: "2px",
|
|
229
|
+
flex: "1",
|
|
230
|
+
},
|
|
231
|
+
".cm-tooltip-lint .cm-diagnostic": {
|
|
232
|
+
padding: "0",
|
|
233
|
+
borderTop: "none",
|
|
234
|
+
borderLeft: "none",
|
|
235
|
+
},
|
|
236
|
+
".cm-tooltip-lint .cm-diagnostic-error": {
|
|
237
|
+
borderLeft: "none",
|
|
238
|
+
fontWeight: "bold",
|
|
239
|
+
},
|
|
240
|
+
".cm-tooltip-lint .cm-diagnostic-info": {
|
|
241
|
+
borderLeft: "none",
|
|
242
|
+
},
|
|
243
|
+
".diagnostic-row + .diagnostic-row": {
|
|
244
|
+
marginTop: "8px",
|
|
245
|
+
paddingTop: "8px",
|
|
246
|
+
borderTop: "1px solid",
|
|
247
|
+
},
|
|
248
|
+
}),
|
|
249
|
+
],
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=create_editor_state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_editor_state.js","sourceRoot":"","sources":["../../src/codemirror/create_editor_state.ts"],"names":[],"mappings":"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","sourcesContent":["import { autocompletion, closeBrackets } from \"@codemirror/autocomplete\";\nimport { json as jsonExtension } from \"@codemirror/lang-json\";\nimport { linter, lintGutter } from \"@codemirror/lint\";\nimport { EditorState, Extension } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { tokyoNight } from \"@uiw/codemirror-theme-tokyo-night\";\nimport { tokyoNightDay } from \"@uiw/codemirror-theme-tokyo-night-day\";\nimport { basicSetup } from \"codemirror\";\nimport { makeJsonTemplate } from \"../json/to_json\";\nimport type { Json, RecordDefinition, TypeDefinition } from \"../json/types\";\nimport { enterKeyHandler } from \"./enter_key_handler\";\nimport { jsonCompletion } from \"./json_completion\";\nimport { jsonLinter } from \"./json_linter\";\nimport { debouncedJsonParser } from \"./json_state\";\nimport { statusBar } from \"./status_bar\";\n\nexport type CreateEditorStateParams = {\n schema: TypeDefinition;\n readOnly?: true;\n json?: Json;\n theme?: \"tokyo-night\" | \"tokyo-night-day\" | CustomTheme;\n};\n\nexport function createEditorState({\n schema,\n readOnly,\n json,\n theme,\n}: CreateEditorStateParams): EditorState {\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n const content = json ?? makeJsonTemplate(schema.type, idToRecordDef);\n\n switch (theme) {\n case undefined:\n case \"tokyo-night\": {\n theme = {\n backgroundColor: \"#1a1b26\",\n lighterBgColor: \"#1f2335\",\n borderColor: \"#414868\",\n foregroundColor: \"#c0caf5\",\n accentColor: \"#7aa2f7\",\n errorColor: \"#f7768e\",\n selectionColor: \"#515c7e40\",\n themeExtension: tokyoNight,\n };\n break;\n }\n case \"tokyo-night-day\": {\n theme = {\n backgroundColor: \"#d5d6db\",\n lighterBgColor: \"#e1e2e7\",\n borderColor: \"#adb0bb\",\n foregroundColor: \"#3760bf\",\n accentColor: \"#2e7de9\",\n errorColor: \"#f52a65\",\n selectionColor: \"#3760bf33\",\n themeExtension: tokyoNightDay,\n };\n break;\n }\n }\n\n return EditorState.create({\n doc: JSON.stringify(content, null, 2),\n extensions: [\n EditorState.readOnly.of(!!readOnly),\n enterKeyHandler(schema),\n basicSetup,\n EditorState.languageData.of(() => [\n {\n closeBrackets: { before: \",]}\" },\n },\n ]),\n closeBrackets(),\n theme.themeExtension ?? [],\n jsonExtension(),\n debouncedJsonParser(schema),\n linter(jsonLinter(readOnly ? \"read-only\" : \"editable\")),\n autocompletion({\n override: [jsonCompletion(schema)],\n }),\n lintGutter(),\n statusBar(),\n EditorView.theme({\n \"&\": {\n fontSize: \"14px\",\n height: \"100%\",\n },\n \".cm-scroller\": {\n fontFamily: \"'JetBrains Mono', monospace\",\n overflow: \"auto\",\n },\n \".cm-lintRange-info\": {\n backgroundImage: \"none\",\n },\n \".cm-lintRange-info:hover\": {\n backgroundColor: theme.selectionColor,\n },\n \".cm-lintRange-error\": {\n backgroundImage: \"none\",\n borderBottom: `3px solid ${theme.errorColor}`,\n },\n \".cm-tooltip-hover\": {\n backgroundColor: theme.lighterBgColor,\n border: `1px solid ${theme.borderColor}`,\n borderRadius: \"4px\",\n padding: \"8px 12px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.5)\",\n fontSize: \"14px\",\n lineHeight: \"1.4\",\n color: theme.foregroundColor,\n },\n \".cm-tooltip.cm-tooltip-lint\": {\n backgroundColor: theme.lighterBgColor,\n border: `1px solid ${theme.borderColor}`,\n borderRadius: \"4px\",\n padding: \"8px 12px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.5)\",\n fontSize: \"14px\", // Ensure consistency\n color: theme.foregroundColor,\n },\n \".cm-tooltip-lint .cm-diagnostic-error\": {\n fontWeight: \"bold\",\n color: theme.errorColor,\n },\n \".cm-status-bar\": {\n backgroundColor: theme.lighterBgColor,\n borderTopColor: theme.borderColor,\n color: theme.accentColor,\n },\n \".cm-diagnostic-textarea\": {\n backgroundColor: theme.lighterBgColor,\n borderColor: theme.borderColor,\n color: theme.foregroundColor,\n },\n \".cm-diagnostic-textarea[readonly]\": {\n backgroundColor: theme.backgroundColor,\n },\n \".cm-diagnostic-input\": {\n backgroundColor: theme.lighterBgColor,\n borderColor: theme.borderColor,\n color: theme.foregroundColor,\n },\n \".cm-diagnostic-button\": {\n backgroundColor: theme.lighterBgColor,\n borderColor: theme.borderColor,\n color: theme.foregroundColor,\n },\n \".cm-diagnostic-button:hover\": {\n backgroundColor: theme.borderColor,\n },\n \".cm-diagnostic-error-message\": {\n color: theme.errorColor,\n },\n \".diagnostic-row + .diagnostic-row\": {\n borderTopColor: theme.borderColor,\n },\n }),\n EditorView.baseTheme({\n \".cm-lint-marker-info\": {\n display: \"none\",\n },\n \".cm-status-bar\": {\n display: \"flex\",\n flexDirection: \"row-reverse\",\n justifyContent: \"flex-end\",\n padding: \"4px 12px\",\n borderTop: \"1px solid\",\n fontSize: \"12px\",\n height: \"16px\",\n },\n \".cm-status-bar-link\": {\n textDecoration: \"none\",\n cursor: \"pointer\",\n },\n \".cm-status-bar-link:hover\": {\n textDecoration: \"underline\",\n },\n \".cm-status-bar-link:hover ~ .cm-status-bar-link\": {\n textDecoration: \"underline\",\n },\n \".cm-diagnostic-wrapper\": {\n fontSize: \"12px\",\n lineHeight: \"1.3\",\n padding: \"2px\",\n },\n \".cm-diagnostic-controls\": {\n marginTop: \"4px\",\n display: \"flex\",\n gap: \"6px\",\n alignItems: \"center\",\n },\n \".cm-diagnostic-label\": {\n whiteSpace: \"nowrap\",\n fontWeight: \"500\",\n minWidth: \"64px\",\n },\n \".cm-diagnostic-textarea\": {\n flex: \"1\",\n padding: \"3px 6px\",\n border: \"1px solid\",\n borderRadius: \"3px\",\n fontSize: \"12px\",\n fontFamily: \"'JetBrains Mono', monospace\",\n resize: \"none\",\n overflow: \"auto\",\n boxSizing: \"border-box\",\n },\n \".cm-diagnostic-textarea[readonly]\": {\n cursor: \"default\",\n },\n \".cm-diagnostic-input\": {\n padding: \"3px 6px\",\n border: \"1px solid\",\n borderRadius: \"3px\",\n fontSize: \"12px\",\n fontFamily: \"'JetBrains Mono', monospace\",\n boxSizing: \"border-box\",\n width: \"100%\",\n },\n \".cm-diagnostic-button\": {\n padding: \"3px 12px\",\n border: \"1px solid\",\n borderRadius: \"3px\",\n fontSize: \"12px\",\n fontFamily: \"'JetBrains Mono', monospace\",\n cursor: \"pointer\",\n boxSizing: \"border-box\",\n },\n \".cm-diagnostic-button:active\": {\n transform: \"translateY(1px)\",\n },\n \".cm-diagnostic-error-message\": {\n fontSize: \"11px\",\n marginTop: \"2px\",\n fontWeight: \"500\",\n },\n \".cm-timestamp-field\": {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n flex: \"1\",\n },\n \".cm-tooltip-lint .cm-diagnostic\": {\n padding: \"0\",\n borderTop: \"none\",\n borderLeft: \"none\",\n },\n \".cm-tooltip-lint .cm-diagnostic-error\": {\n borderLeft: \"none\",\n fontWeight: \"bold\",\n },\n \".cm-tooltip-lint .cm-diagnostic-info\": {\n borderLeft: \"none\",\n },\n \".diagnostic-row + .diagnostic-row\": {\n marginTop: \"8px\",\n paddingTop: \"8px\",\n borderTop: \"1px solid\",\n },\n }),\n ],\n });\n}\n\nexport interface CustomTheme {\n backgroundColor: string;\n lighterBgColor: string;\n borderColor: string;\n foregroundColor: string;\n accentColor: string;\n errorColor: string;\n selectionColor: string;\n themeExtension?: Extension;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Extension } from "@codemirror/state";
|
|
2
|
+
import { TypeDefinition } from "../json/types";
|
|
3
|
+
/**
|
|
4
|
+
* Triggered when the Enter key is pressed between 2 consecutive curly braces or
|
|
5
|
+
* square brackets.
|
|
6
|
+
*/
|
|
7
|
+
export declare function enterKeyHandler(schema: TypeDefinition): Extension;
|
|
8
|
+
//# sourceMappingURL=enter_key_handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enter_key_handler.d.ts","sourceRoot":"","sources":["../../src/codemirror/enter_key_handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EAKL,cAAc,EACf,MAAM,eAAe,CAAC;AAGvB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAmGjE"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { keymap } from "@codemirror/view";
|
|
2
|
+
import { makeJsonTemplate } from "../json/to_json";
|
|
3
|
+
import { ensureJsonState } from "./json_state";
|
|
4
|
+
/**
|
|
5
|
+
* Triggered when the Enter key is pressed between 2 consecutive curly braces or
|
|
6
|
+
* square brackets.
|
|
7
|
+
*/
|
|
8
|
+
export function enterKeyHandler(schema) {
|
|
9
|
+
return keymap.of([
|
|
10
|
+
{
|
|
11
|
+
key: "Enter",
|
|
12
|
+
run: (view) => {
|
|
13
|
+
const { state } = view;
|
|
14
|
+
const { selection } = state;
|
|
15
|
+
const { main } = selection;
|
|
16
|
+
// Get the current cursor position
|
|
17
|
+
const cursorPos = main.head;
|
|
18
|
+
const textAround = state.doc.sliceString(cursorPos - 1, cursorPos + 1);
|
|
19
|
+
if (textAround !== "{}" && textAround !== "[]") {
|
|
20
|
+
return false; // Allow default Enter behavior
|
|
21
|
+
}
|
|
22
|
+
// Ensure JSON state is up-to-date
|
|
23
|
+
const jsonState = ensureJsonState(view, schema);
|
|
24
|
+
const parseResult = jsonState.parseResult;
|
|
25
|
+
if (!parseResult.value) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const jsonValue = parseResult.value;
|
|
29
|
+
const idToRecordDef = {};
|
|
30
|
+
for (const record of schema.records) {
|
|
31
|
+
idToRecordDef[record.id] = record;
|
|
32
|
+
}
|
|
33
|
+
const type = findTypeByLeftBracketPos(jsonValue, cursorPos - 1, idToRecordDef);
|
|
34
|
+
if (type === null) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
let codeToInsert;
|
|
38
|
+
if (type.kind === "array") {
|
|
39
|
+
codeToInsert = JSON.stringify(makeJsonTemplate(type.value.item, idToRecordDef), null, 2);
|
|
40
|
+
}
|
|
41
|
+
else if (type.kind === "record") {
|
|
42
|
+
const recordDef = idToRecordDef[type.value];
|
|
43
|
+
if (recordDef.kind === "struct") {
|
|
44
|
+
codeToInsert = JSON.stringify(makeJsonTemplate(type, idToRecordDef), null, 2);
|
|
45
|
+
if (codeToInsert === "{}") {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// Remove the curly brackets at the start and end of the string and
|
|
49
|
+
// unindent each line.
|
|
50
|
+
codeToInsert = codeToInsert
|
|
51
|
+
.split("\n")
|
|
52
|
+
.slice(1, -1)
|
|
53
|
+
.map((line) => line.substring(2))
|
|
54
|
+
.join("\n");
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Enum
|
|
58
|
+
codeToInsert = ['"kind": "",', '"value": {}'].join("\n");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (type.kind === "timestamp") {
|
|
62
|
+
codeToInsert =
|
|
63
|
+
'"unix_millis": 0,\n"formatted": "1970-01-01T00:00:00.000Z"';
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const _ = type;
|
|
67
|
+
throw new Error(_);
|
|
68
|
+
}
|
|
69
|
+
// Indent the code to insert based on the current line's indentation
|
|
70
|
+
const lineIndentation = getLineIndentation(state.doc.toString(), cursorPos - 1);
|
|
71
|
+
codeToInsert = indent(codeToInsert, " " + lineIndentation);
|
|
72
|
+
codeToInsert = `\n${codeToInsert}\n${lineIndentation}`;
|
|
73
|
+
// Apply the transaction
|
|
74
|
+
view.dispatch({
|
|
75
|
+
changes: {
|
|
76
|
+
from: cursorPos,
|
|
77
|
+
to: cursorPos,
|
|
78
|
+
insert: codeToInsert,
|
|
79
|
+
},
|
|
80
|
+
// Move cursor to the end of the inserted text
|
|
81
|
+
selection: { anchor: cursorPos + codeToInsert.length },
|
|
82
|
+
});
|
|
83
|
+
return true; // Prevent default Enter behavior
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
function findTypeByLeftBracketPos(jsonValue, leftBracketPos, idToRecordDef) {
|
|
89
|
+
let { expectedType } = jsonValue;
|
|
90
|
+
if (!expectedType) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
if (expectedType.kind === "optional") {
|
|
94
|
+
expectedType = expectedType.value;
|
|
95
|
+
}
|
|
96
|
+
switch (jsonValue.kind) {
|
|
97
|
+
case "array": {
|
|
98
|
+
if (expectedType.kind !== "array") {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (leftBracketPos === jsonValue.firstToken.start) {
|
|
102
|
+
// We have a match
|
|
103
|
+
return expectedType;
|
|
104
|
+
}
|
|
105
|
+
// If no match, we can continue searching in the elements.
|
|
106
|
+
for (const element of jsonValue.values) {
|
|
107
|
+
if (leftBracketPos < element.firstToken.start) {
|
|
108
|
+
return null; // No need to continue (optimization)
|
|
109
|
+
}
|
|
110
|
+
const maybeResult = findTypeByLeftBracketPos(element, leftBracketPos, idToRecordDef);
|
|
111
|
+
if (maybeResult) {
|
|
112
|
+
return maybeResult;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
case "object": {
|
|
118
|
+
if (expectedType.kind === "primitive" &&
|
|
119
|
+
expectedType.value === "timestamp" &&
|
|
120
|
+
leftBracketPos === jsonValue.firstToken.start) {
|
|
121
|
+
return { kind: "timestamp" };
|
|
122
|
+
}
|
|
123
|
+
if (expectedType.kind !== "record") {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
if (leftBracketPos === jsonValue.firstToken.start) {
|
|
127
|
+
// We have a match
|
|
128
|
+
return expectedType;
|
|
129
|
+
}
|
|
130
|
+
// If no match, we can continue searching in the values.
|
|
131
|
+
const recordDef = idToRecordDef[expectedType.value];
|
|
132
|
+
if (recordDef.kind === "struct") {
|
|
133
|
+
for (const keyValue of Object.values(jsonValue.keyValues)) {
|
|
134
|
+
const maybeResult = findTypeByLeftBracketPos(keyValue.value, leftBracketPos, idToRecordDef);
|
|
135
|
+
if (maybeResult) {
|
|
136
|
+
return maybeResult;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const valueKv = jsonValue.keyValues["value"];
|
|
142
|
+
if (valueKv) {
|
|
143
|
+
const maybeResult = findTypeByLeftBracketPos(valueKv.value, leftBracketPos, idToRecordDef);
|
|
144
|
+
if (maybeResult) {
|
|
145
|
+
return maybeResult;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
case "literal": {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Returns the indentation at the line containing `position`. */
|
|
157
|
+
function getLineIndentation(text, position) {
|
|
158
|
+
if (position < 0 || position >= text.length) {
|
|
159
|
+
return "";
|
|
160
|
+
}
|
|
161
|
+
// Find the start of the line containing the position
|
|
162
|
+
let lineStart = position;
|
|
163
|
+
while (lineStart > 0 && text[lineStart - 1] !== "\n") {
|
|
164
|
+
lineStart--;
|
|
165
|
+
}
|
|
166
|
+
// Extract indentation (spaces at the beginning of the line)
|
|
167
|
+
let indentation = "";
|
|
168
|
+
let i = lineStart;
|
|
169
|
+
while (i < text.length && text[i] === " ") {
|
|
170
|
+
indentation += " ";
|
|
171
|
+
i++;
|
|
172
|
+
}
|
|
173
|
+
return indentation;
|
|
174
|
+
}
|
|
175
|
+
function indent(text, indentation) {
|
|
176
|
+
return text
|
|
177
|
+
.split("\n")
|
|
178
|
+
.map((line) => indentation + line)
|
|
179
|
+
.join("\n");
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=enter_key_handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enter_key_handler.js","sourceRoot":"","sources":["../../src/codemirror/enter_key_handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,OAAO,MAAM,CAAC,EAAE,CAAC;QACf;YACE,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,CAAC,IAAgB,EAAW,EAAE;gBACjC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;gBACvB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;gBAE3B,kCAAkC;gBAClC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;gBAE5B,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;gBACvE,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC/C,OAAO,KAAK,CAAC,CAAC,+BAA+B;gBAC/C,CAAC;gBAED,kCAAkC;gBAClC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAChD,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;oBACvB,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,SAAS,GAAc,WAAW,CAAC,KAAK,CAAC;gBAE/C,MAAM,aAAa,GAAuC,EAAE,CAAC;gBAC7D,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;gBACpC,CAAC;gBACD,MAAM,IAAI,GAAG,wBAAwB,CACnC,SAAS,EACT,SAAS,GAAG,CAAC,EACb,aAAa,CACd,CAAC;gBACF,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAClB,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,IAAI,YAAoB,CAAC;gBACzB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC1B,YAAY,GAAG,IAAI,CAAC,SAAS,CAC3B,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,EAChD,IAAI,EACJ,CAAC,CACF,CAAC;gBACJ,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAClC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC5C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAChC,YAAY,GAAG,IAAI,CAAC,SAAS,CAC3B,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,EACrC,IAAI,EACJ,CAAC,CACF,CAAC;wBACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;4BAC1B,OAAO,KAAK,CAAC;wBACf,CAAC;wBACD,mEAAmE;wBACnE,sBAAsB;wBACtB,YAAY,GAAG,YAAY;6BACxB,KAAK,CAAC,IAAI,CAAC;6BACX,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;6BACZ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;6BAChC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACN,OAAO;wBACP,YAAY,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC3D,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACrC,YAAY;wBACV,4DAA4D,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAU,IAAI,CAAC;oBACtB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,CAAC;gBAED,oEAAoE;gBACpE,MAAM,eAAe,GAAG,kBAAkB,CACxC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EACpB,SAAS,GAAG,CAAC,CACd,CAAC;gBACF,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,GAAG,eAAe,CAAC,CAAC;gBAE5D,YAAY,GAAG,KAAK,YAAY,KAAK,eAAe,EAAE,CAAC;gBAEvD,wBAAwB;gBACxB,IAAI,CAAC,QAAQ,CAAC;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,SAAS;wBACf,EAAE,EAAE,SAAS;wBACb,MAAM,EAAE,YAAY;qBACrB;oBACD,8CAA8C;oBAC9C,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE;iBACvD,CAAC,CAAC;gBAEH,OAAO,IAAI,CAAC,CAAC,iCAAiC;YAChD,CAAC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,wBAAwB,CAC/B,SAAoB,EACpB,cAAsB,EACtB,aAAiD;IAEjD,IAAI,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACjC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACrC,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC;IACpC,CAAC;IACD,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,cAAc,KAAK,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBAClD,kBAAkB;gBAClB,OAAO,YAAY,CAAC;YACtB,CAAC;YACD,0DAA0D;YAC1D,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;gBACvC,IAAI,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;oBAC9C,OAAO,IAAI,CAAC,CAAC,qCAAqC;gBACpD,CAAC;gBACD,MAAM,WAAW,GAAG,wBAAwB,CAC1C,OAAO,EACP,cAAc,EACd,aAAa,CACd,CAAC;gBACF,IAAI,WAAW,EAAE,CAAC;oBAChB,OAAO,WAAW,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IACE,YAAY,CAAC,IAAI,KAAK,WAAW;gBACjC,YAAY,CAAC,KAAK,KAAK,WAAW;gBAClC,cAAc,KAAK,SAAS,CAAC,UAAU,CAAC,KAAK,EAC7C,CAAC;gBACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;YAC/B,CAAC;YACD,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,cAAc,KAAK,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBAClD,kBAAkB;gBAClB,OAAO,YAAY,CAAC;YACtB,CAAC;YACD,wDAAwD;YACxD,MAAM,SAAS,GAAG,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpD,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC1D,MAAM,WAAW,GAAG,wBAAwB,CAC1C,QAAQ,CAAC,KAAK,EACd,cAAc,EACd,aAAa,CACd,CAAC;oBACF,IAAI,WAAW,EAAE,CAAC;wBAChB,OAAO,WAAW,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAC7C,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,WAAW,GAAG,wBAAwB,CAC1C,OAAO,CAAC,KAAK,EACb,cAAc,EACd,aAAa,CACd,CAAC;oBACF,IAAI,WAAW,EAAE,CAAC;wBAChB,OAAO,WAAW,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,SAAS,kBAAkB,CAAC,IAAY,EAAE,QAAgB;IACxD,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,qDAAqD;IACrD,IAAI,SAAS,GAAG,QAAQ,CAAC;IACzB,OAAO,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACrD,SAAS,EAAE,CAAC;IACd,CAAC;IAED,4DAA4D;IAC5D,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC,GAAG,SAAS,CAAC;IAClB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1C,WAAW,IAAI,GAAG,CAAC;QACnB,CAAC,EAAE,CAAC;IACN,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,WAAmB;IAC/C,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;SACjC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC","sourcesContent":["import { Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport { makeJsonTemplate } from \"../json/to_json\";\nimport {\n ArrayTypeSignature,\n JsonValue,\n RecordDefinition,\n RecordTypeSignature,\n TypeDefinition,\n} from \"../json/types\";\nimport { ensureJsonState } from \"./json_state\";\n\n/**\n * Triggered when the Enter key is pressed between 2 consecutive curly braces or\n * square brackets.\n */\nexport function enterKeyHandler(schema: TypeDefinition): Extension {\n return keymap.of([\n {\n key: \"Enter\",\n run: (view: EditorView): boolean => {\n const { state } = view;\n const { selection } = state;\n const { main } = selection;\n\n // Get the current cursor position\n const cursorPos = main.head;\n\n const textAround = state.doc.sliceString(cursorPos - 1, cursorPos + 1);\n if (textAround !== \"{}\" && textAround !== \"[]\") {\n return false; // Allow default Enter behavior\n }\n\n // Ensure JSON state is up-to-date\n const jsonState = ensureJsonState(view, schema);\n const parseResult = jsonState.parseResult;\n if (!parseResult.value) {\n return false;\n }\n const jsonValue: JsonValue = parseResult.value;\n\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n const type = findTypeByLeftBracketPos(\n jsonValue,\n cursorPos - 1,\n idToRecordDef,\n );\n if (type === null) {\n return false;\n }\n\n let codeToInsert: string;\n if (type.kind === \"array\") {\n codeToInsert = JSON.stringify(\n makeJsonTemplate(type.value.item, idToRecordDef),\n null,\n 2,\n );\n } else if (type.kind === \"record\") {\n const recordDef = idToRecordDef[type.value];\n if (recordDef.kind === \"struct\") {\n codeToInsert = JSON.stringify(\n makeJsonTemplate(type, idToRecordDef),\n null,\n 2,\n );\n if (codeToInsert === \"{}\") {\n return false;\n }\n // Remove the curly brackets at the start and end of the string and\n // unindent each line.\n codeToInsert = codeToInsert\n .split(\"\\n\")\n .slice(1, -1)\n .map((line) => line.substring(2))\n .join(\"\\n\");\n } else {\n // Enum\n codeToInsert = ['\"kind\": \"\",', '\"value\": {}'].join(\"\\n\");\n }\n } else if (type.kind === \"timestamp\") {\n codeToInsert =\n '\"unix_millis\": 0,\\n\"formatted\": \"1970-01-01T00:00:00.000Z\"';\n } else {\n const _: never = type;\n throw new Error(_);\n }\n\n // Indent the code to insert based on the current line's indentation\n const lineIndentation = getLineIndentation(\n state.doc.toString(),\n cursorPos - 1,\n );\n codeToInsert = indent(codeToInsert, \" \" + lineIndentation);\n\n codeToInsert = `\\n${codeToInsert}\\n${lineIndentation}`;\n\n // Apply the transaction\n view.dispatch({\n changes: {\n from: cursorPos,\n to: cursorPos,\n insert: codeToInsert,\n },\n // Move cursor to the end of the inserted text\n selection: { anchor: cursorPos + codeToInsert.length },\n });\n\n return true; // Prevent default Enter behavior\n },\n },\n ]);\n}\n\nfunction findTypeByLeftBracketPos(\n jsonValue: JsonValue,\n leftBracketPos: number,\n idToRecordDef: { [id: string]: RecordDefinition },\n): ArrayTypeSignature | RecordTypeSignature | { kind: \"timestamp\" } | null {\n let { expectedType } = jsonValue;\n if (!expectedType) {\n return null;\n }\n if (expectedType.kind === \"optional\") {\n expectedType = expectedType.value;\n }\n switch (jsonValue.kind) {\n case \"array\": {\n if (expectedType.kind !== \"array\") {\n return null;\n }\n if (leftBracketPos === jsonValue.firstToken.start) {\n // We have a match\n return expectedType;\n }\n // If no match, we can continue searching in the elements.\n for (const element of jsonValue.values) {\n if (leftBracketPos < element.firstToken.start) {\n return null; // No need to continue (optimization)\n }\n const maybeResult = findTypeByLeftBracketPos(\n element,\n leftBracketPos,\n idToRecordDef,\n );\n if (maybeResult) {\n return maybeResult;\n }\n }\n return null;\n }\n case \"object\": {\n if (\n expectedType.kind === \"primitive\" &&\n expectedType.value === \"timestamp\" &&\n leftBracketPos === jsonValue.firstToken.start\n ) {\n return { kind: \"timestamp\" };\n }\n if (expectedType.kind !== \"record\") {\n return null;\n }\n if (leftBracketPos === jsonValue.firstToken.start) {\n // We have a match\n return expectedType;\n }\n // If no match, we can continue searching in the values.\n const recordDef = idToRecordDef[expectedType.value];\n if (recordDef.kind === \"struct\") {\n for (const keyValue of Object.values(jsonValue.keyValues)) {\n const maybeResult = findTypeByLeftBracketPos(\n keyValue.value,\n leftBracketPos,\n idToRecordDef,\n );\n if (maybeResult) {\n return maybeResult;\n }\n }\n } else {\n const valueKv = jsonValue.keyValues[\"value\"];\n if (valueKv) {\n const maybeResult = findTypeByLeftBracketPos(\n valueKv.value,\n leftBracketPos,\n idToRecordDef,\n );\n if (maybeResult) {\n return maybeResult;\n }\n }\n }\n return null;\n }\n case \"literal\": {\n return null;\n }\n }\n}\n\n/** Returns the indentation at the line containing `position`. */\nfunction getLineIndentation(text: string, position: number): string {\n if (position < 0 || position >= text.length) {\n return \"\";\n }\n\n // Find the start of the line containing the position\n let lineStart = position;\n while (lineStart > 0 && text[lineStart - 1] !== \"\\n\") {\n lineStart--;\n }\n\n // Extract indentation (spaces at the beginning of the line)\n let indentation = \"\";\n let i = lineStart;\n while (i < text.length && text[i] === \" \") {\n indentation += \" \";\n i++;\n }\n\n return indentation;\n}\n\nfunction indent(text: string, indentation: string): string {\n return text\n .split(\"\\n\")\n .map((line) => indentation + line)\n .join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CompletionContext, CompletionResult } from "@codemirror/autocomplete";
|
|
2
|
+
import { TypeDefinition } from "../json/types";
|
|
3
|
+
export declare function jsonCompletion(schema: TypeDefinition): (context: CompletionContext) => CompletionResult | null;
|
|
4
|
+
//# sourceMappingURL=json_completion.d.ts.map
|