skir-codemirror-plugin 1.0.2 → 1.0.4

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.
Files changed (42) hide show
  1. package/README.md +15 -6
  2. package/dist/codemirror/create_editor_state.d.ts +4 -2
  3. package/dist/codemirror/create_editor_state.d.ts.map +1 -1
  4. package/dist/codemirror/create_editor_state.js +178 -31
  5. package/dist/codemirror/create_editor_state.js.map +1 -1
  6. package/dist/codemirror/json_linter.d.ts.map +1 -1
  7. package/dist/codemirror/json_linter.js +67 -3
  8. package/dist/codemirror/json_linter.js.map +1 -1
  9. package/dist/codemirror/json_state.d.ts +5 -1
  10. package/dist/codemirror/json_state.d.ts.map +1 -1
  11. package/dist/codemirror/json_state.js +26 -1
  12. package/dist/codemirror/json_state.js.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/json/json_parser.js +35 -1
  17. package/dist/json/json_parser.js.map +1 -1
  18. package/dist/json/json_parser.test.js +48 -0
  19. package/dist/json/json_parser.test.js.map +1 -1
  20. package/dist/json/schema_validator.d.ts.map +1 -1
  21. package/dist/json/schema_validator.js +22 -14
  22. package/dist/json/schema_validator.js.map +1 -1
  23. package/dist/json/schema_validator.test.js +146 -5
  24. package/dist/json/schema_validator.test.js.map +1 -1
  25. package/dist/json/to_json.d.ts +1 -1
  26. package/dist/json/to_json.d.ts.map +1 -1
  27. package/dist/json/to_json.js +3 -3
  28. package/dist/json/to_json.js.map +1 -1
  29. package/dist/json/types.d.ts +4 -0
  30. package/dist/json/types.d.ts.map +1 -1
  31. package/dist/json/types.js.map +1 -1
  32. package/package.json +4 -6
  33. package/src/codemirror/create_editor_state.ts +272 -31
  34. package/src/codemirror/json_linter.ts +89 -4
  35. package/src/codemirror/json_state.ts +44 -1
  36. package/src/index.ts +1 -0
  37. package/src/json/json_parser.test.ts +51 -0
  38. package/src/json/json_parser.ts +37 -1
  39. package/src/json/schema_validator.test.ts +166 -5
  40. package/src/json/schema_validator.ts +26 -13
  41. package/src/json/to_json.ts +3 -3
  42. package/src/json/types.ts +7 -0
@@ -14,7 +14,7 @@ export function toJson(value) {
14
14
  }
15
15
  }
16
16
  }
17
- export function makeJsonTemplate(type, idToRecordDef, depth) {
17
+ export function makeJsonTemplate(type, idToRecordDef, nested) {
18
18
  switch (type.kind) {
19
19
  case "array": {
20
20
  return [];
@@ -25,12 +25,12 @@ export function makeJsonTemplate(type, idToRecordDef, depth) {
25
25
  case "record": {
26
26
  const recordDef = idToRecordDef[type.value];
27
27
  if (recordDef.kind === "struct") {
28
- if (depth) {
28
+ if (nested) {
29
29
  return {};
30
30
  }
31
31
  return Object.fromEntries(recordDef.fields.map((field) => [
32
32
  field.name,
33
- makeJsonTemplate(field.type, idToRecordDef, "depth"),
33
+ makeJsonTemplate(field.type, idToRecordDef, "nested"),
34
34
  ]));
35
35
  }
36
36
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"to_json.js","sourceRoot":"","sources":["../../src/json/to_json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,MAAM,CAAC,KAAgB;IACrC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAC/C,QAAQ,CAAC,GAAG;gBACZ,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;aACvB,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAmB,EACnB,aAAiD,EACjD,KAAe;IAEf,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;YAC7C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChC,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,OAAO,MAAM,CAAC,WAAW,CACvB,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI;oBACV,gBAAgB,CAAC,KAAK,CAAC,IAAK,EAAE,aAAa,EAAE,OAAO,CAAC;iBACtD,CAAC,CACH,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,KAAK,MAAM;oBACT,OAAO,KAAK,CAAC;gBACf,KAAK,OAAO,CAAC;gBACb,KAAK,SAAS,CAAC;gBACf,KAAK,SAAS;oBACZ,OAAO,CAAC,CAAC;gBACX,KAAK,OAAO,CAAC;gBACb,KAAK,QAAQ;oBACX,OAAO,GAAG,CAAC;gBACb,KAAK,WAAW;oBACd,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAAC;gBAC/D,KAAK,QAAQ,CAAC;gBACd,KAAK,OAAO;oBACV,OAAO,EAAE,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type { Json, JsonValue, RecordDefinition, TypeSignature } from \"./types\";\n\nexport function toJson(value: JsonValue): Json {\n switch (value.kind) {\n case \"literal\": {\n return JSON.parse(value.jsonCode);\n }\n case \"array\": {\n return value.values.map(toJson);\n }\n case \"object\": {\n return Object.fromEntries(\n Object.values(value.keyValues).map((keyValue) => [\n keyValue.key,\n toJson(keyValue.value),\n ]),\n );\n }\n }\n}\n\nexport function makeJsonTemplate(\n type: TypeSignature,\n idToRecordDef: { [id: string]: RecordDefinition },\n depth?: \"depth\",\n): Json {\n switch (type.kind) {\n case \"array\": {\n return [];\n }\n case \"optional\": {\n return null;\n }\n case \"record\": {\n const recordDef = idToRecordDef[type.value]!;\n if (recordDef.kind === \"struct\") {\n if (depth) {\n return {};\n }\n return Object.fromEntries(\n recordDef.fields.map((field) => [\n field.name,\n makeJsonTemplate(field.type!, idToRecordDef, \"depth\"),\n ]),\n );\n } else {\n // Enum\n return \"UNKNOWN\";\n }\n }\n case \"primitive\": {\n switch (type.value) {\n case \"bool\":\n return false;\n case \"int32\":\n case \"float32\":\n case \"float64\":\n return 0;\n case \"int64\":\n case \"hash64\":\n return \"0\";\n case \"timestamp\":\n return { unix_millis: 0, formatted: \"1970-01-01T00:00:00Z\" };\n case \"string\":\n case \"bytes\":\n return \"\";\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"to_json.js","sourceRoot":"","sources":["../../src/json/to_json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,MAAM,CAAC,KAAgB;IACrC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAC/C,QAAQ,CAAC,GAAG;gBACZ,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;aACvB,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAmB,EACnB,aAAiD,EACjD,MAAiB;IAEjB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;YAC7C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChC,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,EAAE,CAAC;gBACZ,CAAC;gBACD,OAAO,MAAM,CAAC,WAAW,CACvB,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI;oBACV,gBAAgB,CAAC,KAAK,CAAC,IAAK,EAAE,aAAa,EAAE,QAAQ,CAAC;iBACvD,CAAC,CACH,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,KAAK,MAAM;oBACT,OAAO,KAAK,CAAC;gBACf,KAAK,OAAO,CAAC;gBACb,KAAK,SAAS,CAAC;gBACf,KAAK,SAAS;oBACZ,OAAO,CAAC,CAAC;gBACX,KAAK,OAAO,CAAC;gBACb,KAAK,QAAQ;oBACX,OAAO,GAAG,CAAC;gBACb,KAAK,WAAW;oBACd,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAAC;gBAC/D,KAAK,QAAQ,CAAC;gBACd,KAAK,OAAO;oBACV,OAAO,EAAE,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type { Json, JsonValue, RecordDefinition, TypeSignature } from \"./types\";\n\nexport function toJson(value: JsonValue): Json {\n switch (value.kind) {\n case \"literal\": {\n return JSON.parse(value.jsonCode);\n }\n case \"array\": {\n return value.values.map(toJson);\n }\n case \"object\": {\n return Object.fromEntries(\n Object.values(value.keyValues).map((keyValue) => [\n keyValue.key,\n toJson(keyValue.value),\n ]),\n );\n }\n }\n}\n\nexport function makeJsonTemplate(\n type: TypeSignature,\n idToRecordDef: { [id: string]: RecordDefinition },\n nested?: \"nested\",\n): Json {\n switch (type.kind) {\n case \"array\": {\n return [];\n }\n case \"optional\": {\n return null;\n }\n case \"record\": {\n const recordDef = idToRecordDef[type.value]!;\n if (recordDef.kind === \"struct\") {\n if (nested) {\n return {};\n }\n return Object.fromEntries(\n recordDef.fields.map((field) => [\n field.name,\n makeJsonTemplate(field.type!, idToRecordDef, \"nested\"),\n ]),\n );\n } else {\n // Enum\n return \"UNKNOWN\";\n }\n }\n case \"primitive\": {\n switch (type.value) {\n case \"bool\":\n return false;\n case \"int32\":\n case \"float32\":\n case \"float64\":\n return 0;\n case \"int64\":\n case \"hash64\":\n return \"0\";\n case \"timestamp\":\n return { unix_millis: 0, formatted: \"1970-01-01T00:00:00Z\" };\n case \"string\":\n case \"bytes\":\n return \"\";\n }\n }\n }\n}\n"]}
@@ -17,6 +17,7 @@ export interface JsonArray {
17
17
  readonly firstToken: Segment;
18
18
  readonly segment: Segment;
19
19
  readonly values: JsonValue[];
20
+ readonly indent: number;
20
21
  expectedType?: TypeSignature;
21
22
  }
22
23
  export interface JsonKey {
@@ -37,6 +38,7 @@ export interface JsonObject {
37
38
  [key: string]: JsonKeyValue;
38
39
  };
39
40
  readonly allKeys: readonly JsonKey[];
41
+ readonly indent: number;
40
42
  expectedType?: TypeSignature;
41
43
  }
42
44
  export interface JsonLiteral {
@@ -45,6 +47,7 @@ export interface JsonLiteral {
45
47
  readonly segment: Segment;
46
48
  readonly jsonCode: string;
47
49
  readonly type: "boolean" | "null" | "number" | "string";
50
+ readonly indent: number;
48
51
  expectedType?: TypeSignature;
49
52
  }
50
53
  export interface Segment {
@@ -148,6 +151,7 @@ export interface TypeHint {
148
151
  readonly message: string | readonly string[];
149
152
  readonly valueContext: JsonValueContext;
150
153
  readonly childHints: readonly TypeHint[];
154
+ readonly enumDefinition?: EnumDefinition;
151
155
  }
152
156
  export type Hint = {
153
157
  readonly segment: Segment;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/json/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/json/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/json/types.ts"],"names":[],"mappings":"","sourcesContent":["// To use instead of `any`\nexport type Json =\n | null\n | boolean\n | number\n | string\n | readonly Json[]\n | Readonly<{ [name: string]: Json }>;\n\n// -----------------------------------------------------------------------------\n// ERRORS\n// -----------------------------------------------------------------------------\n\nexport interface JsonError {\n readonly kind: \"error\";\n readonly segment: Segment;\n readonly message: string;\n}\n\n// -----------------------------------------------------------------------------\n// PARSING\n// -----------------------------------------------------------------------------\n\nexport interface JsonParseResult {\n /// If `undefined`, then `errors` is guaranteed not to be empty.\n readonly value: JsonValue | undefined;\n readonly errors: readonly JsonError[];\n /// Set of edits to apply to the original JSON code to fix formatting and\n // comma errors (no comma between consecutive values, trailing comma).\n readonly edits: readonly JsonEdit[];\n}\n\nexport type JsonValue = JsonArray | JsonObject | JsonLiteral;\n\nexport interface JsonArray {\n readonly kind: \"array\";\n /// Position of the '[' token.\n readonly firstToken: Segment;\n /// From '[' to ']' included.\n readonly segment: Segment;\n readonly values: JsonValue[];\n expectedType?: TypeSignature;\n}\n\nexport interface JsonKey {\n readonly keySegment: Segment;\n readonly key: string;\n}\n\nexport interface JsonKeyValue {\n readonly keySegment: Segment;\n readonly key: string;\n readonly value: JsonValue;\n expectedType?: TypeSignature;\n}\n\nexport interface JsonObject {\n readonly kind: \"object\";\n /// Position of the '{' token.\n readonly firstToken: Segment;\n /// From '{' to '}' included.\n readonly segment: Segment;\n readonly keyValues: { [key: string]: JsonKeyValue };\n /// Includes \"broken\" keys which produced a parsing error.\n readonly allKeys: readonly JsonKey[];\n expectedType?: TypeSignature;\n}\n\nexport interface JsonLiteral {\n readonly kind: \"literal\";\n /// Position of the first and only token. Same as `segment`.\n readonly firstToken: Segment;\n readonly segment: Segment;\n readonly jsonCode: string;\n readonly type: \"boolean\" | \"null\" | \"number\" | \"string\";\n expectedType?: TypeSignature;\n}\n\nexport interface Segment {\n readonly start: number;\n readonly end: number;\n}\n\n/// Path to a sub-value within a valid Skir value.\nexport type Path =\n | {\n readonly kind: \"root\";\n }\n | {\n readonly kind: \"field-value\";\n /// Name of the field of the struct\n readonly fieldName: string;\n /// Path to the struct value\n readonly structPath: Path;\n }\n | {\n readonly kind: \"variant-value\";\n /// Name of the wrapper variant of the enum\n readonly variantName: string;\n /// Path to the enum value\n readonly enumPath: Path;\n }\n | {\n readonly kind: \"array-item\";\n readonly index: number;\n readonly key: string | null;\n readonly arrayPath: Path;\n };\n\nexport interface JsonValueContext {\n readonly value: JsonValue;\n readonly path: Path;\n}\n\nexport interface JsonEdit {\n readonly segment: Segment;\n readonly replacement: string;\n}\n\n// -----------------------------------------------------------------------------\n// SCHEMA\n// -----------------------------------------------------------------------------\n\n/** JSON representation of a `TypeDescriptor`. */\nexport type TypeDefinition = {\n readonly type: TypeSignature;\n readonly records: readonly RecordDefinition[];\n};\n\n/** A type in the JSON representation of a `TypeDescriptor`. */\nexport type TypeSignature =\n | {\n kind: \"optional\";\n value: TypeSignature;\n }\n | ArrayTypeSignature\n | RecordTypeSignature\n | {\n kind: \"primitive\";\n value: PrimitiveType;\n };\n\nexport interface ArrayTypeSignature {\n readonly kind: \"array\";\n readonly value: {\n readonly item: TypeSignature;\n readonly key_extractor?: string;\n };\n}\n\nexport interface RecordTypeSignature {\n readonly kind: \"record\";\n readonly value: string;\n}\n\nexport type PrimitiveType =\n | \"bool\"\n | \"int32\"\n | \"int64\"\n | \"hash64\"\n | \"float32\"\n | \"float64\"\n | \"timestamp\"\n | \"string\"\n | \"bytes\";\n\nexport type RecordDefinition = StructDefinition | EnumDefinition;\n\n/** Definition of a struct in the JSON representation of a `TypeDescriptor`. */\nexport type StructDefinition = {\n readonly kind: \"struct\";\n readonly id: string;\n readonly doc?: string;\n readonly fields: readonly FieldDefinition[];\n readonly removed_numbers?: readonly number[];\n};\n\n/**\n * Definition of a struct field in the JSON representation of a\n * `TypeDescriptor`.\n */\nexport type FieldDefinition = {\n readonly name: string;\n readonly type: TypeSignature;\n readonly number: number;\n readonly doc?: string;\n};\n\n/** Definition of an enum in the JSON representation of a `TypeDescriptor`. */\nexport type EnumDefinition = {\n readonly kind: \"enum\";\n readonly id: string;\n readonly doc?: string;\n readonly variants: readonly VariantDefinition[];\n readonly removed_numbers?: readonly number[];\n};\n\n/**\n * Definition of an enum variant in the JSON representation of a\n * `TypeDescriptor`.\n */\nexport type VariantDefinition = {\n readonly name: string;\n readonly type?: TypeSignature;\n readonly number: number;\n readonly doc?: string;\n};\n\n// -----------------------------------------------------------------------------\n// SCHEMA VALIDATION\n// -----------------------------------------------------------------------------\n\nexport interface ValidationResult {\n readonly errors: JsonError[];\n readonly hints: Hint[];\n readonly rootTypeHint: TypeHint | undefined;\n readonly pathToTypeHint: ReadonlyMap<Path, TypeHint>;\n}\n\nexport interface TypeHint {\n readonly segment: Segment;\n readonly message: string | readonly string[];\n readonly valueContext: JsonValueContext;\n /// In order. All are included in 'valueContext.value.segment'.\n readonly childHints: readonly TypeHint[];\n}\n\nexport type Hint =\n | {\n readonly segment: Segment;\n readonly message: string;\n readonly valueContext?: undefined;\n }\n | TypeHint;\n\nexport interface MutableTypeHint extends TypeHint {\n readonly childHints: TypeHint[];\n}\n\n// -----------------------------------------------------------------------------\n// METHOD LIST\n// -----------------------------------------------------------------------------\n\nexport interface MethodList {\n readonly methods: readonly Method[];\n}\n\nexport interface Method {\n readonly method: string;\n readonly number: number | string;\n readonly request: TypeDefinition;\n readonly response: TypeDefinition;\n readonly doc?: string;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/json/types.ts"],"names":[],"mappings":"","sourcesContent":["// To use instead of `any`\nexport type Json =\n | null\n | boolean\n | number\n | string\n | readonly Json[]\n | Readonly<{ [name: string]: Json }>;\n\n// -----------------------------------------------------------------------------\n// ERRORS\n// -----------------------------------------------------------------------------\n\nexport interface JsonError {\n readonly kind: \"error\";\n readonly segment: Segment;\n readonly message: string;\n}\n\n// -----------------------------------------------------------------------------\n// PARSING\n// -----------------------------------------------------------------------------\n\nexport interface JsonParseResult {\n /// If `undefined`, then `errors` is guaranteed not to be empty.\n readonly value: JsonValue | undefined;\n readonly errors: readonly JsonError[];\n /// Set of edits to apply to the original JSON code to fix formatting and\n // comma errors (no comma between consecutive values, trailing comma).\n readonly edits: readonly JsonEdit[];\n}\n\nexport type JsonValue = JsonArray | JsonObject | JsonLiteral;\n\nexport interface JsonArray {\n readonly kind: \"array\";\n /// Position of the '[' token.\n readonly firstToken: Segment;\n /// From '[' to ']' included.\n readonly segment: Segment;\n readonly values: JsonValue[];\n readonly indent: number;\n expectedType?: TypeSignature;\n}\n\nexport interface JsonKey {\n readonly keySegment: Segment;\n readonly key: string;\n}\n\nexport interface JsonKeyValue {\n readonly keySegment: Segment;\n readonly key: string;\n readonly value: JsonValue;\n expectedType?: TypeSignature;\n}\n\nexport interface JsonObject {\n readonly kind: \"object\";\n /// Position of the '{' token.\n readonly firstToken: Segment;\n /// From '{' to '}' included.\n readonly segment: Segment;\n readonly keyValues: { [key: string]: JsonKeyValue };\n /// Includes \"broken\" keys which produced a parsing error.\n readonly allKeys: readonly JsonKey[];\n readonly indent: number;\n expectedType?: TypeSignature;\n}\n\nexport interface JsonLiteral {\n readonly kind: \"literal\";\n /// Position of the first and only token. Same as `segment`.\n readonly firstToken: Segment;\n readonly segment: Segment;\n readonly jsonCode: string;\n readonly type: \"boolean\" | \"null\" | \"number\" | \"string\";\n readonly indent: number;\n expectedType?: TypeSignature;\n}\n\nexport interface Segment {\n readonly start: number;\n readonly end: number;\n}\n\n/// Path to a sub-value within a valid Skir value.\nexport type Path =\n | {\n readonly kind: \"root\";\n }\n | {\n readonly kind: \"field-value\";\n /// Name of the field of the struct\n readonly fieldName: string;\n /// Path to the struct value\n readonly structPath: Path;\n }\n | {\n readonly kind: \"variant-value\";\n /// Name of the wrapper variant of the enum\n readonly variantName: string;\n /// Path to the enum value\n readonly enumPath: Path;\n }\n | {\n readonly kind: \"array-item\";\n readonly index: number;\n readonly key: string | null;\n readonly arrayPath: Path;\n };\n\nexport interface JsonValueContext {\n readonly value: JsonValue;\n readonly path: Path;\n}\n\nexport interface JsonEdit {\n readonly segment: Segment;\n readonly replacement: string;\n}\n\n// -----------------------------------------------------------------------------\n// SCHEMA\n// -----------------------------------------------------------------------------\n\n/** JSON representation of a `TypeDescriptor`. */\nexport type TypeDefinition = {\n readonly type: TypeSignature;\n readonly records: readonly RecordDefinition[];\n};\n\n/** A type in the JSON representation of a `TypeDescriptor`. */\nexport type TypeSignature =\n | {\n kind: \"optional\";\n value: TypeSignature;\n }\n | ArrayTypeSignature\n | RecordTypeSignature\n | {\n kind: \"primitive\";\n value: PrimitiveType;\n };\n\nexport interface ArrayTypeSignature {\n readonly kind: \"array\";\n readonly value: {\n readonly item: TypeSignature;\n readonly key_extractor?: string;\n };\n}\n\nexport interface RecordTypeSignature {\n readonly kind: \"record\";\n readonly value: string;\n}\n\nexport type PrimitiveType =\n | \"bool\"\n | \"int32\"\n | \"int64\"\n | \"hash64\"\n | \"float32\"\n | \"float64\"\n | \"timestamp\"\n | \"string\"\n | \"bytes\";\n\nexport type RecordDefinition = StructDefinition | EnumDefinition;\n\n/** Definition of a struct in the JSON representation of a `TypeDescriptor`. */\nexport type StructDefinition = {\n readonly kind: \"struct\";\n readonly id: string;\n readonly doc?: string;\n readonly fields: readonly FieldDefinition[];\n readonly removed_numbers?: readonly number[];\n};\n\n/**\n * Definition of a struct field in the JSON representation of a\n * `TypeDescriptor`.\n */\nexport type FieldDefinition = {\n readonly name: string;\n readonly type: TypeSignature;\n readonly number: number;\n readonly doc?: string;\n};\n\n/** Definition of an enum in the JSON representation of a `TypeDescriptor`. */\nexport type EnumDefinition = {\n readonly kind: \"enum\";\n readonly id: string;\n readonly doc?: string;\n readonly variants: readonly VariantDefinition[];\n readonly removed_numbers?: readonly number[];\n};\n\n/**\n * Definition of an enum variant in the JSON representation of a\n * `TypeDescriptor`.\n */\nexport type VariantDefinition = {\n readonly name: string;\n readonly type?: TypeSignature;\n readonly number: number;\n readonly doc?: string;\n};\n\n// -----------------------------------------------------------------------------\n// SCHEMA VALIDATION\n// -----------------------------------------------------------------------------\n\nexport interface ValidationResult {\n readonly errors: JsonError[];\n readonly hints: Hint[];\n readonly rootTypeHint: TypeHint | undefined;\n readonly pathToTypeHint: ReadonlyMap<Path, TypeHint>;\n}\n\nexport interface TypeHint {\n readonly segment: Segment;\n readonly message: string | readonly string[];\n readonly valueContext: JsonValueContext;\n /// In order. All are included in 'valueContext.value.segment'.\n readonly childHints: readonly TypeHint[];\n /// Set if the expected type is an enum and the value is a literal string.\n /// In that case, the editor can show a dropdown with the possible variants\n /// of the enum.\n readonly enumDefinition?: EnumDefinition;\n}\n\nexport type Hint =\n | {\n readonly segment: Segment;\n readonly message: string;\n readonly valueContext?: undefined;\n }\n | TypeHint;\n\nexport interface MutableTypeHint extends TypeHint {\n readonly childHints: TypeHint[];\n}\n\n// -----------------------------------------------------------------------------\n// METHOD LIST\n// -----------------------------------------------------------------------------\n\nexport interface MethodList {\n readonly methods: readonly Method[];\n}\n\nexport interface Method {\n readonly method: string;\n readonly number: number | string;\n readonly request: TypeDefinition;\n readonly response: TypeDefinition;\n readonly doc?: string;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skir-codemirror-plugin",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/gepheum/skir-codemirror-plugin#readme",
6
6
  "bugs": {
@@ -46,10 +46,9 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@codemirror/lang-json": "^6.0.2",
49
- "@uiw/codemirror-theme-tokyo-night": "^4.25.4",
50
- "@uiw/codemirror-theme-tokyo-night-day": "^4.25.9",
49
+ "@uiw/codemirror-themes-all": "^4.25.9",
51
50
  "codemirror": "^6.0.2",
52
- "skir-client": "^1.0.11"
51
+ "skir-client": "^1.0.18"
53
52
  },
54
53
  "devDependencies": {
55
54
  "@custom-elements-manifest/analyzer": "^0.6.3",
@@ -74,6 +73,5 @@
74
73
  "diff": "^8.0.3",
75
74
  "minimatch": "^10.2.1",
76
75
  "serialize-javascript": "^7.0.4"
77
- },
78
- "customElements": "custom-elements.json"
76
+ }
79
77
  }
@@ -3,8 +3,7 @@ import { json as jsonExtension } from "@codemirror/lang-json";
3
3
  import { linter, lintGutter } from "@codemirror/lint";
4
4
  import { EditorState, Extension } from "@codemirror/state";
5
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";
6
+ import * as codeMirrorThemes from "@uiw/codemirror-themes-all";
8
7
  import { basicSetup } from "codemirror";
9
8
  import { makeJsonTemplate } from "../json/to_json";
10
9
  import type { Json, RecordDefinition, TypeDefinition } from "../json/types";
@@ -18,14 +17,279 @@ export type CreateEditorStateParams = {
18
17
  schema: TypeDefinition;
19
18
  readOnly?: true;
20
19
  json?: Json;
21
- theme?: "tokyo-night" | "tokyo-night-day" | CustomTheme;
20
+ theme?: BuiltinThemeName | CustomTheme;
21
+ otherExtension?: Extension;
22
22
  };
23
23
 
24
+ export type BuiltinThemeName =
25
+ | "abcdef"
26
+ | "abyss"
27
+ | "androidstudio"
28
+ | "andromeda"
29
+ | "atomone"
30
+ | "aura"
31
+ | "basic-dark"
32
+ | "basic-light"
33
+ | "bbedit"
34
+ | "bespin"
35
+ | "console-dark"
36
+ | "console-light"
37
+ | "copilot"
38
+ | "darcula"
39
+ | "dracula"
40
+ | "duotone-dark"
41
+ | "duotone-light"
42
+ | "eclipse"
43
+ | "github-dark"
44
+ | "github-light"
45
+ | "gruvbox-dark"
46
+ | "gruvbox-light"
47
+ | "kimbie"
48
+ | "material"
49
+ | "material-dark"
50
+ | "material-light"
51
+ | "monokai"
52
+ | "monokai-dimmed"
53
+ | "noctis-lilac"
54
+ | "nord"
55
+ | "okaidia"
56
+ | "quietlight"
57
+ | "red"
58
+ | "solarized-dark"
59
+ | "solarized-light"
60
+ | "sublime"
61
+ | "tokyo-night"
62
+ | "tokyo-night-day"
63
+ | "tokyo-night-storm"
64
+ | "tomorrow-night-blue"
65
+ | "vscode-dark"
66
+ | "vscode-light"
67
+ | "white"
68
+ | "white-dark"
69
+ | "white-light"
70
+ | "xcode-dark"
71
+ | "xcode-light";
72
+
73
+ const WHITE_THEME_COLORS: Omit<CustomTheme, "themeExtension"> = {
74
+ backgroundColor: "#fffdf7",
75
+ lighterBgColor: "#f3eee1",
76
+ borderColor: "#d4d0c4",
77
+ foregroundColor: "#111111",
78
+ accentColor: "#111111",
79
+ errorColor: "#232323",
80
+ selectionColor: "#d9d4c7",
81
+ };
82
+
83
+ const TOKYO_NIGHT_THEME_COLORS: Omit<CustomTheme, "themeExtension"> = {
84
+ backgroundColor: "#1a1b26",
85
+ lighterBgColor: "#1f2335",
86
+ borderColor: "#414868",
87
+ foregroundColor: "#c0caf5",
88
+ accentColor: "#7aa2f7",
89
+ errorColor: "#f7768e",
90
+ selectionColor: "#515c7e40",
91
+ };
92
+
93
+ const TOKYO_NIGHT_DAY_THEME_COLORS: Omit<CustomTheme, "themeExtension"> = {
94
+ backgroundColor: "#d5d6db",
95
+ lighterBgColor: "#e1e2e7",
96
+ borderColor: "#adb0bb",
97
+ foregroundColor: "#3760bf",
98
+ accentColor: "#2e7de9",
99
+ errorColor: "#f52a65",
100
+ selectionColor: "#3760bf33",
101
+ };
102
+
103
+ type ThemeDefaults = Partial<{
104
+ background: string;
105
+ foreground: string;
106
+ caret: string;
107
+ selection: string;
108
+ selectionMatch: string;
109
+ gutterBackground: string;
110
+ gutterForeground: string;
111
+ gutterBorder: string;
112
+ lineHighlight: string;
113
+ }>;
114
+
115
+ const BUILTIN_THEME_EXTENSIONS: Record<BuiltinThemeName, Extension> = {
116
+ abcdef: codeMirrorThemes.abcdef,
117
+ abyss: codeMirrorThemes.abyss,
118
+ androidstudio: codeMirrorThemes.androidstudio,
119
+ andromeda: codeMirrorThemes.andromeda,
120
+ atomone: codeMirrorThemes.atomone,
121
+ aura: codeMirrorThemes.aura,
122
+ "basic-dark": codeMirrorThemes.basicDark,
123
+ "basic-light": codeMirrorThemes.basicLight,
124
+ bbedit: codeMirrorThemes.bbedit,
125
+ bespin: codeMirrorThemes.bespin,
126
+ "console-dark": codeMirrorThemes.consoleDark,
127
+ "console-light": codeMirrorThemes.consoleLight,
128
+ copilot: codeMirrorThemes.copilot,
129
+ darcula: codeMirrorThemes.darcula,
130
+ dracula: codeMirrorThemes.dracula,
131
+ "duotone-dark": codeMirrorThemes.duotoneDark,
132
+ "duotone-light": codeMirrorThemes.duotoneLight,
133
+ eclipse: codeMirrorThemes.eclipse,
134
+ "github-dark": codeMirrorThemes.githubDark,
135
+ "github-light": codeMirrorThemes.githubLight,
136
+ "gruvbox-dark": codeMirrorThemes.gruvboxDark,
137
+ "gruvbox-light": codeMirrorThemes.gruvboxLight,
138
+ kimbie: codeMirrorThemes.kimbie,
139
+ material: codeMirrorThemes.material,
140
+ "material-dark": codeMirrorThemes.materialDark,
141
+ "material-light": codeMirrorThemes.materialLight,
142
+ monokai: codeMirrorThemes.monokai,
143
+ "monokai-dimmed": codeMirrorThemes.monokaiDimmed,
144
+ "noctis-lilac": codeMirrorThemes.noctisLilac,
145
+ nord: codeMirrorThemes.nord,
146
+ okaidia: codeMirrorThemes.okaidia,
147
+ quietlight: codeMirrorThemes.quietlight,
148
+ red: codeMirrorThemes.red,
149
+ "solarized-dark": codeMirrorThemes.solarizedDark,
150
+ "solarized-light": codeMirrorThemes.solarizedLight,
151
+ sublime: codeMirrorThemes.sublime,
152
+ "tokyo-night": codeMirrorThemes.tokyoNight,
153
+ "tokyo-night-day": codeMirrorThemes.tokyoNightDay,
154
+ "tokyo-night-storm": codeMirrorThemes.tokyoNightStorm,
155
+ "tomorrow-night-blue": codeMirrorThemes.tomorrowNightBlue,
156
+ "vscode-dark": codeMirrorThemes.vscodeDark,
157
+ "vscode-light": codeMirrorThemes.vscodeLight,
158
+ white: codeMirrorThemes.whiteLight,
159
+ "white-dark": codeMirrorThemes.whiteDark,
160
+ "white-light": codeMirrorThemes.whiteLight,
161
+ "xcode-dark": codeMirrorThemes.xcodeDark,
162
+ "xcode-light": codeMirrorThemes.xcodeLight,
163
+ };
164
+
165
+ const BUILTIN_THEME_DEFAULTS: Record<BuiltinThemeName, ThemeDefaults> = {
166
+ abcdef: codeMirrorThemes.defaultSettingsAbcdef,
167
+ abyss: codeMirrorThemes.defaultSettingsAbyss,
168
+ androidstudio: codeMirrorThemes.defaultSettingsAndroidstudio,
169
+ andromeda: codeMirrorThemes.defaultSettingsAndromeda,
170
+ atomone: codeMirrorThemes.defaultSettingsAtomone,
171
+ aura: codeMirrorThemes.defaultSettingsAura,
172
+ "basic-dark": codeMirrorThemes.defaultSettingsBasicDark,
173
+ "basic-light": codeMirrorThemes.defaultSettingsBasicLight,
174
+ bbedit: codeMirrorThemes.defaultSettingsBbedit,
175
+ bespin: codeMirrorThemes.defaultSettingsBespin,
176
+ "console-dark": codeMirrorThemes.defaultSettingsConsoleDark,
177
+ "console-light": codeMirrorThemes.defaultSettingsConsoleLight,
178
+ copilot: codeMirrorThemes.defaultSettingsCopilot,
179
+ darcula: codeMirrorThemes.defaultSettingsDarcula,
180
+ dracula: codeMirrorThemes.defaultSettingsDracula,
181
+ "duotone-dark": codeMirrorThemes.defaultSettingsDuotoneDark,
182
+ "duotone-light": codeMirrorThemes.defaultSettingsDuotoneLight,
183
+ eclipse: codeMirrorThemes.defaultSettingsEclipse,
184
+ "github-dark": codeMirrorThemes.defaultSettingsGithubDark,
185
+ "github-light": codeMirrorThemes.defaultSettingsGithubLight,
186
+ "gruvbox-dark": codeMirrorThemes.defaultSettingsGruvboxDark,
187
+ "gruvbox-light": codeMirrorThemes.defaultSettingsGruvboxLight,
188
+ kimbie: codeMirrorThemes.defaultSettingsKimbie,
189
+ material: codeMirrorThemes.defaultSettingsMaterial,
190
+ "material-dark": codeMirrorThemes.defaultSettingsMaterialDark,
191
+ "material-light": codeMirrorThemes.defaultSettingsMaterialLight,
192
+ monokai: codeMirrorThemes.defaultSettingsMonokai,
193
+ "monokai-dimmed": codeMirrorThemes.defaultSettingsMonokaiDimmed,
194
+ "noctis-lilac": codeMirrorThemes.defaultSettingsNoctisLilac,
195
+ nord: codeMirrorThemes.defaultSettingsNord,
196
+ okaidia: codeMirrorThemes.defaultSettingsOkaidia,
197
+ quietlight: codeMirrorThemes.defaultSettingsQuietlight,
198
+ red: codeMirrorThemes.defaultSettingsRed,
199
+ "solarized-dark": codeMirrorThemes.defaultSettingsSolarizedDark,
200
+ "solarized-light": codeMirrorThemes.defaultSettingsSolarizedLight,
201
+ sublime: codeMirrorThemes.defaultSettingsSublime,
202
+ "tokyo-night": codeMirrorThemes.defaultSettingsTokyoNight,
203
+ "tokyo-night-day": codeMirrorThemes.defaultSettingsTokyoNightDay,
204
+ "tokyo-night-storm": codeMirrorThemes.defaultSettingsTokyoNightStorm,
205
+ "tomorrow-night-blue": codeMirrorThemes.defaultSettingsTomorrowNightBlue,
206
+ "vscode-dark": codeMirrorThemes.defaultSettingsVscodeDark,
207
+ "vscode-light": codeMirrorThemes.defaultSettingsVscodeLight,
208
+ white: codeMirrorThemes.defaultSettingsWhiteLight,
209
+ "white-dark": codeMirrorThemes.defaultSettingsWhiteDark,
210
+ "white-light": codeMirrorThemes.defaultSettingsWhiteLight,
211
+ "xcode-dark": codeMirrorThemes.defaultSettingsXcodeDark,
212
+ "xcode-light": codeMirrorThemes.defaultSettingsXcodeLight,
213
+ };
214
+
215
+ function pickColor(
216
+ ...candidates: Array<string | undefined>
217
+ ): string | undefined {
218
+ for (const candidate of candidates) {
219
+ if (candidate && candidate !== "transparent") {
220
+ return candidate;
221
+ }
222
+ }
223
+ return undefined;
224
+ }
225
+
226
+ function themeFromDefaults(
227
+ defaults: ThemeDefaults,
228
+ themeExtension: Extension,
229
+ ): CustomTheme {
230
+ const background = pickColor(defaults.background, defaults.gutterBackground);
231
+ const foreground = pickColor(
232
+ defaults.caret,
233
+ defaults.foreground,
234
+ defaults.gutterForeground,
235
+ );
236
+ const selection = pickColor(
237
+ defaults.selection,
238
+ defaults.selectionMatch,
239
+ defaults.lineHighlight,
240
+ );
241
+ return {
242
+ backgroundColor: background ?? "#1a1b26",
243
+ lighterBgColor:
244
+ pickColor(
245
+ defaults.gutterBackground,
246
+ defaults.lineHighlight,
247
+ background,
248
+ ) ?? "#1f2335",
249
+ borderColor:
250
+ pickColor(
251
+ defaults.gutterBorder,
252
+ defaults.selectionMatch,
253
+ defaults.selection,
254
+ defaults.foreground,
255
+ ) ?? "#414868",
256
+ foregroundColor: foreground ?? "#c0caf5",
257
+ accentColor: pickColor(defaults.foreground, defaults.caret) ?? "#7aa2f7",
258
+ errorColor: pickColor(defaults.caret, defaults.foreground) ?? "#f7768e",
259
+ selectionColor: selection ?? "#515c7e40",
260
+ themeExtension,
261
+ };
262
+ }
263
+
264
+ function resolveBuiltinTheme(themeName: BuiltinThemeName): CustomTheme {
265
+ const themeExtension = BUILTIN_THEME_EXTENSIONS[themeName];
266
+ if (themeName === "white") {
267
+ return {
268
+ ...WHITE_THEME_COLORS,
269
+ themeExtension,
270
+ };
271
+ }
272
+ if (themeName === "tokyo-night") {
273
+ return {
274
+ ...TOKYO_NIGHT_THEME_COLORS,
275
+ themeExtension,
276
+ };
277
+ }
278
+ if (themeName === "tokyo-night-day") {
279
+ return {
280
+ ...TOKYO_NIGHT_DAY_THEME_COLORS,
281
+ themeExtension,
282
+ };
283
+ }
284
+ return themeFromDefaults(BUILTIN_THEME_DEFAULTS[themeName], themeExtension);
285
+ }
286
+
24
287
  export function createEditorState({
25
288
  schema,
26
289
  readOnly,
27
290
  json,
28
291
  theme,
292
+ otherExtension,
29
293
  }: CreateEditorStateParams): EditorState {
30
294
  const idToRecordDef: { [id: string]: RecordDefinition } = {};
31
295
  for (const record of schema.records) {
@@ -33,34 +297,10 @@ export function createEditorState({
33
297
  }
34
298
  const content = json ?? makeJsonTemplate(schema.type, idToRecordDef);
35
299
 
36
- switch (theme) {
37
- case undefined:
38
- case "tokyo-night": {
39
- theme = {
40
- backgroundColor: "#1a1b26",
41
- lighterBgColor: "#1f2335",
42
- borderColor: "#414868",
43
- foregroundColor: "#c0caf5",
44
- accentColor: "#7aa2f7",
45
- errorColor: "#f7768e",
46
- selectionColor: "#515c7e40",
47
- themeExtension: tokyoNight,
48
- };
49
- break;
50
- }
51
- case "tokyo-night-day": {
52
- theme = {
53
- backgroundColor: "#d5d6db",
54
- lighterBgColor: "#e1e2e7",
55
- borderColor: "#adb0bb",
56
- foregroundColor: "#3760bf",
57
- accentColor: "#2e7de9",
58
- errorColor: "#f52a65",
59
- selectionColor: "#3760bf33",
60
- themeExtension: tokyoNightDay,
61
- };
62
- break;
63
- }
300
+ if (theme === undefined) {
301
+ theme = resolveBuiltinTheme("tokyo-night");
302
+ } else if (typeof theme === "string") {
303
+ theme = resolveBuiltinTheme(theme);
64
304
  }
65
305
 
66
306
  return EditorState.create({
@@ -262,6 +502,7 @@ export function createEditorState({
262
502
  borderTop: "1px solid",
263
503
  },
264
504
  }),
505
+ otherExtension ?? [],
265
506
  ],
266
507
  });
267
508
  }
@@ -1,7 +1,8 @@
1
1
  import { Diagnostic } from "@codemirror/lint";
2
2
  import { EditorView } from "@codemirror/view";
3
+ import { makeJsonTemplate } from "../json/to_json";
3
4
  import { Hint, JsonError, JsonLiteral, TypeHint } from "../json/types";
4
- import { ensureJsonState, jsonStateField } from "./json_state";
5
+ import { jsonStateField } from "./json_state";
5
6
 
6
7
  export function jsonLinter(
7
8
  editable: "editable" | "read-only",
@@ -221,8 +222,6 @@ function getTimestampControlRows(
221
222
  insert: newJsonString,
222
223
  },
223
224
  });
224
-
225
- ensureJsonState(view, (view as any).schema);
226
225
  };
227
226
 
228
227
  // Enter key handler for unix_millis input
@@ -300,6 +299,84 @@ function getTimestampControlRows(
300
299
  return [headerRow, controlsRow];
301
300
  }
302
301
 
302
+ function getEnumDropdown(
303
+ view: EditorView,
304
+ typeHint: TypeHint,
305
+ enumDefinition: NonNullable<TypeHint["enumDefinition"]>,
306
+ ): HTMLDivElement {
307
+ const controlsRow = document.createElement("div");
308
+ controlsRow.className = "cm-diagnostic-controls";
309
+
310
+ const label = document.createElement("span");
311
+ label.className = "cm-diagnostic-label";
312
+ label.textContent = "Variant:";
313
+
314
+ const select = document.createElement("select");
315
+ select.className = "cm-diagnostic-input";
316
+
317
+ {
318
+ // Add the UNKNOWN variant
319
+ const option = document.createElement("option");
320
+ option.value = "UNKNOWN";
321
+ option.textContent = "UNKNOWN";
322
+ select.appendChild(option);
323
+ }
324
+ for (const variant of enumDefinition.variants) {
325
+ const option = document.createElement("option");
326
+ option.value = variant.name;
327
+ option.textContent = variant.name;
328
+ select.appendChild(option);
329
+ }
330
+
331
+ const currentValue = typeHint.valueContext?.value;
332
+ if (
333
+ currentValue &&
334
+ currentValue.kind === "literal" &&
335
+ currentValue.type === "string"
336
+ ) {
337
+ try {
338
+ select.value = JSON.parse(currentValue.jsonCode) as string;
339
+ } catch {
340
+ // Ignore invalid value and keep the default selection.
341
+ }
342
+ }
343
+
344
+ select.addEventListener("change", () => {
345
+ const variant = enumDefinition.variants.find(
346
+ (variant) => variant.name === select.value,
347
+ )!;
348
+ let newJsonString: string;
349
+ if (variant.type) {
350
+ const jsonState = view.state.field(jsonStateField, false)!;
351
+ const valueJson = makeJsonTemplate(
352
+ variant.type,
353
+ jsonState.recordIdToDefinition,
354
+ );
355
+ newJsonString = JSON.stringify(
356
+ {
357
+ kind: variant.name,
358
+ value: valueJson,
359
+ },
360
+ null,
361
+ 2,
362
+ ).replaceAll("\n", "\n" + " ".repeat(typeHint.valueContext.value.indent));
363
+ } else {
364
+ newJsonString = JSON.stringify(variant.name);
365
+ }
366
+ view.dispatch({
367
+ changes: {
368
+ from: typeHint.segment.start,
369
+ to: typeHint.segment.end,
370
+ insert: newJsonString,
371
+ },
372
+ });
373
+ });
374
+
375
+ controlsRow.appendChild(label);
376
+ controlsRow.appendChild(select);
377
+ return controlsRow;
378
+ }
379
+
303
380
  function hintToDiagnostic(
304
381
  typeHint: Hint,
305
382
  editable: "editable" | "read-only",
@@ -337,13 +414,21 @@ function hintToDiagnostic(
337
414
  // Render a timestamp editing control for timestamp hints.
338
415
  rows = getTimestampControlRows(view, typeHint);
339
416
  } else {
340
- // Display the message for non-string types
417
+ // Display the message.
341
418
  const pieces = typeof message === "string" ? [message] : message;
342
419
  rows = pieces.map((piece) => {
343
420
  const row = document.createElement("div");
344
421
  row.textContent = piece;
345
422
  return row;
346
423
  });
424
+ if (
425
+ typeHint.valueContext &&
426
+ typeHint.enumDefinition &&
427
+ editable === "editable"
428
+ ) {
429
+ // Render a dropdown for selecting a different variant.
430
+ rows.push(getEnumDropdown(view, typeHint, typeHint.enumDefinition));
431
+ }
347
432
  }
348
433
 
349
434
  for (const row of rows) {