@formspec/build 0.1.0-alpha.13 → 0.1.0-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -20
- package/dist/__tests__/alias-chain-propagation.test.d.ts +9 -0
- package/dist/__tests__/alias-chain-propagation.test.d.ts.map +1 -0
- package/dist/__tests__/extension-runtime.integration.test.d.ts +2 -0
- package/dist/__tests__/extension-runtime.integration.test.d.ts.map +1 -0
- package/dist/__tests__/fixtures/alias-chains.d.ts +37 -0
- package/dist/__tests__/fixtures/alias-chains.d.ts.map +1 -0
- package/dist/__tests__/fixtures/edge-cases.d.ts +11 -0
- package/dist/__tests__/fixtures/edge-cases.d.ts.map +1 -1
- package/dist/__tests__/fixtures/example-a-builtins.d.ts +13 -13
- package/dist/__tests__/fixtures/example-interface-types.d.ts +33 -33
- package/dist/__tests__/fixtures/example-interface-types.d.ts.map +1 -1
- package/dist/__tests__/jsdoc-constraints.test.d.ts +4 -5
- package/dist/__tests__/jsdoc-constraints.test.d.ts.map +1 -1
- package/dist/__tests__/json-utils.test.d.ts +5 -0
- package/dist/__tests__/json-utils.test.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/plan-status/chain-dsl.d.ts +19 -0
- package/dist/__tests__/parity/fixtures/plan-status/chain-dsl.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/plan-status/expected-ir.d.ts +6 -0
- package/dist/__tests__/parity/fixtures/plan-status/expected-ir.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/plan-status/tsdoc.d.ts +17 -0
- package/dist/__tests__/parity/fixtures/plan-status/tsdoc.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/usd-cents/chain-dsl.d.ts +9 -0
- package/dist/__tests__/parity/fixtures/usd-cents/chain-dsl.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/usd-cents/expected-ir.d.ts +6 -0
- package/dist/__tests__/parity/fixtures/usd-cents/expected-ir.d.ts.map +1 -0
- package/dist/__tests__/parity/fixtures/usd-cents/tsdoc.d.ts +19 -0
- package/dist/__tests__/parity/fixtures/usd-cents/tsdoc.d.ts.map +1 -0
- package/dist/__tests__/parity/utils.d.ts +6 -1
- package/dist/__tests__/parity/utils.d.ts.map +1 -1
- package/dist/__tests__/path-target-parser.test.d.ts +9 -0
- package/dist/__tests__/path-target-parser.test.d.ts.map +1 -0
- package/dist/analyzer/class-analyzer.d.ts +1 -1
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/jsdoc-constraints.d.ts +8 -52
- package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
- package/dist/analyzer/json-utils.d.ts +22 -0
- package/dist/analyzer/json-utils.d.ts.map +1 -0
- package/dist/analyzer/tsdoc-parser.d.ts +24 -12
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +452 -94
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +15 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +450 -94
- package/dist/browser.js.map +1 -1
- package/dist/build.d.ts +132 -5
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts +3 -3
- package/dist/cli.cjs +406 -104
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +407 -104
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +386 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +20 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +386 -104
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +597 -172
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +597 -172
- package/dist/internals.js.map +1 -1
- package/dist/json-schema/generator.d.ts +8 -2
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts +25 -2
- package/dist/json-schema/ir-generator.d.ts.map +1 -1
- package/dist/json-schema/types.d.ts +1 -1
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/validate/constraint-validator.d.ts +3 -7
- package/dist/validate/constraint-validator.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -182,7 +182,7 @@ function canonicalizeArrayField(field) {
|
|
|
182
182
|
const itemsType = {
|
|
183
183
|
kind: "object",
|
|
184
184
|
properties: itemProperties,
|
|
185
|
-
additionalProperties:
|
|
185
|
+
additionalProperties: true
|
|
186
186
|
};
|
|
187
187
|
const type = { kind: "array", items: itemsType };
|
|
188
188
|
const constraints = [];
|
|
@@ -217,7 +217,7 @@ function canonicalizeObjectField(field) {
|
|
|
217
217
|
const type = {
|
|
218
218
|
kind: "object",
|
|
219
219
|
properties,
|
|
220
|
-
additionalProperties:
|
|
220
|
+
additionalProperties: true
|
|
221
221
|
};
|
|
222
222
|
return buildFieldNode(field.name, type, field.required, buildAnnotations(field.label));
|
|
223
223
|
}
|
|
@@ -415,11 +415,21 @@ var init_canonicalize = __esm({
|
|
|
415
415
|
});
|
|
416
416
|
|
|
417
417
|
// src/json-schema/ir-generator.ts
|
|
418
|
-
function makeContext() {
|
|
419
|
-
|
|
418
|
+
function makeContext(options) {
|
|
419
|
+
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
420
|
+
if (!vendorPrefix.startsWith("x-")) {
|
|
421
|
+
throw new Error(
|
|
422
|
+
`Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
defs: {},
|
|
427
|
+
extensionRegistry: options?.extensionRegistry,
|
|
428
|
+
vendorPrefix
|
|
429
|
+
};
|
|
420
430
|
}
|
|
421
|
-
function generateJsonSchemaFromIR(ir) {
|
|
422
|
-
const ctx = makeContext();
|
|
431
|
+
function generateJsonSchemaFromIR(ir, options) {
|
|
432
|
+
const ctx = makeContext(options);
|
|
423
433
|
for (const [name, typeDef] of Object.entries(ir.typeRegistry)) {
|
|
424
434
|
ctx.defs[name] = generateTypeNode(typeDef.type, ctx);
|
|
425
435
|
}
|
|
@@ -462,8 +472,70 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
462
472
|
}
|
|
463
473
|
function generateFieldSchema(field, ctx) {
|
|
464
474
|
const schema = generateTypeNode(field.type, ctx);
|
|
465
|
-
|
|
466
|
-
|
|
475
|
+
const directConstraints = [];
|
|
476
|
+
const pathConstraints = [];
|
|
477
|
+
for (const c of field.constraints) {
|
|
478
|
+
if (c.path) {
|
|
479
|
+
pathConstraints.push(c);
|
|
480
|
+
} else {
|
|
481
|
+
directConstraints.push(c);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
applyConstraints(schema, directConstraints, ctx);
|
|
485
|
+
applyAnnotations(schema, field.annotations, ctx);
|
|
486
|
+
if (pathConstraints.length === 0) {
|
|
487
|
+
return schema;
|
|
488
|
+
}
|
|
489
|
+
return applyPathTargetedConstraints(schema, pathConstraints, ctx);
|
|
490
|
+
}
|
|
491
|
+
function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
492
|
+
if (schema.type === "array" && schema.items) {
|
|
493
|
+
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx);
|
|
494
|
+
return schema;
|
|
495
|
+
}
|
|
496
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
497
|
+
for (const c of pathConstraints) {
|
|
498
|
+
const target = c.path?.segments[0];
|
|
499
|
+
if (!target) continue;
|
|
500
|
+
const group = byTarget.get(target) ?? [];
|
|
501
|
+
group.push(c);
|
|
502
|
+
byTarget.set(target, group);
|
|
503
|
+
}
|
|
504
|
+
const propertyOverrides = {};
|
|
505
|
+
for (const [target, constraints] of byTarget) {
|
|
506
|
+
const subSchema = {};
|
|
507
|
+
applyConstraints(subSchema, constraints, ctx);
|
|
508
|
+
propertyOverrides[target] = subSchema;
|
|
509
|
+
}
|
|
510
|
+
if (schema.$ref) {
|
|
511
|
+
const { $ref, ...rest } = schema;
|
|
512
|
+
const refPart = { $ref };
|
|
513
|
+
const overridePart = {
|
|
514
|
+
properties: propertyOverrides,
|
|
515
|
+
...rest
|
|
516
|
+
};
|
|
517
|
+
return { allOf: [refPart, overridePart] };
|
|
518
|
+
}
|
|
519
|
+
if (schema.type === "object" && schema.properties) {
|
|
520
|
+
const missingOverrides = {};
|
|
521
|
+
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
522
|
+
if (schema.properties[target]) {
|
|
523
|
+
Object.assign(schema.properties[target], overrideSchema);
|
|
524
|
+
} else {
|
|
525
|
+
missingOverrides[target] = overrideSchema;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
if (Object.keys(missingOverrides).length === 0) {
|
|
529
|
+
return schema;
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
allOf: [schema, { properties: missingOverrides }]
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
if (schema.allOf) {
|
|
536
|
+
schema.allOf = [...schema.allOf, { properties: propertyOverrides }];
|
|
537
|
+
return schema;
|
|
538
|
+
}
|
|
467
539
|
return schema;
|
|
468
540
|
}
|
|
469
541
|
function generateTypeNode(type, ctx) {
|
|
@@ -476,6 +548,8 @@ function generateTypeNode(type, ctx) {
|
|
|
476
548
|
return generateArrayType(type, ctx);
|
|
477
549
|
case "object":
|
|
478
550
|
return generateObjectType(type, ctx);
|
|
551
|
+
case "record":
|
|
552
|
+
return generateRecordType(type, ctx);
|
|
479
553
|
case "union":
|
|
480
554
|
return generateUnionType(type, ctx);
|
|
481
555
|
case "reference":
|
|
@@ -483,7 +557,7 @@ function generateTypeNode(type, ctx) {
|
|
|
483
557
|
case "dynamic":
|
|
484
558
|
return generateDynamicType(type);
|
|
485
559
|
case "custom":
|
|
486
|
-
return generateCustomType(type);
|
|
560
|
+
return generateCustomType(type, ctx);
|
|
487
561
|
default: {
|
|
488
562
|
const _exhaustive = type;
|
|
489
563
|
return _exhaustive;
|
|
@@ -532,16 +606,27 @@ function generateObjectType(type, ctx) {
|
|
|
532
606
|
}
|
|
533
607
|
return schema;
|
|
534
608
|
}
|
|
609
|
+
function generateRecordType(type, ctx) {
|
|
610
|
+
return {
|
|
611
|
+
type: "object",
|
|
612
|
+
additionalProperties: generateTypeNode(type.valueType, ctx)
|
|
613
|
+
};
|
|
614
|
+
}
|
|
535
615
|
function generatePropertySchema(prop, ctx) {
|
|
536
616
|
const schema = generateTypeNode(prop.type, ctx);
|
|
537
|
-
applyConstraints(schema, prop.constraints);
|
|
538
|
-
applyAnnotations(schema, prop.annotations);
|
|
617
|
+
applyConstraints(schema, prop.constraints, ctx);
|
|
618
|
+
applyAnnotations(schema, prop.annotations, ctx);
|
|
539
619
|
return schema;
|
|
540
620
|
}
|
|
541
621
|
function generateUnionType(type, ctx) {
|
|
542
622
|
if (isBooleanUnion(type)) {
|
|
543
623
|
return { type: "boolean" };
|
|
544
624
|
}
|
|
625
|
+
if (isNullableUnion(type)) {
|
|
626
|
+
return {
|
|
627
|
+
oneOf: type.members.map((m) => generateTypeNode(m, ctx))
|
|
628
|
+
};
|
|
629
|
+
}
|
|
545
630
|
return {
|
|
546
631
|
anyOf: type.members.map((m) => generateTypeNode(m, ctx))
|
|
547
632
|
};
|
|
@@ -551,6 +636,13 @@ function isBooleanUnion(type) {
|
|
|
551
636
|
const kinds = type.members.map((m) => m.kind);
|
|
552
637
|
return kinds.every((k) => k === "primitive") && type.members.every((m) => m.kind === "primitive" && m.primitiveKind === "boolean");
|
|
553
638
|
}
|
|
639
|
+
function isNullableUnion(type) {
|
|
640
|
+
if (type.members.length !== 2) return false;
|
|
641
|
+
const nullCount = type.members.filter(
|
|
642
|
+
(m) => m.kind === "primitive" && m.primitiveKind === "null"
|
|
643
|
+
).length;
|
|
644
|
+
return nullCount === 1;
|
|
645
|
+
}
|
|
554
646
|
function generateReferenceType(type) {
|
|
555
647
|
return { $ref: `#/$defs/${type.name}` };
|
|
556
648
|
}
|
|
@@ -571,10 +663,7 @@ function generateDynamicType(type) {
|
|
|
571
663
|
"x-formspec-schemaSource": type.sourceKey
|
|
572
664
|
};
|
|
573
665
|
}
|
|
574
|
-
function
|
|
575
|
-
return { type: "object" };
|
|
576
|
-
}
|
|
577
|
-
function applyConstraints(schema, constraints) {
|
|
666
|
+
function applyConstraints(schema, constraints, ctx) {
|
|
578
667
|
for (const constraint of constraints) {
|
|
579
668
|
switch (constraint.constraintKind) {
|
|
580
669
|
case "minimum":
|
|
@@ -619,6 +708,7 @@ function applyConstraints(schema, constraints) {
|
|
|
619
708
|
case "allowedMembers":
|
|
620
709
|
break;
|
|
621
710
|
case "custom":
|
|
711
|
+
applyCustomConstraint(schema, constraint, ctx);
|
|
622
712
|
break;
|
|
623
713
|
default: {
|
|
624
714
|
const _exhaustive = constraint;
|
|
@@ -627,7 +717,7 @@ function applyConstraints(schema, constraints) {
|
|
|
627
717
|
}
|
|
628
718
|
}
|
|
629
719
|
}
|
|
630
|
-
function applyAnnotations(schema, annotations) {
|
|
720
|
+
function applyAnnotations(schema, annotations, ctx) {
|
|
631
721
|
for (const annotation of annotations) {
|
|
632
722
|
switch (annotation.annotationKind) {
|
|
633
723
|
case "displayName":
|
|
@@ -647,6 +737,7 @@ function applyAnnotations(schema, annotations) {
|
|
|
647
737
|
case "formatHint":
|
|
648
738
|
break;
|
|
649
739
|
case "custom":
|
|
740
|
+
applyCustomAnnotation(schema, annotation, ctx);
|
|
650
741
|
break;
|
|
651
742
|
default: {
|
|
652
743
|
const _exhaustive = annotation;
|
|
@@ -655,6 +746,36 @@ function applyAnnotations(schema, annotations) {
|
|
|
655
746
|
}
|
|
656
747
|
}
|
|
657
748
|
}
|
|
749
|
+
function generateCustomType(type, ctx) {
|
|
750
|
+
const registration = ctx.extensionRegistry?.findType(type.typeId);
|
|
751
|
+
if (registration === void 0) {
|
|
752
|
+
throw new Error(
|
|
753
|
+
`Cannot generate JSON Schema for custom type "${type.typeId}" without a matching extension registration`
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
return registration.toJsonSchema(type.payload, ctx.vendorPrefix);
|
|
757
|
+
}
|
|
758
|
+
function applyCustomConstraint(schema, constraint, ctx) {
|
|
759
|
+
const registration = ctx.extensionRegistry?.findConstraint(constraint.constraintId);
|
|
760
|
+
if (registration === void 0) {
|
|
761
|
+
throw new Error(
|
|
762
|
+
`Cannot generate JSON Schema for custom constraint "${constraint.constraintId}" without a matching extension registration`
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
Object.assign(schema, registration.toJsonSchema(constraint.payload, ctx.vendorPrefix));
|
|
766
|
+
}
|
|
767
|
+
function applyCustomAnnotation(schema, annotation, ctx) {
|
|
768
|
+
const registration = ctx.extensionRegistry?.findAnnotation(annotation.annotationId);
|
|
769
|
+
if (registration === void 0) {
|
|
770
|
+
throw new Error(
|
|
771
|
+
`Cannot generate JSON Schema for custom annotation "${annotation.annotationId}" without a matching extension registration`
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
if (registration.toJsonSchema === void 0) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
Object.assign(schema, registration.toJsonSchema(annotation.value, ctx.vendorPrefix));
|
|
778
|
+
}
|
|
658
779
|
var init_ir_generator = __esm({
|
|
659
780
|
"src/json-schema/ir-generator.ts"() {
|
|
660
781
|
"use strict";
|
|
@@ -662,9 +783,9 @@ var init_ir_generator = __esm({
|
|
|
662
783
|
});
|
|
663
784
|
|
|
664
785
|
// src/json-schema/generator.ts
|
|
665
|
-
function generateJsonSchema(form) {
|
|
786
|
+
function generateJsonSchema(form, options) {
|
|
666
787
|
const ir = canonicalizeChainDSL(form);
|
|
667
|
-
return generateJsonSchemaFromIR(ir);
|
|
788
|
+
return generateJsonSchemaFromIR(ir, options);
|
|
668
789
|
}
|
|
669
790
|
var init_generator = __esm({
|
|
670
791
|
"src/json-schema/generator.ts"() {
|
|
@@ -925,6 +1046,61 @@ var init_types = __esm({
|
|
|
925
1046
|
}
|
|
926
1047
|
});
|
|
927
1048
|
|
|
1049
|
+
// src/extensions/registry.ts
|
|
1050
|
+
function createExtensionRegistry(extensions) {
|
|
1051
|
+
const typeMap = /* @__PURE__ */ new Map();
|
|
1052
|
+
const constraintMap = /* @__PURE__ */ new Map();
|
|
1053
|
+
const annotationMap = /* @__PURE__ */ new Map();
|
|
1054
|
+
for (const ext of extensions) {
|
|
1055
|
+
if (ext.types !== void 0) {
|
|
1056
|
+
for (const type of ext.types) {
|
|
1057
|
+
const qualifiedId = `${ext.extensionId}/${type.typeName}`;
|
|
1058
|
+
if (typeMap.has(qualifiedId)) {
|
|
1059
|
+
throw new Error(`Duplicate custom type ID: "${qualifiedId}"`);
|
|
1060
|
+
}
|
|
1061
|
+
typeMap.set(qualifiedId, type);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
if (ext.constraints !== void 0) {
|
|
1065
|
+
for (const constraint of ext.constraints) {
|
|
1066
|
+
const qualifiedId = `${ext.extensionId}/${constraint.constraintName}`;
|
|
1067
|
+
if (constraintMap.has(qualifiedId)) {
|
|
1068
|
+
throw new Error(`Duplicate custom constraint ID: "${qualifiedId}"`);
|
|
1069
|
+
}
|
|
1070
|
+
constraintMap.set(qualifiedId, constraint);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
if (ext.annotations !== void 0) {
|
|
1074
|
+
for (const annotation of ext.annotations) {
|
|
1075
|
+
const qualifiedId = `${ext.extensionId}/${annotation.annotationName}`;
|
|
1076
|
+
if (annotationMap.has(qualifiedId)) {
|
|
1077
|
+
throw new Error(`Duplicate custom annotation ID: "${qualifiedId}"`);
|
|
1078
|
+
}
|
|
1079
|
+
annotationMap.set(qualifiedId, annotation);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
return {
|
|
1084
|
+
extensions,
|
|
1085
|
+
findType: (typeId) => typeMap.get(typeId),
|
|
1086
|
+
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
1087
|
+
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
var init_registry = __esm({
|
|
1091
|
+
"src/extensions/registry.ts"() {
|
|
1092
|
+
"use strict";
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
// src/extensions/index.ts
|
|
1097
|
+
var init_extensions = __esm({
|
|
1098
|
+
"src/extensions/index.ts"() {
|
|
1099
|
+
"use strict";
|
|
1100
|
+
init_registry();
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
|
|
928
1104
|
// src/json-schema/schema.ts
|
|
929
1105
|
import { z as z3 } from "zod";
|
|
930
1106
|
var jsonSchemaTypeSchema, jsonSchema7Schema;
|
|
@@ -1070,6 +1246,20 @@ var init_program = __esm({
|
|
|
1070
1246
|
}
|
|
1071
1247
|
});
|
|
1072
1248
|
|
|
1249
|
+
// src/analyzer/json-utils.ts
|
|
1250
|
+
function tryParseJson(text) {
|
|
1251
|
+
try {
|
|
1252
|
+
return JSON.parse(text);
|
|
1253
|
+
} catch {
|
|
1254
|
+
return null;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
var init_json_utils = __esm({
|
|
1258
|
+
"src/analyzer/json-utils.ts"() {
|
|
1259
|
+
"use strict";
|
|
1260
|
+
}
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1073
1263
|
// src/analyzer/tsdoc-parser.ts
|
|
1074
1264
|
import * as ts2 from "typescript";
|
|
1075
1265
|
import {
|
|
@@ -1082,11 +1272,10 @@ import {
|
|
|
1082
1272
|
TextRange
|
|
1083
1273
|
} from "@microsoft/tsdoc";
|
|
1084
1274
|
import {
|
|
1085
|
-
BUILTIN_CONSTRAINT_DEFINITIONS
|
|
1275
|
+
BUILTIN_CONSTRAINT_DEFINITIONS,
|
|
1276
|
+
normalizeConstraintTagName,
|
|
1277
|
+
isBuiltinConstraintName
|
|
1086
1278
|
} from "@formspec/core";
|
|
1087
|
-
function isBuiltinConstraintName(tagName) {
|
|
1088
|
-
return tagName in BUILTIN_CONSTRAINT_DEFINITIONS;
|
|
1089
|
-
}
|
|
1090
1279
|
function createFormSpecTSDocConfig() {
|
|
1091
1280
|
const config = new TSDocConfiguration();
|
|
1092
1281
|
for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS)) {
|
|
@@ -1098,6 +1287,15 @@ function createFormSpecTSDocConfig() {
|
|
|
1098
1287
|
})
|
|
1099
1288
|
);
|
|
1100
1289
|
}
|
|
1290
|
+
for (const tagName of ["displayName", "description"]) {
|
|
1291
|
+
config.addTagDefinition(
|
|
1292
|
+
new TSDocTagDefinition({
|
|
1293
|
+
tagName: "@" + tagName,
|
|
1294
|
+
syntaxKind: TSDocTagSyntaxKind.BlockTag,
|
|
1295
|
+
allowMultiple: true
|
|
1296
|
+
})
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1101
1299
|
return config;
|
|
1102
1300
|
}
|
|
1103
1301
|
function getParser() {
|
|
@@ -1125,7 +1323,28 @@ function parseTSDocTags(node, file = "") {
|
|
|
1125
1323
|
);
|
|
1126
1324
|
const docComment = parserContext.docComment;
|
|
1127
1325
|
for (const block of docComment.customBlocks) {
|
|
1128
|
-
const tagName = block.blockTag.tagName.substring(1);
|
|
1326
|
+
const tagName = normalizeConstraintTagName(block.blockTag.tagName.substring(1));
|
|
1327
|
+
if (tagName === "displayName" || tagName === "description") {
|
|
1328
|
+
const text2 = extractBlockText(block).trim();
|
|
1329
|
+
if (text2 === "") continue;
|
|
1330
|
+
const provenance2 = provenanceForComment(range, sourceFile, file, tagName);
|
|
1331
|
+
if (tagName === "displayName") {
|
|
1332
|
+
annotations.push({
|
|
1333
|
+
kind: "annotation",
|
|
1334
|
+
annotationKind: "displayName",
|
|
1335
|
+
value: text2,
|
|
1336
|
+
provenance: provenance2
|
|
1337
|
+
});
|
|
1338
|
+
} else {
|
|
1339
|
+
annotations.push({
|
|
1340
|
+
kind: "annotation",
|
|
1341
|
+
annotationKind: "description",
|
|
1342
|
+
value: text2,
|
|
1343
|
+
provenance: provenance2
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
continue;
|
|
1347
|
+
}
|
|
1129
1348
|
if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
1130
1349
|
const text = extractBlockText(block).trim();
|
|
1131
1350
|
if (text === "") continue;
|
|
@@ -1146,7 +1365,7 @@ function parseTSDocTags(node, file = "") {
|
|
|
1146
1365
|
}
|
|
1147
1366
|
const jsDocTagsAll = ts2.getJSDocTags(node);
|
|
1148
1367
|
for (const tag of jsDocTagsAll) {
|
|
1149
|
-
const tagName = tag.tagName.text;
|
|
1368
|
+
const tagName = normalizeConstraintTagName(tag.tagName.text);
|
|
1150
1369
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
1151
1370
|
const commentText = getTagCommentText(tag);
|
|
1152
1371
|
if (commentText === void 0 || commentText.trim() === "") continue;
|
|
@@ -1157,43 +1376,17 @@ function parseTSDocTags(node, file = "") {
|
|
|
1157
1376
|
constraints.push(constraintNode);
|
|
1158
1377
|
}
|
|
1159
1378
|
}
|
|
1160
|
-
let displayName;
|
|
1161
|
-
let description;
|
|
1162
|
-
let displayNameTag;
|
|
1163
|
-
let descriptionTag;
|
|
1164
|
-
for (const tag of jsDocTagsAll) {
|
|
1165
|
-
const tagName = tag.tagName.text;
|
|
1166
|
-
const commentText = getTagCommentText(tag);
|
|
1167
|
-
if (commentText === void 0 || commentText.trim() === "") {
|
|
1168
|
-
continue;
|
|
1169
|
-
}
|
|
1170
|
-
const trimmed = commentText.trim();
|
|
1171
|
-
if (tagName === "Field_displayName") {
|
|
1172
|
-
displayName = trimmed;
|
|
1173
|
-
displayNameTag = tag;
|
|
1174
|
-
} else if (tagName === "Field_description") {
|
|
1175
|
-
description = trimmed;
|
|
1176
|
-
descriptionTag = tag;
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
if (displayName !== void 0 && displayNameTag) {
|
|
1180
|
-
annotations.push({
|
|
1181
|
-
kind: "annotation",
|
|
1182
|
-
annotationKind: "displayName",
|
|
1183
|
-
value: displayName,
|
|
1184
|
-
provenance: provenanceForJSDocTag(displayNameTag, file)
|
|
1185
|
-
});
|
|
1186
|
-
}
|
|
1187
|
-
if (description !== void 0 && descriptionTag) {
|
|
1188
|
-
annotations.push({
|
|
1189
|
-
kind: "annotation",
|
|
1190
|
-
annotationKind: "description",
|
|
1191
|
-
value: description,
|
|
1192
|
-
provenance: provenanceForJSDocTag(descriptionTag, file)
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
1379
|
return { constraints, annotations };
|
|
1196
1380
|
}
|
|
1381
|
+
function extractPathTarget(text) {
|
|
1382
|
+
const trimmed = text.trimStart();
|
|
1383
|
+
const match = /^:([a-zA-Z_]\w*)\s+([\s\S]*)$/.exec(trimmed);
|
|
1384
|
+
if (!match?.[1] || !match[2]) return null;
|
|
1385
|
+
return {
|
|
1386
|
+
path: { segments: [match[1]] },
|
|
1387
|
+
remainingText: match[2]
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1197
1390
|
function extractBlockText(block) {
|
|
1198
1391
|
return extractPlainText(block.content);
|
|
1199
1392
|
}
|
|
@@ -1216,9 +1409,12 @@ function parseConstraintValue(tagName, text, provenance) {
|
|
|
1216
1409
|
if (!isBuiltinConstraintName(tagName)) {
|
|
1217
1410
|
return null;
|
|
1218
1411
|
}
|
|
1412
|
+
const pathResult = extractPathTarget(text);
|
|
1413
|
+
const effectiveText = pathResult ? pathResult.remainingText : text;
|
|
1414
|
+
const path4 = pathResult?.path;
|
|
1219
1415
|
const expectedType = BUILTIN_CONSTRAINT_DEFINITIONS[tagName];
|
|
1220
1416
|
if (expectedType === "number") {
|
|
1221
|
-
const value = Number(
|
|
1417
|
+
const value = Number(effectiveText);
|
|
1222
1418
|
if (Number.isNaN(value)) {
|
|
1223
1419
|
return null;
|
|
1224
1420
|
}
|
|
@@ -1228,6 +1424,7 @@ function parseConstraintValue(tagName, text, provenance) {
|
|
|
1228
1424
|
kind: "constraint",
|
|
1229
1425
|
constraintKind: numericKind,
|
|
1230
1426
|
value,
|
|
1427
|
+
...path4 && { path: path4 },
|
|
1231
1428
|
provenance
|
|
1232
1429
|
};
|
|
1233
1430
|
}
|
|
@@ -1237,42 +1434,41 @@ function parseConstraintValue(tagName, text, provenance) {
|
|
|
1237
1434
|
kind: "constraint",
|
|
1238
1435
|
constraintKind: lengthKind,
|
|
1239
1436
|
value,
|
|
1437
|
+
...path4 && { path: path4 },
|
|
1240
1438
|
provenance
|
|
1241
1439
|
};
|
|
1242
1440
|
}
|
|
1243
1441
|
return null;
|
|
1244
1442
|
}
|
|
1245
1443
|
if (expectedType === "json") {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
members.push(id);
|
|
1259
|
-
}
|
|
1444
|
+
const parsed = tryParseJson(effectiveText);
|
|
1445
|
+
if (!Array.isArray(parsed)) {
|
|
1446
|
+
return null;
|
|
1447
|
+
}
|
|
1448
|
+
const members = [];
|
|
1449
|
+
for (const item of parsed) {
|
|
1450
|
+
if (typeof item === "string" || typeof item === "number") {
|
|
1451
|
+
members.push(item);
|
|
1452
|
+
} else if (typeof item === "object" && item !== null && "id" in item) {
|
|
1453
|
+
const id = item["id"];
|
|
1454
|
+
if (typeof id === "string" || typeof id === "number") {
|
|
1455
|
+
members.push(id);
|
|
1260
1456
|
}
|
|
1261
1457
|
}
|
|
1262
|
-
return {
|
|
1263
|
-
kind: "constraint",
|
|
1264
|
-
constraintKind: "allowedMembers",
|
|
1265
|
-
members,
|
|
1266
|
-
provenance
|
|
1267
|
-
};
|
|
1268
|
-
} catch {
|
|
1269
|
-
return null;
|
|
1270
1458
|
}
|
|
1459
|
+
return {
|
|
1460
|
+
kind: "constraint",
|
|
1461
|
+
constraintKind: "allowedMembers",
|
|
1462
|
+
members,
|
|
1463
|
+
...path4 && { path: path4 },
|
|
1464
|
+
provenance
|
|
1465
|
+
};
|
|
1271
1466
|
}
|
|
1272
1467
|
return {
|
|
1273
1468
|
kind: "constraint",
|
|
1274
1469
|
constraintKind: "pattern",
|
|
1275
|
-
pattern:
|
|
1470
|
+
pattern: effectiveText,
|
|
1471
|
+
...path4 && { path: path4 },
|
|
1276
1472
|
provenance
|
|
1277
1473
|
};
|
|
1278
1474
|
}
|
|
@@ -1310,25 +1506,26 @@ var NUMERIC_CONSTRAINT_MAP, LENGTH_CONSTRAINT_MAP, TAGS_REQUIRING_RAW_TEXT, shar
|
|
|
1310
1506
|
var init_tsdoc_parser = __esm({
|
|
1311
1507
|
"src/analyzer/tsdoc-parser.ts"() {
|
|
1312
1508
|
"use strict";
|
|
1509
|
+
init_json_utils();
|
|
1313
1510
|
NUMERIC_CONSTRAINT_MAP = {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1511
|
+
minimum: "minimum",
|
|
1512
|
+
maximum: "maximum",
|
|
1513
|
+
exclusiveMinimum: "exclusiveMinimum",
|
|
1514
|
+
exclusiveMaximum: "exclusiveMaximum",
|
|
1515
|
+
multipleOf: "multipleOf"
|
|
1318
1516
|
};
|
|
1319
1517
|
LENGTH_CONSTRAINT_MAP = {
|
|
1320
|
-
|
|
1321
|
-
|
|
1518
|
+
minLength: "minLength",
|
|
1519
|
+
maxLength: "maxLength",
|
|
1520
|
+
minItems: "minItems",
|
|
1521
|
+
maxItems: "maxItems"
|
|
1322
1522
|
};
|
|
1323
|
-
TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["
|
|
1523
|
+
TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions"]);
|
|
1324
1524
|
}
|
|
1325
1525
|
});
|
|
1326
1526
|
|
|
1327
1527
|
// src/analyzer/jsdoc-constraints.ts
|
|
1328
1528
|
import * as ts3 from "typescript";
|
|
1329
|
-
import {
|
|
1330
|
-
BUILTIN_CONSTRAINT_DEFINITIONS as BUILTIN_CONSTRAINT_DEFINITIONS2
|
|
1331
|
-
} from "@formspec/core";
|
|
1332
1529
|
function extractJSDocConstraintNodes(node, file = "") {
|
|
1333
1530
|
const result = parseTSDocTags(node, file);
|
|
1334
1531
|
return [...result.constraints];
|
|
@@ -1472,18 +1669,19 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting) {
|
|
|
1472
1669
|
const tsType = checker.getTypeAtLocation(prop);
|
|
1473
1670
|
const optional = prop.questionToken !== void 0;
|
|
1474
1671
|
const provenance = provenanceForNode(prop, file);
|
|
1475
|
-
|
|
1672
|
+
let type = resolveTypeNode(tsType, checker, file, typeRegistry, visiting);
|
|
1476
1673
|
const constraints = [];
|
|
1477
1674
|
if (prop.type) {
|
|
1478
1675
|
constraints.push(...extractTypeAliasConstraintNodes(prop.type, checker, file));
|
|
1479
1676
|
}
|
|
1480
1677
|
constraints.push(...extractJSDocConstraintNodes(prop, file));
|
|
1481
|
-
|
|
1678
|
+
let annotations = [];
|
|
1482
1679
|
annotations.push(...extractJSDocAnnotationNodes(prop, file));
|
|
1483
1680
|
const defaultAnnotation = extractDefaultValueAnnotation(prop.initializer, file);
|
|
1484
1681
|
if (defaultAnnotation) {
|
|
1485
1682
|
annotations.push(defaultAnnotation);
|
|
1486
1683
|
}
|
|
1684
|
+
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
1487
1685
|
return {
|
|
1488
1686
|
kind: "field",
|
|
1489
1687
|
name,
|
|
@@ -1502,14 +1700,15 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
1502
1700
|
const tsType = checker.getTypeAtLocation(prop);
|
|
1503
1701
|
const optional = prop.questionToken !== void 0;
|
|
1504
1702
|
const provenance = provenanceForNode(prop, file);
|
|
1505
|
-
|
|
1703
|
+
let type = resolveTypeNode(tsType, checker, file, typeRegistry, visiting);
|
|
1506
1704
|
const constraints = [];
|
|
1507
1705
|
if (prop.type) {
|
|
1508
1706
|
constraints.push(...extractTypeAliasConstraintNodes(prop.type, checker, file));
|
|
1509
1707
|
}
|
|
1510
1708
|
constraints.push(...extractJSDocConstraintNodes(prop, file));
|
|
1511
|
-
|
|
1709
|
+
let annotations = [];
|
|
1512
1710
|
annotations.push(...extractJSDocAnnotationNodes(prop, file));
|
|
1711
|
+
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
1513
1712
|
return {
|
|
1514
1713
|
kind: "field",
|
|
1515
1714
|
name,
|
|
@@ -1520,6 +1719,68 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
1520
1719
|
provenance
|
|
1521
1720
|
};
|
|
1522
1721
|
}
|
|
1722
|
+
function applyEnumMemberDisplayNames(type, annotations) {
|
|
1723
|
+
if (!annotations.some(
|
|
1724
|
+
(annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
|
|
1725
|
+
)) {
|
|
1726
|
+
return { type, annotations: [...annotations] };
|
|
1727
|
+
}
|
|
1728
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
1729
|
+
const nextType = rewriteEnumDisplayNames(type, annotations, consumed);
|
|
1730
|
+
if (consumed.size === 0) {
|
|
1731
|
+
return { type, annotations: [...annotations] };
|
|
1732
|
+
}
|
|
1733
|
+
return {
|
|
1734
|
+
type: nextType,
|
|
1735
|
+
annotations: annotations.filter((annotation) => !consumed.has(annotation))
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
function rewriteEnumDisplayNames(type, annotations, consumed) {
|
|
1739
|
+
switch (type.kind) {
|
|
1740
|
+
case "enum":
|
|
1741
|
+
return applyEnumMemberDisplayNamesToEnum(type, annotations, consumed);
|
|
1742
|
+
case "union": {
|
|
1743
|
+
return {
|
|
1744
|
+
...type,
|
|
1745
|
+
members: type.members.map(
|
|
1746
|
+
(member) => rewriteEnumDisplayNames(member, annotations, consumed)
|
|
1747
|
+
)
|
|
1748
|
+
};
|
|
1749
|
+
}
|
|
1750
|
+
default:
|
|
1751
|
+
return type;
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
function applyEnumMemberDisplayNamesToEnum(type, annotations, consumed) {
|
|
1755
|
+
const displayNames = /* @__PURE__ */ new Map();
|
|
1756
|
+
for (const annotation of annotations) {
|
|
1757
|
+
if (annotation.annotationKind !== "displayName") continue;
|
|
1758
|
+
const parsed = parseEnumMemberDisplayName(annotation.value);
|
|
1759
|
+
if (!parsed) continue;
|
|
1760
|
+
consumed.add(annotation);
|
|
1761
|
+
const member = type.members.find((m) => String(m.value) === parsed.value);
|
|
1762
|
+
if (!member) continue;
|
|
1763
|
+
displayNames.set(String(member.value), parsed.label);
|
|
1764
|
+
}
|
|
1765
|
+
if (displayNames.size === 0) {
|
|
1766
|
+
return type;
|
|
1767
|
+
}
|
|
1768
|
+
return {
|
|
1769
|
+
...type,
|
|
1770
|
+
members: type.members.map((member) => {
|
|
1771
|
+
const displayName = displayNames.get(String(member.value));
|
|
1772
|
+
return displayName !== void 0 ? { ...member, displayName } : member;
|
|
1773
|
+
})
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1776
|
+
function parseEnumMemberDisplayName(value) {
|
|
1777
|
+
const trimmed = value.trim();
|
|
1778
|
+
const match = /^:([^\s]+)\s+([\s\S]+)$/.exec(trimmed);
|
|
1779
|
+
if (!match?.[1] || !match[2]) return null;
|
|
1780
|
+
const label = match[2].trim();
|
|
1781
|
+
if (label === "") return null;
|
|
1782
|
+
return { value: match[1], label };
|
|
1783
|
+
}
|
|
1523
1784
|
function resolveTypeNode(type, checker, file, typeRegistry, visiting) {
|
|
1524
1785
|
if (type.flags & ts4.TypeFlags.String) {
|
|
1525
1786
|
return { kind: "primitive", primitiveKind: "string" };
|
|
@@ -1630,7 +1891,30 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting) {
|
|
|
1630
1891
|
const items = elementType ? resolveTypeNode(elementType, checker, file, typeRegistry, visiting) : { kind: "primitive", primitiveKind: "string" };
|
|
1631
1892
|
return { kind: "array", items };
|
|
1632
1893
|
}
|
|
1894
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting) {
|
|
1895
|
+
if (type.getProperties().length > 0) {
|
|
1896
|
+
return null;
|
|
1897
|
+
}
|
|
1898
|
+
const indexInfo = checker.getIndexInfoOfType(type, ts4.IndexKind.String);
|
|
1899
|
+
if (!indexInfo) {
|
|
1900
|
+
return null;
|
|
1901
|
+
}
|
|
1902
|
+
if (visiting.has(type)) {
|
|
1903
|
+
return null;
|
|
1904
|
+
}
|
|
1905
|
+
visiting.add(type);
|
|
1906
|
+
try {
|
|
1907
|
+
const valueType = resolveTypeNode(indexInfo.type, checker, file, typeRegistry, visiting);
|
|
1908
|
+
return { kind: "record", valueType };
|
|
1909
|
+
} finally {
|
|
1910
|
+
visiting.delete(type);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1633
1913
|
function resolveObjectType(type, checker, file, typeRegistry, visiting) {
|
|
1914
|
+
const recordNode = tryResolveRecordType(type, checker, file, typeRegistry, visiting);
|
|
1915
|
+
if (recordNode) {
|
|
1916
|
+
return recordNode;
|
|
1917
|
+
}
|
|
1634
1918
|
if (visiting.has(type)) {
|
|
1635
1919
|
return { kind: "object", properties: [], additionalProperties: false };
|
|
1636
1920
|
}
|
|
@@ -1662,7 +1946,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting) {
|
|
|
1662
1946
|
const objectNode = {
|
|
1663
1947
|
kind: "object",
|
|
1664
1948
|
properties,
|
|
1665
|
-
additionalProperties:
|
|
1949
|
+
additionalProperties: true
|
|
1666
1950
|
};
|
|
1667
1951
|
if (typeName) {
|
|
1668
1952
|
typeRegistry[typeName] = {
|
|
@@ -1731,14 +2015,22 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting) {
|
|
|
1731
2015
|
}
|
|
1732
2016
|
return map;
|
|
1733
2017
|
}
|
|
1734
|
-
function extractTypeAliasConstraintNodes(typeNode, checker, file) {
|
|
2018
|
+
function extractTypeAliasConstraintNodes(typeNode, checker, file, depth = 0) {
|
|
1735
2019
|
if (!ts4.isTypeReferenceNode(typeNode)) return [];
|
|
2020
|
+
if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
|
|
2021
|
+
const aliasName = typeNode.typeName.getText();
|
|
2022
|
+
throw new Error(
|
|
2023
|
+
`Type alias chain exceeds maximum depth of ${String(MAX_ALIAS_CHAIN_DEPTH)} at alias "${aliasName}" in ${file}. Simplify the alias chain or check for circular references.`
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
1736
2026
|
const symbol = checker.getSymbolAtLocation(typeNode.typeName);
|
|
1737
2027
|
if (!symbol?.declarations) return [];
|
|
1738
2028
|
const aliasDecl = symbol.declarations.find(ts4.isTypeAliasDeclaration);
|
|
1739
2029
|
if (!aliasDecl) return [];
|
|
1740
2030
|
if (ts4.isTypeLiteralNode(aliasDecl.type)) return [];
|
|
1741
|
-
|
|
2031
|
+
const constraints = extractJSDocConstraintNodes(aliasDecl, file);
|
|
2032
|
+
constraints.push(...extractTypeAliasConstraintNodes(aliasDecl.type, checker, file, depth + 1));
|
|
2033
|
+
return constraints;
|
|
1742
2034
|
}
|
|
1743
2035
|
function provenanceForNode(node, file) {
|
|
1744
2036
|
const sourceFile = node.getSourceFile();
|
|
@@ -1811,10 +2103,12 @@ function detectFormSpecReference(typeNode) {
|
|
|
1811
2103
|
}
|
|
1812
2104
|
return null;
|
|
1813
2105
|
}
|
|
2106
|
+
var MAX_ALIAS_CHAIN_DEPTH;
|
|
1814
2107
|
var init_class_analyzer = __esm({
|
|
1815
2108
|
"src/analyzer/class-analyzer.ts"() {
|
|
1816
2109
|
"use strict";
|
|
1817
2110
|
init_jsdoc_constraints();
|
|
2111
|
+
MAX_ALIAS_CHAIN_DEPTH = 8;
|
|
1818
2112
|
}
|
|
1819
2113
|
});
|
|
1820
2114
|
|
|
@@ -1878,7 +2172,9 @@ __export(index_exports, {
|
|
|
1878
2172
|
categorizationSchema: () => categorizationSchema,
|
|
1879
2173
|
categorySchema: () => categorySchema,
|
|
1880
2174
|
controlSchema: () => controlSchema,
|
|
2175
|
+
createExtensionRegistry: () => createExtensionRegistry,
|
|
1881
2176
|
generateJsonSchema: () => generateJsonSchema,
|
|
2177
|
+
generateJsonSchemaFromIR: () => generateJsonSchemaFromIR,
|
|
1882
2178
|
generateSchemas: () => generateSchemas,
|
|
1883
2179
|
generateSchemasFromClass: () => generateSchemasFromClass,
|
|
1884
2180
|
generateUiSchema: () => generateUiSchema,
|
|
@@ -1901,15 +2197,19 @@ __export(index_exports, {
|
|
|
1901
2197
|
});
|
|
1902
2198
|
import * as fs from "fs";
|
|
1903
2199
|
import * as path2 from "path";
|
|
1904
|
-
function buildFormSchemas(form) {
|
|
2200
|
+
function buildFormSchemas(form, options) {
|
|
1905
2201
|
return {
|
|
1906
|
-
jsonSchema: generateJsonSchema(form),
|
|
2202
|
+
jsonSchema: generateJsonSchema(form, options),
|
|
1907
2203
|
uiSchema: generateUiSchema(form)
|
|
1908
2204
|
};
|
|
1909
2205
|
}
|
|
1910
2206
|
function writeSchemas(form, options) {
|
|
1911
|
-
const { outDir, name = "schema", indent = 2 } = options;
|
|
1912
|
-
const
|
|
2207
|
+
const { outDir, name = "schema", indent = 2, extensionRegistry, vendorPrefix } = options;
|
|
2208
|
+
const buildOptions = extensionRegistry === void 0 && vendorPrefix === void 0 ? void 0 : {
|
|
2209
|
+
extensionRegistry,
|
|
2210
|
+
vendorPrefix
|
|
2211
|
+
};
|
|
2212
|
+
const { jsonSchema, uiSchema: uiSchema2 } = buildFormSchemas(form, buildOptions);
|
|
1913
2213
|
if (!fs.existsSync(outDir)) {
|
|
1914
2214
|
fs.mkdirSync(outDir, { recursive: true });
|
|
1915
2215
|
}
|
|
@@ -1924,10 +2224,13 @@ var init_index = __esm({
|
|
|
1924
2224
|
"use strict";
|
|
1925
2225
|
init_generator();
|
|
1926
2226
|
init_generator2();
|
|
2227
|
+
init_ir_generator();
|
|
1927
2228
|
init_types();
|
|
2229
|
+
init_extensions();
|
|
1928
2230
|
init_schema();
|
|
1929
2231
|
init_schema2();
|
|
1930
2232
|
init_generator();
|
|
2233
|
+
init_ir_generator();
|
|
1931
2234
|
init_generator2();
|
|
1932
2235
|
init_class_schema();
|
|
1933
2236
|
}
|