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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Json, JsonValue, RecordDefinition, TypeSignature } from "./types";
|
|
2
|
+
|
|
3
|
+
export function toJson(value: JsonValue): Json {
|
|
4
|
+
switch (value.kind) {
|
|
5
|
+
case "literal": {
|
|
6
|
+
return JSON.parse(value.jsonCode);
|
|
7
|
+
}
|
|
8
|
+
case "array": {
|
|
9
|
+
return value.values.map(toJson);
|
|
10
|
+
}
|
|
11
|
+
case "object": {
|
|
12
|
+
return Object.fromEntries(
|
|
13
|
+
Object.values(value.keyValues).map((keyValue) => [
|
|
14
|
+
keyValue.key,
|
|
15
|
+
toJson(keyValue.value),
|
|
16
|
+
]),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function makeJsonTemplate(
|
|
23
|
+
type: TypeSignature,
|
|
24
|
+
idToRecordDef: { [id: string]: RecordDefinition },
|
|
25
|
+
depth?: "depth",
|
|
26
|
+
): Json {
|
|
27
|
+
switch (type.kind) {
|
|
28
|
+
case "array": {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
case "optional": {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
case "record": {
|
|
35
|
+
const recordDef = idToRecordDef[type.value]!;
|
|
36
|
+
if (recordDef.kind === "struct") {
|
|
37
|
+
if (depth) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
return Object.fromEntries(
|
|
41
|
+
recordDef.fields.map((field) => [
|
|
42
|
+
field.name,
|
|
43
|
+
makeJsonTemplate(field.type!, idToRecordDef, "depth"),
|
|
44
|
+
]),
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
// Enum
|
|
48
|
+
return "UNKNOWN";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
case "primitive": {
|
|
52
|
+
switch (type.value) {
|
|
53
|
+
case "bool":
|
|
54
|
+
return false;
|
|
55
|
+
case "int32":
|
|
56
|
+
case "float32":
|
|
57
|
+
case "float64":
|
|
58
|
+
return 0;
|
|
59
|
+
case "int64":
|
|
60
|
+
case "hash64":
|
|
61
|
+
return "0";
|
|
62
|
+
case "timestamp":
|
|
63
|
+
return { unix_millis: 0, formatted: "1970-01-01T00:00:00Z" };
|
|
64
|
+
case "string":
|
|
65
|
+
case "bytes":
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// To use instead of `any`
|
|
2
|
+
export type Json =
|
|
3
|
+
| null
|
|
4
|
+
| boolean
|
|
5
|
+
| number
|
|
6
|
+
| string
|
|
7
|
+
| readonly Json[]
|
|
8
|
+
| Readonly<{ [name: string]: Json }>;
|
|
9
|
+
|
|
10
|
+
// -----------------------------------------------------------------------------
|
|
11
|
+
// ERRORS
|
|
12
|
+
// -----------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
export interface JsonError {
|
|
15
|
+
readonly kind: "error";
|
|
16
|
+
readonly segment: Segment;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// -----------------------------------------------------------------------------
|
|
21
|
+
// PARSING
|
|
22
|
+
// -----------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
export interface JsonParseResult {
|
|
25
|
+
/// If `undefined`, then `errors` is guaranteed not to be empty.
|
|
26
|
+
readonly value: JsonValue | undefined;
|
|
27
|
+
readonly errors: readonly JsonError[];
|
|
28
|
+
/// Set of edits to apply to the original JSON code to fix formatting and
|
|
29
|
+
// comma errors (no comma between consecutive values, trailing comma).
|
|
30
|
+
readonly edits: readonly JsonEdit[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type JsonValue = JsonArray | JsonObject | JsonLiteral;
|
|
34
|
+
|
|
35
|
+
export interface JsonArray {
|
|
36
|
+
readonly kind: "array";
|
|
37
|
+
/// Position of the '[' token.
|
|
38
|
+
readonly firstToken: Segment;
|
|
39
|
+
/// From '[' to ']' included.
|
|
40
|
+
readonly segment: Segment;
|
|
41
|
+
readonly values: JsonValue[];
|
|
42
|
+
expectedType?: TypeSignature;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface JsonKey {
|
|
46
|
+
readonly keySegment: Segment;
|
|
47
|
+
readonly key: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface JsonKeyValue {
|
|
51
|
+
readonly keySegment: Segment;
|
|
52
|
+
readonly key: string;
|
|
53
|
+
readonly value: JsonValue;
|
|
54
|
+
expectedType?: TypeSignature;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface JsonObject {
|
|
58
|
+
readonly kind: "object";
|
|
59
|
+
/// Position of the '{' token.
|
|
60
|
+
readonly firstToken: Segment;
|
|
61
|
+
/// From '{' to '}' included.
|
|
62
|
+
readonly segment: Segment;
|
|
63
|
+
readonly keyValues: { [key: string]: JsonKeyValue };
|
|
64
|
+
/// Includes "broken" keys which produced a parsing error.
|
|
65
|
+
readonly allKeys: readonly JsonKey[];
|
|
66
|
+
expectedType?: TypeSignature;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface JsonLiteral {
|
|
70
|
+
readonly kind: "literal";
|
|
71
|
+
/// Position of the first and only token. Same as `segment`.
|
|
72
|
+
readonly firstToken: Segment;
|
|
73
|
+
readonly segment: Segment;
|
|
74
|
+
readonly jsonCode: string;
|
|
75
|
+
readonly type: "boolean" | "null" | "number" | "string";
|
|
76
|
+
expectedType?: TypeSignature;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface Segment {
|
|
80
|
+
readonly start: number;
|
|
81
|
+
readonly end: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// Path to a sub-value within a valid Skir value.
|
|
85
|
+
export type Path =
|
|
86
|
+
| {
|
|
87
|
+
readonly kind: "root";
|
|
88
|
+
}
|
|
89
|
+
| {
|
|
90
|
+
readonly kind: "field-value";
|
|
91
|
+
/// Name of the field of the struct
|
|
92
|
+
readonly fieldName: string;
|
|
93
|
+
/// Path to the struct value
|
|
94
|
+
readonly structPath: Path;
|
|
95
|
+
}
|
|
96
|
+
| {
|
|
97
|
+
readonly kind: "variant-value";
|
|
98
|
+
/// Name of the wrapper variant of the enum
|
|
99
|
+
readonly variantName: string;
|
|
100
|
+
/// Path to the enum value
|
|
101
|
+
readonly enumPath: Path;
|
|
102
|
+
}
|
|
103
|
+
| {
|
|
104
|
+
readonly kind: "array-item";
|
|
105
|
+
readonly index: number;
|
|
106
|
+
readonly key: string | null;
|
|
107
|
+
readonly arrayPath: Path;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export interface JsonValueContext {
|
|
111
|
+
readonly value: JsonValue;
|
|
112
|
+
readonly path: Path;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface JsonEdit {
|
|
116
|
+
readonly segment: Segment;
|
|
117
|
+
readonly replacement: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// -----------------------------------------------------------------------------
|
|
121
|
+
// SCHEMA
|
|
122
|
+
// -----------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
/** JSON representation of a `TypeDescriptor`. */
|
|
125
|
+
export type TypeDefinition = {
|
|
126
|
+
readonly type: TypeSignature;
|
|
127
|
+
readonly records: readonly RecordDefinition[];
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/** A type in the JSON representation of a `TypeDescriptor`. */
|
|
131
|
+
export type TypeSignature =
|
|
132
|
+
| {
|
|
133
|
+
kind: "optional";
|
|
134
|
+
value: TypeSignature;
|
|
135
|
+
}
|
|
136
|
+
| ArrayTypeSignature
|
|
137
|
+
| RecordTypeSignature
|
|
138
|
+
| {
|
|
139
|
+
kind: "primitive";
|
|
140
|
+
value: PrimitiveType;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export interface ArrayTypeSignature {
|
|
144
|
+
readonly kind: "array";
|
|
145
|
+
readonly value: {
|
|
146
|
+
readonly item: TypeSignature;
|
|
147
|
+
readonly key_extractor?: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface RecordTypeSignature {
|
|
152
|
+
readonly kind: "record";
|
|
153
|
+
readonly value: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export type PrimitiveType =
|
|
157
|
+
| "bool"
|
|
158
|
+
| "int32"
|
|
159
|
+
| "int64"
|
|
160
|
+
| "hash64"
|
|
161
|
+
| "float32"
|
|
162
|
+
| "float64"
|
|
163
|
+
| "timestamp"
|
|
164
|
+
| "string"
|
|
165
|
+
| "bytes";
|
|
166
|
+
|
|
167
|
+
export type RecordDefinition = StructDefinition | EnumDefinition;
|
|
168
|
+
|
|
169
|
+
/** Definition of a struct in the JSON representation of a `TypeDescriptor`. */
|
|
170
|
+
export type StructDefinition = {
|
|
171
|
+
readonly kind: "struct";
|
|
172
|
+
readonly id: string;
|
|
173
|
+
readonly doc?: string;
|
|
174
|
+
readonly fields: readonly FieldDefinition[];
|
|
175
|
+
readonly removed_numbers?: readonly number[];
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Definition of a struct field in the JSON representation of a
|
|
180
|
+
* `TypeDescriptor`.
|
|
181
|
+
*/
|
|
182
|
+
export type FieldDefinition = {
|
|
183
|
+
readonly name: string;
|
|
184
|
+
readonly type: TypeSignature;
|
|
185
|
+
readonly number: number;
|
|
186
|
+
readonly doc?: string;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/** Definition of an enum in the JSON representation of a `TypeDescriptor`. */
|
|
190
|
+
export type EnumDefinition = {
|
|
191
|
+
readonly kind: "enum";
|
|
192
|
+
readonly id: string;
|
|
193
|
+
readonly doc?: string;
|
|
194
|
+
readonly variants: readonly VariantDefinition[];
|
|
195
|
+
readonly removed_numbers?: readonly number[];
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Definition of an enum variant in the JSON representation of a
|
|
200
|
+
* `TypeDescriptor`.
|
|
201
|
+
*/
|
|
202
|
+
export type VariantDefinition = {
|
|
203
|
+
readonly name: string;
|
|
204
|
+
readonly type?: TypeSignature;
|
|
205
|
+
readonly number: number;
|
|
206
|
+
readonly doc?: string;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// -----------------------------------------------------------------------------
|
|
210
|
+
// SCHEMA VALIDATION
|
|
211
|
+
// -----------------------------------------------------------------------------
|
|
212
|
+
|
|
213
|
+
export interface ValidationResult {
|
|
214
|
+
readonly errors: JsonError[];
|
|
215
|
+
readonly hints: Hint[];
|
|
216
|
+
readonly rootTypeHint: TypeHint | undefined;
|
|
217
|
+
readonly pathToTypeHint: ReadonlyMap<Path, TypeHint>;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface TypeHint {
|
|
221
|
+
readonly segment: Segment;
|
|
222
|
+
readonly message: string | readonly string[];
|
|
223
|
+
readonly valueContext: JsonValueContext;
|
|
224
|
+
/// In order. All are included in 'valueContext.value.segment'.
|
|
225
|
+
readonly childHints: readonly TypeHint[];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export type Hint =
|
|
229
|
+
| {
|
|
230
|
+
readonly segment: Segment;
|
|
231
|
+
readonly message: string;
|
|
232
|
+
readonly valueContext?: undefined;
|
|
233
|
+
}
|
|
234
|
+
| TypeHint;
|
|
235
|
+
|
|
236
|
+
export interface MutableTypeHint extends TypeHint {
|
|
237
|
+
readonly childHints: TypeHint[];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// -----------------------------------------------------------------------------
|
|
241
|
+
// METHOD LIST
|
|
242
|
+
// -----------------------------------------------------------------------------
|
|
243
|
+
|
|
244
|
+
export interface MethodList {
|
|
245
|
+
readonly methods: readonly Method[];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface Method {
|
|
249
|
+
readonly method: string;
|
|
250
|
+
readonly number: number | string;
|
|
251
|
+
readonly request: TypeDefinition;
|
|
252
|
+
readonly response: TypeDefinition;
|
|
253
|
+
readonly doc?: string;
|
|
254
|
+
}
|