skir-codemirror-plugin 1.0.3 → 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.
@@ -168,7 +168,8 @@ class SchemaValidator {
168
168
  // Enum
169
169
  const nameToVariantDef = {};
170
170
  recordDef.variants.forEach((variant) => {
171
- nameToVariantDef[variant.name] = variant;
171
+ nameToVariantDef[variant.name.toLowerCase()] = variant;
172
+ nameToVariantDef[variant.name.toUpperCase()] = variant;
172
173
  });
173
174
  if (value.kind === "object") {
174
175
  pushTypeHint();
@@ -185,7 +186,7 @@ class SchemaValidator {
185
186
  message: "Expected: uppercase variant name",
186
187
  });
187
188
  }
188
- else if (name === "UNKNOWN" || fieldDef) {
189
+ else if (name === "unknown" || name === "UNKNOWN" || fieldDef) {
189
190
  pushTypeHint({ enumDefinition: recordDef });
190
191
  typeHintStack.pop();
191
192
  }
@@ -232,11 +233,13 @@ class SchemaValidator {
232
233
  return;
233
234
  }
234
235
  const kind = JSON.parse(kindKv.value.jsonCode);
235
- if (kind !== kind.toLowerCase()) {
236
+ const isLowercase = kind === kind.toLowerCase();
237
+ const isUppercase = kind === kind.toUpperCase();
238
+ if (!isLowercase && !isUppercase) {
236
239
  this.errors.push({
237
240
  kind: "error",
238
241
  segment: kindKv.value.segment,
239
- message: "Expected: lowercase variant name",
242
+ message: "Expected: lowercase or uppercase variant name",
240
243
  });
241
244
  return;
242
245
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schema_validator.js","sourceRoot":"","sources":["../../src/json/schema_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAmBnC,MAAM,UAAU,cAAc,CAC5B,KAAgB,EAChB,MAAsB;IAEtB,MAAM,aAAa,GAAuC,EAAE,CAAC;IAC7D,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;IACpC,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,IAAI,GAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAC9B,IAAI,YAAY,EAAE,CAAC;YACjB,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,cAAc,EAAE,cAAc;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,eAAe;IACnB,YAAqB,aAAiD;QAAjD,kBAAa,GAAb,aAAa,CAAoC;QAC7D,WAAM,GAAgB,EAAE,CAAC;QACzB,UAAK,GAAW,EAAE,CAAC;QACX,kBAAa,GAAsB,EAAE,CAAC;IAHkB,CAAC;IAM1E,QAAQ,CACN,KAAgB,EAChB,IAAU,EACV,MAAqB,EACrB,cAA8B;QAE9B,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;QAC9C,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;QAC5B,kFAAkF;QAClF,MAAM,YAAY,GAAG,CAAC,OAErB,EAAQ,EAAE;YACT,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC3B,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;gBAChC,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YACD,MAAM,IAAI,GAAoB;gBAC5B,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;gBACpD,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC7B,UAAU,EAAE,EAAE;gBACd,cAAc,EAAE,OAAO,EAAE,cAAc;aACxC,CAAC;YACF,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;gBACzB,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC3D,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC;QACF,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,YAAY,EAAE,CAAC;oBACf,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;wBACnD,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,GACrD,MAAM,CAAC,KAAK,CAAC;wBACf,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;wBACnD,MAAM,QAAQ,GAAS;4BACrB,IAAI,EAAE,YAAY;4BAClB,KAAK,EAAE,KAAK;4BACZ,GAAG,EAAE,OAAO;4BACZ,SAAS,EAAE,IAAI;yBAChB,CAAC;wBACF,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;oBAC5C,CAAC;oBACD,aAAa,CAAC,GAAG,EAAE,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,OAAO,EAAE,iBAAiB;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;oBAC1D,YAAY,EAAE,CAAC;oBACf,aAAa,CAAC,GAAG,EAAE,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACnD,CAAC;gBACD,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;gBACnC,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;oBAClC,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;wBAClC,YAAY,EAAE,CAAC;wBACf,aAAa,CAAC,GAAG,EAAE,CAAC;oBACtB,CAAC;gBACH,CAAC;qBAAM,IAAI,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,CAAC;oBAClD,YAAY,EAAE,CAAC;oBACf,aAAa,CAAC,GAAG,EAAE,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,OAAO;wBACb,OAAO,EAAE,KAAK,CAAC,UAAU;wBACzB,OAAO,EAAE,aAAa,aAAa,EAAE;qBACtC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC9C,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAChC,MAAM,cAAc,GAAwC,EAAE,CAAC;oBAC/D,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;wBACjC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;oBACrC,CAAC,CAAC,CAAC;oBACH,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC5B,YAAY,EAAE,CAAC;wBACf,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;4BACtD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;4BAChC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;4BACrC,IAAI,QAAQ,EAAE,CAAC;gCACb,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;oCACjB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;wCACd,OAAO,EAAE,QAAQ,CAAC,UAAU;wCAC5B,OAAO,EAAE,QAAQ,CAAC,GAAG;qCACtB,CAAC,CAAC;gCACL,CAAC;gCACD,MAAM,SAAS,GAAS;oCACtB,IAAI,EAAE,aAAa;oCACnB,SAAS,EAAE,GAAG;oCACd,UAAU,EAAE,IAAI;iCACjB,CAAC;gCACF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,IAAK,CAAC,CAAC;4BAClD,CAAC;iCAAM,CAAC;gCACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oCACf,IAAI,EAAE,OAAO;oCACb,OAAO,EAAE,QAAQ,CAAC,UAAU;oCAC5B,OAAO,EAAE,eAAe;iCACzB,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;wBACD,aAAa,CAAC,GAAG,EAAE,CAAC;oBACtB,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;4BACf,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,KAAK,CAAC,UAAU;4BACzB,OAAO,EAAE,kBAAkB;yBAC5B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO;oBACP,MAAM,gBAAgB,GAA0C,EAAE,CAAC;oBACnE,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;wBACrC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;oBAC3C,CAAC,CAAC,CAAC;oBACH,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC5B,YAAY,EAAE,CAAC;wBACf,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;wBACvD,aAAa,CAAC,GAAG,EAAE,CAAC;oBACtB,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;wBACxC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;wBACxC,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;4BAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gCACf,IAAI,EAAE,OAAO;gCACb,OAAO,EAAE,KAAK,CAAC,OAAO;gCACtB,OAAO,EAAE,kCAAkC;6BAC5C,CAAC,CAAC;wBACL,CAAC;6BAAM,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC;4BAC1C,YAAY,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC;4BAC5C,aAAa,CAAC,GAAG,EAAE,CAAC;wBACtB,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gCACf,IAAI,EAAE,OAAO;gCACb,OAAO,EAAE,KAAK,CAAC,OAAO;gCACtB,OAAO,EAAE,iBAAiB;6BAC3B,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;4BACf,IAAI,EAAE,OAAO;4BACb,OAAO,EAAE,KAAK,CAAC,UAAU;4BACzB,OAAO,EAAE,4BAA4B;yBACtC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBACD,MAAM;YACR,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,CAAC,GAAU,MAAM,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB,CAChB,MAAkB,EAClB,QAAc,EACd,gBAAuD;QAEvD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,iBAAiB;aAC3B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;gBAChC,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAW,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;gBAC7B,OAAO,EAAE,kCAAkC;aAC5C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;gBAC7B,OAAO,EAAE,iBAAiB;aAC3B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,GAAG,CAAC,UAAU;oBACvB,OAAO,EAAE,kBAAkB;iBAC5B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAS;YACjB,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,UAAU,CAAC,IAAI;YAC5B,QAAQ,EAAE,QAAQ;SACnB,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,IAAK,CAAC,CAAC;IACvD,CAAC;IAEO,iBAAiB,CAAC,KAAgB;QACxC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,OAAO,EAAE,qBAAqB;aAC/B,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,OAAO,EAAE,wBAAwB;aAClC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YACrC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EACpC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU;gBACtC,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAW,CAAC;QACxD,IAAI,UAAU,GAAG,CAAC,gBAAgB,IAAI,gBAAgB,GAAG,UAAU,EAAE,CAAC;YACpE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU;gBACtC,OAAO,EAAE,wBAAwB;aAClC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,qDAAqD;QACrD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IACE,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YAClC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EACjC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,UAAU;gBACnC,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAW,CAAC;QACvD,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,UAAU;gBACnC,OAAO,EAAE,8BAA8B;aACxC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,UAAU;gBACnC,OAAO,EAAE,8BAA8B;aACxC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,IAAI,GAAG,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;gBACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,GAAG,CAAC,UAAU;oBACvB,OAAO,EAAE,kBAAkB;iBAC5B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,SAAS,cAAc,CACrB,IAAe,EACf,YAAgC;IAEhC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,QAAQ;YACR,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,QAAQ;YACR,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;IACnB,CAAC;IACD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,SAAS;oBACZ,OAAO,KAAK,CAAC,QAAQ,CAAC;YAC1B,CAAC;YACD,QAAQ;YACR,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC1C,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,QAAQ;gBACR,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,QAAQ;YACR,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAgB,EAChB,YAA2B;IAE3B,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;QAC9D,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;QACvE,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,SAAS,CAAC,KAAK,EAAE,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC7D,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC;gBACH,mBAAmB,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC1D,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,wCAAwC;YACxC,MAAM,IAAI,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB,EAAE,GAAW,EAAE,GAAW;IAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAkB,CAAC;IACvB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnC,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC;AAClC,CAAC;AAED,SAAS,OAAO,CAAC,KAAgB;IAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IACL,KAAK,CAAC,IAAI,KAAK,QAAQ;QACvB,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO;YACzB,KAAK,CAAC,QAAQ,KAAK,YAAY;YAC/B,KAAK,CAAC,QAAQ,KAAK,aAAa,CAAC,EACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAmB;IACtC,SAAS,WAAW,CAAC,IAAmB;QACtC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,KAAK,CAAC;YACpB,KAAK,OAAO;gBACV,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YAC7C,KAAK,UAAU;gBACb,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YACvC,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC5B,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IACD,SAAS,aAAa,CAAC,IAAmB;QACxC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC;YACd,KAAK,OAAO;gBACV,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,KAAK,UAAU;gBACb,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC5B,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/D,CAAC;AAED,SAAS,UAAU,CACjB,IAAmB,EACnB,aAA2D;IAE3D,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,WAAW;YACd,OAAO,SAAS,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACpD,KAAK,UAAU;YACb,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QAC/C,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;YAC5B,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAE,CAAC;YAC3C,OAAO,SAAS,CAAC,GAAG,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { primitiveSerializer } from \"skir-client\";\nimport { toJson } from \"./to_json\";\nimport type {\n EnumDefinition,\n FieldDefinition,\n Hint,\n JsonError,\n JsonObject,\n JsonValue,\n MutableTypeHint,\n Path,\n PrimitiveType,\n RecordDefinition,\n TypeDefinition,\n TypeHint,\n TypeSignature,\n ValidationResult,\n VariantDefinition,\n} from \"./types\";\n\nexport function validateSchema(\n value: JsonValue,\n schema: TypeDefinition,\n): ValidationResult {\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n\n const validator = new SchemaValidator(idToRecordDef);\n const root: Path = { kind: \"root\" };\n validator.validate(value, root, schema.type);\n const pathToTypeHint = new Map<Path, TypeHint>();\n for (const hint of validator.hints) {\n const { valueContext } = hint;\n if (valueContext) {\n pathToTypeHint.set(valueContext.path, hint);\n }\n }\n return {\n errors: validator.errors,\n hints: validator.hints,\n rootTypeHint: validator.rootTypeHint,\n pathToTypeHint: pathToTypeHint,\n };\n}\n\nclass SchemaValidator {\n constructor(readonly idToRecordDef: { [id: string]: RecordDefinition }) {}\n readonly errors: JsonError[] = [];\n readonly hints: Hint[] = [];\n private readonly typeHintStack: MutableTypeHint[] = [];\n rootTypeHint: TypeHint | undefined;\n\n validate(\n value: JsonValue,\n path: Path,\n schema: TypeSignature,\n optionalSchema?: TypeSignature,\n ): void {\n const { idToRecordDef, typeHintStack } = this;\n value.expectedType = schema;\n // For every call to pushTypeHint() there emust be one call to typeHintStack.pop()\n const pushTypeHint = (options?: {\n enumDefinition?: EnumDefinition;\n }): void => {\n const typeDesc = getTypeDesc(optionalSchema ?? schema);\n const typeDoc = getTypeDoc(schema, idToRecordDef);\n const message = [typeDesc];\n if (typeDoc) {\n message.push(typeDoc);\n }\n if (value.kind === \"array\") {\n const { length } = value.values;\n if (length) {\n message.push(`Length: ${length}`);\n }\n }\n const hint: MutableTypeHint = {\n segment: value.firstToken,\n message: message.length === 1 ? message[0] : message,\n valueContext: { value, path },\n childHints: [],\n enumDefinition: options?.enumDefinition,\n };\n if (typeHintStack.length) {\n const topOfStack = typeHintStack[typeHintStack.length - 1];\n topOfStack.childHints.push(hint);\n } else {\n this.rootTypeHint = hint;\n }\n this.hints.push(hint);\n typeHintStack.push(hint);\n };\n switch (schema.kind) {\n case \"array\": {\n if (value.kind === \"array\") {\n pushTypeHint();\n for (const [index, item] of value.values.entries()) {\n const { key_extractor: keyExtractor, item: itemSchema } =\n schema.value;\n const itemKey = extractItemKey(item, keyExtractor);\n const itemPath: Path = {\n kind: \"array-item\",\n index: index,\n key: itemKey,\n arrayPath: path,\n };\n this.validate(item, itemPath, itemSchema);\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: array\",\n });\n }\n break;\n }\n case \"optional\": {\n if (value.kind === \"literal\" && value.jsonCode === \"null\") {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.validate(value, path, schema.value, schema);\n }\n break;\n }\n case \"primitive\": {\n const primitiveType = schema.value;\n if (primitiveType === \"timestamp\") {\n if (this.validateTimestamp(value)) {\n pushTypeHint();\n typeHintStack.pop();\n }\n } else if (hasPrimitiveType(value, primitiveType)) {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: `Expected: ${primitiveType}`,\n });\n }\n break;\n }\n case \"record\": {\n const recordDef = idToRecordDef[schema.value];\n if (recordDef.kind === \"struct\") {\n const nameToFieldDef: { [name: string]: FieldDefinition } = {};\n recordDef.fields.forEach((field) => {\n nameToFieldDef[field.name] = field;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n for (const keyValue of Object.values(value.keyValues)) {\n const { key, value } = keyValue;\n const fieldDef = nameToFieldDef[key];\n if (fieldDef) {\n if (fieldDef.doc) {\n this.hints.push({\n segment: keyValue.keySegment,\n message: fieldDef.doc,\n });\n }\n const valuePath: Path = {\n kind: \"field-value\",\n fieldName: key,\n structPath: path,\n };\n this.validate(value, valuePath, fieldDef.type!);\n } else {\n this.errors.push({\n kind: \"error\",\n segment: keyValue.keySegment,\n message: \"Unknown field\",\n });\n }\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object\",\n });\n }\n } else {\n // Enum\n const nameToVariantDef: { [name: string]: VariantDefinition } = {};\n recordDef.variants.forEach((variant) => {\n nameToVariantDef[variant.name] = variant;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n this.validateEnumObject(value, path, nameToVariantDef);\n typeHintStack.pop();\n } else if (value.kind === \"literal\" && value.type === \"string\") {\n const name = JSON.parse(value.jsonCode);\n const fieldDef = nameToVariantDef[name];\n if (fieldDef && fieldDef.type) {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: uppercase variant name\",\n });\n } else if (name === \"UNKNOWN\" || fieldDef) {\n pushTypeHint({ enumDefinition: recordDef });\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Unknown variant\",\n });\n }\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object or string\",\n });\n }\n }\n break;\n }\n default: {\n const _: never = schema;\n throw new Error(_);\n }\n }\n }\n\n validateEnumObject(\n object: JsonObject,\n enumPath: Path,\n nameToVariantDef: { [name: string]: VariantDefinition },\n ): void {\n const kindKv = object.keyValues[\"kind\"];\n if (!kindKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'kind'\",\n });\n return;\n }\n if (kindKv.value.kind !== \"literal\" || kindKv.value.type !== \"string\") {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.firstToken,\n message: \"Expected: string\",\n });\n return;\n }\n const kind: string = JSON.parse(kindKv.value.jsonCode);\n if (kind !== kind.toLowerCase()) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Expected: lowercase variant name\",\n });\n return;\n }\n const variantDef = nameToVariantDef[kind];\n if (!variantDef) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Unknown variant\",\n });\n return;\n }\n const valueKv = object.keyValues[\"value\"];\n if (!valueKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'value'\",\n });\n return;\n }\n for (const key of object.allKeys) {\n if (key.key !== \"kind\" && key.key !== \"value\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n const path: Path = {\n kind: \"variant-value\",\n variantName: variantDef.name,\n enumPath: enumPath,\n };\n this.validate(valueKv.value, path, variantDef.type!);\n }\n\n private validateTimestamp(value: JsonValue): boolean {\n if (value.kind !== \"object\") {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: timestamp\",\n });\n return false;\n }\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (!unixMillisKv) {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Missing: 'unix_millis'\",\n });\n return true;\n }\n if (\n unixMillisKv.value.kind !== \"literal\" ||\n unixMillisKv.value.type !== \"number\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Expected: number\",\n });\n return true;\n }\n const unixMillis = toJson(unixMillisKv.value) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Timestamp out of range\",\n });\n return true;\n }\n // At this point: the timestamp is technically valid.\n const formatted = value.keyValues[\"formatted\"];\n if (!formatted) {\n return true;\n }\n if (\n formatted.value.kind !== \"literal\" ||\n formatted.value.type !== \"string\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Expected: string\",\n });\n return true;\n }\n const formattedStr = toJson(formatted.value) as string;\n if (formattedStr === \"n/a\") {\n return true;\n }\n const parsedMillis = Date.parse(formattedStr);\n if (Number.isNaN(parsedMillis)) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Invalid ISO 8601 date string\",\n });\n return true;\n }\n if (parsedMillis !== unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Does not match 'unix_millis'\",\n });\n }\n for (const key of value.allKeys) {\n if (key.key !== \"unix_millis\" && key.key !== \"formatted\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n return true;\n }\n}\n\nfunction extractItemKey(\n item: JsonValue,\n keyExtractor: string | undefined,\n): string | null {\n if (keyExtractor === undefined) {\n return null;\n }\n const pieces = keyExtractor.split(\".\");\n let value = item;\n for (const piece of pieces) {\n if (value.kind !== \"object\") {\n // Error\n return null;\n }\n const kv = value.keyValues[piece];\n if (!kv) {\n // Error\n return null;\n }\n value = kv.value;\n }\n switch (value.kind) {\n case \"literal\": {\n switch (value.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return value.jsonCode;\n }\n // Error\n return null;\n }\n case \"object\": {\n const kv = value.keyValues[\"unix_millis\"];\n if (kv && kv.value.kind === \"literal\" && kv.value.type === \"number\") {\n return kv.value.jsonCode;\n } else {\n // Error\n return null;\n }\n }\n case \"array\": {\n // Error\n return null;\n }\n }\n}\n\nfunction hasPrimitiveType(\n value: JsonValue,\n expectedType: PrimitiveType,\n): boolean {\n switch (expectedType) {\n case \"bool\":\n return value.kind === \"literal\" && value.type === \"boolean\";\n case \"int32\": {\n return isInteger(value, -2147483648n, 2147483647n);\n }\n case \"int64\": {\n return isInteger(value, -9223372036854775808n, 9223372036854775807n);\n }\n case \"hash64\": {\n return isInteger(value, 0n, 18446744073709551615n);\n }\n case \"float32\":\n case \"float64\": {\n return isFloat(value);\n }\n case \"string\": {\n return value.kind === \"literal\" && value.type === \"string\";\n }\n case \"bytes\": {\n if (value.kind !== \"literal\") {\n return false;\n }\n try {\n primitiveSerializer(\"bytes\").fromJsonCode(value.jsonCode);\n return true;\n } catch {\n return false;\n }\n }\n case \"timestamp\": {\n // Case handled separately in validate()\n throw new Error();\n }\n }\n}\n\nfunction isInteger(value: JsonValue, min: bigint, max: bigint): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n let decimalRep: string;\n if (value.type === \"string\") {\n decimalRep = JSON.parse(value.jsonCode);\n } else if (value.type === \"number\") {\n decimalRep = value.jsonCode;\n } else {\n return false;\n }\n let int: bigint;\n try {\n int = BigInt(decimalRep);\n } catch {\n return false;\n }\n return min <= int && int <= max;\n}\n\nfunction isFloat(value: JsonValue): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n if (value.type === \"number\") {\n return true;\n } else if (\n value.type === \"string\" &&\n (value.jsonCode === '\"NaN\"' ||\n value.jsonCode === '\"Infinity\"' ||\n value.jsonCode === '\"-Infinity\"')\n ) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction getTypeDesc(type: TypeSignature): string {\n function getTypePart(type: TypeSignature): string {\n switch (type.kind) {\n case \"primitive\":\n return type.value;\n case \"array\":\n return `[${getTypePart(type.value.item)}]`;\n case \"optional\":\n return `${getTypePart(type.value)}?`;\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[1];\n }\n }\n }\n function getModulePart(type: TypeSignature): string | null {\n switch (type.kind) {\n case \"primitive\":\n return null;\n case \"array\":\n return getModulePart(type.value.item);\n case \"optional\":\n return getModulePart(type.value);\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[0];\n }\n }\n }\n const typePart = getTypePart(type);\n const modulePart = getModulePart(type);\n return modulePart ? `${typePart} (${modulePart})` : typePart;\n}\n\nfunction getTypeDoc(\n type: TypeSignature,\n idToRecordDef: Readonly<{ [id: string]: RecordDefinition }>,\n): string | undefined {\n switch (type.kind) {\n case \"primitive\":\n return undefined;\n case \"array\":\n return getTypeDoc(type.value.item, idToRecordDef);\n case \"optional\":\n return getTypeDoc(type.value, idToRecordDef);\n case \"record\": {\n const recordId = type.value;\n const recordDef = idToRecordDef[recordId]!;\n return recordDef.doc;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"schema_validator.js","sourceRoot":"","sources":["../../src/json/schema_validator.ts"],"names":[],"mappings":"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","sourcesContent":["import { primitiveSerializer } from \"skir-client\";\nimport { toJson } from \"./to_json\";\nimport type {\n EnumDefinition,\n FieldDefinition,\n Hint,\n JsonError,\n JsonObject,\n JsonValue,\n MutableTypeHint,\n Path,\n PrimitiveType,\n RecordDefinition,\n TypeDefinition,\n TypeHint,\n TypeSignature,\n ValidationResult,\n VariantDefinition,\n} from \"./types\";\n\nexport function validateSchema(\n value: JsonValue,\n schema: TypeDefinition,\n): ValidationResult {\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n\n const validator = new SchemaValidator(idToRecordDef);\n const root: Path = { kind: \"root\" };\n validator.validate(value, root, schema.type);\n const pathToTypeHint = new Map<Path, TypeHint>();\n for (const hint of validator.hints) {\n const { valueContext } = hint;\n if (valueContext) {\n pathToTypeHint.set(valueContext.path, hint);\n }\n }\n return {\n errors: validator.errors,\n hints: validator.hints,\n rootTypeHint: validator.rootTypeHint,\n pathToTypeHint: pathToTypeHint,\n };\n}\n\nclass SchemaValidator {\n constructor(readonly idToRecordDef: { [id: string]: RecordDefinition }) {}\n readonly errors: JsonError[] = [];\n readonly hints: Hint[] = [];\n private readonly typeHintStack: MutableTypeHint[] = [];\n rootTypeHint: TypeHint | undefined;\n\n validate(\n value: JsonValue,\n path: Path,\n schema: TypeSignature,\n optionalSchema?: TypeSignature,\n ): void {\n const { idToRecordDef, typeHintStack } = this;\n value.expectedType = schema;\n // For every call to pushTypeHint() there emust be one call to typeHintStack.pop()\n const pushTypeHint = (options?: {\n enumDefinition?: EnumDefinition;\n }): void => {\n const typeDesc = getTypeDesc(optionalSchema ?? schema);\n const typeDoc = getTypeDoc(schema, idToRecordDef);\n const message = [typeDesc];\n if (typeDoc) {\n message.push(typeDoc);\n }\n if (value.kind === \"array\") {\n const { length } = value.values;\n if (length) {\n message.push(`Length: ${length}`);\n }\n }\n const hint: MutableTypeHint = {\n segment: value.firstToken,\n message: message.length === 1 ? message[0] : message,\n valueContext: { value, path },\n childHints: [],\n enumDefinition: options?.enumDefinition,\n };\n if (typeHintStack.length) {\n const topOfStack = typeHintStack[typeHintStack.length - 1];\n topOfStack.childHints.push(hint);\n } else {\n this.rootTypeHint = hint;\n }\n this.hints.push(hint);\n typeHintStack.push(hint);\n };\n switch (schema.kind) {\n case \"array\": {\n if (value.kind === \"array\") {\n pushTypeHint();\n for (const [index, item] of value.values.entries()) {\n const { key_extractor: keyExtractor, item: itemSchema } =\n schema.value;\n const itemKey = extractItemKey(item, keyExtractor);\n const itemPath: Path = {\n kind: \"array-item\",\n index: index,\n key: itemKey,\n arrayPath: path,\n };\n this.validate(item, itemPath, itemSchema);\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: array\",\n });\n }\n break;\n }\n case \"optional\": {\n if (value.kind === \"literal\" && value.jsonCode === \"null\") {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.validate(value, path, schema.value, schema);\n }\n break;\n }\n case \"primitive\": {\n const primitiveType = schema.value;\n if (primitiveType === \"timestamp\") {\n if (this.validateTimestamp(value)) {\n pushTypeHint();\n typeHintStack.pop();\n }\n } else if (hasPrimitiveType(value, primitiveType)) {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: `Expected: ${primitiveType}`,\n });\n }\n break;\n }\n case \"record\": {\n const recordDef = idToRecordDef[schema.value];\n if (recordDef.kind === \"struct\") {\n const nameToFieldDef: { [name: string]: FieldDefinition } = {};\n recordDef.fields.forEach((field) => {\n nameToFieldDef[field.name] = field;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n for (const keyValue of Object.values(value.keyValues)) {\n const { key, value } = keyValue;\n const fieldDef = nameToFieldDef[key];\n if (fieldDef) {\n if (fieldDef.doc) {\n this.hints.push({\n segment: keyValue.keySegment,\n message: fieldDef.doc,\n });\n }\n const valuePath: Path = {\n kind: \"field-value\",\n fieldName: key,\n structPath: path,\n };\n this.validate(value, valuePath, fieldDef.type!);\n } else {\n this.errors.push({\n kind: \"error\",\n segment: keyValue.keySegment,\n message: \"Unknown field\",\n });\n }\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object\",\n });\n }\n } else {\n // Enum\n const nameToVariantDef: { [name: string]: VariantDefinition } = {};\n recordDef.variants.forEach((variant) => {\n nameToVariantDef[variant.name.toLowerCase()] = variant;\n nameToVariantDef[variant.name.toUpperCase()] = variant;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n this.validateEnumObject(value, path, nameToVariantDef);\n typeHintStack.pop();\n } else if (value.kind === \"literal\" && value.type === \"string\") {\n const name = JSON.parse(value.jsonCode);\n const fieldDef = nameToVariantDef[name];\n if (fieldDef && fieldDef.type) {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: uppercase variant name\",\n });\n } else if (name === \"unknown\" || name === \"UNKNOWN\" || fieldDef) {\n pushTypeHint({ enumDefinition: recordDef });\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Unknown variant\",\n });\n }\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object or string\",\n });\n }\n }\n break;\n }\n default: {\n const _: never = schema;\n throw new Error(_);\n }\n }\n }\n\n validateEnumObject(\n object: JsonObject,\n enumPath: Path,\n nameToVariantDef: { [name: string]: VariantDefinition },\n ): void {\n const kindKv = object.keyValues[\"kind\"];\n if (!kindKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'kind'\",\n });\n return;\n }\n if (kindKv.value.kind !== \"literal\" || kindKv.value.type !== \"string\") {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.firstToken,\n message: \"Expected: string\",\n });\n return;\n }\n const kind: string = JSON.parse(kindKv.value.jsonCode);\n const isLowercase = kind === kind.toLowerCase();\n const isUppercase = kind === kind.toUpperCase();\n if (!isLowercase && !isUppercase) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Expected: lowercase or uppercase variant name\",\n });\n return;\n }\n const variantDef = nameToVariantDef[kind];\n if (!variantDef) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Unknown variant\",\n });\n return;\n }\n const valueKv = object.keyValues[\"value\"];\n if (!valueKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'value'\",\n });\n return;\n }\n for (const key of object.allKeys) {\n if (key.key !== \"kind\" && key.key !== \"value\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n const path: Path = {\n kind: \"variant-value\",\n variantName: variantDef.name,\n enumPath: enumPath,\n };\n this.validate(valueKv.value, path, variantDef.type!);\n }\n\n private validateTimestamp(value: JsonValue): boolean {\n if (value.kind !== \"object\") {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: timestamp\",\n });\n return false;\n }\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (!unixMillisKv) {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Missing: 'unix_millis'\",\n });\n return true;\n }\n if (\n unixMillisKv.value.kind !== \"literal\" ||\n unixMillisKv.value.type !== \"number\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Expected: number\",\n });\n return true;\n }\n const unixMillis = toJson(unixMillisKv.value) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Timestamp out of range\",\n });\n return true;\n }\n // At this point: the timestamp is technically valid.\n const formatted = value.keyValues[\"formatted\"];\n if (!formatted) {\n return true;\n }\n if (\n formatted.value.kind !== \"literal\" ||\n formatted.value.type !== \"string\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Expected: string\",\n });\n return true;\n }\n const formattedStr = toJson(formatted.value) as string;\n if (formattedStr === \"n/a\") {\n return true;\n }\n const parsedMillis = Date.parse(formattedStr);\n if (Number.isNaN(parsedMillis)) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Invalid ISO 8601 date string\",\n });\n return true;\n }\n if (parsedMillis !== unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Does not match 'unix_millis'\",\n });\n }\n for (const key of value.allKeys) {\n if (key.key !== \"unix_millis\" && key.key !== \"formatted\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n return true;\n }\n}\n\nfunction extractItemKey(\n item: JsonValue,\n keyExtractor: string | undefined,\n): string | null {\n if (keyExtractor === undefined) {\n return null;\n }\n const pieces = keyExtractor.split(\".\");\n let value = item;\n for (const piece of pieces) {\n if (value.kind !== \"object\") {\n // Error\n return null;\n }\n const kv = value.keyValues[piece];\n if (!kv) {\n // Error\n return null;\n }\n value = kv.value;\n }\n switch (value.kind) {\n case \"literal\": {\n switch (value.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return value.jsonCode;\n }\n // Error\n return null;\n }\n case \"object\": {\n const kv = value.keyValues[\"unix_millis\"];\n if (kv && kv.value.kind === \"literal\" && kv.value.type === \"number\") {\n return kv.value.jsonCode;\n } else {\n // Error\n return null;\n }\n }\n case \"array\": {\n // Error\n return null;\n }\n }\n}\n\nfunction hasPrimitiveType(\n value: JsonValue,\n expectedType: PrimitiveType,\n): boolean {\n switch (expectedType) {\n case \"bool\":\n return value.kind === \"literal\" && value.type === \"boolean\";\n case \"int32\": {\n return isInteger(value, -2147483648n, 2147483647n);\n }\n case \"int64\": {\n return isInteger(value, -9223372036854775808n, 9223372036854775807n);\n }\n case \"hash64\": {\n return isInteger(value, 0n, 18446744073709551615n);\n }\n case \"float32\":\n case \"float64\": {\n return isFloat(value);\n }\n case \"string\": {\n return value.kind === \"literal\" && value.type === \"string\";\n }\n case \"bytes\": {\n if (value.kind !== \"literal\") {\n return false;\n }\n try {\n primitiveSerializer(\"bytes\").fromJsonCode(value.jsonCode);\n return true;\n } catch {\n return false;\n }\n }\n case \"timestamp\": {\n // Case handled separately in validate()\n throw new Error();\n }\n }\n}\n\nfunction isInteger(value: JsonValue, min: bigint, max: bigint): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n let decimalRep: string;\n if (value.type === \"string\") {\n decimalRep = JSON.parse(value.jsonCode);\n } else if (value.type === \"number\") {\n decimalRep = value.jsonCode;\n } else {\n return false;\n }\n let int: bigint;\n try {\n int = BigInt(decimalRep);\n } catch {\n return false;\n }\n return min <= int && int <= max;\n}\n\nfunction isFloat(value: JsonValue): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n if (value.type === \"number\") {\n return true;\n } else if (\n value.type === \"string\" &&\n (value.jsonCode === '\"NaN\"' ||\n value.jsonCode === '\"Infinity\"' ||\n value.jsonCode === '\"-Infinity\"')\n ) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction getTypeDesc(type: TypeSignature): string {\n function getTypePart(type: TypeSignature): string {\n switch (type.kind) {\n case \"primitive\":\n return type.value;\n case \"array\":\n return `[${getTypePart(type.value.item)}]`;\n case \"optional\":\n return `${getTypePart(type.value)}?`;\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[1];\n }\n }\n }\n function getModulePart(type: TypeSignature): string | null {\n switch (type.kind) {\n case \"primitive\":\n return null;\n case \"array\":\n return getModulePart(type.value.item);\n case \"optional\":\n return getModulePart(type.value);\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[0];\n }\n }\n }\n const typePart = getTypePart(type);\n const modulePart = getModulePart(type);\n return modulePart ? `${typePart} (${modulePart})` : typePart;\n}\n\nfunction getTypeDoc(\n type: TypeSignature,\n idToRecordDef: Readonly<{ [id: string]: RecordDefinition }>,\n): string | undefined {\n switch (type.kind) {\n case \"primitive\":\n return undefined;\n case \"array\":\n return getTypeDoc(type.value.item, idToRecordDef);\n case \"optional\":\n return getTypeDoc(type.value, idToRecordDef);\n case \"record\": {\n const recordId = type.value;\n const recordDef = idToRecordDef[recordId]!;\n return recordDef.doc;\n }\n }\n}\n"]}
@@ -140,7 +140,7 @@ describe("schema_validator", () => {
140
140
  },
141
141
  ]);
142
142
  });
143
- it("validates enum (string literal)", () => {
143
+ it("validates enum (string literal accepts lower and upper)", () => {
144
144
  const schema = {
145
145
  type: { kind: "record", value: "MyEnum" },
146
146
  records: [
@@ -148,14 +148,84 @@ describe("schema_validator", () => {
148
148
  kind: "enum",
149
149
  id: "MyEnum",
150
150
  variants: [
151
- { name: "First", number: 1 },
152
- { name: "Second", number: 2 },
151
+ { name: "FOO", number: 1 },
152
+ { name: "BAR", number: 2 },
153
153
  ],
154
154
  },
155
155
  ],
156
156
  };
157
- const result = validateSchema(parse('"First"'), schema);
158
- expect(result).toMatch({ errors: [] });
157
+ const lowerResult = validateSchema(parse('"foo"'), schema);
158
+ expect(lowerResult).toMatch({ errors: [] });
159
+ const upperResult = validateSchema(parse('"FOO"'), schema);
160
+ expect(upperResult).toMatch({ errors: [] });
161
+ });
162
+ it("rejects mixed-case enum string literal", () => {
163
+ const schema = {
164
+ type: { kind: "record", value: "MyEnum" },
165
+ records: [
166
+ {
167
+ kind: "enum",
168
+ id: "MyEnum",
169
+ variants: [{ name: "FOO", number: 1 }],
170
+ },
171
+ ],
172
+ };
173
+ const result = validateSchema(parse('"Foo"'), schema);
174
+ expect(result.errors).toMatch([
175
+ {
176
+ message: "Unknown variant",
177
+ },
178
+ ]);
179
+ });
180
+ it("accepts UNKNOWN and unknown enum literals", () => {
181
+ const schema = {
182
+ type: { kind: "record", value: "MyEnum" },
183
+ records: [
184
+ {
185
+ kind: "enum",
186
+ id: "MyEnum",
187
+ variants: [{ name: "FOO", number: 1 }],
188
+ },
189
+ ],
190
+ };
191
+ expect(validateSchema(parse('"UNKNOWN"'), schema)).toMatch({ errors: [] });
192
+ expect(validateSchema(parse('"unknown"'), schema)).toMatch({ errors: [] });
193
+ const mixedCaseResult = validateSchema(parse('"Unknown"'), schema);
194
+ expect(mixedCaseResult.errors).toMatch([
195
+ {
196
+ message: "Unknown variant",
197
+ },
198
+ ]);
199
+ });
200
+ it("validates enum object kind in lower and upper", () => {
201
+ const schema = {
202
+ type: { kind: "record", value: "MyEnum" },
203
+ records: [
204
+ {
205
+ kind: "enum",
206
+ id: "MyEnum",
207
+ variants: [
208
+ {
209
+ name: "COMPLEX",
210
+ number: 1,
211
+ type: { kind: "primitive", value: "int32" },
212
+ },
213
+ ],
214
+ },
215
+ ],
216
+ };
217
+ expect(validateSchema(parse('{"kind": "complex", "value": 123}'), schema)).toMatch({
218
+ errors: [],
219
+ });
220
+ expect(validateSchema(parse('{"kind": "COMPLEX", "value": 123}'), schema)).toMatch({
221
+ errors: [],
222
+ });
223
+ const mixedCaseResult = validateSchema(parse('{"kind": "Complex", "value": 123}'), schema);
224
+ expect(mixedCaseResult.errors).toMatch([
225
+ {
226
+ message: "Expected: lowercase or uppercase variant name",
227
+ },
228
+ ]);
159
229
  });
160
230
  it("reports unknown enum variant", () => {
161
231
  const schema = {
@@ -1 +1 @@
1
- {"version":3,"file":"schema_validator.test.js","sourceRoot":"","sources":["../../src/json/schema_validator.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"buckwheat\";\nimport { describe, it } from \"mocha\";\nimport { parseJsonValue } from \"./json_parser.js\";\nimport { validateSchema } from \"./schema_validator.js\";\nimport { JsonValue, TypeDefinition } from \"./types.js\";\n\nfunction parse(json: string): JsonValue {\n const result = parseJsonValue(json);\n if (!result.value) {\n throw new Error(`JSON parse error: ${JSON.stringify(result.errors)}`);\n }\n return result.value;\n}\n\ndescribe(\"schema_validator\", () => {\n it(\"validates primitive int32\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n if (result.hints.length === 0) {\n throw new Error(\"Expected type hints\");\n }\n });\n\n it(\"validates primitive string\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"string\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for type mismatch (int32 vs string)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n },\n ]);\n });\n\n it(\"validates array of primitives\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse(\"[1, 2, 3]\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for invalid array item\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse('[1, \"bad\", 3]'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n segment: {\n start: 4,\n end: 9,\n },\n },\n ]);\n });\n\n it(\"validates optional field (present)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates optional field (null)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"null\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"foo\",\n number: 1,\n type: { kind: \"primitive\", value: \"string\" },\n },\n {\n name: \"bar\",\n number: 2,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n const result = validateSchema(parse('{\"foo\": \"hi\", \"bar\": 123}'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports unknown field in struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [],\n },\n ],\n };\n const result = validateSchema(parse('{\"unknown\": 1}'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown field\",\n segment: {\n start: 1,\n end: 10,\n },\n },\n ]);\n });\n\n it(\"validates enum (string literal)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n const result = validateSchema(parse('\"First\"'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports unknown enum variant\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"First\", number: 1 }],\n },\n ],\n };\n const result = validateSchema(parse('\"Unknown\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"stores enum definition in type hint for UNKNOWN enum literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('\"UNKNOWN\"'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n expect(result.rootTypeHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"stores enum definition in nested UNKNOWN enum field hint\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"status\",\n number: 1,\n type: { kind: \"record\", value: \"MyEnum\" },\n },\n ],\n },\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('{\"status\": \"UNKNOWN\"}'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n if (result.rootTypeHint.childHints.length !== 1) {\n throw new Error(\"Expected one child type hint\");\n }\n const statusHint = result.rootTypeHint.childHints[0];\n expect(statusHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"validates enum (object with kind)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"complex\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({ errors: [] });\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": \"foo\"}'), schema),\n ).toMatch({\n errors: [\n {\n message: \"Expected: int32\",\n },\n ],\n });\n expect(validateSchema(parse('{\"kind\": \"complex\"}'), schema)).toMatch({\n errors: [\n {\n message: \"Missing: 'value'\",\n },\n ],\n });\n });\n});\n"]}
1
+ {"version":3,"file":"schema_validator.test.js","sourceRoot":"","sources":["../../src/json/schema_validator.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"buckwheat\";\nimport { describe, it } from \"mocha\";\nimport { parseJsonValue } from \"./json_parser.js\";\nimport { validateSchema } from \"./schema_validator.js\";\nimport { JsonValue, TypeDefinition } from \"./types.js\";\n\nfunction parse(json: string): JsonValue {\n const result = parseJsonValue(json);\n if (!result.value) {\n throw new Error(`JSON parse error: ${JSON.stringify(result.errors)}`);\n }\n return result.value;\n}\n\ndescribe(\"schema_validator\", () => {\n it(\"validates primitive int32\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n if (result.hints.length === 0) {\n throw new Error(\"Expected type hints\");\n }\n });\n\n it(\"validates primitive string\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"string\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for type mismatch (int32 vs string)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n },\n ]);\n });\n\n it(\"validates array of primitives\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse(\"[1, 2, 3]\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for invalid array item\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse('[1, \"bad\", 3]'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n segment: {\n start: 4,\n end: 9,\n },\n },\n ]);\n });\n\n it(\"validates optional field (present)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates optional field (null)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"null\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"foo\",\n number: 1,\n type: { kind: \"primitive\", value: \"string\" },\n },\n {\n name: \"bar\",\n number: 2,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n const result = validateSchema(parse('{\"foo\": \"hi\", \"bar\": 123}'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports unknown field in struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [],\n },\n ],\n };\n const result = validateSchema(parse('{\"unknown\": 1}'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown field\",\n segment: {\n start: 1,\n end: 10,\n },\n },\n ]);\n });\n\n it(\"validates enum (string literal accepts lower and upper)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"FOO\", number: 1 },\n { name: \"BAR\", number: 2 },\n ],\n },\n ],\n };\n const lowerResult = validateSchema(parse('\"foo\"'), schema);\n expect(lowerResult).toMatch({ errors: [] });\n\n const upperResult = validateSchema(parse('\"FOO\"'), schema);\n expect(upperResult).toMatch({ errors: [] });\n });\n\n it(\"rejects mixed-case enum string literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n const result = validateSchema(parse('\"Foo\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"accepts UNKNOWN and unknown enum literals\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n expect(validateSchema(parse('\"UNKNOWN\"'), schema)).toMatch({ errors: [] });\n expect(validateSchema(parse('\"unknown\"'), schema)).toMatch({ errors: [] });\n\n const mixedCaseResult = validateSchema(parse('\"Unknown\"'), schema);\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"validates enum object kind in lower and upper\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"COMPLEX\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n expect(\n validateSchema(parse('{\"kind\": \"COMPLEX\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n\n const mixedCaseResult = validateSchema(\n parse('{\"kind\": \"Complex\", \"value\": 123}'),\n schema,\n );\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Expected: lowercase or uppercase variant name\",\n },\n ]);\n });\n\n it(\"reports unknown enum variant\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"First\", number: 1 }],\n },\n ],\n };\n const result = validateSchema(parse('\"Unknown\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"stores enum definition in type hint for UNKNOWN enum literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('\"UNKNOWN\"'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n expect(result.rootTypeHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"stores enum definition in nested UNKNOWN enum field hint\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"status\",\n number: 1,\n type: { kind: \"record\", value: \"MyEnum\" },\n },\n ],\n },\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('{\"status\": \"UNKNOWN\"}'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n if (result.rootTypeHint.childHints.length !== 1) {\n throw new Error(\"Expected one child type hint\");\n }\n const statusHint = result.rootTypeHint.childHints[0];\n expect(statusHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"validates enum (object with kind)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"complex\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({ errors: [] });\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": \"foo\"}'), schema),\n ).toMatch({\n errors: [\n {\n message: \"Expected: int32\",\n },\n ],\n });\n expect(validateSchema(parse('{\"kind\": \"complex\"}'), schema)).toMatch({\n errors: [\n {\n message: \"Missing: 'value'\",\n },\n ],\n });\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skir-codemirror-plugin",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/gepheum/skir-codemirror-plugin#readme",
6
6
  "bugs": {
@@ -48,7 +48,7 @@
48
48
  "@codemirror/lang-json": "^6.0.2",
49
49
  "@uiw/codemirror-themes-all": "^4.25.9",
50
50
  "codemirror": "^6.0.2",
51
- "skir-client": "^1.0.11"
51
+ "skir-client": "^1.0.18"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@custom-elements-manifest/analyzer": "^0.6.3",
@@ -73,6 +73,5 @@
73
73
  "diff": "^8.0.3",
74
74
  "minimatch": "^10.2.1",
75
75
  "serialize-javascript": "^7.0.4"
76
- },
77
- "customElements": "custom-elements.json"
76
+ }
78
77
  }
@@ -152,7 +152,7 @@ describe("schema_validator", () => {
152
152
  ]);
153
153
  });
154
154
 
155
- it("validates enum (string literal)", () => {
155
+ it("validates enum (string literal accepts lower and upper)", () => {
156
156
  const schema: TypeDefinition = {
157
157
  type: { kind: "record", value: "MyEnum" },
158
158
  records: [
@@ -160,14 +160,100 @@ describe("schema_validator", () => {
160
160
  kind: "enum",
161
161
  id: "MyEnum",
162
162
  variants: [
163
- { name: "First", number: 1 },
164
- { name: "Second", number: 2 },
163
+ { name: "FOO", number: 1 },
164
+ { name: "BAR", number: 2 },
165
165
  ],
166
166
  },
167
167
  ],
168
168
  };
169
- const result = validateSchema(parse('"First"'), schema);
170
- expect(result).toMatch({ errors: [] });
169
+ const lowerResult = validateSchema(parse('"foo"'), schema);
170
+ expect(lowerResult).toMatch({ errors: [] });
171
+
172
+ const upperResult = validateSchema(parse('"FOO"'), schema);
173
+ expect(upperResult).toMatch({ errors: [] });
174
+ });
175
+
176
+ it("rejects mixed-case enum string literal", () => {
177
+ const schema: TypeDefinition = {
178
+ type: { kind: "record", value: "MyEnum" },
179
+ records: [
180
+ {
181
+ kind: "enum",
182
+ id: "MyEnum",
183
+ variants: [{ name: "FOO", number: 1 }],
184
+ },
185
+ ],
186
+ };
187
+
188
+ const result = validateSchema(parse('"Foo"'), schema);
189
+ expect(result.errors).toMatch([
190
+ {
191
+ message: "Unknown variant",
192
+ },
193
+ ]);
194
+ });
195
+
196
+ it("accepts UNKNOWN and unknown enum literals", () => {
197
+ const schema: TypeDefinition = {
198
+ type: { kind: "record", value: "MyEnum" },
199
+ records: [
200
+ {
201
+ kind: "enum",
202
+ id: "MyEnum",
203
+ variants: [{ name: "FOO", number: 1 }],
204
+ },
205
+ ],
206
+ };
207
+
208
+ expect(validateSchema(parse('"UNKNOWN"'), schema)).toMatch({ errors: [] });
209
+ expect(validateSchema(parse('"unknown"'), schema)).toMatch({ errors: [] });
210
+
211
+ const mixedCaseResult = validateSchema(parse('"Unknown"'), schema);
212
+ expect(mixedCaseResult.errors).toMatch([
213
+ {
214
+ message: "Unknown variant",
215
+ },
216
+ ]);
217
+ });
218
+
219
+ it("validates enum object kind in lower and upper", () => {
220
+ const schema: TypeDefinition = {
221
+ type: { kind: "record", value: "MyEnum" },
222
+ records: [
223
+ {
224
+ kind: "enum",
225
+ id: "MyEnum",
226
+ variants: [
227
+ {
228
+ name: "COMPLEX",
229
+ number: 1,
230
+ type: { kind: "primitive", value: "int32" },
231
+ },
232
+ ],
233
+ },
234
+ ],
235
+ };
236
+
237
+ expect(
238
+ validateSchema(parse('{"kind": "complex", "value": 123}'), schema),
239
+ ).toMatch({
240
+ errors: [],
241
+ });
242
+ expect(
243
+ validateSchema(parse('{"kind": "COMPLEX", "value": 123}'), schema),
244
+ ).toMatch({
245
+ errors: [],
246
+ });
247
+
248
+ const mixedCaseResult = validateSchema(
249
+ parse('{"kind": "Complex", "value": 123}'),
250
+ schema,
251
+ );
252
+ expect(mixedCaseResult.errors).toMatch([
253
+ {
254
+ message: "Expected: lowercase or uppercase variant name",
255
+ },
256
+ ]);
171
257
  });
172
258
 
173
259
  it("reports unknown enum variant", () => {
@@ -191,7 +191,8 @@ class SchemaValidator {
191
191
  // Enum
192
192
  const nameToVariantDef: { [name: string]: VariantDefinition } = {};
193
193
  recordDef.variants.forEach((variant) => {
194
- nameToVariantDef[variant.name] = variant;
194
+ nameToVariantDef[variant.name.toLowerCase()] = variant;
195
+ nameToVariantDef[variant.name.toUpperCase()] = variant;
195
196
  });
196
197
  if (value.kind === "object") {
197
198
  pushTypeHint();
@@ -206,7 +207,7 @@ class SchemaValidator {
206
207
  segment: value.segment,
207
208
  message: "Expected: uppercase variant name",
208
209
  });
209
- } else if (name === "UNKNOWN" || fieldDef) {
210
+ } else if (name === "unknown" || name === "UNKNOWN" || fieldDef) {
210
211
  pushTypeHint({ enumDefinition: recordDef });
211
212
  typeHintStack.pop();
212
213
  } else {
@@ -256,11 +257,13 @@ class SchemaValidator {
256
257
  return;
257
258
  }
258
259
  const kind: string = JSON.parse(kindKv.value.jsonCode);
259
- if (kind !== kind.toLowerCase()) {
260
+ const isLowercase = kind === kind.toLowerCase();
261
+ const isUppercase = kind === kind.toUpperCase();
262
+ if (!isLowercase && !isUppercase) {
260
263
  this.errors.push({
261
264
  kind: "error",
262
265
  segment: kindKv.value.segment,
263
- message: "Expected: lowercase variant name",
266
+ message: "Expected: lowercase or uppercase variant name",
264
267
  });
265
268
  return;
266
269
  }