@formspec/build 0.1.0-alpha.44 → 0.1.0-alpha.46

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 (44) hide show
  1. package/dist/analyzer/class-analyzer.d.ts.map +1 -1
  2. package/dist/analyzer/program.d.ts +4 -1
  3. package/dist/analyzer/program.d.ts.map +1 -1
  4. package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
  5. package/dist/browser.cjs +33 -7
  6. package/dist/browser.cjs.map +1 -1
  7. package/dist/browser.js +34 -10
  8. package/dist/browser.js.map +1 -1
  9. package/dist/build-alpha.d.ts +106 -5
  10. package/dist/build-beta.d.ts +106 -5
  11. package/dist/build-internal.d.ts +106 -5
  12. package/dist/build.d.ts +106 -5
  13. package/dist/cli.cjs +364 -116
  14. package/dist/cli.cjs.map +1 -1
  15. package/dist/cli.js +360 -115
  16. package/dist/cli.js.map +1 -1
  17. package/dist/extensions/index.d.ts +1 -1
  18. package/dist/extensions/index.d.ts.map +1 -1
  19. package/dist/extensions/registry.d.ts +64 -5
  20. package/dist/extensions/registry.d.ts.map +1 -1
  21. package/dist/extensions/symbol-registry.d.ts +33 -0
  22. package/dist/extensions/symbol-registry.d.ts.map +1 -0
  23. package/dist/generators/class-schema.d.ts +32 -0
  24. package/dist/generators/class-schema.d.ts.map +1 -1
  25. package/dist/generators/discovered-schema.d.ts.map +1 -1
  26. package/dist/index.cjs +350 -109
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +351 -112
  31. package/dist/index.js.map +1 -1
  32. package/dist/internals.cjs +121 -23
  33. package/dist/internals.cjs.map +1 -1
  34. package/dist/internals.d.ts +2 -2
  35. package/dist/internals.d.ts.map +1 -1
  36. package/dist/internals.js +121 -26
  37. package/dist/internals.js.map +1 -1
  38. package/dist/json-schema/generator.d.ts.map +1 -1
  39. package/dist/metadata/collision-guards.d.ts.map +1 -1
  40. package/dist/metadata/policy.d.ts.map +1 -1
  41. package/dist/metadata/resolve.d.ts.map +1 -1
  42. package/dist/ui-schema/ir-generator.d.ts.map +1 -1
  43. package/dist/validate/constraint-validator.d.ts.map +1 -1
  44. package/package.json +5 -5
@@ -49,6 +49,7 @@ __export(internals_exports, {
49
49
  generateJsonSchemaFromIR: () => generateJsonSchemaFromIR,
50
50
  generateMethodSchemas: () => generateMethodSchemas,
51
51
  generateUiSchemaFromIR: () => generateUiSchemaFromIR,
52
+ resolveStaticOptions: () => resolveStaticOptions,
52
53
  validateIR: () => validateIR
53
54
  });
54
55
  module.exports = __toCommonJS(internals_exports);
@@ -275,7 +276,9 @@ function resolveTypeNodeMetadata(type, options) {
275
276
  case "object":
276
277
  return {
277
278
  ...type,
278
- properties: type.properties.map((property) => resolveObjectPropertyMetadata(property, options))
279
+ properties: type.properties.map(
280
+ (property) => resolveObjectPropertyMetadata(property, options)
281
+ )
279
282
  };
280
283
  case "record":
281
284
  return {
@@ -1632,30 +1635,70 @@ function isObjectType(type) {
1632
1635
  function isIntersectionType(type) {
1633
1636
  return !!(type.flags & ts3.TypeFlags.Intersection);
1634
1637
  }
1638
+ function collectBrandIdentifiers(type) {
1639
+ if (!type.isIntersection()) {
1640
+ return [];
1641
+ }
1642
+ const brands = [];
1643
+ for (const prop of type.getProperties()) {
1644
+ const decl = prop.valueDeclaration ?? prop.declarations?.[0];
1645
+ if (decl === void 0) continue;
1646
+ if (!ts3.isPropertySignature(decl) && !ts3.isPropertyDeclaration(decl)) continue;
1647
+ if (!ts3.isComputedPropertyName(decl.name)) continue;
1648
+ if (!ts3.isIdentifier(decl.name.expression)) continue;
1649
+ brands.push(decl.name.expression.text);
1650
+ }
1651
+ return brands;
1652
+ }
1653
+ function resolveCanonicalSymbol(type, checker) {
1654
+ const raw = type.aliasSymbol ?? type.getSymbol();
1655
+ if (raw === void 0) return void 0;
1656
+ return raw.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
1657
+ }
1658
+ function resolveSymbolBasedCustomType(type, extensionRegistry, checker) {
1659
+ if (extensionRegistry === void 0) {
1660
+ return null;
1661
+ }
1662
+ const canonical = resolveCanonicalSymbol(type, checker);
1663
+ if (canonical === void 0) {
1664
+ return null;
1665
+ }
1666
+ const registration = extensionRegistry.findTypeBySymbol(canonical);
1667
+ if (registration === void 0) {
1668
+ return null;
1669
+ }
1670
+ return {
1671
+ kind: "custom",
1672
+ typeId: `${registration.extensionId}/${registration.registration.typeName}`,
1673
+ payload: null
1674
+ };
1675
+ }
1635
1676
  function isIntegerBrandedType(type) {
1636
1677
  if (!type.isIntersection()) {
1637
1678
  return false;
1638
1679
  }
1639
- const hasNumberBase = type.types.some(
1640
- (member) => !!(member.flags & ts3.TypeFlags.Number)
1641
- );
1680
+ const hasNumberBase = type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number));
1642
1681
  if (!hasNumberBase) {
1643
1682
  return false;
1644
1683
  }
1645
- return type.getProperties().some((prop) => {
1646
- const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
1647
- if (declaration === void 0) {
1648
- return false;
1649
- }
1650
- if (!ts3.isPropertySignature(declaration) && !ts3.isPropertyDeclaration(declaration)) {
1651
- return false;
1652
- }
1653
- const name = declaration.name;
1654
- if (!ts3.isComputedPropertyName(name)) {
1655
- return false;
1684
+ return collectBrandIdentifiers(type).includes("__integerBrand");
1685
+ }
1686
+ function resolveBrandedCustomType(type, extensionRegistry) {
1687
+ if (extensionRegistry === void 0) {
1688
+ return null;
1689
+ }
1690
+ for (const brand of collectBrandIdentifiers(type)) {
1691
+ const registration = extensionRegistry.findTypeByBrand(brand);
1692
+ if (registration === void 0) {
1693
+ continue;
1656
1694
  }
1657
- return ts3.isIdentifier(name.expression) && name.expression.text === "__integerBrand";
1658
- });
1695
+ return {
1696
+ kind: "custom",
1697
+ typeId: `${registration.extensionId}/${registration.registration.typeName}`,
1698
+ payload: null
1699
+ };
1700
+ }
1701
+ return null;
1659
1702
  }
1660
1703
  function isResolvableObjectLikeAliasTypeNode(typeNode) {
1661
1704
  if (ts3.isParenthesizedTypeNode(typeNode)) {
@@ -2768,6 +2811,14 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
2768
2811
  if (customType) {
2769
2812
  return customType;
2770
2813
  }
2814
+ const symbolCustomType = resolveSymbolBasedCustomType(type, extensionRegistry, checker);
2815
+ if (symbolCustomType) {
2816
+ return symbolCustomType;
2817
+ }
2818
+ const brandedCustomType = resolveBrandedCustomType(type, extensionRegistry);
2819
+ if (brandedCustomType) {
2820
+ return brandedCustomType;
2821
+ }
2771
2822
  const primitiveAlias = tryResolveNamedPrimitiveAlias(
2772
2823
  type,
2773
2824
  checker,
@@ -3712,7 +3763,7 @@ function createProgramContextFromProgram(program, filePath) {
3712
3763
  sourceFile
3713
3764
  };
3714
3765
  }
3715
- function createProgramContext(filePath) {
3766
+ function createProgramContext(filePath, additionalFiles) {
3716
3767
  const absolutePath = path.resolve(filePath);
3717
3768
  const fileDir = path.dirname(absolutePath);
3718
3769
  const configPath = ts4.findConfigFile(fileDir, ts4.sys.fileExists.bind(ts4.sys), "tsconfig.json");
@@ -3735,7 +3786,8 @@ function createProgramContext(filePath) {
3735
3786
  throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
3736
3787
  }
3737
3788
  compilerOptions = parsed.options;
3738
- fileNames = parsed.fileNames.includes(absolutePath) ? parsed.fileNames : [...parsed.fileNames, absolutePath];
3789
+ const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
3790
+ fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
3739
3791
  } else {
3740
3792
  compilerOptions = {
3741
3793
  target: ts4.ScriptTarget.ES2022,
@@ -3745,7 +3797,8 @@ function createProgramContext(filePath) {
3745
3797
  skipLibCheck: true,
3746
3798
  declaration: true
3747
3799
  };
3748
- fileNames = [absolutePath];
3800
+ const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
3801
+ fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
3749
3802
  }
3750
3803
  const program = ts4.createProgram(fileNames, compilerOptions);
3751
3804
  const sourceFile = program.getSourceFile(absolutePath);
@@ -4039,7 +4092,7 @@ function makeFileProvenance(filePath) {
4039
4092
  }
4040
4093
 
4041
4094
  // src/generators/class-schema.ts
4042
- var ts5 = __toESM(require("typescript"), 1);
4095
+ var ts6 = __toESM(require("typescript"), 1);
4043
4096
 
4044
4097
  // src/metadata/collision-guards.ts
4045
4098
  function assertUniqueSerializedNames(entries, scope) {
@@ -4886,8 +4939,10 @@ function buildConstraintTagSources(extensions) {
4886
4939
  }
4887
4940
  function createExtensionRegistry(extensions) {
4888
4941
  const reservedTagSources = buildConstraintTagSources(extensions);
4942
+ let symbolMap = /* @__PURE__ */ new Map();
4889
4943
  const typeMap = /* @__PURE__ */ new Map();
4890
4944
  const typeNameMap = /* @__PURE__ */ new Map();
4945
+ const brandMap = /* @__PURE__ */ new Map();
4891
4946
  const constraintMap = /* @__PURE__ */ new Map();
4892
4947
  const constraintTagMap = /* @__PURE__ */ new Map();
4893
4948
  const builtinBroadeningMap = /* @__PURE__ */ new Map();
@@ -4911,6 +4966,20 @@ function createExtensionRegistry(extensions) {
4911
4966
  registration: type
4912
4967
  });
4913
4968
  }
4969
+ if (type.brand !== void 0) {
4970
+ if (type.brand === "__integerBrand") {
4971
+ throw new Error(
4972
+ `Brand "__integerBrand" is reserved for the builtin Integer type and cannot be registered by extensions`
4973
+ );
4974
+ }
4975
+ if (brandMap.has(type.brand)) {
4976
+ throw new Error(`Duplicate custom type brand: "${type.brand}"`);
4977
+ }
4978
+ brandMap.set(type.brand, {
4979
+ extensionId: ext.extensionId,
4980
+ registration: type
4981
+ });
4982
+ }
4914
4983
  if (type.builtinConstraintBroadenings !== void 0) {
4915
4984
  for (const broadening of type.builtinConstraintBroadenings) {
4916
4985
  const key = `${qualifiedId}:${broadening.tagName}`;
@@ -4980,7 +5049,10 @@ function createExtensionRegistry(extensions) {
4980
5049
  `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
4981
5050
  );
4982
5051
  }
4983
- if (Object.hasOwn(import_internals5.BUILTIN_CONSTRAINT_DEFINITIONS, (0, import_internals5.normalizeConstraintTagName)(canonicalTagName))) {
5052
+ if (Object.hasOwn(
5053
+ import_internals5.BUILTIN_CONSTRAINT_DEFINITIONS,
5054
+ (0, import_internals5.normalizeConstraintTagName)(canonicalTagName)
5055
+ )) {
4984
5056
  throw new Error(
4985
5057
  `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${(0, import_internals5.normalizeConstraintTagName)(canonicalTagName)}".`
4986
5058
  );
@@ -5001,6 +5073,11 @@ function createExtensionRegistry(extensions) {
5001
5073
  extensions,
5002
5074
  findType: (typeId) => typeMap.get(typeId),
5003
5075
  findTypeByName: (typeName) => typeNameMap.get(typeName),
5076
+ findTypeByBrand: (brand) => brandMap.get(brand),
5077
+ findTypeBySymbol: (symbol) => symbolMap.get(symbol),
5078
+ setSymbolMap: (map) => {
5079
+ symbolMap = map;
5080
+ },
5004
5081
  findConstraint: (constraintId) => constraintMap.get(constraintId),
5005
5082
  findConstraintTag: (tagName) => constraintTagMap.get((0, import_internal3.normalizeFormSpecTagName)(tagName)),
5006
5083
  findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
@@ -5008,6 +5085,10 @@ function createExtensionRegistry(extensions) {
5008
5085
  };
5009
5086
  }
5010
5087
 
5088
+ // src/extensions/symbol-registry.ts
5089
+ var ts5 = __toESM(require("typescript"), 1);
5090
+ var path2 = __toESM(require("path"), 1);
5091
+
5011
5092
  // src/ui-schema/schema.ts
5012
5093
  var import_zod = require("zod");
5013
5094
  var jsonPointerSchema = import_zod.z.string();
@@ -5216,7 +5297,10 @@ function irElementsToUiSchema(elements, fieldNameMap, parentRule) {
5216
5297
  break;
5217
5298
  }
5218
5299
  case "conditional": {
5219
- const newRule = createShowRule(fieldNameMap.get(element.fieldName) ?? element.fieldName, element.value);
5300
+ const newRule = createShowRule(
5301
+ fieldNameMap.get(element.fieldName) ?? element.fieldName,
5302
+ element.value
5303
+ );
5220
5304
  const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
5221
5305
  const childElements = irElementsToUiSchema(element.elements, fieldNameMap, combinedRule);
5222
5306
  result.push(...childElements);
@@ -5393,6 +5477,19 @@ ${lines.map((line) => `- ${line}`).join("\n")}`;
5393
5477
  function formatLocation(location) {
5394
5478
  return `${location.file}:${String(location.line)}:${String(location.column)}`;
5395
5479
  }
5480
+ function resolveStaticOptions(options) {
5481
+ const legacyRegistry = options.extensionRegistry;
5482
+ const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
5483
+ return {
5484
+ extensionRegistry: legacyRegistry ?? configRegistry,
5485
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5486
+ vendorPrefix: options.vendorPrefix ?? options.config?.vendorPrefix,
5487
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5488
+ enumSerialization: options.enumSerialization ?? options.config?.enumSerialization,
5489
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5490
+ metadata: options.metadata ?? options.config?.metadata
5491
+ };
5492
+ }
5396
5493
 
5397
5494
  // src/generators/method-schema.ts
5398
5495
  var import_internals6 = require("@formspec/core/internals");
@@ -5537,6 +5634,7 @@ function collectFormSpecReferences(methods) {
5537
5634
  generateJsonSchemaFromIR,
5538
5635
  generateMethodSchemas,
5539
5636
  generateUiSchemaFromIR,
5637
+ resolveStaticOptions,
5540
5638
  validateIR
5541
5639
  });
5542
5640
  //# sourceMappingURL=internals.cjs.map