@formspec/build 0.1.0-alpha.49 → 0.1.0-alpha.50

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/dist/cli.cjs CHANGED
@@ -2292,6 +2292,134 @@ var init_schema2 = __esm({
2292
2292
  }
2293
2293
  });
2294
2294
 
2295
+ // src/extensions/ts-type-utils.ts
2296
+ function collectBrandIdentifiers(type) {
2297
+ if (!type.isIntersection()) {
2298
+ return [];
2299
+ }
2300
+ const brands = [];
2301
+ for (const prop of type.getProperties()) {
2302
+ const decl = prop.valueDeclaration ?? prop.declarations?.[0];
2303
+ if (decl === void 0) continue;
2304
+ if (!ts.isPropertySignature(decl) && !ts.isPropertyDeclaration(decl)) continue;
2305
+ if (!ts.isComputedPropertyName(decl.name)) continue;
2306
+ if (!ts.isIdentifier(decl.name.expression)) continue;
2307
+ brands.push(decl.name.expression.text);
2308
+ }
2309
+ return brands;
2310
+ }
2311
+ function resolveCanonicalSymbol(type, checker) {
2312
+ const raw = type.aliasSymbol ?? type.getSymbol();
2313
+ if (raw === void 0) return void 0;
2314
+ return raw.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
2315
+ }
2316
+ function extractTypeNodeFromSource(sourceNode) {
2317
+ if (ts.isPropertyDeclaration(sourceNode) || ts.isPropertySignature(sourceNode) || ts.isParameter(sourceNode) || ts.isTypeAliasDeclaration(sourceNode)) {
2318
+ return sourceNode.type;
2319
+ }
2320
+ if (ts.isTypeNode(sourceNode)) {
2321
+ return sourceNode;
2322
+ }
2323
+ return void 0;
2324
+ }
2325
+ function resolveAliasedSymbol(symbol, checker) {
2326
+ if (symbol === void 0) return void 0;
2327
+ return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
2328
+ }
2329
+ function getTypeAliasDeclarationFromTypeReference(typeNode, checker) {
2330
+ const symbol = checker.getSymbolAtLocation(typeNode.typeName);
2331
+ return resolveAliasedSymbol(symbol, checker)?.declarations?.find(ts.isTypeAliasDeclaration);
2332
+ }
2333
+ var ts;
2334
+ var init_ts_type_utils = __esm({
2335
+ "src/extensions/ts-type-utils.ts"() {
2336
+ "use strict";
2337
+ ts = __toESM(require("typescript"), 1);
2338
+ }
2339
+ });
2340
+
2341
+ // src/extensions/resolve-custom-type.ts
2342
+ function getTypeNodeRegistrationName(typeNode) {
2343
+ if (ts2.isTypeReferenceNode(typeNode)) {
2344
+ return ts2.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : typeNode.typeName.right.text;
2345
+ }
2346
+ if (ts2.isParenthesizedTypeNode(typeNode)) {
2347
+ return getTypeNodeRegistrationName(typeNode.type);
2348
+ }
2349
+ if (typeNode.kind === ts2.SyntaxKind.BigIntKeyword || typeNode.kind === ts2.SyntaxKind.StringKeyword || typeNode.kind === ts2.SyntaxKind.NumberKeyword || typeNode.kind === ts2.SyntaxKind.BooleanKeyword) {
2350
+ return typeNode.getText();
2351
+ }
2352
+ return null;
2353
+ }
2354
+ function resolveByNameFromTypeNode(typeNode, registry, checker) {
2355
+ if (ts2.isParenthesizedTypeNode(typeNode)) {
2356
+ return resolveByNameFromTypeNode(typeNode.type, registry, checker);
2357
+ }
2358
+ const typeName = getTypeNodeRegistrationName(typeNode);
2359
+ if (typeName !== null) {
2360
+ const byName = registry.findTypeByName(typeName);
2361
+ if (byName !== void 0) {
2362
+ return byName;
2363
+ }
2364
+ }
2365
+ if (ts2.isTypeReferenceNode(typeNode) && ts2.isIdentifier(typeNode.typeName)) {
2366
+ const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
2367
+ if (aliasDecl !== void 0) {
2368
+ return resolveByNameFromTypeNode(aliasDecl.type, registry, checker);
2369
+ }
2370
+ }
2371
+ return null;
2372
+ }
2373
+ function resolveCustomTypeFromTsType(type, checker, registry, sourceNode) {
2374
+ if (registry === void 0) {
2375
+ return null;
2376
+ }
2377
+ const stripped = (0, import_internal2.stripNullishUnion)(type);
2378
+ if (sourceNode !== void 0) {
2379
+ const typeNode = extractTypeNodeFromSource(sourceNode);
2380
+ if (typeNode !== void 0) {
2381
+ const byName = resolveByNameFromTypeNode(typeNode, registry, checker);
2382
+ if (byName !== null) {
2383
+ return byName;
2384
+ }
2385
+ }
2386
+ } else {
2387
+ const typeName = (stripped.aliasSymbol ?? stripped.getSymbol())?.getName();
2388
+ if (typeName !== void 0) {
2389
+ const byName = registry.findTypeByName(typeName);
2390
+ if (byName !== void 0) {
2391
+ return byName;
2392
+ }
2393
+ }
2394
+ }
2395
+ const canonical = resolveCanonicalSymbol(stripped, checker);
2396
+ if (canonical !== void 0) {
2397
+ const bySymbol = registry.findTypeBySymbol(canonical);
2398
+ if (bySymbol !== void 0) {
2399
+ return bySymbol;
2400
+ }
2401
+ }
2402
+ for (const brand of collectBrandIdentifiers(stripped)) {
2403
+ const byBrand = registry.findTypeByBrand(brand);
2404
+ if (byBrand !== void 0) {
2405
+ return byBrand;
2406
+ }
2407
+ }
2408
+ return null;
2409
+ }
2410
+ function customTypeIdFromLookup(result) {
2411
+ return `${result.extensionId}/${result.registration.typeName}`;
2412
+ }
2413
+ var ts2, import_internal2;
2414
+ var init_resolve_custom_type = __esm({
2415
+ "src/extensions/resolve-custom-type.ts"() {
2416
+ "use strict";
2417
+ ts2 = __toESM(require("typescript"), 1);
2418
+ import_internal2 = require("@formspec/analysis/internal");
2419
+ init_ts_type_utils();
2420
+ }
2421
+ });
2422
+
2295
2423
  // src/analyzer/tsdoc-parser.ts
2296
2424
  function sharedTagValueOptions(options) {
2297
2425
  return {
@@ -2312,23 +2440,23 @@ function getExtensionTypeNames(registry) {
2312
2440
  function collectImportedNames(sourceFile) {
2313
2441
  const importedNames = /* @__PURE__ */ new Set();
2314
2442
  for (const statement of sourceFile.statements) {
2315
- if (ts.isImportDeclaration(statement) && statement.importClause !== void 0) {
2443
+ if (ts3.isImportDeclaration(statement) && statement.importClause !== void 0) {
2316
2444
  const clause = statement.importClause;
2317
2445
  if (clause.name !== void 0) {
2318
2446
  importedNames.add(clause.name.text);
2319
2447
  }
2320
2448
  if (clause.namedBindings !== void 0) {
2321
- if (ts.isNamedImports(clause.namedBindings)) {
2449
+ if (ts3.isNamedImports(clause.namedBindings)) {
2322
2450
  for (const specifier of clause.namedBindings.elements) {
2323
2451
  importedNames.add(specifier.name.text);
2324
2452
  }
2325
- } else if (ts.isNamespaceImport(clause.namedBindings)) {
2453
+ } else if (ts3.isNamespaceImport(clause.namedBindings)) {
2326
2454
  importedNames.add(clause.namedBindings.name.text);
2327
2455
  }
2328
2456
  }
2329
2457
  continue;
2330
2458
  }
2331
- if (ts.isImportEqualsDeclaration(statement)) {
2459
+ if (ts3.isImportEqualsDeclaration(statement)) {
2332
2460
  importedNames.add(statement.name.text);
2333
2461
  }
2334
2462
  }
@@ -2336,13 +2464,13 @@ function collectImportedNames(sourceFile) {
2336
2464
  }
2337
2465
  function isNonReferenceIdentifier(node) {
2338
2466
  const parent = node.parent;
2339
- if ((ts.isBindingElement(parent) || ts.isClassDeclaration(parent) || ts.isEnumDeclaration(parent) || ts.isEnumMember(parent) || ts.isFunctionDeclaration(parent) || ts.isFunctionExpression(parent) || ts.isImportClause(parent) || ts.isImportEqualsDeclaration(parent) || ts.isImportSpecifier(parent) || ts.isInterfaceDeclaration(parent) || ts.isMethodDeclaration(parent) || ts.isMethodSignature(parent) || ts.isModuleDeclaration(parent) || ts.isNamespaceExport(parent) || ts.isNamespaceImport(parent) || ts.isParameter(parent) || ts.isPropertyDeclaration(parent) || ts.isPropertySignature(parent) || ts.isSetAccessorDeclaration(parent) || ts.isGetAccessorDeclaration(parent) || ts.isTypeAliasDeclaration(parent) || ts.isTypeParameterDeclaration(parent) || ts.isVariableDeclaration(parent)) && parent.name === node) {
2467
+ if ((ts3.isBindingElement(parent) || ts3.isClassDeclaration(parent) || ts3.isEnumDeclaration(parent) || ts3.isEnumMember(parent) || ts3.isFunctionDeclaration(parent) || ts3.isFunctionExpression(parent) || ts3.isImportClause(parent) || ts3.isImportEqualsDeclaration(parent) || ts3.isImportSpecifier(parent) || ts3.isInterfaceDeclaration(parent) || ts3.isMethodDeclaration(parent) || ts3.isMethodSignature(parent) || ts3.isModuleDeclaration(parent) || ts3.isNamespaceExport(parent) || ts3.isNamespaceImport(parent) || ts3.isParameter(parent) || ts3.isPropertyDeclaration(parent) || ts3.isPropertySignature(parent) || ts3.isSetAccessorDeclaration(parent) || ts3.isGetAccessorDeclaration(parent) || ts3.isTypeAliasDeclaration(parent) || ts3.isTypeParameterDeclaration(parent) || ts3.isVariableDeclaration(parent)) && parent.name === node) {
2340
2468
  return true;
2341
2469
  }
2342
- if ((ts.isPropertyAssignment(parent) || ts.isPropertyAccessExpression(parent)) && parent.name === node) {
2470
+ if ((ts3.isPropertyAssignment(parent) || ts3.isPropertyAccessExpression(parent)) && parent.name === node) {
2343
2471
  return true;
2344
2472
  }
2345
- if (ts.isQualifiedName(parent) && parent.right === node) {
2473
+ if (ts3.isQualifiedName(parent) && parent.right === node) {
2346
2474
  return true;
2347
2475
  }
2348
2476
  return false;
@@ -2356,11 +2484,11 @@ function statementReferencesImportedName(statement, importedNames) {
2356
2484
  if (referencesImportedName) {
2357
2485
  return;
2358
2486
  }
2359
- if (ts.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2487
+ if (ts3.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2360
2488
  referencesImportedName = true;
2361
2489
  return;
2362
2490
  }
2363
- ts.forEachChild(node, visit);
2491
+ ts3.forEachChild(node, visit);
2364
2492
  };
2365
2493
  visit(statement);
2366
2494
  return referencesImportedName;
@@ -2371,9 +2499,9 @@ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2371
2499
  [...importedNames].filter((name) => !extensionTypeNames.has(name))
2372
2500
  );
2373
2501
  return sourceFile.statements.filter((statement) => {
2374
- if (ts.isImportDeclaration(statement)) return false;
2375
- if (ts.isImportEqualsDeclaration(statement)) return false;
2376
- if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
2502
+ if (ts3.isImportDeclaration(statement)) return false;
2503
+ if (ts3.isImportEqualsDeclaration(statement)) return false;
2504
+ if (ts3.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
2377
2505
  return false;
2378
2506
  if (statementReferencesImportedName(statement, importedNamesToSkip)) {
2379
2507
  return false;
@@ -2405,7 +2533,7 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
2405
2533
  pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2406
2534
  return;
2407
2535
  }
2408
- const constraintNode = (0, import_internal2.parseConstraintTagValue)(
2536
+ const constraintNode = (0, import_internal3.parseConstraintTagValue)(
2409
2537
  tagName,
2410
2538
  text,
2411
2539
  provenance,
@@ -2455,12 +2583,12 @@ function supportsConstraintCapability(type, checker, capability) {
2455
2583
  if (capability === void 0) {
2456
2584
  return true;
2457
2585
  }
2458
- if ((0, import_internal2.hasTypeSemanticCapability)(type, checker, capability)) {
2586
+ if ((0, import_internal3.hasTypeSemanticCapability)(type, checker, capability)) {
2459
2587
  return true;
2460
2588
  }
2461
2589
  if (capability === "string-like") {
2462
2590
  const itemType = getArrayElementType(type, checker);
2463
- return itemType !== null && (0, import_internal2.hasTypeSemanticCapability)(itemType, checker, capability);
2591
+ return itemType !== null && (0, import_internal3.hasTypeSemanticCapability)(itemType, checker, capability);
2464
2592
  }
2465
2593
  return false;
2466
2594
  }
@@ -2469,7 +2597,7 @@ function stripHintNullishUnion(type) {
2469
2597
  return type;
2470
2598
  }
2471
2599
  const nonNullish = type.types.filter(
2472
- (member) => (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) === 0
2600
+ (member) => (member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined)) === 0
2473
2601
  );
2474
2602
  if (nonNullish.length === 1 && nonNullish[0] !== void 0) {
2475
2603
  return nonNullish[0];
@@ -2485,10 +2613,10 @@ function isUserEmittableHintProperty(property, declaration) {
2485
2613
  }
2486
2614
  if ("name" in declaration && declaration.name !== void 0) {
2487
2615
  const name = declaration.name;
2488
- if (ts.isComputedPropertyName(name) || ts.isPrivateIdentifier(name)) {
2616
+ if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
2489
2617
  return false;
2490
2618
  }
2491
- if (!ts.isIdentifier(name) && !ts.isStringLiteral(name) && !ts.isNumericLiteral(name)) {
2619
+ if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
2492
2620
  return false;
2493
2621
  }
2494
2622
  }
@@ -2504,7 +2632,7 @@ function collectObjectSubfieldCandidates(type, checker, capability) {
2504
2632
  if (isCallableType(stripped)) {
2505
2633
  return;
2506
2634
  }
2507
- if (!(0, import_internal2.hasTypeSemanticCapability)(stripped, checker, "object-like")) {
2635
+ if (!(0, import_internal3.hasTypeSemanticCapability)(stripped, checker, "object-like")) {
2508
2636
  return;
2509
2637
  }
2510
2638
  for (const property of stripped.getProperties()) {
@@ -2522,7 +2650,7 @@ function collectObjectSubfieldCandidates(type, checker, capability) {
2522
2650
  continue;
2523
2651
  }
2524
2652
  const strippedPropertyType = stripHintNullishUnion(propertyType);
2525
- if (!isCallableType(strippedPropertyType) && (0, import_internal2.hasTypeSemanticCapability)(strippedPropertyType, checker, "object-like")) {
2653
+ if (!isCallableType(strippedPropertyType) && (0, import_internal3.hasTypeSemanticCapability)(strippedPropertyType, checker, "object-like")) {
2526
2654
  visit(strippedPropertyType, path5, depth + 1);
2527
2655
  }
2528
2656
  }
@@ -2531,7 +2659,7 @@ function collectObjectSubfieldCandidates(type, checker, capability) {
2531
2659
  return out;
2532
2660
  }
2533
2661
  function buildPathTargetHint(subjectType, checker, capability, tagName, argumentText) {
2534
- if (!(0, import_internal2.hasTypeSemanticCapability)(subjectType, checker, "object-like")) {
2662
+ if (!(0, import_internal3.hasTypeSemanticCapability)(subjectType, checker, "object-like")) {
2535
2663
  return null;
2536
2664
  }
2537
2665
  const candidates = collectObjectSubfieldCandidates(subjectType, checker, capability);
@@ -2642,11 +2770,11 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2642
2770
  if (checker === void 0 || subjectType === void 0) {
2643
2771
  return [];
2644
2772
  }
2645
- const placement = (0, import_internal2.resolveDeclarationPlacement)(node);
2773
+ const placement = (0, import_internal3.resolveDeclarationPlacement)(node);
2646
2774
  if (placement === null) {
2647
2775
  return [];
2648
2776
  }
2649
- const definition = (0, import_internal2.getTagDefinition)(tagName, options?.extensionRegistry?.extensions);
2777
+ const definition = (0, import_internal3.getTagDefinition)(tagName, options?.extensionRegistry?.extensions);
2650
2778
  if (definition === null) {
2651
2779
  return [];
2652
2780
  }
@@ -2660,7 +2788,8 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2660
2788
  ];
2661
2789
  }
2662
2790
  const target = parsedTag?.target ?? null;
2663
- const hasBroadening = target === null && hasBuiltinConstraintBroadening(tagName, options);
2791
+ let evaluatedType = subjectType;
2792
+ let targetLabel = node.getText(sourceFile);
2664
2793
  if (target !== null) {
2665
2794
  if (target.kind !== "path") {
2666
2795
  return [
@@ -2680,7 +2809,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2680
2809
  )
2681
2810
  ];
2682
2811
  }
2683
- const resolution = (0, import_internal2.resolvePathTargetType)(subjectType, checker, target.path.segments);
2812
+ const resolution = (0, import_internal3.resolvePathTargetType)(subjectType, checker, target.path.segments);
2684
2813
  if (resolution.kind === "missing-property") {
2685
2814
  return [
2686
2815
  makeDiagnostic(
@@ -2700,29 +2829,30 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2700
2829
  )
2701
2830
  ];
2702
2831
  }
2703
- const requiredCapability = definition.capabilities[0];
2704
- if (requiredCapability !== void 0 && !supportsConstraintCapability(resolution.type, checker, requiredCapability)) {
2705
- const actualType = checker.typeToString(resolution.type, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2706
- return [
2707
- makeDiagnostic(
2708
- "TYPE_MISMATCH",
2709
- `Target "${target.rawText}": constraint "${tagName}" is only valid on ${capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`,
2710
- provenance
2711
- )
2712
- ];
2832
+ evaluatedType = resolution.type;
2833
+ targetLabel = target.rawText;
2834
+ }
2835
+ const hasBroadening = (() => {
2836
+ if (target === null) {
2837
+ return hasBuiltinConstraintBroadening(tagName, options);
2713
2838
  }
2714
- } else if (!hasBroadening) {
2839
+ const registry = options?.extensionRegistry;
2840
+ if (registry === void 0) return false;
2841
+ const resolved = resolveCustomTypeFromTsType(evaluatedType, checker, registry);
2842
+ return resolved !== null && registry.findBuiltinConstraintBroadening(customTypeIdFromLookup(resolved), tagName) !== void 0;
2843
+ })();
2844
+ if (!hasBroadening) {
2715
2845
  const requiredCapability = definition.capabilities[0];
2716
- if (requiredCapability !== void 0 && !supportsConstraintCapability(subjectType, checker, requiredCapability)) {
2717
- const actualType = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2718
- const baseMessage = `Target "${node.getText(sourceFile)}": constraint "${tagName}" is only valid on ${capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`;
2719
- const hint = buildPathTargetHint(
2846
+ if (requiredCapability !== void 0 && !supportsConstraintCapability(evaluatedType, checker, requiredCapability)) {
2847
+ const actualType = checker.typeToString(evaluatedType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2848
+ const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`;
2849
+ const hint = target === null ? buildPathTargetHint(
2720
2850
  subjectType,
2721
2851
  checker,
2722
2852
  requiredCapability,
2723
2853
  tagName,
2724
2854
  parsedTag?.argumentText
2725
- );
2855
+ ) : null;
2726
2856
  return [
2727
2857
  makeDiagnostic(
2728
2858
  "TYPE_MISMATCH",
@@ -2745,7 +2875,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2745
2875
  const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2746
2876
  const hostType = options?.hostType ?? subjectType;
2747
2877
  const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2748
- const result = (0, import_internal2.checkSyntheticTagApplication)({
2878
+ const result = (0, import_internal3.checkSyntheticTagApplication)({
2749
2879
  tagName,
2750
2880
  placement,
2751
2881
  hostType: hostTypeText,
@@ -2795,10 +2925,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2795
2925
  function getExtensionTagNames(options) {
2796
2926
  return [
2797
2927
  ...options?.extensionRegistry?.extensions.flatMap(
2798
- (extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName))
2928
+ (extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal3.normalizeFormSpecTagName)(tag.tagName))
2799
2929
  ) ?? [],
2800
2930
  ...options?.extensionRegistry?.extensions.flatMap(
2801
- (extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal2.normalizeFormSpecTagName)(slot.tagName))
2931
+ (extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal3.normalizeFormSpecTagName)(slot.tagName))
2802
2932
  ) ?? []
2803
2933
  ].sort();
2804
2934
  }
@@ -2810,9 +2940,9 @@ function getExtensionRegistryCacheKey(registry) {
2810
2940
  (extension) => JSON.stringify({
2811
2941
  extensionId: extension.extensionId,
2812
2942
  typeNames: extension.types?.map((type) => type.typeName) ?? [],
2813
- constraintTags: extension.constraintTags?.map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName)) ?? [],
2943
+ constraintTags: extension.constraintTags?.map((tag) => (0, import_internal3.normalizeFormSpecTagName)(tag.tagName)) ?? [],
2814
2944
  metadataSlots: extension.metadataSlots?.map((slot) => ({
2815
- tagName: (0, import_internal2.normalizeFormSpecTagName)(slot.tagName),
2945
+ tagName: (0, import_internal3.normalizeFormSpecTagName)(slot.tagName),
2816
2946
  declarationKinds: [...slot.declarationKinds].sort(),
2817
2947
  allowBare: slot.allowBare !== false,
2818
2948
  qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
@@ -2855,12 +2985,12 @@ function parseTSDocTags(node, file = "", options) {
2855
2985
  const sourceText = sourceFile.getFullText();
2856
2986
  const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
2857
2987
  const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
2858
- const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
2988
+ const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
2859
2989
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
2860
2990
  const extensionTagNames = getExtensionTagNames(options);
2861
2991
  if (commentRanges) {
2862
2992
  for (const range of commentRanges) {
2863
- if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
2993
+ if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
2864
2994
  continue;
2865
2995
  }
2866
2996
  const commentText = sourceText.substring(range.pos, range.end);
@@ -2868,7 +2998,7 @@ function parseTSDocTags(node, file = "", options) {
2868
2998
  continue;
2869
2999
  }
2870
3000
  const extensions = options?.extensionRegistry?.extensions;
2871
- const unified = (0, import_internal2.parseUnifiedComment)(commentText, {
3001
+ const unified = (0, import_internal3.parseUnifiedComment)(commentText, {
2872
3002
  offset: range.pos,
2873
3003
  extensionTagNames,
2874
3004
  ...extensions !== void 0 ? { extensions } : {}
@@ -2903,13 +3033,13 @@ function parseTSDocTags(node, file = "", options) {
2903
3033
  }
2904
3034
  continue;
2905
3035
  }
2906
- if (import_internal2.TAGS_REQUIRING_RAW_TEXT.has(tagName)) {
3036
+ if (import_internal3.TAGS_REQUIRING_RAW_TEXT.has(tagName)) {
2907
3037
  const fallback = rawTextFallbacks.get(tagName)?.shift();
2908
- const text2 = (0, import_internal2.choosePreferredPayloadText)(tag.resolvedPayloadText, fallback?.text ?? "");
3038
+ const text2 = (0, import_internal3.choosePreferredPayloadText)(tag.resolvedPayloadText, fallback?.text ?? "");
2909
3039
  if (text2 === "") continue;
2910
3040
  const provenance2 = provenanceForParsedTag(tag, sourceFile, file);
2911
3041
  if (tagName === "defaultValue") {
2912
- annotations.push((0, import_internal2.parseDefaultValueTagValue)(text2, provenance2));
3042
+ annotations.push((0, import_internal3.parseDefaultValueTagValue)(text2, provenance2));
2913
3043
  continue;
2914
3044
  }
2915
3045
  processConstraintTag(
@@ -2991,7 +3121,7 @@ function parseTSDocTags(node, file = "", options) {
2991
3121
  if (text === "") continue;
2992
3122
  const provenance = fallback.provenance;
2993
3123
  if (tagName === "defaultValue") {
2994
- annotations.push((0, import_internal2.parseDefaultValueTagValue)(text, provenance));
3124
+ annotations.push((0, import_internal3.parseDefaultValueTagValue)(text, provenance));
2995
3125
  continue;
2996
3126
  }
2997
3127
  processConstraintTag(
@@ -3017,13 +3147,13 @@ function extractDisplayNameMetadata(node) {
3017
3147
  const memberDisplayNames = /* @__PURE__ */ new Map();
3018
3148
  const sourceFile = node.getSourceFile();
3019
3149
  const sourceText = sourceFile.getFullText();
3020
- const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
3150
+ const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
3021
3151
  if (commentRanges) {
3022
3152
  for (const range of commentRanges) {
3023
- if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) continue;
3153
+ if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) continue;
3024
3154
  const commentText = sourceText.substring(range.pos, range.end);
3025
3155
  if (!commentText.startsWith("/**")) continue;
3026
- const unified = (0, import_internal2.parseUnifiedComment)(commentText);
3156
+ const unified = (0, import_internal3.parseUnifiedComment)(commentText);
3027
3157
  for (const tag of unified.tags) {
3028
3158
  if (tag.normalizedTagName !== "displayName") {
3029
3159
  continue;
@@ -3045,9 +3175,9 @@ function extractDisplayNameMetadata(node) {
3045
3175
  }
3046
3176
  function collectRawTextFallbacks(node, file) {
3047
3177
  const fallbacks = /* @__PURE__ */ new Map();
3048
- for (const tag of ts.getJSDocTags(node)) {
3178
+ for (const tag of ts3.getJSDocTags(node)) {
3049
3179
  const tagName = (0, import_internals4.normalizeConstraintTagName)(tag.tagName.text);
3050
- if (!import_internal2.TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
3180
+ if (!import_internal3.TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
3051
3181
  const commentText = getTagCommentText(tag)?.trim() ?? "";
3052
3182
  if (commentText === "") continue;
3053
3183
  const entries = fallbacks.get(tagName) ?? [];
@@ -3060,7 +3190,7 @@ function collectRawTextFallbacks(node, file) {
3060
3190
  return fallbacks;
3061
3191
  }
3062
3192
  function isMemberTargetDisplayName(text) {
3063
- return (0, import_internal2.parseTagSyntax)("displayName", text).target !== null;
3193
+ return (0, import_internal3.parseTagSyntax)("displayName", text).target !== null;
3064
3194
  }
3065
3195
  function provenanceForComment(range, sourceFile, file, tagName) {
3066
3196
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(range.pos);
@@ -3100,17 +3230,18 @@ function getTagCommentText(tag) {
3100
3230
  if (typeof tag.comment === "string") {
3101
3231
  return tag.comment;
3102
3232
  }
3103
- return ts.getTextOfJSDocComment(tag.comment);
3233
+ return ts3.getTextOfJSDocComment(tag.comment);
3104
3234
  }
3105
- var ts, import_internal2, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3235
+ var ts3, import_internal3, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3106
3236
  var init_tsdoc_parser = __esm({
3107
3237
  "src/analyzer/tsdoc-parser.ts"() {
3108
3238
  "use strict";
3109
- ts = __toESM(require("typescript"), 1);
3110
- import_internal2 = require("@formspec/analysis/internal");
3239
+ ts3 = __toESM(require("typescript"), 1);
3240
+ import_internal3 = require("@formspec/analysis/internal");
3111
3241
  import_internals4 = require("@formspec/core/internals");
3112
3242
  import_internals5 = require("@formspec/core/internals");
3113
- SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3243
+ init_resolve_custom_type();
3244
+ SYNTHETIC_TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3114
3245
  MAX_HINT_CANDIDATES = 5;
3115
3246
  MAX_HINT_DEPTH = 3;
3116
3247
  parseResultCache = /* @__PURE__ */ new Map();
@@ -3132,18 +3263,18 @@ function extractJSDocAnnotationNodes(node, file = "", options) {
3132
3263
  function extractDefaultValueAnnotation(initializer, file = "") {
3133
3264
  if (!initializer) return null;
3134
3265
  let value;
3135
- if (ts2.isStringLiteral(initializer)) {
3266
+ if (ts4.isStringLiteral(initializer)) {
3136
3267
  value = initializer.text;
3137
- } else if (ts2.isNumericLiteral(initializer)) {
3268
+ } else if (ts4.isNumericLiteral(initializer)) {
3138
3269
  value = Number(initializer.text);
3139
- } else if (initializer.kind === ts2.SyntaxKind.TrueKeyword) {
3270
+ } else if (initializer.kind === ts4.SyntaxKind.TrueKeyword) {
3140
3271
  value = true;
3141
- } else if (initializer.kind === ts2.SyntaxKind.FalseKeyword) {
3272
+ } else if (initializer.kind === ts4.SyntaxKind.FalseKeyword) {
3142
3273
  value = false;
3143
- } else if (initializer.kind === ts2.SyntaxKind.NullKeyword) {
3274
+ } else if (initializer.kind === ts4.SyntaxKind.NullKeyword) {
3144
3275
  value = null;
3145
- } else if (ts2.isPrefixUnaryExpression(initializer)) {
3146
- if (initializer.operator === ts2.SyntaxKind.MinusToken && ts2.isNumericLiteral(initializer.operand)) {
3276
+ } else if (ts4.isPrefixUnaryExpression(initializer)) {
3277
+ if (initializer.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(initializer.operand)) {
3147
3278
  value = -Number(initializer.operand.text);
3148
3279
  }
3149
3280
  }
@@ -3162,104 +3293,49 @@ function extractDefaultValueAnnotation(initializer, file = "") {
3162
3293
  }
3163
3294
  };
3164
3295
  }
3165
- var ts2;
3296
+ var ts4;
3166
3297
  var init_jsdoc_constraints = __esm({
3167
3298
  "src/analyzer/jsdoc-constraints.ts"() {
3168
3299
  "use strict";
3169
- ts2 = __toESM(require("typescript"), 1);
3300
+ ts4 = __toESM(require("typescript"), 1);
3170
3301
  init_tsdoc_parser();
3171
3302
  }
3172
3303
  });
3173
3304
 
3174
3305
  // src/analyzer/class-analyzer.ts
3175
3306
  function isObjectType(type) {
3176
- return !!(type.flags & ts3.TypeFlags.Object);
3307
+ return !!(type.flags & ts5.TypeFlags.Object);
3177
3308
  }
3178
3309
  function isIntersectionType(type) {
3179
- return !!(type.flags & ts3.TypeFlags.Intersection);
3180
- }
3181
- function collectBrandIdentifiers(type) {
3182
- if (!type.isIntersection()) {
3183
- return [];
3184
- }
3185
- const brands = [];
3186
- for (const prop of type.getProperties()) {
3187
- const decl = prop.valueDeclaration ?? prop.declarations?.[0];
3188
- if (decl === void 0) continue;
3189
- if (!ts3.isPropertySignature(decl) && !ts3.isPropertyDeclaration(decl)) continue;
3190
- if (!ts3.isComputedPropertyName(decl.name)) continue;
3191
- if (!ts3.isIdentifier(decl.name.expression)) continue;
3192
- brands.push(decl.name.expression.text);
3193
- }
3194
- return brands;
3195
- }
3196
- function resolveCanonicalSymbol(type, checker) {
3197
- const raw = type.aliasSymbol ?? type.getSymbol();
3198
- if (raw === void 0) return void 0;
3199
- return raw.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
3200
- }
3201
- function resolveSymbolBasedCustomType(type, extensionRegistry, checker) {
3202
- if (extensionRegistry === void 0) {
3203
- return null;
3204
- }
3205
- const canonical = resolveCanonicalSymbol(type, checker);
3206
- if (canonical === void 0) {
3207
- return null;
3208
- }
3209
- const registration = extensionRegistry.findTypeBySymbol(canonical);
3210
- if (registration === void 0) {
3211
- return null;
3212
- }
3213
- return {
3214
- kind: "custom",
3215
- typeId: `${registration.extensionId}/${registration.registration.typeName}`,
3216
- payload: null
3217
- };
3310
+ return !!(type.flags & ts5.TypeFlags.Intersection);
3218
3311
  }
3219
3312
  function isIntegerBrandedType(type) {
3220
3313
  if (!type.isIntersection()) {
3221
3314
  return false;
3222
3315
  }
3223
- const hasNumberBase = type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number));
3316
+ const hasNumberBase = type.types.some((member) => !!(member.flags & ts5.TypeFlags.Number));
3224
3317
  if (!hasNumberBase) {
3225
3318
  return false;
3226
3319
  }
3227
3320
  return collectBrandIdentifiers(type).includes("__integerBrand");
3228
3321
  }
3229
- function resolveBrandedCustomType(type, extensionRegistry) {
3230
- if (extensionRegistry === void 0) {
3231
- return null;
3232
- }
3233
- for (const brand of collectBrandIdentifiers(type)) {
3234
- const registration = extensionRegistry.findTypeByBrand(brand);
3235
- if (registration === void 0) {
3236
- continue;
3237
- }
3238
- return {
3239
- kind: "custom",
3240
- typeId: `${registration.extensionId}/${registration.registration.typeName}`,
3241
- payload: null
3242
- };
3243
- }
3244
- return null;
3245
- }
3246
3322
  function isResolvableObjectLikeAliasTypeNode(typeNode) {
3247
- if (ts3.isParenthesizedTypeNode(typeNode)) {
3323
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
3248
3324
  return isResolvableObjectLikeAliasTypeNode(typeNode.type);
3249
3325
  }
3250
- if (ts3.isTypeLiteralNode(typeNode) || ts3.isTypeReferenceNode(typeNode)) {
3326
+ if (ts5.isTypeLiteralNode(typeNode) || ts5.isTypeReferenceNode(typeNode)) {
3251
3327
  return true;
3252
3328
  }
3253
- return ts3.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
3329
+ return ts5.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
3254
3330
  }
3255
3331
  function isSemanticallyPlainObjectLikeType(type, checker) {
3256
3332
  if (isIntersectionType(type)) {
3257
3333
  return type.types.length > 0 && type.types.every((member) => isSemanticallyPlainObjectLikeType(member, checker));
3258
3334
  }
3259
- return isObjectType(type) && checker.getSignaturesOfType(type, ts3.SignatureKind.Call).length === 0 && checker.getSignaturesOfType(type, ts3.SignatureKind.Construct).length === 0 && !checker.isArrayType(type) && !checker.isTupleType(type);
3335
+ return isObjectType(type) && checker.getSignaturesOfType(type, ts5.SignatureKind.Call).length === 0 && checker.getSignaturesOfType(type, ts5.SignatureKind.Construct).length === 0 && !checker.isArrayType(type) && !checker.isTupleType(type);
3260
3336
  }
3261
3337
  function isTypeReference(type) {
3262
- return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
3338
+ return !!(type.flags & ts5.TypeFlags.Object) && !!(type.objectFlags & ts5.ObjectFlags.Reference);
3263
3339
  }
3264
3340
  function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, hostType) {
3265
3341
  if (extensionRegistry === void 0 && fieldType === void 0 && checker === void 0 && subjectType === void 0 && hostType === void 0) {
@@ -3281,7 +3357,7 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
3281
3357
  };
3282
3358
  }
3283
3359
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
3284
- const analysis = (0, import_internal3.analyzeMetadataForNodeWithChecker)({
3360
+ const analysis = (0, import_internal4.analyzeMetadataForNodeWithChecker)({
3285
3361
  checker,
3286
3362
  node,
3287
3363
  logicalName,
@@ -3319,7 +3395,7 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
3319
3395
  function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
3320
3396
  const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3321
3397
  const declarationType = checker.getTypeAtLocation(declaration);
3322
- const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
3398
+ const logicalName = ts5.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
3323
3399
  const docResult = extractJSDocParseResult(
3324
3400
  declaration,
3325
3401
  file,
@@ -3367,7 +3443,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3367
3443
  const instanceMethods = [];
3368
3444
  const staticMethods = [];
3369
3445
  for (const member of classDecl.members) {
3370
- if (ts3.isPropertyDeclaration(member)) {
3446
+ if (ts5.isPropertyDeclaration(member)) {
3371
3447
  const fieldNode = analyzeFieldToIR(
3372
3448
  member,
3373
3449
  checker,
@@ -3383,10 +3459,10 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3383
3459
  fields.push(fieldNode);
3384
3460
  fieldLayouts.push({});
3385
3461
  }
3386
- } else if (ts3.isMethodDeclaration(member)) {
3462
+ } else if (ts5.isMethodDeclaration(member)) {
3387
3463
  const methodInfo = analyzeMethod(member, checker);
3388
3464
  if (methodInfo) {
3389
- const isStatic = member.modifiers?.some((m) => m.kind === ts3.SyntaxKind.StaticKeyword);
3465
+ const isStatic = member.modifiers?.some((m) => m.kind === ts5.SyntaxKind.StaticKeyword);
3390
3466
  if (isStatic) {
3391
3467
  staticMethods.push(methodInfo);
3392
3468
  } else {
@@ -3449,7 +3525,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3449
3525
  diagnostics.push(...interfaceDoc.diagnostics);
3450
3526
  const visiting = /* @__PURE__ */ new Set();
3451
3527
  for (const member of interfaceDecl.members) {
3452
- if (ts3.isPropertySignature(member)) {
3528
+ if (ts5.isPropertySignature(member)) {
3453
3529
  const fieldNode = analyzeInterfacePropertyToIR(
3454
3530
  member,
3455
3531
  checker,
@@ -3507,7 +3583,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3507
3583
  if (members === null) {
3508
3584
  const sourceFile = typeAlias.getSourceFile();
3509
3585
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3510
- const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3586
+ const kindDesc = ts5.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3511
3587
  return {
3512
3588
  ok: false,
3513
3589
  kind: "not-object-like",
@@ -3542,7 +3618,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3542
3618
  diagnostics.push(...typeAliasDoc.diagnostics);
3543
3619
  const visiting = /* @__PURE__ */ new Set();
3544
3620
  for (const member of members) {
3545
- if (ts3.isPropertySignature(member)) {
3621
+ if (ts5.isPropertySignature(member)) {
3546
3622
  const fieldNode = analyzeInterfacePropertyToIR(
3547
3623
  member,
3548
3624
  checker,
@@ -3609,20 +3685,20 @@ function makeAnalysisDiagnostic(code, message, primaryLocation, relatedLocations
3609
3685
  function getLeadingParsedTags(node) {
3610
3686
  const sourceFile = node.getSourceFile();
3611
3687
  const sourceText = sourceFile.getFullText();
3612
- const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
3688
+ const commentRanges = ts5.getLeadingCommentRanges(sourceText, node.getFullStart());
3613
3689
  if (commentRanges === void 0) {
3614
3690
  return [];
3615
3691
  }
3616
3692
  const parsedTags = [];
3617
3693
  for (const range of commentRanges) {
3618
- if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
3694
+ if (range.kind !== ts5.SyntaxKind.MultiLineCommentTrivia) {
3619
3695
  continue;
3620
3696
  }
3621
3697
  const commentText = sourceText.slice(range.pos, range.end);
3622
3698
  if (!commentText.startsWith("/**")) {
3623
3699
  continue;
3624
3700
  }
3625
- parsedTags.push(...(0, import_internal3.parseCommentBlock)(commentText, { offset: range.pos }).tags);
3701
+ parsedTags.push(...(0, import_internal4.parseCommentBlock)(commentText, { offset: range.pos }).tags);
3626
3702
  }
3627
3703
  return parsedTags;
3628
3704
  }
@@ -3633,19 +3709,19 @@ function resolveDiscriminatorProperty(node, checker, fieldName) {
3633
3709
  return null;
3634
3710
  }
3635
3711
  const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
3636
- (candidate) => ts3.isPropertyDeclaration(candidate) || ts3.isPropertySignature(candidate)
3712
+ (candidate) => ts5.isPropertyDeclaration(candidate) || ts5.isPropertySignature(candidate)
3637
3713
  ) ?? propertySymbol.declarations?.[0];
3638
3714
  return {
3639
3715
  declaration,
3640
3716
  type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
3641
- optional: !!(propertySymbol.flags & ts3.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
3717
+ optional: !!(propertySymbol.flags & ts5.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
3642
3718
  };
3643
3719
  }
3644
3720
  function isLocalTypeParameterName(node, typeParameterName) {
3645
3721
  return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
3646
3722
  }
3647
3723
  function isNullishSemanticType(type) {
3648
- if (type.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined | ts3.TypeFlags.Void | ts3.TypeFlags.Unknown | ts3.TypeFlags.Any)) {
3724
+ if (type.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined | ts5.TypeFlags.Void | ts5.TypeFlags.Unknown | ts5.TypeFlags.Any)) {
3649
3725
  return true;
3650
3726
  }
3651
3727
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
@@ -3655,7 +3731,7 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
3655
3731
  return false;
3656
3732
  }
3657
3733
  seen.add(type);
3658
- if (type.flags & ts3.TypeFlags.StringLike) {
3734
+ if (type.flags & ts5.TypeFlags.StringLike) {
3659
3735
  return true;
3660
3736
  }
3661
3737
  if (type.isUnion()) {
@@ -3668,13 +3744,13 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
3668
3744
  return false;
3669
3745
  }
3670
3746
  function getObjectLikeTypeAliasMembers(typeNode) {
3671
- if (ts3.isParenthesizedTypeNode(typeNode)) {
3747
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
3672
3748
  return getObjectLikeTypeAliasMembers(typeNode.type);
3673
3749
  }
3674
- if (ts3.isTypeLiteralNode(typeNode)) {
3750
+ if (ts5.isTypeLiteralNode(typeNode)) {
3675
3751
  return [...typeNode.members];
3676
3752
  }
3677
- if (ts3.isIntersectionTypeNode(typeNode)) {
3753
+ if (ts5.isIntersectionTypeNode(typeNode)) {
3678
3754
  const members = [];
3679
3755
  for (const intersectionMember of typeNode.types) {
3680
3756
  const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
@@ -3837,7 +3913,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, check
3837
3913
  }
3838
3914
  if (propertyType.isUnion()) {
3839
3915
  const nonNullMembers = propertyType.types.filter(
3840
- (member) => !(member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined))
3916
+ (member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
3841
3917
  );
3842
3918
  if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
3843
3919
  diagnostics.push(
@@ -3886,13 +3962,13 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
3886
3962
  seen.add(type);
3887
3963
  const symbol = type.aliasSymbol ?? type.getSymbol();
3888
3964
  if (symbol !== void 0) {
3889
- const aliased = symbol.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
3965
+ const aliased = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
3890
3966
  const targetSymbol = aliased ?? symbol;
3891
3967
  const declaration = targetSymbol.declarations?.find(
3892
- (candidate) => ts3.isClassDeclaration(candidate) || ts3.isInterfaceDeclaration(candidate) || ts3.isTypeAliasDeclaration(candidate) || ts3.isEnumDeclaration(candidate)
3968
+ (candidate) => ts5.isClassDeclaration(candidate) || ts5.isInterfaceDeclaration(candidate) || ts5.isTypeAliasDeclaration(candidate) || ts5.isEnumDeclaration(candidate)
3893
3969
  );
3894
3970
  if (declaration !== void 0) {
3895
- if (ts3.isTypeAliasDeclaration(declaration) && ts3.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
3971
+ if (ts5.isTypeAliasDeclaration(declaration) && ts5.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
3896
3972
  return resolveNamedDiscriminatorDeclaration(
3897
3973
  checker.getTypeFromTypeNode(declaration.type),
3898
3974
  checker,
@@ -3920,7 +3996,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
3920
3996
  }
3921
3997
  if (boundType.isUnion()) {
3922
3998
  const nonNullMembers = boundType.types.filter(
3923
- (member) => !(member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined))
3999
+ (member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
3924
4000
  );
3925
4001
  if (nonNullMembers.every((member) => member.isStringLiteral())) {
3926
4002
  diagnostics.push(
@@ -3965,7 +4041,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
3965
4041
  return null;
3966
4042
  }
3967
4043
  function getDeclarationName(node) {
3968
- if (ts3.isClassDeclaration(node) || ts3.isInterfaceDeclaration(node) || ts3.isTypeAliasDeclaration(node) || ts3.isEnumDeclaration(node)) {
4044
+ if (ts5.isClassDeclaration(node) || ts5.isInterfaceDeclaration(node) || ts5.isTypeAliasDeclaration(node) || ts5.isEnumDeclaration(node)) {
3969
4045
  return node.name?.text ?? "anonymous";
3970
4046
  }
3971
4047
  return "anonymous";
@@ -4020,11 +4096,11 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
4020
4096
  if (sourceTypeNode === void 0) {
4021
4097
  return [];
4022
4098
  }
4023
- const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
4099
+ const unwrapParentheses = (typeNode) => ts5.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
4024
4100
  const directTypeNode = unwrapParentheses(sourceTypeNode);
4025
- const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
4101
+ const referenceTypeNode = ts5.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
4026
4102
  const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
4027
- return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
4103
+ return ts5.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
4028
4104
  })();
4029
4105
  if (referenceTypeNode?.typeArguments === void 0) {
4030
4106
  return [];
@@ -4079,7 +4155,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
4079
4155
  );
4080
4156
  }
4081
4157
  function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
4082
- if (!ts3.isIdentifier(prop.name)) {
4158
+ if (!ts5.isIdentifier(prop.name)) {
4083
4159
  return null;
4084
4160
  }
4085
4161
  const name = prop.name.text;
@@ -4206,7 +4282,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
4206
4282
  const seen = /* @__PURE__ */ new Set();
4207
4283
  const duplicates = /* @__PURE__ */ new Set();
4208
4284
  for (const member of members) {
4209
- if (!ts3.isPropertySignature(member)) {
4285
+ if (!ts5.isPropertySignature(member)) {
4210
4286
  continue;
4211
4287
  }
4212
4288
  const name = getAnalyzableObjectLikePropertyName(member.name);
@@ -4222,7 +4298,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
4222
4298
  return [...duplicates].sort();
4223
4299
  }
4224
4300
  function getAnalyzableObjectLikePropertyName(name) {
4225
- if (ts3.isIdentifier(name) || ts3.isStringLiteral(name) || ts3.isNumericLiteral(name)) {
4301
+ if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
4226
4302
  return name.text;
4227
4303
  }
4228
4304
  return null;
@@ -4289,74 +4365,20 @@ function parseEnumMemberDisplayName(value) {
4289
4365
  if (label === "") return null;
4290
4366
  return { value: match[1], label };
4291
4367
  }
4292
- function resolveRegisteredCustomType(sourceNode, extensionRegistry, checker) {
4293
- if (sourceNode === void 0 || extensionRegistry === void 0) {
4294
- return null;
4295
- }
4296
- const typeNode = extractTypeNodeFromSource(sourceNode);
4297
- if (typeNode === void 0) {
4298
- return null;
4299
- }
4300
- return resolveRegisteredCustomTypeFromTypeNode(typeNode, extensionRegistry, checker);
4301
- }
4302
- function resolveRegisteredCustomTypeFromTypeNode(typeNode, extensionRegistry, checker) {
4303
- if (ts3.isParenthesizedTypeNode(typeNode)) {
4304
- return resolveRegisteredCustomTypeFromTypeNode(typeNode.type, extensionRegistry, checker);
4305
- }
4306
- const typeName = getTypeNodeRegistrationName(typeNode);
4307
- if (typeName === null) {
4308
- return null;
4309
- }
4310
- const registration = extensionRegistry.findTypeByName(typeName);
4311
- if (registration !== void 0) {
4368
+ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4369
+ const customTypeLookup = resolveCustomTypeFromTsType(
4370
+ type,
4371
+ checker,
4372
+ extensionRegistry,
4373
+ sourceNode
4374
+ );
4375
+ if (customTypeLookup !== null) {
4312
4376
  return {
4313
4377
  kind: "custom",
4314
- typeId: `${registration.extensionId}/${registration.registration.typeName}`,
4378
+ typeId: customTypeIdFromLookup(customTypeLookup),
4315
4379
  payload: null
4316
4380
  };
4317
4381
  }
4318
- if (ts3.isTypeReferenceNode(typeNode) && ts3.isIdentifier(typeNode.typeName)) {
4319
- const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
4320
- if (aliasDecl !== void 0) {
4321
- return resolveRegisteredCustomTypeFromTypeNode(aliasDecl.type, extensionRegistry, checker);
4322
- }
4323
- }
4324
- return null;
4325
- }
4326
- function extractTypeNodeFromSource(sourceNode) {
4327
- if (ts3.isPropertyDeclaration(sourceNode) || ts3.isPropertySignature(sourceNode) || ts3.isParameter(sourceNode) || ts3.isTypeAliasDeclaration(sourceNode)) {
4328
- return sourceNode.type;
4329
- }
4330
- if (ts3.isTypeNode(sourceNode)) {
4331
- return sourceNode;
4332
- }
4333
- return void 0;
4334
- }
4335
- function getTypeNodeRegistrationName(typeNode) {
4336
- if (ts3.isTypeReferenceNode(typeNode)) {
4337
- return ts3.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : typeNode.typeName.right.text;
4338
- }
4339
- if (ts3.isParenthesizedTypeNode(typeNode)) {
4340
- return getTypeNodeRegistrationName(typeNode.type);
4341
- }
4342
- if (typeNode.kind === ts3.SyntaxKind.BigIntKeyword || typeNode.kind === ts3.SyntaxKind.StringKeyword || typeNode.kind === ts3.SyntaxKind.NumberKeyword || typeNode.kind === ts3.SyntaxKind.BooleanKeyword) {
4343
- return typeNode.getText();
4344
- }
4345
- return null;
4346
- }
4347
- function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4348
- const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
4349
- if (customType) {
4350
- return customType;
4351
- }
4352
- const symbolCustomType = resolveSymbolBasedCustomType(type, extensionRegistry, checker);
4353
- if (symbolCustomType) {
4354
- return symbolCustomType;
4355
- }
4356
- const brandedCustomType = resolveBrandedCustomType(type, extensionRegistry);
4357
- if (brandedCustomType) {
4358
- return brandedCustomType;
4359
- }
4360
4382
  const primitiveAlias = tryResolveNamedPrimitiveAlias(
4361
4383
  type,
4362
4384
  checker,
@@ -4374,25 +4396,25 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4374
4396
  if (isIntegerBrandedType(type)) {
4375
4397
  return { kind: "primitive", primitiveKind: "integer" };
4376
4398
  }
4377
- if (type.flags & ts3.TypeFlags.String) {
4399
+ if (type.flags & ts5.TypeFlags.String) {
4378
4400
  return { kind: "primitive", primitiveKind: "string" };
4379
4401
  }
4380
- if (type.flags & ts3.TypeFlags.Number) {
4402
+ if (type.flags & ts5.TypeFlags.Number) {
4381
4403
  return { kind: "primitive", primitiveKind: "number" };
4382
4404
  }
4383
- if (type.flags & (ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral)) {
4405
+ if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
4384
4406
  return { kind: "primitive", primitiveKind: "bigint" };
4385
4407
  }
4386
- if (type.flags & ts3.TypeFlags.Boolean) {
4408
+ if (type.flags & ts5.TypeFlags.Boolean) {
4387
4409
  return { kind: "primitive", primitiveKind: "boolean" };
4388
4410
  }
4389
- if (type.flags & ts3.TypeFlags.Null) {
4411
+ if (type.flags & ts5.TypeFlags.Null) {
4390
4412
  return { kind: "primitive", primitiveKind: "null" };
4391
4413
  }
4392
- if (type.flags & ts3.TypeFlags.Undefined) {
4414
+ if (type.flags & ts5.TypeFlags.Undefined) {
4393
4415
  return { kind: "primitive", primitiveKind: "null" };
4394
4416
  }
4395
- if (type.flags & ts3.TypeFlags.Void) {
4417
+ if (type.flags & ts5.TypeFlags.Void) {
4396
4418
  return { kind: "primitive", primitiveKind: "null" };
4397
4419
  }
4398
4420
  if (type.isStringLiteral()) {
@@ -4479,10 +4501,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4479
4501
  return { kind: "primitive", primitiveKind: "string" };
4480
4502
  }
4481
4503
  function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4482
- if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null)) && !isIntegerBrandedType(type)) {
4504
+ if (!(type.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null)) && !isIntegerBrandedType(type)) {
4483
4505
  return null;
4484
4506
  }
4485
- const aliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
4507
+ const aliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
4486
4508
  if (!aliasDecl) {
4487
4509
  return null;
4488
4510
  }
@@ -4532,14 +4554,14 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
4532
4554
  return { kind: "reference", name: aliasName, typeArguments: [] };
4533
4555
  }
4534
4556
  function getReferencedTypeAliasDeclaration(sourceNode, checker) {
4535
- const typeNode = sourceNode && (ts3.isPropertyDeclaration(sourceNode) || ts3.isPropertySignature(sourceNode) || ts3.isParameter(sourceNode)) ? sourceNode.type : void 0;
4536
- if (!typeNode || !ts3.isTypeReferenceNode(typeNode)) {
4557
+ const typeNode = sourceNode && (ts5.isPropertyDeclaration(sourceNode) || ts5.isPropertySignature(sourceNode) || ts5.isParameter(sourceNode)) ? sourceNode.type : void 0;
4558
+ if (!typeNode || !ts5.isTypeReferenceNode(typeNode)) {
4537
4559
  return void 0;
4538
4560
  }
4539
4561
  return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
4540
4562
  }
4541
4563
  function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4542
- if (!ts3.isTypeReferenceNode(typeNode)) {
4564
+ if (!ts5.isTypeReferenceNode(typeNode)) {
4543
4565
  return false;
4544
4566
  }
4545
4567
  const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
@@ -4547,10 +4569,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4547
4569
  return false;
4548
4570
  }
4549
4571
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
4550
- return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
4572
+ return !!(resolved.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null));
4551
4573
  }
4552
4574
  function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
4553
- const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
4575
+ const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration);
4554
4576
  if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
4555
4577
  visitedAliases.add(nestedAliasDecl);
4556
4578
  return resolveAliasedPrimitiveTarget(
@@ -4568,19 +4590,19 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4568
4590
  if (isIntegerBrandedType(type)) {
4569
4591
  return { kind: "primitive", primitiveKind: "integer" };
4570
4592
  }
4571
- if (type.flags & ts3.TypeFlags.String) {
4593
+ if (type.flags & ts5.TypeFlags.String) {
4572
4594
  return { kind: "primitive", primitiveKind: "string" };
4573
4595
  }
4574
- if (type.flags & ts3.TypeFlags.Number) {
4596
+ if (type.flags & ts5.TypeFlags.Number) {
4575
4597
  return { kind: "primitive", primitiveKind: "number" };
4576
4598
  }
4577
- if (type.flags & (ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral)) {
4599
+ if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
4578
4600
  return { kind: "primitive", primitiveKind: "bigint" };
4579
4601
  }
4580
- if (type.flags & ts3.TypeFlags.Boolean) {
4602
+ if (type.flags & ts5.TypeFlags.Boolean) {
4581
4603
  return { kind: "primitive", primitiveKind: "boolean" };
4582
4604
  }
4583
- if (type.flags & ts3.TypeFlags.Null) {
4605
+ if (type.flags & ts5.TypeFlags.Null) {
4584
4606
  return { kind: "primitive", primitiveKind: "null" };
4585
4607
  }
4586
4608
  return resolveTypeNode(
@@ -4607,13 +4629,13 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4607
4629
  (memberTypeNode) => !isNullishTypeNode(resolveAliasedTypeNode(memberTypeNode, checker))
4608
4630
  );
4609
4631
  const nonNullTypes = allTypes.filter(
4610
- (memberType) => !(memberType.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined))
4632
+ (memberType) => !(memberType.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
4611
4633
  );
4612
4634
  const nonNullMembers = nonNullTypes.map((memberType, index) => ({
4613
4635
  memberType,
4614
4636
  sourceNode: nonNullSourceNodes.length === nonNullTypes.length ? nonNullSourceNodes[index] : void 0
4615
4637
  }));
4616
- const hasNull = allTypes.some((t) => t.flags & ts3.TypeFlags.Null);
4638
+ const hasNull = allTypes.some((t) => t.flags & ts5.TypeFlags.Null);
4617
4639
  const memberDisplayNames = /* @__PURE__ */ new Map();
4618
4640
  if (namedDecl) {
4619
4641
  for (const [value, label] of extractDisplayNameMetadata(namedDecl).memberDisplayNames) {
@@ -4656,7 +4678,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4656
4678
  const displayName = memberDisplayNames.get(String(value));
4657
4679
  return displayName !== void 0 ? { value, displayName } : { value };
4658
4680
  });
4659
- const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts3.TypeFlags.BooleanLiteral);
4681
+ const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
4660
4682
  if (isBooleanUnion2) {
4661
4683
  const boolNode = { kind: "primitive", primitiveKind: "boolean" };
4662
4684
  const result = hasNull ? {
@@ -4748,7 +4770,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metad
4748
4770
  if (type.getProperties().length > 0) {
4749
4771
  return null;
4750
4772
  }
4751
- const indexInfo = checker.getIndexInfoOfType(type, ts3.IndexKind.String);
4773
+ const indexInfo = checker.getIndexInfoOfType(type, ts5.IndexKind.String);
4752
4774
  if (!indexInfo) {
4753
4775
  return null;
4754
4776
  }
@@ -4796,10 +4818,10 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
4796
4818
  }
4797
4819
  if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
4798
4820
  const name = declaration.name;
4799
- if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
4821
+ if (ts5.isComputedPropertyName(name) || ts5.isPrivateIdentifier(name)) {
4800
4822
  return false;
4801
4823
  }
4802
- if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
4824
+ if (!ts5.isIdentifier(name) && !ts5.isStringLiteral(name) && !ts5.isNumericLiteral(name)) {
4803
4825
  return false;
4804
4826
  }
4805
4827
  }
@@ -4925,7 +4947,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4925
4947
  if (!declaration) continue;
4926
4948
  if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
4927
4949
  const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
4928
- const optional = !!(prop.flags & ts3.SymbolFlags.Optional);
4950
+ const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
4929
4951
  const propTypeNode = resolveTypeNode(
4930
4952
  propType,
4931
4953
  checker,
@@ -4938,7 +4960,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4938
4960
  collectedDiagnostics
4939
4961
  );
4940
4962
  const fieldNodeInfo = fieldInfoMap?.get(prop.name);
4941
- const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
4963
+ const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts5.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
4942
4964
  declaration,
4943
4965
  checker,
4944
4966
  file,
@@ -4948,7 +4970,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4948
4970
  type,
4949
4971
  metadataPolicy,
4950
4972
  extensionRegistry
4951
- ) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
4973
+ ) : ts5.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
4952
4974
  declaration,
4953
4975
  checker,
4954
4976
  file,
@@ -4976,7 +4998,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4976
4998
  visiting.delete(type);
4977
4999
  const objectNode = {
4978
5000
  kind: "object",
4979
- properties: namedDecl !== void 0 && (ts3.isClassDeclaration(namedDecl) || ts3.isInterfaceDeclaration(namedDecl) || ts3.isTypeAliasDeclaration(namedDecl)) ? applyDiscriminatorToObjectProperties(
5001
+ properties: namedDecl !== void 0 && (ts5.isClassDeclaration(namedDecl) || ts5.isInterfaceDeclaration(namedDecl) || ts5.isTypeAliasDeclaration(namedDecl)) ? applyDiscriminatorToObjectProperties(
4980
5002
  properties,
4981
5003
  namedDecl,
4982
5004
  type,
@@ -5024,12 +5046,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5024
5046
  for (const symbol of symbols) {
5025
5047
  const declarations = symbol.declarations;
5026
5048
  if (!declarations) continue;
5027
- const classDecl = declarations.find(ts3.isClassDeclaration);
5049
+ const classDecl = declarations.find(ts5.isClassDeclaration);
5028
5050
  if (classDecl) {
5029
5051
  const map = /* @__PURE__ */ new Map();
5030
5052
  const hostType = checker.getTypeAtLocation(classDecl);
5031
5053
  for (const member of classDecl.members) {
5032
- if (ts3.isPropertyDeclaration(member) && ts3.isIdentifier(member.name)) {
5054
+ if (ts5.isPropertyDeclaration(member) && ts5.isIdentifier(member.name)) {
5033
5055
  const fieldNode = analyzeFieldToIR(
5034
5056
  member,
5035
5057
  checker,
@@ -5053,7 +5075,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5053
5075
  }
5054
5076
  return map;
5055
5077
  }
5056
- const interfaceDecl = declarations.find(ts3.isInterfaceDeclaration);
5078
+ const interfaceDecl = declarations.find(ts5.isInterfaceDeclaration);
5057
5079
  if (interfaceDecl) {
5058
5080
  return buildFieldNodeInfoMap(
5059
5081
  interfaceDecl.members,
@@ -5067,7 +5089,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5067
5089
  extensionRegistry
5068
5090
  );
5069
5091
  }
5070
- const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
5092
+ const typeAliasDecl = declarations.find(ts5.isTypeAliasDeclaration);
5071
5093
  const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
5072
5094
  if (typeAliasDecl && typeAliasMembers !== null) {
5073
5095
  return buildFieldNodeInfoMap(
@@ -5091,10 +5113,10 @@ function extractArrayElementTypeNode(sourceNode, checker) {
5091
5113
  return void 0;
5092
5114
  }
5093
5115
  const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
5094
- if (ts3.isArrayTypeNode(resolvedTypeNode)) {
5116
+ if (ts5.isArrayTypeNode(resolvedTypeNode)) {
5095
5117
  return resolvedTypeNode.elementType;
5096
5118
  }
5097
- if (ts3.isTypeReferenceNode(resolvedTypeNode) && ts3.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
5119
+ if (ts5.isTypeReferenceNode(resolvedTypeNode) && ts5.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
5098
5120
  return resolvedTypeNode.typeArguments[0];
5099
5121
  }
5100
5122
  return void 0;
@@ -5105,13 +5127,13 @@ function extractUnionMemberTypeNodes(sourceNode, checker) {
5105
5127
  return [];
5106
5128
  }
5107
5129
  const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
5108
- return ts3.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
5130
+ return ts5.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
5109
5131
  }
5110
5132
  function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
5111
- if (ts3.isParenthesizedTypeNode(typeNode)) {
5133
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
5112
5134
  return resolveAliasedTypeNode(typeNode.type, checker, visited);
5113
5135
  }
5114
- if (!ts3.isTypeReferenceNode(typeNode) || !ts3.isIdentifier(typeNode.typeName)) {
5136
+ if (!ts5.isTypeReferenceNode(typeNode) || !ts5.isIdentifier(typeNode.typeName)) {
5115
5137
  return typeNode;
5116
5138
  }
5117
5139
  const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
@@ -5122,15 +5144,15 @@ function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new
5122
5144
  return resolveAliasedTypeNode(aliasDecl.type, checker, visited);
5123
5145
  }
5124
5146
  function isNullishTypeNode(typeNode) {
5125
- if (typeNode.kind === ts3.SyntaxKind.NullKeyword || typeNode.kind === ts3.SyntaxKind.UndefinedKeyword) {
5147
+ if (typeNode.kind === ts5.SyntaxKind.NullKeyword || typeNode.kind === ts5.SyntaxKind.UndefinedKeyword) {
5126
5148
  return true;
5127
5149
  }
5128
- return ts3.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts3.SyntaxKind.NullKeyword || typeNode.literal.kind === ts3.SyntaxKind.UndefinedKeyword);
5150
+ return ts5.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts5.SyntaxKind.NullKeyword || typeNode.literal.kind === ts5.SyntaxKind.UndefinedKeyword);
5129
5151
  }
5130
5152
  function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
5131
5153
  const map = /* @__PURE__ */ new Map();
5132
5154
  for (const member of members) {
5133
- if (ts3.isPropertySignature(member)) {
5155
+ if (ts5.isPropertySignature(member)) {
5134
5156
  const fieldNode = analyzeInterfacePropertyToIR(
5135
5157
  member,
5136
5158
  checker,
@@ -5155,17 +5177,16 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, m
5155
5177
  return map;
5156
5178
  }
5157
5179
  function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegistry, depth = 0) {
5158
- if (!ts3.isTypeReferenceNode(typeNode)) return [];
5180
+ if (!ts5.isTypeReferenceNode(typeNode)) return [];
5159
5181
  if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
5160
5182
  const aliasName = typeNode.typeName.getText();
5161
5183
  throw new Error(
5162
5184
  `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.`
5163
5185
  );
5164
5186
  }
5165
- const symbol = checker.getSymbolAtLocation(typeNode.typeName);
5166
- const aliasDecl = getAliasedTypeAliasDeclaration(symbol, checker);
5187
+ const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
5167
5188
  if (!aliasDecl) return [];
5168
- if (ts3.isTypeLiteralNode(aliasDecl.type)) return [];
5189
+ if (ts5.isTypeLiteralNode(aliasDecl.type)) return [];
5169
5190
  const aliasFieldType = resolveTypeNode(
5170
5191
  checker.getTypeAtLocation(aliasDecl.type),
5171
5192
  checker,
@@ -5186,18 +5207,6 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
5186
5207
  );
5187
5208
  return constraints;
5188
5209
  }
5189
- function getAliasedSymbol(symbol, checker) {
5190
- if (symbol === void 0) {
5191
- return void 0;
5192
- }
5193
- return symbol.flags & ts3.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
5194
- }
5195
- function getAliasedTypeAliasDeclaration(symbol, checker) {
5196
- return getAliasedSymbol(symbol, checker)?.declarations?.find(ts3.isTypeAliasDeclaration);
5197
- }
5198
- function getTypeAliasDeclarationFromTypeReference(typeNode, checker) {
5199
- return getAliasedTypeAliasDeclaration(checker.getSymbolAtLocation(typeNode.typeName), checker);
5200
- }
5201
5210
  function provenanceForNode(node, file) {
5202
5211
  const sourceFile = node.getSourceFile();
5203
5212
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
@@ -5221,14 +5230,14 @@ function getNamedTypeName(type) {
5221
5230
  const symbol = type.getSymbol();
5222
5231
  if (symbol?.declarations) {
5223
5232
  const decl = symbol.declarations[0];
5224
- if (decl && (ts3.isClassDeclaration(decl) || ts3.isInterfaceDeclaration(decl) || ts3.isTypeAliasDeclaration(decl))) {
5225
- const name = ts3.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
5233
+ if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
5234
+ const name = ts5.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
5226
5235
  if (name) return name;
5227
5236
  }
5228
5237
  }
5229
5238
  const aliasSymbol = type.aliasSymbol;
5230
5239
  if (aliasSymbol?.declarations) {
5231
- const aliasDecl = aliasSymbol.declarations.find(ts3.isTypeAliasDeclaration);
5240
+ const aliasDecl = aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
5232
5241
  if (aliasDecl) {
5233
5242
  return aliasDecl.name.text;
5234
5243
  }
@@ -5239,24 +5248,24 @@ function getNamedTypeDeclaration(type) {
5239
5248
  const symbol = type.getSymbol();
5240
5249
  if (symbol?.declarations) {
5241
5250
  const decl = symbol.declarations[0];
5242
- if (decl && (ts3.isClassDeclaration(decl) || ts3.isInterfaceDeclaration(decl) || ts3.isTypeAliasDeclaration(decl))) {
5251
+ if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
5243
5252
  return decl;
5244
5253
  }
5245
5254
  }
5246
5255
  const aliasSymbol = type.aliasSymbol;
5247
5256
  if (aliasSymbol?.declarations) {
5248
- return aliasSymbol.declarations.find(ts3.isTypeAliasDeclaration);
5257
+ return aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
5249
5258
  }
5250
5259
  return void 0;
5251
5260
  }
5252
5261
  function analyzeMethod(method, checker) {
5253
- if (!ts3.isIdentifier(method.name)) {
5262
+ if (!ts5.isIdentifier(method.name)) {
5254
5263
  return null;
5255
5264
  }
5256
5265
  const name = method.name.text;
5257
5266
  const parameters = [];
5258
5267
  for (const param of method.parameters) {
5259
- if (ts3.isIdentifier(param.name)) {
5268
+ if (ts5.isIdentifier(param.name)) {
5260
5269
  const paramInfo = analyzeParameter(param, checker);
5261
5270
  parameters.push(paramInfo);
5262
5271
  }
@@ -5267,7 +5276,7 @@ function analyzeMethod(method, checker) {
5267
5276
  return { name, parameters, returnTypeNode, returnType };
5268
5277
  }
5269
5278
  function analyzeParameter(param, checker) {
5270
- const name = ts3.isIdentifier(param.name) ? param.name.text : "param";
5279
+ const name = ts5.isIdentifier(param.name) ? param.name.text : "param";
5271
5280
  const typeNode = param.type;
5272
5281
  const type = checker.getTypeAtLocation(param);
5273
5282
  const formSpecExportName = detectFormSpecReference(typeNode);
@@ -5276,27 +5285,29 @@ function analyzeParameter(param, checker) {
5276
5285
  }
5277
5286
  function detectFormSpecReference(typeNode) {
5278
5287
  if (!typeNode) return null;
5279
- if (!ts3.isTypeReferenceNode(typeNode)) return null;
5280
- const typeName = ts3.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts3.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
5288
+ if (!ts5.isTypeReferenceNode(typeNode)) return null;
5289
+ const typeName = ts5.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts5.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
5281
5290
  if (typeName !== "InferSchema" && typeName !== "InferFormSchema") return null;
5282
5291
  const typeArg = typeNode.typeArguments?.[0];
5283
- if (!typeArg || !ts3.isTypeQueryNode(typeArg)) return null;
5284
- if (ts3.isIdentifier(typeArg.exprName)) {
5292
+ if (!typeArg || !ts5.isTypeQueryNode(typeArg)) return null;
5293
+ if (ts5.isIdentifier(typeArg.exprName)) {
5285
5294
  return typeArg.exprName.text;
5286
5295
  }
5287
- if (ts3.isQualifiedName(typeArg.exprName)) {
5296
+ if (ts5.isQualifiedName(typeArg.exprName)) {
5288
5297
  return typeArg.exprName.right.text;
5289
5298
  }
5290
5299
  return null;
5291
5300
  }
5292
- var ts3, import_internal3, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
5301
+ var ts5, import_internal4, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
5293
5302
  var init_class_analyzer = __esm({
5294
5303
  "src/analyzer/class-analyzer.ts"() {
5295
5304
  "use strict";
5296
- ts3 = __toESM(require("typescript"), 1);
5297
- import_internal3 = require("@formspec/analysis/internal");
5305
+ ts5 = __toESM(require("typescript"), 1);
5306
+ import_internal4 = require("@formspec/analysis/internal");
5298
5307
  init_jsdoc_constraints();
5299
5308
  init_tsdoc_parser();
5309
+ init_resolve_custom_type();
5310
+ init_ts_type_utils();
5300
5311
  init_metadata();
5301
5312
  RESOLVING_TYPE_PLACEHOLDER = {
5302
5313
  kind: "object",
@@ -5323,23 +5334,23 @@ function createProgramContextFromProgram(program, filePath) {
5323
5334
  function createProgramContext(filePath, additionalFiles) {
5324
5335
  const absolutePath = path.resolve(filePath);
5325
5336
  const fileDir = path.dirname(absolutePath);
5326
- const configPath = ts4.findConfigFile(fileDir, ts4.sys.fileExists.bind(ts4.sys), "tsconfig.json");
5337
+ const configPath = ts6.findConfigFile(fileDir, ts6.sys.fileExists.bind(ts6.sys), "tsconfig.json");
5327
5338
  let compilerOptions;
5328
5339
  let fileNames;
5329
5340
  if (configPath) {
5330
- const configFile = ts4.readConfigFile(configPath, ts4.sys.readFile.bind(ts4.sys));
5341
+ const configFile = ts6.readConfigFile(configPath, ts6.sys.readFile.bind(ts6.sys));
5331
5342
  if (configFile.error) {
5332
5343
  throw new Error(
5333
- `Error reading tsconfig.json: ${ts4.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
5344
+ `Error reading tsconfig.json: ${ts6.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
5334
5345
  );
5335
5346
  }
5336
- const parsed = ts4.parseJsonConfigFileContent(
5347
+ const parsed = ts6.parseJsonConfigFileContent(
5337
5348
  configFile.config,
5338
- ts4.sys,
5349
+ ts6.sys,
5339
5350
  path.dirname(configPath)
5340
5351
  );
5341
5352
  if (parsed.errors.length > 0) {
5342
- const errorMessages = parsed.errors.map((e) => ts4.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
5353
+ const errorMessages = parsed.errors.map((e) => ts6.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
5343
5354
  throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
5344
5355
  }
5345
5356
  compilerOptions = parsed.options;
@@ -5347,9 +5358,9 @@ function createProgramContext(filePath, additionalFiles) {
5347
5358
  fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
5348
5359
  } else {
5349
5360
  compilerOptions = {
5350
- target: ts4.ScriptTarget.ES2022,
5351
- module: ts4.ModuleKind.NodeNext,
5352
- moduleResolution: ts4.ModuleResolutionKind.NodeNext,
5361
+ target: ts6.ScriptTarget.ES2022,
5362
+ module: ts6.ModuleKind.NodeNext,
5363
+ moduleResolution: ts6.ModuleResolutionKind.NodeNext,
5353
5364
  strict: true,
5354
5365
  skipLibCheck: true,
5355
5366
  declaration: true
@@ -5357,7 +5368,7 @@ function createProgramContext(filePath, additionalFiles) {
5357
5368
  const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
5358
5369
  fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
5359
5370
  }
5360
- const program = ts4.createProgram(fileNames, compilerOptions);
5371
+ const program = ts6.createProgram(fileNames, compilerOptions);
5361
5372
  const sourceFile = program.getSourceFile(absolutePath);
5362
5373
  if (!sourceFile) {
5363
5374
  throw new Error(`Could not find source file: ${absolutePath}`);
@@ -5376,19 +5387,19 @@ function findNodeByName(sourceFile, name, predicate, getName) {
5376
5387
  result = node;
5377
5388
  return;
5378
5389
  }
5379
- ts4.forEachChild(node, visit);
5390
+ ts6.forEachChild(node, visit);
5380
5391
  }
5381
5392
  visit(sourceFile);
5382
5393
  return result;
5383
5394
  }
5384
5395
  function findClassByName(sourceFile, className) {
5385
- return findNodeByName(sourceFile, className, ts4.isClassDeclaration, (n) => n.name?.text);
5396
+ return findNodeByName(sourceFile, className, ts6.isClassDeclaration, (n) => n.name?.text);
5386
5397
  }
5387
5398
  function findInterfaceByName(sourceFile, interfaceName) {
5388
- return findNodeByName(sourceFile, interfaceName, ts4.isInterfaceDeclaration, (n) => n.name.text);
5399
+ return findNodeByName(sourceFile, interfaceName, ts6.isInterfaceDeclaration, (n) => n.name.text);
5389
5400
  }
5390
5401
  function findTypeAliasByName(sourceFile, aliasName) {
5391
- return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
5402
+ return findNodeByName(sourceFile, aliasName, ts6.isTypeAliasDeclaration, (n) => n.name.text);
5392
5403
  }
5393
5404
  function getResolvedObjectRootType(rootType, typeRegistry) {
5394
5405
  if (rootType.kind === "object") {
@@ -5428,22 +5439,22 @@ function createResolvedObjectAliasAnalysis(name, rootType, typeRegistry, rootInf
5428
5439
  };
5429
5440
  }
5430
5441
  function containsTypeReferenceInObjectLikeAlias(typeNode) {
5431
- if (ts4.isParenthesizedTypeNode(typeNode)) {
5442
+ if (ts6.isParenthesizedTypeNode(typeNode)) {
5432
5443
  return containsTypeReferenceInObjectLikeAlias(typeNode.type);
5433
5444
  }
5434
- if (ts4.isTypeReferenceNode(typeNode)) {
5445
+ if (ts6.isTypeReferenceNode(typeNode)) {
5435
5446
  return true;
5436
5447
  }
5437
- return ts4.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
5448
+ return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
5438
5449
  }
5439
5450
  function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
5440
- if (ts4.isParenthesizedTypeNode(typeNode)) {
5451
+ if (ts6.isParenthesizedTypeNode(typeNode)) {
5441
5452
  return collectFallbackAliasMemberPropertyNames(typeNode.type, checker);
5442
5453
  }
5443
- if (ts4.isTypeLiteralNode(typeNode)) {
5454
+ if (ts6.isTypeLiteralNode(typeNode)) {
5444
5455
  const propertyNames = [];
5445
5456
  for (const member of typeNode.members) {
5446
- if (!ts4.isPropertySignature(member)) {
5457
+ if (!ts6.isPropertySignature(member)) {
5447
5458
  continue;
5448
5459
  }
5449
5460
  const propertyName = getAnalyzableObjectLikePropertyName(member.name);
@@ -5453,13 +5464,13 @@ function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
5453
5464
  }
5454
5465
  return propertyNames;
5455
5466
  }
5456
- if (ts4.isTypeReferenceNode(typeNode)) {
5467
+ if (ts6.isTypeReferenceNode(typeNode)) {
5457
5468
  return checker.getTypeFromTypeNode(typeNode).getProperties().map((property) => property.getName());
5458
5469
  }
5459
5470
  return null;
5460
5471
  }
5461
5472
  function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
5462
- if (!ts4.isIntersectionTypeNode(typeNode)) {
5473
+ if (!ts6.isIntersectionTypeNode(typeNode)) {
5463
5474
  return [];
5464
5475
  }
5465
5476
  const seen = /* @__PURE__ */ new Set();
@@ -5658,11 +5669,11 @@ function makeFileProvenance(filePath) {
5658
5669
  column: 0
5659
5670
  };
5660
5671
  }
5661
- var ts4, path;
5672
+ var ts6, path;
5662
5673
  var init_program = __esm({
5663
5674
  "src/analyzer/program.ts"() {
5664
5675
  "use strict";
5665
- ts4 = __toESM(require("typescript"), 1);
5676
+ ts6 = __toESM(require("typescript"), 1);
5666
5677
  path = __toESM(require("path"), 1);
5667
5678
  init_class_analyzer();
5668
5679
  }
@@ -5677,10 +5688,10 @@ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistr
5677
5688
  return symbolMap;
5678
5689
  }
5679
5690
  function visit(node) {
5680
- if (ts5.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
5691
+ if (ts7.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
5681
5692
  processDefineCustomTypeCall(node);
5682
5693
  }
5683
- ts5.forEachChild(node, visit);
5694
+ ts7.forEachChild(node, visit);
5684
5695
  }
5685
5696
  function processDefineCustomTypeCall(call) {
5686
5697
  const typeArgNode = call.typeArguments?.[0];
@@ -5688,7 +5699,7 @@ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistr
5688
5699
  return;
5689
5700
  }
5690
5701
  const resolvedType = checker.getTypeFromTypeNode(typeArgNode);
5691
- const canonical = resolveCanonicalSymbol2(resolvedType, checker);
5702
+ const canonical = resolveCanonicalSymbol(resolvedType, checker);
5692
5703
  if (canonical === void 0) {
5693
5704
  return;
5694
5705
  }
@@ -5717,7 +5728,7 @@ function isDefineCustomTypeCall(node, checker) {
5717
5728
  if (node.typeArguments === void 0 || node.typeArguments.length === 0) return false;
5718
5729
  const callSymbol = checker.getSymbolAtLocation(node.expression);
5719
5730
  if (callSymbol !== void 0) {
5720
- const resolved = callSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5731
+ const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5721
5732
  const decl = resolved.declarations?.[0];
5722
5733
  if (decl !== void 0) {
5723
5734
  const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
@@ -5725,29 +5736,24 @@ function isDefineCustomTypeCall(node, checker) {
5725
5736
  (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5726
5737
  }
5727
5738
  }
5728
- return ts5.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
5729
- }
5730
- function resolveCanonicalSymbol2(type, checker) {
5731
- const raw = type.aliasSymbol ?? type.getSymbol();
5732
- if (raw === void 0) return void 0;
5733
- return raw.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(raw) : raw;
5739
+ return ts7.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
5734
5740
  }
5735
5741
  function extractTypeNameFromCallArg(call) {
5736
5742
  const arg = call.arguments[0];
5737
- if (arg === void 0 || !ts5.isObjectLiteralExpression(arg)) {
5743
+ if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
5738
5744
  return null;
5739
5745
  }
5740
5746
  const typeNameProp = arg.properties.find(
5741
- (p) => ts5.isPropertyAssignment(p) && ts5.isIdentifier(p.name) && p.name.text === "typeName"
5747
+ (p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "typeName"
5742
5748
  );
5743
- if (typeNameProp === void 0 || !ts5.isStringLiteral(typeNameProp.initializer)) {
5749
+ if (typeNameProp === void 0 || !ts7.isStringLiteral(typeNameProp.initializer)) {
5744
5750
  return null;
5745
5751
  }
5746
5752
  return typeNameProp.initializer.text;
5747
5753
  }
5748
5754
  function extractEnclosingExtensionId(call, checker) {
5749
- for (let node = call.parent; !ts5.isSourceFile(node); node = node.parent) {
5750
- if (ts5.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
5755
+ for (let node = call.parent; !ts7.isSourceFile(node); node = node.parent) {
5756
+ if (ts7.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
5751
5757
  return extractExtensionIdFromCallArg(node);
5752
5758
  }
5753
5759
  }
@@ -5756,24 +5762,24 @@ function extractEnclosingExtensionId(call, checker) {
5756
5762
  function isDefineExtensionCall(node, checker) {
5757
5763
  const callSymbol = checker.getSymbolAtLocation(node.expression);
5758
5764
  if (callSymbol !== void 0) {
5759
- const resolved = callSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5765
+ const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5760
5766
  const decl = resolved.declarations?.[0];
5761
5767
  if (decl !== void 0) {
5762
5768
  const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
5763
5769
  return resolved.name === "defineExtension" && (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5764
5770
  }
5765
5771
  }
5766
- return ts5.isIdentifier(node.expression) && node.expression.text === "defineExtension";
5772
+ return ts7.isIdentifier(node.expression) && node.expression.text === "defineExtension";
5767
5773
  }
5768
5774
  function extractExtensionIdFromCallArg(call) {
5769
5775
  const arg = call.arguments[0];
5770
- if (arg === void 0 || !ts5.isObjectLiteralExpression(arg)) {
5776
+ if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
5771
5777
  return null;
5772
5778
  }
5773
5779
  const prop = arg.properties.find(
5774
- (p) => ts5.isPropertyAssignment(p) && ts5.isIdentifier(p.name) && p.name.text === "extensionId"
5780
+ (p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "extensionId"
5775
5781
  );
5776
- if (prop === void 0 || !ts5.isStringLiteral(prop.initializer)) {
5782
+ if (prop === void 0 || !ts7.isStringLiteral(prop.initializer)) {
5777
5783
  return null;
5778
5784
  }
5779
5785
  return prop.initializer.text;
@@ -5791,18 +5797,19 @@ function findRegistrationByTypeName(registry, typeName) {
5791
5797
  }
5792
5798
  return void 0;
5793
5799
  }
5794
- var ts5, path2;
5800
+ var ts7, path2;
5795
5801
  var init_symbol_registry = __esm({
5796
5802
  "src/extensions/symbol-registry.ts"() {
5797
5803
  "use strict";
5798
- ts5 = __toESM(require("typescript"), 1);
5804
+ ts7 = __toESM(require("typescript"), 1);
5799
5805
  path2 = __toESM(require("path"), 1);
5806
+ init_ts_type_utils();
5800
5807
  }
5801
5808
  });
5802
5809
 
5803
5810
  // src/validate/constraint-validator.ts
5804
5811
  function validateFieldNode(ctx, field) {
5805
- const analysis = (0, import_internal4.analyzeConstraintTargets)(
5812
+ const analysis = (0, import_internal5.analyzeConstraintTargets)(
5806
5813
  field.name,
5807
5814
  field.type,
5808
5815
  field.constraints,
@@ -5820,7 +5827,7 @@ function validateFieldNode(ctx, field) {
5820
5827
  }
5821
5828
  function validateObjectProperty(ctx, parentName, property) {
5822
5829
  const qualifiedName = `${parentName}.${property.name}`;
5823
- const analysis = (0, import_internal4.analyzeConstraintTargets)(
5830
+ const analysis = (0, import_internal5.analyzeConstraintTargets)(
5824
5831
  qualifiedName,
5825
5832
  property.type,
5826
5833
  property.constraints,
@@ -5871,11 +5878,11 @@ function validateIR(ir, options) {
5871
5878
  valid: ctx.diagnostics.every((diagnostic) => diagnostic.severity !== "error")
5872
5879
  };
5873
5880
  }
5874
- var import_internal4;
5881
+ var import_internal5;
5875
5882
  var init_constraint_validator = __esm({
5876
5883
  "src/validate/constraint-validator.ts"() {
5877
5884
  "use strict";
5878
- import_internal4 = require("@formspec/analysis/internal");
5885
+ import_internal5 = require("@formspec/analysis/internal");
5879
5886
  }
5880
5887
  });
5881
5888
 
@@ -6057,7 +6064,7 @@ function generateSchemasBatch(options) {
6057
6064
  return options.targets.map((target) => {
6058
6065
  let ctx;
6059
6066
  try {
6060
- const cacheKey = ts6.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
6067
+ const cacheKey = ts8.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
6061
6068
  const cachedContext = contextCache.get(cacheKey);
6062
6069
  if (cachedContext === void 0) {
6063
6070
  const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
@@ -6211,11 +6218,11 @@ function createProgramContextFailureDiagnostic(filePath, error) {
6211
6218
  relatedLocations: []
6212
6219
  };
6213
6220
  }
6214
- var ts6;
6221
+ var ts8;
6215
6222
  var init_class_schema = __esm({
6216
6223
  "src/generators/class-schema.ts"() {
6217
6224
  "use strict";
6218
- ts6 = __toESM(require("typescript"), 1);
6225
+ ts8 = __toESM(require("typescript"), 1);
6219
6226
  init_program();
6220
6227
  init_class_analyzer();
6221
6228
  init_canonicalize();
@@ -6242,7 +6249,7 @@ function getModuleSymbol(context) {
6242
6249
  return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
6243
6250
  }
6244
6251
  function isSchemaSourceDeclaration(declaration) {
6245
- return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
6252
+ return ts9.isClassDeclaration(declaration) || ts9.isInterfaceDeclaration(declaration) || ts9.isTypeAliasDeclaration(declaration);
6246
6253
  }
6247
6254
  function resolveModuleExport(context, exportName = "default") {
6248
6255
  const moduleSymbol = getModuleSymbol(context);
@@ -6253,16 +6260,16 @@ function resolveModuleExport(context, exportName = "default") {
6253
6260
  if (exportSymbol === null) {
6254
6261
  return null;
6255
6262
  }
6256
- return exportSymbol.flags & ts7.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
6263
+ return exportSymbol.flags & ts9.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
6257
6264
  }
6258
6265
  function resolveModuleExportDeclaration(context, exportName = "default") {
6259
6266
  return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
6260
6267
  }
6261
- var ts7;
6268
+ var ts9;
6262
6269
  var init_static_build = __esm({
6263
6270
  "src/static-build.ts"() {
6264
6271
  "use strict";
6265
- ts7 = __toESM(require("typescript"), 1);
6272
+ ts9 = __toESM(require("typescript"), 1);
6266
6273
  init_program();
6267
6274
  }
6268
6275
  });
@@ -6275,17 +6282,17 @@ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
6275
6282
  };
6276
6283
  }
6277
6284
  function isNamedTypeDeclaration(declaration) {
6278
- return ts8.isClassDeclaration(declaration) || ts8.isInterfaceDeclaration(declaration) || ts8.isTypeAliasDeclaration(declaration);
6285
+ return ts10.isClassDeclaration(declaration) || ts10.isInterfaceDeclaration(declaration) || ts10.isTypeAliasDeclaration(declaration);
6279
6286
  }
6280
6287
  function hasConcreteTypeArguments(type, checker) {
6281
6288
  if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
6282
6289
  return true;
6283
6290
  }
6284
- if ((type.flags & ts8.TypeFlags.Object) === 0) {
6291
+ if ((type.flags & ts10.TypeFlags.Object) === 0) {
6285
6292
  return false;
6286
6293
  }
6287
6294
  const objectType = type;
6288
- if ((objectType.objectFlags & ts8.ObjectFlags.Reference) === 0) {
6295
+ if ((objectType.objectFlags & ts10.ObjectFlags.Reference) === 0) {
6289
6296
  return false;
6290
6297
  }
6291
6298
  return checker.getTypeArguments(objectType).length > 0;
@@ -6298,13 +6305,13 @@ function getNamedTypeDeclaration2(type) {
6298
6305
  return declaration;
6299
6306
  }
6300
6307
  }
6301
- const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts8.isTypeAliasDeclaration);
6308
+ const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts10.isTypeAliasDeclaration);
6302
6309
  return aliasDeclaration;
6303
6310
  }
6304
6311
  function getFallbackName(sourceNode, fallback = "AnonymousType") {
6305
6312
  if (sourceNode !== void 0 && "name" in sourceNode) {
6306
6313
  const namedNode = sourceNode;
6307
- if (namedNode.name !== void 0 && ts8.isIdentifier(namedNode.name)) {
6314
+ if (namedNode.name !== void 0 && ts10.isIdentifier(namedNode.name)) {
6308
6315
  return namedNode.name.text;
6309
6316
  }
6310
6317
  }
@@ -6526,7 +6533,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6526
6533
  function generateSchemasFromDeclaration(options) {
6527
6534
  const filePath = options.declaration.getSourceFile().fileName;
6528
6535
  const resolved = resolveStaticOptions(options);
6529
- if (ts8.isClassDeclaration(options.declaration)) {
6536
+ if (ts10.isClassDeclaration(options.declaration)) {
6530
6537
  return generateSchemasFromAnalysis(
6531
6538
  analyzeClassToIR(
6532
6539
  options.declaration,
@@ -6540,7 +6547,7 @@ function generateSchemasFromDeclaration(options) {
6540
6547
  resolved
6541
6548
  );
6542
6549
  }
6543
- if (ts8.isInterfaceDeclaration(options.declaration)) {
6550
+ if (ts10.isInterfaceDeclaration(options.declaration)) {
6544
6551
  return generateSchemasFromAnalysis(
6545
6552
  analyzeInterfaceToIR(
6546
6553
  options.declaration,
@@ -6554,7 +6561,7 @@ function generateSchemasFromDeclaration(options) {
6554
6561
  resolved
6555
6562
  );
6556
6563
  }
6557
- if (ts8.isTypeAliasDeclaration(options.declaration)) {
6564
+ if (ts10.isTypeAliasDeclaration(options.declaration)) {
6558
6565
  const analyzedAlias = analyzeTypeAliasToIR(
6559
6566
  options.declaration,
6560
6567
  options.context.checker,
@@ -6613,7 +6620,7 @@ function generateSchemasFromReturnType(options) {
6613
6620
  const returnType = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
6614
6621
  const type = unwrapPromiseType(options.context.checker, returnType);
6615
6622
  const sourceNode = type !== returnType ? unwrapPromiseTypeNode(options.declaration.type) ?? options.declaration.type ?? options.declaration : options.declaration.type ?? options.declaration;
6616
- const fallbackName = options.declaration.name !== void 0 && ts8.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
6623
+ const fallbackName = options.declaration.name !== void 0 && ts10.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
6617
6624
  return generateSchemasFromResolvedType({
6618
6625
  ...options,
6619
6626
  type,
@@ -6623,7 +6630,7 @@ function generateSchemasFromReturnType(options) {
6623
6630
  }
6624
6631
  function resolveDeclarationMetadata(options) {
6625
6632
  const resolved = resolveStaticOptions(options);
6626
- const analysis = (0, import_internal5.analyzeMetadataForNodeWithChecker)({
6633
+ const analysis = (0, import_internal6.analyzeMetadataForNodeWithChecker)({
6627
6634
  checker: options.context.checker,
6628
6635
  node: options.declaration,
6629
6636
  metadata: resolved.metadata,
@@ -6660,21 +6667,21 @@ function unwrapPromiseTypeNode(typeNode) {
6660
6667
  if (typeNode === void 0) {
6661
6668
  return void 0;
6662
6669
  }
6663
- if (ts8.isParenthesizedTypeNode(typeNode)) {
6670
+ if (ts10.isParenthesizedTypeNode(typeNode)) {
6664
6671
  const unwrapped = unwrapPromiseTypeNode(typeNode.type);
6665
6672
  return unwrapped ?? typeNode;
6666
6673
  }
6667
6674
  return isPromiseTypeReferenceNode(typeNode) ? typeNode.typeArguments[0] : typeNode;
6668
6675
  }
6669
6676
  function isPromiseTypeReferenceNode(typeNode) {
6670
- return ts8.isTypeReferenceNode(typeNode) && ts8.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6677
+ return ts10.isTypeReferenceNode(typeNode) && ts10.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6671
6678
  }
6672
- var ts8, import_internal5, import_internals6;
6679
+ var ts10, import_internal6, import_internals6;
6673
6680
  var init_discovered_schema = __esm({
6674
6681
  "src/generators/discovered-schema.ts"() {
6675
6682
  "use strict";
6676
- ts8 = __toESM(require("typescript"), 1);
6677
- import_internal5 = require("@formspec/analysis/internal");
6683
+ ts10 = __toESM(require("typescript"), 1);
6684
+ import_internal6 = require("@formspec/analysis/internal");
6678
6685
  init_class_analyzer();
6679
6686
  init_class_schema();
6680
6687
  init_ir_generator();