schemair 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +420 -11
  2. package/dist/authoring/index.cjs +13 -350
  3. package/dist/authoring/index.d.cts +2 -90
  4. package/dist/authoring/index.d.ts +2 -90
  5. package/dist/authoring/index.js +2 -304
  6. package/dist/authoring-D3V0iyTe.js +362 -0
  7. package/dist/authoring-Dnrg5TXm.cjs +389 -0
  8. package/dist/chunk-BgLxgFZR.js +18 -0
  9. package/dist/definition/index.cjs +10 -2
  10. package/dist/definition/index.d.cts +3 -21
  11. package/dist/definition/index.d.ts +3 -21
  12. package/dist/definition/index.js +2 -2
  13. package/dist/definition-BLLBpLKv.cjs +1187 -0
  14. package/dist/definition-DmYnDmQO.js +1115 -0
  15. package/dist/index-4aMF0cTE.d.ts +368 -0
  16. package/dist/index-BqfGAU1K.d.ts +56 -0
  17. package/dist/{index-eK2Xgrwp.d.ts → index-CBbd4hXJ.d.ts} +13 -2
  18. package/dist/index-CIim1dG7.d.cts +92 -0
  19. package/dist/{index-TACcK_mi.d.cts → index-CNjYUKvu.d.cts} +13 -2
  20. package/dist/index-CQynt7ft.d.cts +420 -0
  21. package/dist/index-D3mfwaSO.d.cts +56 -0
  22. package/dist/index-DDMwVy2I.d.cts +368 -0
  23. package/dist/index-DM5DSLLL.d.ts +99 -0
  24. package/dist/index-DXWoNYFB.d.ts +92 -0
  25. package/dist/index-DhmHCGpT.d.cts +99 -0
  26. package/dist/index-bQy-C-1l.d.ts +418 -0
  27. package/dist/index.cjs +64 -52
  28. package/dist/index.d.cts +7 -7
  29. package/dist/index.d.ts +7 -7
  30. package/dist/index.js +7 -5
  31. package/dist/integrations/json-schema/index.cjs +328 -0
  32. package/dist/integrations/json-schema/index.d.cts +53 -0
  33. package/dist/integrations/json-schema/index.d.ts +53 -0
  34. package/dist/integrations/json-schema/index.js +324 -0
  35. package/dist/integrations/standard-schema/index.cjs +32 -0
  36. package/dist/integrations/standard-schema/index.d.cts +22 -0
  37. package/dist/integrations/standard-schema/index.d.ts +22 -0
  38. package/dist/integrations/standard-schema/index.js +32 -0
  39. package/dist/payload/index.cjs +1 -1
  40. package/dist/payload/index.d.cts +1 -55
  41. package/dist/payload/index.d.ts +1 -55
  42. package/dist/payload/index.js +1 -1
  43. package/dist/relations/index.cjs +3 -1
  44. package/dist/relations/index.d.cts +2 -2
  45. package/dist/relations/index.d.ts +2 -2
  46. package/dist/relations/index.js +2 -2
  47. package/dist/{relations-CMz_0nf4.cjs → relations-Cymx4iTc.cjs} +158 -5
  48. package/dist/{relations-By0bK3UK.js → relations-ysXDmi-Z.js} +147 -6
  49. package/dist/spec/index.cjs +9 -0
  50. package/dist/spec/index.d.cts +2 -2
  51. package/dist/spec/index.d.ts +2 -2
  52. package/dist/spec/index.js +3 -1
  53. package/dist/standard/index.cjs +810 -0
  54. package/dist/standard/index.d.cts +3 -0
  55. package/dist/standard/index.d.ts +3 -0
  56. package/dist/standard/index.js +777 -0
  57. package/dist/standard-DhKsxu9U.js +471 -0
  58. package/dist/standard-etPFZDJI.cjs +513 -0
  59. package/dist/type-interpreter/index.cjs +3 -3
  60. package/dist/type-interpreter/index.d.cts +2 -99
  61. package/dist/type-interpreter/index.d.ts +2 -99
  62. package/dist/type-interpreter/index.js +2 -2
  63. package/dist/{type-interpreter-Ck0VDhzn.js → type-interpreter-DnrId8aM.js} +5 -284
  64. package/dist/{type-interpreter-DAIBUqKf.cjs → type-interpreter-OLt2W2yd.cjs} +15 -294
  65. package/package.json +38 -3
  66. package/dist/definition-BXj3T94L.js +0 -467
  67. package/dist/definition-DSZZTz4e.cjs +0 -473
  68. package/dist/index-CEzHfht2.d.ts +0 -269
  69. package/dist/index-rzkFjgrt.d.cts +0 -269
@@ -1,473 +0,0 @@
1
-
2
- //#region src/definition/validator.ts
3
- const NODE_KINDS = new Set([
4
- "primitive",
5
- "literal",
6
- "record",
7
- "array",
8
- "tuple",
9
- "literalUnion",
10
- "nullable",
11
- "taggedUnion",
12
- "ref",
13
- "selfRef"
14
- ]);
15
- const PRIMITIVE_NAMES = new Set([
16
- "string",
17
- "number",
18
- "boolean",
19
- "null"
20
- ]);
21
- function isRecord(value) {
22
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
23
- const prototype = Object.getPrototypeOf(value);
24
- return prototype === Object.prototype || prototype === null;
25
- }
26
- function hasOwn(value, key) {
27
- return Object.prototype.hasOwnProperty.call(value, key);
28
- }
29
- function ownKeys(value) {
30
- return Reflect.ownKeys(value);
31
- }
32
- function hasAccessor(value) {
33
- return ownKeys(value).some((key) => {
34
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
35
- return descriptor !== void 0 && ("get" in descriptor || "set" in descriptor);
36
- });
37
- }
38
- function isDenseArray(value) {
39
- if (!Array.isArray(value)) return false;
40
- for (const key of Reflect.ownKeys(value)) {
41
- if (typeof key === "symbol") return false;
42
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
43
- if (descriptor !== void 0 && ("get" in descriptor || "set" in descriptor)) return false;
44
- if (key !== "length" && !/^(0|[1-9]\d*)$/.test(key)) return false;
45
- }
46
- for (let index = 0; index < value.length; index += 1) if (!hasOwn(value, String(index))) return false;
47
- return true;
48
- }
49
- function isFiniteNumber(value) {
50
- return typeof value === "number" && Number.isFinite(value);
51
- }
52
- function isLiteral(value) {
53
- return typeof value === "string" || typeof value === "boolean" || isFiniteNumber(value);
54
- }
55
- function scalarDomain(value) {
56
- if (typeof value === "string") return "string";
57
- if (typeof value === "boolean") return "boolean";
58
- return "number";
59
- }
60
- function equalLiteral(left, right) {
61
- return typeof left === typeof right && Object.is(left, right) || left === right;
62
- }
63
- function describe(value) {
64
- if (value === null) return "null";
65
- if (Array.isArray(value)) return "array";
66
- return typeof value;
67
- }
68
- var DefinitionValidator = class {
69
- issues = [];
70
- active = /* @__PURE__ */ new WeakSet();
71
- validateRoot(value) {
72
- if (this.validateNode(value, [], true)) return {
73
- ok: true,
74
- node: value,
75
- issues: []
76
- };
77
- return {
78
- ok: false,
79
- issues: this.issues
80
- };
81
- }
82
- issue(code, path, message) {
83
- this.issues.push({
84
- code,
85
- path,
86
- message
87
- });
88
- }
89
- checkObject(value, path, label) {
90
- if (!isRecord(value)) {
91
- this.issue("schema.object.invalid", path, `${label} must be a plain object`);
92
- return false;
93
- }
94
- if (hasAccessor(value)) {
95
- this.issue("schema.object.accessor", path, `${label} must not contain accessor properties`);
96
- return false;
97
- }
98
- if (ownKeys(value).some((key) => typeof key === "symbol")) {
99
- this.issue("schema.object.symbol-key", path, `${label} must not contain symbol keys`);
100
- return false;
101
- }
102
- return true;
103
- }
104
- checkFields(value, allowed, required, path) {
105
- let valid = true;
106
- for (const key of Object.getOwnPropertyNames(value)) if (!allowed.includes(key)) {
107
- this.issue("schema.field.unknown", [...path, key], `unknown field '${key}'`);
108
- valid = false;
109
- }
110
- for (const key of required) if (!hasOwn(value, key)) {
111
- this.issue("schema.field.missing", [...path, key], `missing required field '${key}'`);
112
- valid = false;
113
- }
114
- return valid;
115
- }
116
- enter(value, path) {
117
- if (this.active.has(value)) {
118
- this.issue("schema.cycle", path, "actual object cycles are not valid schema data");
119
- return false;
120
- }
121
- this.active.add(value);
122
- return true;
123
- }
124
- leave(value) {
125
- this.active.delete(value);
126
- }
127
- validateNode(value, path, root) {
128
- if (!this.checkObject(value, path, "schema node")) return false;
129
- if (!this.enter(value, path)) return false;
130
- let valid = true;
131
- const kind = value.kind;
132
- if (typeof kind !== "string" || !NODE_KINDS.has(kind)) {
133
- this.issue("schema.kind.invalid", [...path, "kind"], `unsupported schema kind '${String(kind)}'`);
134
- valid = false;
135
- } else switch (kind) {
136
- case "primitive":
137
- valid = this.validatePrimitive(value, path);
138
- break;
139
- case "literal":
140
- valid = this.validateLiteral(value, path);
141
- break;
142
- case "record":
143
- valid = this.validateRecord(value, path);
144
- break;
145
- case "array":
146
- valid = this.validateArray(value, path);
147
- break;
148
- case "tuple":
149
- valid = this.validateTuple(value, path);
150
- break;
151
- case "literalUnion":
152
- valid = this.validateLiteralUnion(value, path);
153
- break;
154
- case "nullable":
155
- valid = this.validateNullable(value, path);
156
- break;
157
- case "taggedUnion":
158
- valid = this.validateTaggedUnion(value, path);
159
- break;
160
- case "ref":
161
- valid = this.validateRef(value, path);
162
- break;
163
- case "selfRef":
164
- valid = this.checkFields(value, ["kind"], [], path);
165
- if (root) {
166
- this.issue("schema.selfRef.root", path, "a root schema cannot consist only of selfRef");
167
- valid = false;
168
- }
169
- break;
170
- default: valid = false;
171
- }
172
- this.leave(value);
173
- return valid;
174
- }
175
- validatePrimitive(value, path) {
176
- let valid = this.checkFields(value, [
177
- "kind",
178
- "name",
179
- "semanticPath",
180
- "constraints"
181
- ], ["name"], path);
182
- const name = value.name;
183
- if (typeof name !== "string" || !PRIMITIVE_NAMES.has(name)) {
184
- this.issue("schema.primitive.name", [...path, "name"], `primitive name must be one of string, number, boolean, or null`);
185
- return false;
186
- }
187
- if (!(name === "string" || name === "number") && (hasOwn(value, "semanticPath") || hasOwn(value, "constraints"))) {
188
- this.issue("schema.primitive.metadata", path, "semanticPath and constraints are only supported on string and number primitives");
189
- valid = false;
190
- }
191
- if (hasOwn(value, "semanticPath")) valid = this.validatePath(value.semanticPath, [...path, "semanticPath"], "semanticPath") && valid;
192
- if (hasOwn(value, "constraints")) valid = this.validateConstraints(value.constraints, [...path, "constraints"], "constraints") && valid;
193
- return valid;
194
- }
195
- validateLiteral(value, path) {
196
- let valid = this.checkFields(value, ["kind", "literal"], ["literal"], path);
197
- if (!isLiteral(value.literal)) {
198
- this.issue("schema.literal.value", [...path, "literal"], "literal must be a finite string, number, or boolean");
199
- valid = false;
200
- }
201
- return valid;
202
- }
203
- validateRecord(value, path) {
204
- let valid = this.checkFields(value, [
205
- "kind",
206
- "fields",
207
- "additionalFields",
208
- "constraints"
209
- ], ["fields"], path);
210
- if (!isDenseArray(value.fields)) {
211
- this.issue("schema.record.fields", [...path, "fields"], "fields must be a dense array");
212
- return false;
213
- }
214
- const keys = /* @__PURE__ */ new Set();
215
- value.fields.forEach((field, index) => {
216
- const fieldPath = [
217
- ...path,
218
- "fields",
219
- index
220
- ];
221
- if (!this.checkObject(field, fieldPath, "record field")) {
222
- valid = false;
223
- return;
224
- }
225
- valid = this.checkFields(field, [
226
- "key",
227
- "schema",
228
- "required",
229
- "description"
230
- ], ["key", "schema"], fieldPath) && valid;
231
- if (typeof field.key !== "string") {
232
- this.issue("schema.record.field-key", [...fieldPath, "key"], "record field key must be a string");
233
- valid = false;
234
- } else if (keys.has(field.key)) {
235
- this.issue("schema.record.field-key.duplicate", [...fieldPath, "key"], `duplicate record field key '${field.key}'`);
236
- valid = false;
237
- } else keys.add(field.key);
238
- if (hasOwn(field, "required") && typeof field.required !== "boolean") {
239
- this.issue("schema.record.required", [...fieldPath, "required"], "required must be a boolean");
240
- valid = false;
241
- }
242
- if (hasOwn(field, "description") && typeof field.description !== "string") {
243
- this.issue("schema.record.description", [...fieldPath, "description"], "description must be a string");
244
- valid = false;
245
- }
246
- valid = this.validateNode(field.schema, [...fieldPath, "schema"], false) && valid;
247
- });
248
- if (hasOwn(value, "additionalFields")) {
249
- if (value.additionalFields !== true) valid = this.validateNode(value.additionalFields, [...path, "additionalFields"], false) && valid;
250
- }
251
- if (hasOwn(value, "constraints")) valid = this.validateConstraints(value.constraints, [...path, "constraints"], "constraints") && valid;
252
- return valid;
253
- }
254
- validateArray(value, path) {
255
- let valid = this.checkFields(value, [
256
- "kind",
257
- "elementSchema",
258
- "constraints"
259
- ], ["elementSchema"], path);
260
- valid = this.validateNode(value.elementSchema, [...path, "elementSchema"], false) && valid;
261
- if (hasOwn(value, "constraints")) valid = this.validateConstraints(value.constraints, [...path, "constraints"], "constraints") && valid;
262
- return valid;
263
- }
264
- validateTuple(value, path) {
265
- let valid = this.checkFields(value, ["kind", "elementSchemas"], ["elementSchemas"], path);
266
- if (!isDenseArray(value.elementSchemas)) {
267
- this.issue("schema.tuple.elements", [...path, "elementSchemas"], "elementSchemas must be a dense array");
268
- return false;
269
- }
270
- value.elementSchemas.forEach((child, index) => {
271
- valid = this.validateNode(child, [
272
- ...path,
273
- "elementSchemas",
274
- index
275
- ], false) && valid;
276
- });
277
- return valid;
278
- }
279
- validateLiteralUnion(value, path) {
280
- let valid = this.checkFields(value, ["kind", "values"], ["values"], path);
281
- if (!isDenseArray(value.values)) {
282
- this.issue("schema.literalUnion.values", [...path, "values"], "values must be a dense array");
283
- return false;
284
- }
285
- if (value.values.length < 2) {
286
- this.issue("schema.literalUnion.cardinality", [...path, "values"], "literalUnion requires at least two values");
287
- valid = false;
288
- }
289
- let domain;
290
- const literals = [];
291
- value.values.forEach((candidate, index) => {
292
- const candidatePath = [
293
- ...path,
294
- "values",
295
- index
296
- ];
297
- if (!isLiteral(candidate)) {
298
- this.issue("schema.literalUnion.value", candidatePath, "literalUnion values must be finite strings, numbers, or booleans");
299
- valid = false;
300
- return;
301
- }
302
- const candidateDomain = scalarDomain(candidate);
303
- if (domain === void 0) domain = candidateDomain;
304
- else if (domain !== candidateDomain) {
305
- this.issue("schema.literalUnion.domain", candidatePath, "literalUnion values must share one scalar domain");
306
- valid = false;
307
- }
308
- if (literals.some((existing) => equalLiteral(existing, candidate))) {
309
- this.issue("schema.literalUnion.duplicate", candidatePath, "literalUnion values must be unique");
310
- valid = false;
311
- }
312
- literals.push(candidate);
313
- });
314
- return valid;
315
- }
316
- validateNullable(value, path) {
317
- let valid = this.checkFields(value, ["kind", "value"], ["value"], path);
318
- valid = this.validateNode(value.value, [...path, "value"], false) && valid;
319
- if (isRecord(value.value) && (value.value.kind === "nullable" || value.value.kind === "primitive" && value.value.name === "null")) {
320
- this.issue("schema.nullable.redundant", [...path, "value"], "nullable cannot wrap null or another nullable node");
321
- valid = false;
322
- }
323
- return valid;
324
- }
325
- validateTaggedUnion(value, path) {
326
- let valid = this.checkFields(value, [
327
- "kind",
328
- "discriminator",
329
- "variants"
330
- ], ["discriminator", "variants"], path);
331
- if (typeof value.discriminator !== "string") {
332
- this.issue("schema.taggedUnion.discriminator", [...path, "discriminator"], "discriminator must be a string");
333
- valid = false;
334
- }
335
- if (!isDenseArray(value.variants)) {
336
- this.issue("schema.taggedUnion.variants", [...path, "variants"], "variants must be a dense array");
337
- return false;
338
- }
339
- if (value.variants.length < 2) {
340
- this.issue("schema.taggedUnion.cardinality", [...path, "variants"], "taggedUnion requires at least two variants");
341
- valid = false;
342
- }
343
- const variantKeys = /* @__PURE__ */ new Set();
344
- const tags = /* @__PURE__ */ new Set();
345
- value.variants.forEach((variant, index) => {
346
- const variantPath = [
347
- ...path,
348
- "variants",
349
- index
350
- ];
351
- if (!this.checkObject(variant, variantPath, "tagged-union variant")) {
352
- valid = false;
353
- return;
354
- }
355
- valid = this.checkFields(variant, [
356
- "key",
357
- "schema",
358
- "description"
359
- ], ["key", "schema"], variantPath) && valid;
360
- if (typeof variant.key !== "string" || variant.key.trim() === "") {
361
- this.issue("schema.taggedUnion.variant-key", [...variantPath, "key"], "variant key must be a non-blank string");
362
- valid = false;
363
- } else if (variantKeys.has(variant.key)) {
364
- this.issue("schema.taggedUnion.variant-key.duplicate", [...variantPath, "key"], `duplicate variant key '${variant.key}'`);
365
- valid = false;
366
- } else variantKeys.add(variant.key);
367
- if (hasOwn(variant, "description") && typeof variant.description !== "string") {
368
- this.issue("schema.taggedUnion.description", [...variantPath, "description"], "description must be a string");
369
- valid = false;
370
- }
371
- valid = this.validateNode(variant.schema, [...variantPath, "schema"], false) && valid;
372
- if (!isRecord(variant.schema) || variant.schema.kind !== "record") {
373
- this.issue("schema.taggedUnion.variant-schema", [...variantPath, "schema"], "tagged-union variants must be direct record schemas");
374
- valid = false;
375
- return;
376
- }
377
- const field = (isDenseArray(variant.schema.fields) ? variant.schema.fields : []).find((candidate) => isRecord(candidate) && candidate.key === value.discriminator);
378
- if (!field || field.required !== true || !isRecord(field.schema) || field.schema.kind !== "literal" || typeof field.schema.literal !== "string") {
379
- this.issue("schema.taggedUnion.discriminator-field", [
380
- ...variantPath,
381
- "schema",
382
- "fields"
383
- ], "each variant must have a required string-literal discriminator field");
384
- valid = false;
385
- } else if (tags.has(field.schema.literal)) {
386
- this.issue("schema.taggedUnion.discriminator-duplicate", [
387
- ...variantPath,
388
- "schema",
389
- "fields"
390
- ], "discriminator literal tags must be unique");
391
- valid = false;
392
- } else tags.add(field.schema.literal);
393
- });
394
- return valid;
395
- }
396
- validateRef(value, path) {
397
- let valid = this.checkFields(value, ["kind", "refPath"], ["refPath"], path);
398
- valid = this.validatePath(value.refPath, [...path, "refPath"], "refPath") && valid;
399
- return valid;
400
- }
401
- validatePath(value, path, label) {
402
- if (!isDenseArray(value) || value.length === 0 || value.some((segment) => typeof segment !== "string" || segment.trim() === "")) {
403
- this.issue("schema.path.invalid", path, `${label} must be a non-empty dense array of non-blank strings`);
404
- return false;
405
- }
406
- return true;
407
- }
408
- validateConstraints(value, path, label) {
409
- if (!isDenseArray(value)) {
410
- this.issue("schema.constraints.invalid", path, `${label} must be a dense array`);
411
- return false;
412
- }
413
- let valid = true;
414
- value.forEach((constraint, index) => {
415
- const constraintPath = [...path, index];
416
- if (!this.checkObject(constraint, constraintPath, "constraint")) {
417
- valid = false;
418
- return;
419
- }
420
- valid = this.checkFields(constraint, ["constraintPath", "args"], ["constraintPath"], constraintPath) && valid;
421
- valid = this.validatePath(constraint.constraintPath, [...constraintPath, "constraintPath"], "constraintPath") && valid;
422
- if (hasOwn(constraint, "args")) valid = this.validateJsonValue(constraint.args, [...constraintPath, "args"], /* @__PURE__ */ new WeakSet()) && valid;
423
- });
424
- return valid;
425
- }
426
- validateJsonValue(value, path, active) {
427
- if (value === null || typeof value === "string" || typeof value === "boolean") return true;
428
- if (typeof value === "number") {
429
- if (Number.isFinite(value)) return true;
430
- this.issue("schema.json-value.number", path, "JSON numbers must be finite");
431
- return false;
432
- }
433
- if (typeof value !== "object") {
434
- this.issue("schema.json-value.type", path, `value of type ${describe(value)} is not JSON-compatible`);
435
- return false;
436
- }
437
- if (active.has(value)) {
438
- this.issue("schema.json-value.cycle", path, "actual object cycles are not JSON-compatible");
439
- return false;
440
- }
441
- if (Array.isArray(value)) {
442
- if (!isDenseArray(value)) {
443
- this.issue("schema.json-value.array", path, "JSON arrays must be dense and have no symbol keys");
444
- return false;
445
- }
446
- active.add(value);
447
- let valid$1 = true;
448
- value.forEach((child, index) => {
449
- valid$1 = this.validateJsonValue(child, [...path, index], active) && valid$1;
450
- });
451
- active.delete(value);
452
- return valid$1;
453
- }
454
- if (!this.checkObject(value, path, "JSON object")) return false;
455
- active.add(value);
456
- let valid = true;
457
- for (const key of Object.keys(value)) valid = this.validateJsonValue(value[key], [...path, key], active) && valid;
458
- active.delete(value);
459
- return valid;
460
- }
461
- };
462
- /** Validate only the serializable structural definition of one SchemaNode. */
463
- function validateSchemaNodeDefinition(value) {
464
- return new DefinitionValidator().validateRoot(value);
465
- }
466
-
467
- //#endregion
468
- Object.defineProperty(exports, 'validateSchemaNodeDefinition', {
469
- enumerable: true,
470
- get: function () {
471
- return validateSchemaNodeDefinition;
472
- }
473
- });