@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
package/dist/cli.js CHANGED
@@ -243,7 +243,9 @@ function resolveTypeNodeMetadata(type, options) {
243
243
  case "object":
244
244
  return {
245
245
  ...type,
246
- properties: type.properties.map((property) => resolveObjectPropertyMetadata(property, options))
246
+ properties: type.properties.map(
247
+ (property) => resolveObjectPropertyMetadata(property, options)
248
+ )
247
249
  };
248
250
  case "record":
249
251
  return {
@@ -1721,10 +1723,7 @@ function generateJsonSchema(form, options) {
1721
1723
  const metadata = options?.metadata;
1722
1724
  const vendorPrefix = options?.vendorPrefix;
1723
1725
  const enumSerialization = options?.enumSerialization;
1724
- const ir = canonicalizeChainDSL(
1725
- form,
1726
- metadata !== void 0 ? { metadata } : void 0
1727
- );
1726
+ const ir = canonicalizeChainDSL(form, metadata !== void 0 ? { metadata } : void 0);
1728
1727
  const internalOptions = vendorPrefix === void 0 && enumSerialization === void 0 ? void 0 : {
1729
1728
  ...vendorPrefix !== void 0 && { vendorPrefix },
1730
1729
  ...enumSerialization !== void 0 && { enumSerialization }
@@ -1953,7 +1952,10 @@ function irElementsToUiSchema(elements, fieldNameMap, parentRule) {
1953
1952
  break;
1954
1953
  }
1955
1954
  case "conditional": {
1956
- const newRule = createShowRule(fieldNameMap.get(element.fieldName) ?? element.fieldName, element.value);
1955
+ const newRule = createShowRule(
1956
+ fieldNameMap.get(element.fieldName) ?? element.fieldName,
1957
+ element.value
1958
+ );
1957
1959
  const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
1958
1960
  const childElements = irElementsToUiSchema(element.elements, fieldNameMap, combinedRule);
1959
1961
  result.push(...childElements);
@@ -2044,8 +2046,10 @@ function buildConstraintTagSources(extensions) {
2044
2046
  }
2045
2047
  function createExtensionRegistry(extensions) {
2046
2048
  const reservedTagSources = buildConstraintTagSources(extensions);
2049
+ let symbolMap = /* @__PURE__ */ new Map();
2047
2050
  const typeMap = /* @__PURE__ */ new Map();
2048
2051
  const typeNameMap = /* @__PURE__ */ new Map();
2052
+ const brandMap = /* @__PURE__ */ new Map();
2049
2053
  const constraintMap = /* @__PURE__ */ new Map();
2050
2054
  const constraintTagMap = /* @__PURE__ */ new Map();
2051
2055
  const builtinBroadeningMap = /* @__PURE__ */ new Map();
@@ -2069,6 +2073,20 @@ function createExtensionRegistry(extensions) {
2069
2073
  registration: type
2070
2074
  });
2071
2075
  }
2076
+ if (type.brand !== void 0) {
2077
+ if (type.brand === "__integerBrand") {
2078
+ throw new Error(
2079
+ `Brand "__integerBrand" is reserved for the builtin Integer type and cannot be registered by extensions`
2080
+ );
2081
+ }
2082
+ if (brandMap.has(type.brand)) {
2083
+ throw new Error(`Duplicate custom type brand: "${type.brand}"`);
2084
+ }
2085
+ brandMap.set(type.brand, {
2086
+ extensionId: ext.extensionId,
2087
+ registration: type
2088
+ });
2089
+ }
2072
2090
  if (type.builtinConstraintBroadenings !== void 0) {
2073
2091
  for (const broadening of type.builtinConstraintBroadenings) {
2074
2092
  const key = `${qualifiedId}:${broadening.tagName}`;
@@ -2138,7 +2156,10 @@ function createExtensionRegistry(extensions) {
2138
2156
  `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
2139
2157
  );
2140
2158
  }
2141
- if (Object.hasOwn(BUILTIN_CONSTRAINT_DEFINITIONS, normalizeConstraintTagName(canonicalTagName))) {
2159
+ if (Object.hasOwn(
2160
+ BUILTIN_CONSTRAINT_DEFINITIONS,
2161
+ normalizeConstraintTagName(canonicalTagName)
2162
+ )) {
2142
2163
  throw new Error(
2143
2164
  `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${normalizeConstraintTagName(canonicalTagName)}".`
2144
2165
  );
@@ -2159,6 +2180,11 @@ function createExtensionRegistry(extensions) {
2159
2180
  extensions,
2160
2181
  findType: (typeId) => typeMap.get(typeId),
2161
2182
  findTypeByName: (typeName) => typeNameMap.get(typeName),
2183
+ findTypeByBrand: (brand) => brandMap.get(brand),
2184
+ findTypeBySymbol: (symbol) => symbolMap.get(symbol),
2185
+ setSymbolMap: (map) => {
2186
+ symbolMap = map;
2187
+ },
2162
2188
  findConstraint: (constraintId) => constraintMap.get(constraintId),
2163
2189
  findConstraintTag: (tagName) => constraintTagMap.get(normalizeFormSpecTagName(tagName)),
2164
2190
  findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
@@ -3063,30 +3089,70 @@ function isObjectType(type) {
3063
3089
  function isIntersectionType(type) {
3064
3090
  return !!(type.flags & ts3.TypeFlags.Intersection);
3065
3091
  }
3092
+ function collectBrandIdentifiers(type) {
3093
+ if (!type.isIntersection()) {
3094
+ return [];
3095
+ }
3096
+ const brands = [];
3097
+ for (const prop of type.getProperties()) {
3098
+ const decl = prop.valueDeclaration ?? prop.declarations?.[0];
3099
+ if (decl === void 0) continue;
3100
+ if (!ts3.isPropertySignature(decl) && !ts3.isPropertyDeclaration(decl)) continue;
3101
+ if (!ts3.isComputedPropertyName(decl.name)) continue;
3102
+ if (!ts3.isIdentifier(decl.name.expression)) continue;
3103
+ brands.push(decl.name.expression.text);
3104
+ }
3105
+ return brands;
3106
+ }
3107
+ function resolveCanonicalSymbol(type, checker) {
3108
+ const raw = type.aliasSymbol ?? type.getSymbol();
3109
+ if (raw === void 0) return void 0;
3110
+ return raw.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
3111
+ }
3112
+ function resolveSymbolBasedCustomType(type, extensionRegistry, checker) {
3113
+ if (extensionRegistry === void 0) {
3114
+ return null;
3115
+ }
3116
+ const canonical = resolveCanonicalSymbol(type, checker);
3117
+ if (canonical === void 0) {
3118
+ return null;
3119
+ }
3120
+ const registration = extensionRegistry.findTypeBySymbol(canonical);
3121
+ if (registration === void 0) {
3122
+ return null;
3123
+ }
3124
+ return {
3125
+ kind: "custom",
3126
+ typeId: `${registration.extensionId}/${registration.registration.typeName}`,
3127
+ payload: null
3128
+ };
3129
+ }
3066
3130
  function isIntegerBrandedType(type) {
3067
3131
  if (!type.isIntersection()) {
3068
3132
  return false;
3069
3133
  }
3070
- const hasNumberBase = type.types.some(
3071
- (member) => !!(member.flags & ts3.TypeFlags.Number)
3072
- );
3134
+ const hasNumberBase = type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number));
3073
3135
  if (!hasNumberBase) {
3074
3136
  return false;
3075
3137
  }
3076
- return type.getProperties().some((prop) => {
3077
- const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
3078
- if (declaration === void 0) {
3079
- return false;
3080
- }
3081
- if (!ts3.isPropertySignature(declaration) && !ts3.isPropertyDeclaration(declaration)) {
3082
- return false;
3083
- }
3084
- const name = declaration.name;
3085
- if (!ts3.isComputedPropertyName(name)) {
3086
- return false;
3138
+ return collectBrandIdentifiers(type).includes("__integerBrand");
3139
+ }
3140
+ function resolveBrandedCustomType(type, extensionRegistry) {
3141
+ if (extensionRegistry === void 0) {
3142
+ return null;
3143
+ }
3144
+ for (const brand of collectBrandIdentifiers(type)) {
3145
+ const registration = extensionRegistry.findTypeByBrand(brand);
3146
+ if (registration === void 0) {
3147
+ continue;
3087
3148
  }
3088
- return ts3.isIdentifier(name.expression) && name.expression.text === "__integerBrand";
3089
- });
3149
+ return {
3150
+ kind: "custom",
3151
+ typeId: `${registration.extensionId}/${registration.registration.typeName}`,
3152
+ payload: null
3153
+ };
3154
+ }
3155
+ return null;
3090
3156
  }
3091
3157
  function isResolvableObjectLikeAliasTypeNode(typeNode) {
3092
3158
  if (ts3.isParenthesizedTypeNode(typeNode)) {
@@ -4194,6 +4260,14 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4194
4260
  if (customType) {
4195
4261
  return customType;
4196
4262
  }
4263
+ const symbolCustomType = resolveSymbolBasedCustomType(type, extensionRegistry, checker);
4264
+ if (symbolCustomType) {
4265
+ return symbolCustomType;
4266
+ }
4267
+ const brandedCustomType = resolveBrandedCustomType(type, extensionRegistry);
4268
+ if (brandedCustomType) {
4269
+ return brandedCustomType;
4270
+ }
4197
4271
  const primitiveAlias = tryResolveNamedPrimitiveAlias(
4198
4272
  type,
4199
4273
  checker,
@@ -5154,7 +5228,7 @@ function createProgramContextFromProgram(program, filePath) {
5154
5228
  sourceFile
5155
5229
  };
5156
5230
  }
5157
- function createProgramContext(filePath) {
5231
+ function createProgramContext(filePath, additionalFiles) {
5158
5232
  const absolutePath = path.resolve(filePath);
5159
5233
  const fileDir = path.dirname(absolutePath);
5160
5234
  const configPath = ts4.findConfigFile(fileDir, ts4.sys.fileExists.bind(ts4.sys), "tsconfig.json");
@@ -5177,7 +5251,8 @@ function createProgramContext(filePath) {
5177
5251
  throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
5178
5252
  }
5179
5253
  compilerOptions = parsed.options;
5180
- fileNames = parsed.fileNames.includes(absolutePath) ? parsed.fileNames : [...parsed.fileNames, absolutePath];
5254
+ const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
5255
+ fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
5181
5256
  } else {
5182
5257
  compilerOptions = {
5183
5258
  target: ts4.ScriptTarget.ES2022,
@@ -5187,7 +5262,8 @@ function createProgramContext(filePath) {
5187
5262
  skipLibCheck: true,
5188
5263
  declaration: true
5189
5264
  };
5190
- fileNames = [absolutePath];
5265
+ const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
5266
+ fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
5191
5267
  }
5192
5268
  const program = ts4.createProgram(fileNames, compilerOptions);
5193
5269
  const sourceFile = program.getSourceFile(absolutePath);
@@ -5497,10 +5573,139 @@ var init_program = __esm({
5497
5573
  }
5498
5574
  });
5499
5575
 
5576
+ // src/extensions/symbol-registry.ts
5577
+ import * as ts5 from "typescript";
5578
+ import * as path2 from "path";
5579
+ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistry) {
5580
+ const symbolMap = /* @__PURE__ */ new Map();
5581
+ const normalizedPath = path2.resolve(configPath);
5582
+ const configFile = program.getSourceFile(normalizedPath);
5583
+ if (configFile === void 0) {
5584
+ return symbolMap;
5585
+ }
5586
+ function visit(node) {
5587
+ if (ts5.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
5588
+ processDefineCustomTypeCall(node);
5589
+ }
5590
+ ts5.forEachChild(node, visit);
5591
+ }
5592
+ function processDefineCustomTypeCall(call) {
5593
+ const typeArgNode = call.typeArguments?.[0];
5594
+ if (typeArgNode === void 0) {
5595
+ return;
5596
+ }
5597
+ const resolvedType = checker.getTypeFromTypeNode(typeArgNode);
5598
+ const canonical = resolveCanonicalSymbol2(resolvedType, checker);
5599
+ if (canonical === void 0) {
5600
+ return;
5601
+ }
5602
+ const typeName = extractTypeNameFromCallArg(call);
5603
+ if (typeName === null) {
5604
+ return;
5605
+ }
5606
+ let entry;
5607
+ const extensionId = extractEnclosingExtensionId(call, checker);
5608
+ if (extensionId !== null) {
5609
+ const reg = extensionRegistry.findType(`${extensionId}/${typeName}`);
5610
+ if (reg !== void 0) {
5611
+ entry = { extensionId, registration: reg };
5612
+ }
5613
+ }
5614
+ entry ??= findRegistrationByTypeName(extensionRegistry, typeName);
5615
+ if (entry === void 0) {
5616
+ return;
5617
+ }
5618
+ symbolMap.set(canonical, entry);
5619
+ }
5620
+ visit(configFile);
5621
+ return symbolMap;
5622
+ }
5623
+ function isDefineCustomTypeCall(node, checker) {
5624
+ if (node.typeArguments === void 0 || node.typeArguments.length === 0) return false;
5625
+ const callSymbol = checker.getSymbolAtLocation(node.expression);
5626
+ if (callSymbol !== void 0) {
5627
+ const resolved = callSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5628
+ const decl = resolved.declarations?.[0];
5629
+ if (decl !== void 0) {
5630
+ const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
5631
+ return resolved.name === "defineCustomType" && // Match whether in node_modules/@formspec/core or monorepo packages/core.
5632
+ (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5633
+ }
5634
+ }
5635
+ return ts5.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
5636
+ }
5637
+ function resolveCanonicalSymbol2(type, checker) {
5638
+ const raw = type.aliasSymbol ?? type.getSymbol();
5639
+ if (raw === void 0) return void 0;
5640
+ return raw.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
5641
+ }
5642
+ function extractTypeNameFromCallArg(call) {
5643
+ const arg = call.arguments[0];
5644
+ if (arg === void 0 || !ts5.isObjectLiteralExpression(arg)) {
5645
+ return null;
5646
+ }
5647
+ const typeNameProp = arg.properties.find(
5648
+ (p) => ts5.isPropertyAssignment(p) && ts5.isIdentifier(p.name) && p.name.text === "typeName"
5649
+ );
5650
+ if (typeNameProp === void 0 || !ts5.isStringLiteral(typeNameProp.initializer)) {
5651
+ return null;
5652
+ }
5653
+ return typeNameProp.initializer.text;
5654
+ }
5655
+ function extractEnclosingExtensionId(call, checker) {
5656
+ for (let node = call.parent; !ts5.isSourceFile(node); node = node.parent) {
5657
+ if (ts5.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
5658
+ return extractExtensionIdFromCallArg(node);
5659
+ }
5660
+ }
5661
+ return null;
5662
+ }
5663
+ function isDefineExtensionCall(node, checker) {
5664
+ const callSymbol = checker.getSymbolAtLocation(node.expression);
5665
+ if (callSymbol !== void 0) {
5666
+ const resolved = callSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5667
+ const decl = resolved.declarations?.[0];
5668
+ if (decl !== void 0) {
5669
+ const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
5670
+ return resolved.name === "defineExtension" && (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5671
+ }
5672
+ }
5673
+ return ts5.isIdentifier(node.expression) && node.expression.text === "defineExtension";
5674
+ }
5675
+ function extractExtensionIdFromCallArg(call) {
5676
+ const arg = call.arguments[0];
5677
+ if (arg === void 0 || !ts5.isObjectLiteralExpression(arg)) {
5678
+ return null;
5679
+ }
5680
+ const prop = arg.properties.find(
5681
+ (p) => ts5.isPropertyAssignment(p) && ts5.isIdentifier(p.name) && p.name.text === "extensionId"
5682
+ );
5683
+ if (prop === void 0 || !ts5.isStringLiteral(prop.initializer)) {
5684
+ return null;
5685
+ }
5686
+ return prop.initializer.text;
5687
+ }
5688
+ function findRegistrationByTypeName(registry, typeName) {
5689
+ for (const ext of registry.extensions) {
5690
+ if (ext.types === void 0) {
5691
+ continue;
5692
+ }
5693
+ for (const type of ext.types) {
5694
+ if (type.typeName === typeName) {
5695
+ return { extensionId: ext.extensionId, registration: type };
5696
+ }
5697
+ }
5698
+ }
5699
+ return void 0;
5700
+ }
5701
+ var init_symbol_registry = __esm({
5702
+ "src/extensions/symbol-registry.ts"() {
5703
+ "use strict";
5704
+ }
5705
+ });
5706
+
5500
5707
  // src/validate/constraint-validator.ts
5501
- import {
5502
- analyzeConstraintTargets
5503
- } from "@formspec/analysis/internal";
5708
+ import { analyzeConstraintTargets } from "@formspec/analysis/internal";
5504
5709
  function validateFieldNode(ctx, field) {
5505
5710
  const analysis = analyzeConstraintTargets(
5506
5711
  field.name,
@@ -5586,7 +5791,7 @@ var init_validate = __esm({
5586
5791
  });
5587
5792
 
5588
5793
  // src/generators/class-schema.ts
5589
- import * as ts5 from "typescript";
5794
+ import * as ts6 from "typescript";
5590
5795
  function generateClassSchemas(analysis, source, options) {
5591
5796
  const result = generateClassSchemasDetailed(analysis, source, options);
5592
5797
  if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
@@ -5645,7 +5850,8 @@ function formatLocation(location) {
5645
5850
  return `${location.file}:${String(location.line)}:${String(location.column)}`;
5646
5851
  }
5647
5852
  function generateSchemasFromClass(options) {
5648
- const ctx = createProgramContext(options.filePath);
5853
+ const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
5854
+ const ctx = createProgramContext(options.filePath, additionalFiles);
5649
5855
  const classDecl = findClassByName(ctx.sourceFile, options.className);
5650
5856
  if (!classDecl) {
5651
5857
  throw new Error(`Class "${options.className}" not found in ${options.filePath}`);
@@ -5710,7 +5916,8 @@ function generateSchemasDetailed(options) {
5710
5916
  function generateSchemasDetailedInternal(options) {
5711
5917
  let ctx;
5712
5918
  try {
5713
- ctx = createProgramContext(options.filePath);
5919
+ const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
5920
+ ctx = createProgramContext(options.filePath, additionalFiles);
5714
5921
  } catch (error) {
5715
5922
  return {
5716
5923
  ok: false,
@@ -5749,13 +5956,16 @@ function generateSchemasFromProgramDetailedInternal(options) {
5749
5956
  }
5750
5957
  function generateSchemasBatch(options) {
5751
5958
  const contextCache = /* @__PURE__ */ new Map();
5959
+ const resolved = resolveOptions(options);
5960
+ let symbolMapProgram;
5752
5961
  return options.targets.map((target) => {
5753
5962
  let ctx;
5754
5963
  try {
5755
- const cacheKey = ts5.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
5964
+ const cacheKey = ts6.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
5756
5965
  const cachedContext = contextCache.get(cacheKey);
5757
5966
  if (cachedContext === void 0) {
5758
- ctx = createProgramContext(target.filePath);
5967
+ const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
5968
+ ctx = createProgramContext(target.filePath, additionalFiles);
5759
5969
  contextCache.set(cacheKey, ctx);
5760
5970
  } else {
5761
5971
  ctx = cachedContext;
@@ -5766,9 +5976,25 @@ function generateSchemasBatch(options) {
5766
5976
  diagnostics: [createProgramContextFailureDiagnostic(target.filePath, error)]
5767
5977
  });
5768
5978
  }
5979
+ if (options.configPath !== void 0 && resolved.extensionRegistry !== void 0 && isMutableRegistry(resolved.extensionRegistry) && ctx.program !== symbolMapProgram) {
5980
+ const symbolMap = buildSymbolMapFromConfig(
5981
+ options.configPath,
5982
+ ctx.program,
5983
+ ctx.checker,
5984
+ resolved.extensionRegistry
5985
+ );
5986
+ resolved.extensionRegistry.setSymbolMap(symbolMap);
5987
+ symbolMapProgram = ctx.program;
5988
+ }
5769
5989
  return withTarget(
5770
5990
  target,
5771
- generateSchemasFromDetailedProgramContext(ctx, target.filePath, target.typeName, options)
5991
+ generateSchemasFromResolvedOptions(
5992
+ ctx,
5993
+ target.filePath,
5994
+ target.typeName,
5995
+ resolved,
5996
+ options.discriminator
5997
+ )
5772
5998
  );
5773
5999
  });
5774
6000
  }
@@ -5789,11 +6015,32 @@ function generateSchemasBatchFromProgram(options) {
5789
6015
  );
5790
6016
  });
5791
6017
  }
6018
+ function isMutableRegistry(reg) {
6019
+ return "setSymbolMap" in reg && typeof reg.setSymbolMap === "function";
6020
+ }
6021
+ function resolveStaticOptions(options) {
6022
+ const legacyRegistry = options.extensionRegistry;
6023
+ const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6024
+ return {
6025
+ extensionRegistry: legacyRegistry ?? configRegistry,
6026
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6027
+ vendorPrefix: options.vendorPrefix ?? options.config?.vendorPrefix,
6028
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6029
+ enumSerialization: options.enumSerialization ?? options.config?.enumSerialization,
6030
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6031
+ metadata: options.metadata ?? options.config?.metadata
6032
+ };
6033
+ }
5792
6034
  function resolveOptions(options) {
5793
6035
  const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6036
+ const legacyRegistry = options.extensionRegistry;
5794
6037
  return {
5795
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5796
- extensionRegistry: options.extensionRegistry ?? configRegistry,
6038
+ // When the caller provides the deprecated extensionRegistry field directly,
6039
+ // it is typed as the read-only ExtensionRegistry interface. We cast here
6040
+ // because the legacy path was introduced before MutableExtensionRegistry was
6041
+ // split out; callers using createExtensionRegistry() always get a mutable
6042
+ // registry, and this cast is safe for all registries produced by this module.
6043
+ extensionRegistry: legacyRegistry ?? configRegistry,
5797
6044
  // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5798
6045
  vendorPrefix: options.vendorPrefix ?? options.config?.vendorPrefix,
5799
6046
  // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
@@ -5804,13 +6051,31 @@ function resolveOptions(options) {
5804
6051
  }
5805
6052
  function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, options) {
5806
6053
  const resolved = resolveOptions(options);
6054
+ if (options.configPath !== void 0 && resolved.extensionRegistry !== void 0 && isMutableRegistry(resolved.extensionRegistry)) {
6055
+ const symbolMap = buildSymbolMapFromConfig(
6056
+ options.configPath,
6057
+ ctx.program,
6058
+ ctx.checker,
6059
+ resolved.extensionRegistry
6060
+ );
6061
+ resolved.extensionRegistry.setSymbolMap(symbolMap);
6062
+ }
6063
+ return generateSchemasFromResolvedOptions(
6064
+ ctx,
6065
+ filePath,
6066
+ typeName,
6067
+ resolved,
6068
+ options.discriminator
6069
+ );
6070
+ }
6071
+ function generateSchemasFromResolvedOptions(ctx, filePath, typeName, resolved, discriminator) {
5807
6072
  const analysisResult = analyzeNamedTypeToIRFromProgramContextDetailed(
5808
6073
  ctx,
5809
6074
  filePath,
5810
6075
  typeName,
5811
6076
  resolved.extensionRegistry,
5812
6077
  resolved.metadata,
5813
- options.discriminator
6078
+ discriminator
5814
6079
  );
5815
6080
  if (!analysisResult.ok) {
5816
6081
  return {
@@ -5858,13 +6123,14 @@ var init_class_schema = __esm({
5858
6123
  init_canonicalize();
5859
6124
  init_ir_generator();
5860
6125
  init_extensions();
6126
+ init_symbol_registry();
5861
6127
  init_ir_generator2();
5862
6128
  init_validate();
5863
6129
  }
5864
6130
  });
5865
6131
 
5866
6132
  // src/static-build.ts
5867
- import * as ts6 from "typescript";
6133
+ import * as ts7 from "typescript";
5868
6134
  function toStaticBuildContext(context) {
5869
6135
  return context;
5870
6136
  }
@@ -5879,7 +6145,7 @@ function getModuleSymbol(context) {
5879
6145
  return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
5880
6146
  }
5881
6147
  function isSchemaSourceDeclaration(declaration) {
5882
- return ts6.isClassDeclaration(declaration) || ts6.isInterfaceDeclaration(declaration) || ts6.isTypeAliasDeclaration(declaration);
6148
+ return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
5883
6149
  }
5884
6150
  function resolveModuleExport(context, exportName = "default") {
5885
6151
  const moduleSymbol = getModuleSymbol(context);
@@ -5890,7 +6156,7 @@ function resolveModuleExport(context, exportName = "default") {
5890
6156
  if (exportSymbol === null) {
5891
6157
  return null;
5892
6158
  }
5893
- return exportSymbol.flags & ts6.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
6159
+ return exportSymbol.flags & ts7.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
5894
6160
  }
5895
6161
  function resolveModuleExportDeclaration(context, exportName = "default") {
5896
6162
  return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
@@ -5903,7 +6169,7 @@ var init_static_build = __esm({
5903
6169
  });
5904
6170
 
5905
6171
  // src/generators/discovered-schema.ts
5906
- import * as ts7 from "typescript";
6172
+ import * as ts8 from "typescript";
5907
6173
  import { analyzeMetadataForNodeWithChecker as analyzeMetadataForNodeWithChecker2 } from "@formspec/analysis/internal";
5908
6174
  import { IR_VERSION as IR_VERSION3 } from "@formspec/core/internals";
5909
6175
  function toDiscoveredTypeSchemas(result, resolvedMetadata) {
@@ -5913,17 +6179,17 @@ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
5913
6179
  };
5914
6180
  }
5915
6181
  function isNamedTypeDeclaration(declaration) {
5916
- return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
6182
+ return ts8.isClassDeclaration(declaration) || ts8.isInterfaceDeclaration(declaration) || ts8.isTypeAliasDeclaration(declaration);
5917
6183
  }
5918
6184
  function hasConcreteTypeArguments(type, checker) {
5919
6185
  if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
5920
6186
  return true;
5921
6187
  }
5922
- if ((type.flags & ts7.TypeFlags.Object) === 0) {
6188
+ if ((type.flags & ts8.TypeFlags.Object) === 0) {
5923
6189
  return false;
5924
6190
  }
5925
6191
  const objectType = type;
5926
- if ((objectType.objectFlags & ts7.ObjectFlags.Reference) === 0) {
6192
+ if ((objectType.objectFlags & ts8.ObjectFlags.Reference) === 0) {
5927
6193
  return false;
5928
6194
  }
5929
6195
  return checker.getTypeArguments(objectType).length > 0;
@@ -5936,13 +6202,13 @@ function getNamedTypeDeclaration2(type) {
5936
6202
  return declaration;
5937
6203
  }
5938
6204
  }
5939
- const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts7.isTypeAliasDeclaration);
6205
+ const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts8.isTypeAliasDeclaration);
5940
6206
  return aliasDeclaration;
5941
6207
  }
5942
6208
  function getFallbackName(sourceNode, fallback = "AnonymousType") {
5943
6209
  if (sourceNode !== void 0 && "name" in sourceNode) {
5944
6210
  const namedNode = sourceNode;
5945
- if (namedNode.name !== void 0 && ts7.isIdentifier(namedNode.name)) {
6211
+ if (namedNode.name !== void 0 && ts8.isIdentifier(namedNode.name)) {
5946
6212
  return namedNode.name.text;
5947
6213
  }
5948
6214
  }
@@ -5978,10 +6244,9 @@ function omitApiName(metadata) {
5978
6244
  const { apiName: _apiName, ...rest } = metadata;
5979
6245
  return Object.keys(rest).length > 0 ? rest : void 0;
5980
6246
  }
5981
- function enforceRequiredMetadata(metadata, declarationKind, logicalName, options) {
6247
+ function enforceRequiredMetadata(metadata, declarationKind, logicalName, metadataPolicy) {
5982
6248
  const declarationPolicy = getDeclarationMetadataPolicy(
5983
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5984
- normalizeMetadataPolicy(options.metadata),
6249
+ normalizeMetadataPolicy(metadataPolicy),
5985
6250
  declarationKind
5986
6251
  );
5987
6252
  if (metadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
@@ -6026,7 +6291,7 @@ function describeRootType(rootType, typeRegistry, fallbackName) {
6026
6291
  type: definition.type
6027
6292
  };
6028
6293
  }
6029
- function toStandaloneJsonSchema(root, typeRegistry, options) {
6294
+ function toStandaloneJsonSchema(root, typeRegistry, resolved) {
6030
6295
  const syntheticFieldMetadata = omitApiName(root.metadata);
6031
6296
  const syntheticField = {
6032
6297
  kind: "field",
@@ -6055,23 +6320,16 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6055
6320
  provenance: syntheticField.provenance
6056
6321
  },
6057
6322
  {
6058
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6059
- policy: normalizeMetadataPolicy(options?.metadata),
6323
+ policy: normalizeMetadataPolicy(resolved?.metadata),
6060
6324
  surface: "tsdoc",
6061
6325
  rootLogicalName: root.name
6062
6326
  }
6063
6327
  );
6064
- const schema = generateJsonSchemaFromIR(
6065
- ir,
6066
- {
6067
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6068
- extensionRegistry: options?.extensionRegistry,
6069
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6070
- enumSerialization: options?.enumSerialization,
6071
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6072
- vendorPrefix: options?.vendorPrefix
6073
- }
6074
- );
6328
+ const schema = generateJsonSchemaFromIR(ir, {
6329
+ extensionRegistry: resolved?.extensionRegistry,
6330
+ enumSerialization: resolved?.enumSerialization,
6331
+ vendorPrefix: resolved?.vendorPrefix
6332
+ });
6075
6333
  const result = schema.properties?.["__result"];
6076
6334
  if (result === void 0) {
6077
6335
  throw new Error("FormSpec failed to extract the standalone schema root from the synthetic IR.");
@@ -6088,26 +6346,23 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6088
6346
  $defs: schema.$defs
6089
6347
  };
6090
6348
  }
6091
- function generateSchemasFromAnalysis(analysis, filePath, options) {
6349
+ function generateSchemasFromAnalysis(analysis, filePath, resolved) {
6092
6350
  return toDiscoveredTypeSchemas(
6093
6351
  generateClassSchemas(
6094
6352
  analysis,
6095
6353
  { file: filePath },
6096
6354
  {
6097
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6098
- extensionRegistry: options?.extensionRegistry,
6099
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6100
- enumSerialization: options?.enumSerialization,
6101
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6102
- metadata: options?.metadata,
6103
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6104
- vendorPrefix: options?.vendorPrefix
6355
+ extensionRegistry: resolved?.extensionRegistry,
6356
+ enumSerialization: resolved?.enumSerialization,
6357
+ metadata: resolved?.metadata,
6358
+ vendorPrefix: resolved?.vendorPrefix
6105
6359
  }
6106
6360
  ),
6107
6361
  analysis.metadata
6108
6362
  );
6109
6363
  }
6110
6364
  function generateSchemasFromResolvedType(options, skipNamedDeclaration = false, rootOverride) {
6365
+ const resolved = resolveStaticOptions(options);
6111
6366
  const namedDeclaration = skipNamedDeclaration || hasConcreteTypeArguments(options.type, options.context.checker) ? void 0 : getNamedTypeDeclaration2(options.type);
6112
6367
  if (namedDeclaration !== void 0) {
6113
6368
  return generateSchemasFromDeclaration({
@@ -6125,10 +6380,8 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6125
6380
  typeRegistry,
6126
6381
  /* @__PURE__ */ new Set(),
6127
6382
  options.sourceNode,
6128
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6129
- createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
6130
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6131
- options.extensionRegistry,
6383
+ createAnalyzerMetadataPolicy(resolved.metadata, options.discriminator),
6384
+ resolved.extensionRegistry,
6132
6385
  diagnostics
6133
6386
  );
6134
6387
  if (diagnostics.length > 0) {
@@ -6159,71 +6412,64 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6159
6412
  root.annotations
6160
6413
  ),
6161
6414
  filePath,
6162
- options
6415
+ resolved
6163
6416
  );
6164
6417
  }
6165
6418
  return {
6166
- jsonSchema: toStandaloneJsonSchema(root, typeRegistry, options),
6419
+ jsonSchema: toStandaloneJsonSchema(root, typeRegistry, resolved),
6167
6420
  uiSchema: null,
6168
6421
  ...root.metadata !== void 0 && { resolvedMetadata: root.metadata }
6169
6422
  };
6170
6423
  }
6171
6424
  function generateSchemasFromDeclaration(options) {
6172
6425
  const filePath = options.declaration.getSourceFile().fileName;
6173
- if (ts7.isClassDeclaration(options.declaration)) {
6426
+ const resolved = resolveStaticOptions(options);
6427
+ if (ts8.isClassDeclaration(options.declaration)) {
6174
6428
  return generateSchemasFromAnalysis(
6175
6429
  analyzeClassToIR(
6176
6430
  options.declaration,
6177
6431
  options.context.checker,
6178
6432
  filePath,
6179
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6180
- options.extensionRegistry,
6181
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6182
- options.metadata,
6433
+ resolved.extensionRegistry,
6434
+ resolved.metadata,
6183
6435
  options.discriminator
6184
6436
  ),
6185
6437
  filePath,
6186
- options
6438
+ resolved
6187
6439
  );
6188
6440
  }
6189
- if (ts7.isInterfaceDeclaration(options.declaration)) {
6441
+ if (ts8.isInterfaceDeclaration(options.declaration)) {
6190
6442
  return generateSchemasFromAnalysis(
6191
6443
  analyzeInterfaceToIR(
6192
6444
  options.declaration,
6193
6445
  options.context.checker,
6194
6446
  filePath,
6195
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6196
- options.extensionRegistry,
6197
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6198
- options.metadata,
6447
+ resolved.extensionRegistry,
6448
+ resolved.metadata,
6199
6449
  options.discriminator
6200
6450
  ),
6201
6451
  filePath,
6202
- options
6452
+ resolved
6203
6453
  );
6204
6454
  }
6205
- if (ts7.isTypeAliasDeclaration(options.declaration)) {
6455
+ if (ts8.isTypeAliasDeclaration(options.declaration)) {
6206
6456
  const analyzedAlias = analyzeTypeAliasToIR(
6207
6457
  options.declaration,
6208
6458
  options.context.checker,
6209
6459
  filePath,
6210
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6211
- options.extensionRegistry,
6212
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6213
- options.metadata,
6460
+ resolved.extensionRegistry,
6461
+ resolved.metadata,
6214
6462
  options.discriminator
6215
6463
  );
6216
6464
  if (analyzedAlias.ok) {
6217
- return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
6465
+ return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, resolved);
6218
6466
  }
6219
6467
  const aliasRootInfo = analyzeDeclarationRootInfo(
6220
6468
  options.declaration,
6221
6469
  options.context.checker,
6222
6470
  filePath,
6223
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6224
- options.extensionRegistry,
6225
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6226
- options.metadata
6471
+ resolved.extensionRegistry,
6472
+ resolved.metadata
6227
6473
  );
6228
6474
  if (aliasRootInfo.diagnostics.length > 0) {
6229
6475
  const diagnosticDetails = aliasRootInfo.diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ");
@@ -6265,7 +6511,7 @@ function generateSchemasFromReturnType(options) {
6265
6511
  const returnType = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
6266
6512
  const type = unwrapPromiseType(options.context.checker, returnType);
6267
6513
  const sourceNode = type !== returnType ? unwrapPromiseTypeNode(options.declaration.type) ?? options.declaration.type ?? options.declaration : options.declaration.type ?? options.declaration;
6268
- const fallbackName = options.declaration.name !== void 0 && ts7.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
6514
+ const fallbackName = options.declaration.name !== void 0 && ts8.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
6269
6515
  return generateSchemasFromResolvedType({
6270
6516
  ...options,
6271
6517
  type,
@@ -6274,20 +6520,19 @@ function generateSchemasFromReturnType(options) {
6274
6520
  });
6275
6521
  }
6276
6522
  function resolveDeclarationMetadata(options) {
6523
+ const resolved = resolveStaticOptions(options);
6277
6524
  const analysis = analyzeMetadataForNodeWithChecker2({
6278
6525
  checker: options.context.checker,
6279
6526
  node: options.declaration,
6280
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6281
- metadata: options.metadata,
6282
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6283
- extensions: options.extensionRegistry?.extensions,
6527
+ metadata: resolved.metadata,
6528
+ extensions: resolved.extensionRegistry?.extensions,
6284
6529
  buildContext: options.context
6285
6530
  });
6286
6531
  if (analysis === null) {
6287
6532
  return void 0;
6288
6533
  }
6289
6534
  const metadata = analysis.resolvedMetadata;
6290
- enforceRequiredMetadata(metadata, analysis.declarationKind, analysis.logicalName, options);
6535
+ enforceRequiredMetadata(metadata, analysis.declarationKind, analysis.logicalName, resolved.metadata);
6291
6536
  return metadata;
6292
6537
  }
6293
6538
  function unwrapPromiseType(checker, type) {
@@ -6300,14 +6545,14 @@ function unwrapPromiseTypeNode(typeNode) {
6300
6545
  if (typeNode === void 0) {
6301
6546
  return void 0;
6302
6547
  }
6303
- if (ts7.isParenthesizedTypeNode(typeNode)) {
6548
+ if (ts8.isParenthesizedTypeNode(typeNode)) {
6304
6549
  const unwrapped = unwrapPromiseTypeNode(typeNode.type);
6305
6550
  return unwrapped ?? typeNode;
6306
6551
  }
6307
6552
  return isPromiseTypeReferenceNode(typeNode) ? typeNode.typeArguments[0] : typeNode;
6308
6553
  }
6309
6554
  function isPromiseTypeReferenceNode(typeNode) {
6310
- return ts7.isTypeReferenceNode(typeNode) && ts7.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6555
+ return ts8.isTypeReferenceNode(typeNode) && ts8.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6311
6556
  }
6312
6557
  var init_discovered_schema = __esm({
6313
6558
  "src/generators/discovered-schema.ts"() {
@@ -6552,7 +6797,7 @@ __export(index_exports, {
6552
6797
  writeSchemas: () => writeSchemas
6553
6798
  });
6554
6799
  import * as fs from "fs";
6555
- import * as path2 from "path";
6800
+ import * as path3 from "path";
6556
6801
  function buildFormSchemas(form, options) {
6557
6802
  return {
6558
6803
  jsonSchema: generateJsonSchema(form, options),
@@ -6577,8 +6822,8 @@ function writeSchemas(form, options) {
6577
6822
  if (!fs.existsSync(outDir)) {
6578
6823
  fs.mkdirSync(outDir, { recursive: true });
6579
6824
  }
6580
- const jsonSchemaPath = path2.join(outDir, `${name}-schema.json`);
6581
- const uiSchemaPath = path2.join(outDir, `${name}-uischema.json`);
6825
+ const jsonSchemaPath = path3.join(outDir, `${name}-schema.json`);
6826
+ const uiSchemaPath = path3.join(outDir, `${name}-uischema.json`);
6582
6827
  fs.writeFileSync(jsonSchemaPath, JSON.stringify(jsonSchema, null, indent));
6583
6828
  fs.writeFileSync(uiSchemaPath, JSON.stringify(uiSchema2, null, indent));
6584
6829
  return { jsonSchemaPath, uiSchemaPath };
@@ -6605,7 +6850,7 @@ var init_index = __esm({
6605
6850
  });
6606
6851
 
6607
6852
  // src/cli.ts
6608
- import * as path3 from "path";
6853
+ import * as path4 from "path";
6609
6854
  import { pathToFileURL } from "url";
6610
6855
  function printHelp() {
6611
6856
  console.log(`
@@ -6694,7 +6939,7 @@ function parseArgs(args) {
6694
6939
  return null;
6695
6940
  }
6696
6941
  if (!name) {
6697
- name = path3.basename(inputFile, path3.extname(inputFile));
6942
+ name = path4.basename(inputFile, path4.extname(inputFile));
6698
6943
  }
6699
6944
  return { inputFile, outDir, name, enumSerialization };
6700
6945
  }
@@ -6705,7 +6950,7 @@ async function main() {
6705
6950
  process.exit(1);
6706
6951
  }
6707
6952
  const { inputFile, outDir, name, enumSerialization } = options;
6708
- const absoluteInput = path3.resolve(process.cwd(), inputFile);
6953
+ const absoluteInput = path4.resolve(process.cwd(), inputFile);
6709
6954
  try {
6710
6955
  const fileUrl = pathToFileURL(absoluteInput).href;
6711
6956
  const module = await import(fileUrl);