@formspec/build 0.1.0-alpha.57 → 0.1.0-alpha.59

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.js CHANGED
@@ -1048,7 +1048,7 @@ function generateJsonSchemaFromIR(ir, options) {
1048
1048
  applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
1049
1049
  }
1050
1050
  if (typeDef.annotations && typeDef.annotations.length > 0) {
1051
- applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
1051
+ applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx, typeDef.type);
1052
1052
  }
1053
1053
  }
1054
1054
  const properties = {};
@@ -1121,7 +1121,7 @@ function generateFieldSchema(field, ctx) {
1121
1121
  }
1122
1122
  }
1123
1123
  applyResolvedMetadata(schema, field.metadata);
1124
- applyAnnotations(schema, rootAnnotations, ctx);
1124
+ applyAnnotations(schema, rootAnnotations, ctx, field.type);
1125
1125
  if (itemStringSchema !== void 0) {
1126
1126
  applyAnnotations(itemStringSchema, itemAnnotations, ctx);
1127
1127
  }
@@ -1164,32 +1164,36 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
1164
1164
  return schema;
1165
1165
  }
1166
1166
  if (schema.$ref) {
1167
- const { $ref, ...rest } = schema;
1168
- const refPart = { $ref };
1169
- const overridePart = {
1170
- properties: propertyOverrides,
1171
- ...rest
1167
+ return {
1168
+ ...schema,
1169
+ properties: propertyOverrides
1172
1170
  };
1173
- return { allOf: [refPart, overridePart] };
1174
1171
  }
1175
1172
  if (schema.type === "object" && schema.properties) {
1176
- const missingOverrides = {};
1177
1173
  for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
1178
- if (schema.properties[target]) {
1179
- mergeSchemaOverride(schema.properties[target], overrideSchema);
1180
- } else {
1181
- missingOverrides[target] = overrideSchema;
1174
+ if (Object.hasOwn(schema.properties, target)) {
1175
+ const existing = schema.properties[target];
1176
+ if (existing) {
1177
+ mergeSchemaOverride(existing, overrideSchema);
1178
+ continue;
1179
+ }
1182
1180
  }
1181
+ Object.defineProperty(schema.properties, target, {
1182
+ value: overrideSchema,
1183
+ writable: true,
1184
+ enumerable: true,
1185
+ configurable: true
1186
+ });
1183
1187
  }
1184
- if (Object.keys(missingOverrides).length === 0) {
1185
- return schema;
1186
- }
1187
- return {
1188
- allOf: [schema, { properties: missingOverrides }]
1189
- };
1188
+ return schema;
1190
1189
  }
1191
1190
  if (schema.allOf) {
1192
- schema.allOf = [...schema.allOf, { properties: propertyOverrides }];
1191
+ const overrideMember = { properties: propertyOverrides };
1192
+ const flattened = tryFlattenAllOfToSiblings(schema, overrideMember);
1193
+ if (flattened !== void 0) {
1194
+ return flattened;
1195
+ }
1196
+ schema.allOf = [...schema.allOf, overrideMember];
1193
1197
  return schema;
1194
1198
  }
1195
1199
  return schema;
@@ -1302,7 +1306,7 @@ function generatePropertySchema(prop, ctx) {
1302
1306
  const schema = generateTypeNode(prop.type, ctx);
1303
1307
  applyConstraints(schema, prop.constraints, ctx);
1304
1308
  applyResolvedMetadata(schema, prop.metadata);
1305
- applyAnnotations(schema, prop.annotations, ctx);
1309
+ applyAnnotations(schema, prop.annotations, ctx, prop.type);
1306
1310
  return schema;
1307
1311
  }
1308
1312
  function generateUnionType(type, ctx) {
@@ -1405,13 +1409,20 @@ function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
1405
1409
  grouped.push(constraint);
1406
1410
  byTarget.set(target, grouped);
1407
1411
  }
1408
- const overrides = {};
1412
+ const overrides = /* @__PURE__ */ Object.create(null);
1409
1413
  for (const [target, constraints] of byTarget) {
1410
- overrides[resolveSerializedPropertyName(target, typeNode, ctx)] = buildPathOverrideSchema(
1414
+ const resolvedName = resolveSerializedPropertyName(target, typeNode, ctx);
1415
+ const schema = buildPathOverrideSchema(
1411
1416
  constraints.map(stripLeadingPathSegment),
1412
1417
  resolveTargetTypeNode(target, typeNode, ctx),
1413
1418
  ctx
1414
1419
  );
1420
+ Object.defineProperty(overrides, resolvedName, {
1421
+ value: schema,
1422
+ writable: true,
1423
+ enumerable: true,
1424
+ configurable: true
1425
+ });
1415
1426
  }
1416
1427
  return overrides;
1417
1428
  }
@@ -1438,6 +1449,34 @@ function buildPathOverrideSchema(constraints, typeNode, ctx) {
1438
1449
  schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
1439
1450
  return schema;
1440
1451
  }
1452
+ function tryFlattenAllOfToSiblings(schema, overrideMember) {
1453
+ if (schema.allOf?.length !== 1) {
1454
+ return void 0;
1455
+ }
1456
+ const [soleMember] = schema.allOf;
1457
+ if (soleMember === void 0) {
1458
+ return void 0;
1459
+ }
1460
+ const { allOf: _allOf, ...outerRest } = schema;
1461
+ const outerKeys = new Set(Object.keys(outerRest));
1462
+ const memberKeys = new Set(Object.keys(soleMember));
1463
+ const overrideKeys = new Set(Object.keys(overrideMember));
1464
+ for (const key of memberKeys) {
1465
+ if (outerKeys.has(key) || overrideKeys.has(key)) {
1466
+ return void 0;
1467
+ }
1468
+ }
1469
+ for (const key of overrideKeys) {
1470
+ if (outerKeys.has(key)) {
1471
+ return void 0;
1472
+ }
1473
+ }
1474
+ return {
1475
+ ...outerRest,
1476
+ ...soleMember,
1477
+ ...overrideMember
1478
+ };
1479
+ }
1441
1480
  function mergeSchemaOverride(target, override) {
1442
1481
  const nullableValueBranch = getNullableUnionValueSchema(target);
1443
1482
  if (nullableValueBranch !== void 0) {
@@ -1445,11 +1484,16 @@ function mergeSchemaOverride(target, override) {
1445
1484
  return;
1446
1485
  }
1447
1486
  if (override.properties !== void 0) {
1448
- const mergedProperties = target.properties ?? {};
1487
+ const mergedProperties = target.properties ?? /* @__PURE__ */ Object.create(null);
1449
1488
  for (const [name, propertyOverride] of Object.entries(override.properties)) {
1450
- const existing = mergedProperties[name];
1489
+ const existing = Object.hasOwn(mergedProperties, name) ? mergedProperties[name] : void 0;
1451
1490
  if (existing === void 0) {
1452
- mergedProperties[name] = propertyOverride;
1491
+ Object.defineProperty(mergedProperties, name, {
1492
+ value: propertyOverride,
1493
+ writable: true,
1494
+ enumerable: true,
1495
+ configurable: true
1496
+ });
1453
1497
  } else {
1454
1498
  mergeSchemaOverride(existing, propertyOverride);
1455
1499
  }
@@ -1467,7 +1511,12 @@ function mergeSchemaOverride(target, override) {
1467
1511
  if (key === "properties" || key === "items") {
1468
1512
  continue;
1469
1513
  }
1470
- target[key] = value;
1514
+ Object.defineProperty(target, key, {
1515
+ value,
1516
+ writable: true,
1517
+ enumerable: true,
1518
+ configurable: true
1519
+ });
1471
1520
  }
1472
1521
  }
1473
1522
  function stripLeadingPathSegment(constraint) {
@@ -1567,7 +1616,7 @@ function applyConstraints(schema, constraints, ctx) {
1567
1616
  }
1568
1617
  }
1569
1618
  }
1570
- function applyAnnotations(schema, annotations, ctx) {
1619
+ function applyAnnotations(schema, annotations, ctx, typeNode) {
1571
1620
  for (const annotation of annotations) {
1572
1621
  switch (annotation.annotationKind) {
1573
1622
  case "displayName":
@@ -1580,7 +1629,7 @@ function applyAnnotations(schema, annotations, ctx) {
1580
1629
  schema[`${ctx.vendorPrefix}-remarks`] = annotation.value;
1581
1630
  break;
1582
1631
  case "defaultValue":
1583
- schema.default = annotation.value;
1632
+ schema.default = coerceDefaultValue(annotation.value, typeNode, schema, ctx);
1584
1633
  break;
1585
1634
  case "format":
1586
1635
  schema.format = annotation.value;
@@ -1605,6 +1654,34 @@ function applyAnnotations(schema, annotations, ctx) {
1605
1654
  }
1606
1655
  }
1607
1656
  }
1657
+ function coerceDefaultValue(value, typeNode, emittedSchema, ctx) {
1658
+ if (typeNode?.kind !== "custom") {
1659
+ return value;
1660
+ }
1661
+ const registration = ctx.extensionRegistry?.findType(typeNode.typeId);
1662
+ if (registration === void 0) {
1663
+ return value;
1664
+ }
1665
+ if (registration.serializeDefault !== void 0) {
1666
+ return registration.serializeDefault(value, typeNode.payload);
1667
+ }
1668
+ const declaredType = emittedSchema["type"];
1669
+ if (declaredType === "string" && typeof value !== "string") {
1670
+ if (typeof value === "number") {
1671
+ if (!Number.isFinite(value)) {
1672
+ return value;
1673
+ }
1674
+ return String(value);
1675
+ }
1676
+ if (typeof value === "boolean") {
1677
+ return String(value);
1678
+ }
1679
+ if (typeof value === "bigint") {
1680
+ return value.toString();
1681
+ }
1682
+ }
1683
+ return value;
1684
+ }
1608
1685
  function generateCustomType(type, ctx) {
1609
1686
  const registration = ctx.extensionRegistry?.findType(type.typeId);
1610
1687
  if (registration === void 0) {
@@ -2062,7 +2139,9 @@ import {
2062
2139
  import {
2063
2140
  getTagDefinition,
2064
2141
  normalizeFormSpecTagName,
2065
- getSyntheticLogger
2142
+ getSyntheticLogger,
2143
+ _validateExtensionSetup,
2144
+ logSetupDiagnostics
2066
2145
  } from "@formspec/analysis/internal";
2067
2146
  function buildConstraintTagSources(extensions) {
2068
2147
  return extensions.map((extension) => ({
@@ -2071,6 +2150,16 @@ function buildConstraintTagSources(extensions) {
2071
2150
  constraintTags: extension.constraintTags.map((tag) => ({
2072
2151
  tagName: normalizeFormSpecTagName(tag.tagName)
2073
2152
  }))
2153
+ } : {},
2154
+ // Include customTypes so _validateExtensionSetup can check tsTypeNames for
2155
+ // unsupported built-in overrides and invalid identifier patterns.
2156
+ ...extension.types !== void 0 ? {
2157
+ customTypes: extension.types.map((type) => ({
2158
+ // tsTypeNames: deprecated in favour of symbol-based detection, but
2159
+ // still required for name-based validation in _validateExtensionSetup
2160
+ // until the bridge is fully retired (see §synthetic-checker-retirement §4C).
2161
+ tsTypeNames: type.tsTypeNames ?? [type.typeName]
2162
+ }))
2074
2163
  } : {}
2075
2164
  }));
2076
2165
  }
@@ -2080,7 +2169,13 @@ function createExtensionRegistry(extensions) {
2080
2169
  extensionCount: extensions.length,
2081
2170
  extensionIds: extensions.map((e) => e.extensionId)
2082
2171
  });
2083
- const reservedTagSources = buildConstraintTagSources(extensions);
2172
+ const extensionTagSources = buildConstraintTagSources(extensions);
2173
+ const setupDiagnostics = _validateExtensionSetup(extensionTagSources);
2174
+ logSetupDiagnostics(registryLog, {
2175
+ diagnosticCount: setupDiagnostics.length,
2176
+ codes: setupDiagnostics.map((d) => d.kind)
2177
+ });
2178
+ const reservedTagSources = extensionTagSources;
2084
2179
  let symbolMap = /* @__PURE__ */ new Map();
2085
2180
  const typeMap = /* @__PURE__ */ new Map();
2086
2181
  const typeNameMap = /* @__PURE__ */ new Map();
@@ -2217,10 +2312,12 @@ function createExtensionRegistry(extensions) {
2217
2312
  constraintTagCount: constraintTagMap.size,
2218
2313
  broadeningCount: builtinBroadeningMap.size,
2219
2314
  annotationCount: annotationMap.size,
2220
- metadataSlotCount: metadataSlotMap.size
2315
+ metadataSlotCount: metadataSlotMap.size,
2316
+ setupDiagnosticCount: setupDiagnostics.length
2221
2317
  });
2222
2318
  return {
2223
2319
  extensions,
2320
+ setupDiagnostics,
2224
2321
  findType: (typeId) => typeMap.get(typeId),
2225
2322
  findTypeByName: (typeName) => typeNameMap.get(typeName),
2226
2323
  findTypeByBrand: (brand) => brandMap.get(brand),
@@ -2320,21 +2417,6 @@ var init_schema2 = __esm({
2320
2417
 
2321
2418
  // src/extensions/ts-type-utils.ts
2322
2419
  import * as ts from "typescript";
2323
- function collectBrandIdentifiers(type) {
2324
- if (!type.isIntersection()) {
2325
- return [];
2326
- }
2327
- const brands = [];
2328
- for (const prop of type.getProperties()) {
2329
- const decl = prop.valueDeclaration ?? prop.declarations?.[0];
2330
- if (decl === void 0) continue;
2331
- if (!ts.isPropertySignature(decl) && !ts.isPropertyDeclaration(decl)) continue;
2332
- if (!ts.isComputedPropertyName(decl.name)) continue;
2333
- if (!ts.isIdentifier(decl.name.expression)) continue;
2334
- brands.push(decl.name.expression.text);
2335
- }
2336
- return brands;
2337
- }
2338
2420
  function resolveCanonicalSymbol(type, checker) {
2339
2421
  const raw = type.aliasSymbol ?? type.getSymbol();
2340
2422
  if (raw === void 0) return void 0;
@@ -2365,7 +2447,7 @@ var init_ts_type_utils = __esm({
2365
2447
 
2366
2448
  // src/extensions/resolve-custom-type.ts
2367
2449
  import * as ts2 from "typescript";
2368
- import { stripNullishUnion } from "@formspec/analysis/internal";
2450
+ import { _collectBrandIdentifiers, stripNullishUnion } from "@formspec/analysis/internal";
2369
2451
  function getTypeNodeRegistrationName(typeNode) {
2370
2452
  if (ts2.isTypeReferenceNode(typeNode)) {
2371
2453
  return ts2.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : typeNode.typeName.right.text;
@@ -2426,7 +2508,7 @@ function resolveCustomTypeFromTsType(type, checker, registry, sourceNode) {
2426
2508
  return bySymbol;
2427
2509
  }
2428
2510
  }
2429
- for (const brand of collectBrandIdentifiers(stripped)) {
2511
+ for (const brand of _collectBrandIdentifiers(stripped)) {
2430
2512
  const byBrand = registry.findTypeByBrand(brand);
2431
2513
  if (byBrand !== void 0) {
2432
2514
  return byBrand;
@@ -2445,21 +2527,15 @@ var init_resolve_custom_type = __esm({
2445
2527
  });
2446
2528
 
2447
2529
  // src/analyzer/builtin-brands.ts
2448
- import * as ts3 from "typescript";
2449
- function isIntegerBrandedType(type) {
2450
- if (!type.isIntersection()) return false;
2451
- if (!type.types.some((member) => !!(member.flags & ts3.TypeFlags.Number))) return false;
2452
- return collectBrandIdentifiers(type).includes("__integerBrand");
2453
- }
2530
+ import { _isIntegerBrandedType } from "@formspec/analysis/internal";
2454
2531
  var init_builtin_brands = __esm({
2455
2532
  "src/analyzer/builtin-brands.ts"() {
2456
2533
  "use strict";
2457
- init_ts_type_utils();
2458
2534
  }
2459
2535
  });
2460
2536
 
2461
2537
  // src/analyzer/tsdoc-parser.ts
2462
- import * as ts4 from "typescript";
2538
+ import * as ts3 from "typescript";
2463
2539
  import {
2464
2540
  checkSyntheticTagApplication,
2465
2541
  choosePreferredPayloadText,
@@ -2484,9 +2560,15 @@ import {
2484
2560
  import "@formspec/core/internals";
2485
2561
  import { noopLogger as noopLogger4 } from "@formspec/core";
2486
2562
  import {
2563
+ _emitSetupDiagnostics,
2564
+ _mapSetupDiagnosticCode,
2487
2565
  getBuildLogger,
2488
2566
  getBroadeningLogger,
2489
2567
  getSyntheticLogger as getSyntheticLogger2,
2568
+ getTypedParserLogger,
2569
+ extractEffectiveArgumentText,
2570
+ mapTypedParserDiagnosticCode,
2571
+ parseTagArgument,
2490
2572
  describeTypeKind,
2491
2573
  elapsedMicros,
2492
2574
  nowMicros,
@@ -2511,23 +2593,23 @@ function getExtensionTypeNames(registry) {
2511
2593
  function collectImportedNames(sourceFile) {
2512
2594
  const importedNames = /* @__PURE__ */ new Set();
2513
2595
  for (const statement of sourceFile.statements) {
2514
- if (ts4.isImportDeclaration(statement) && statement.importClause !== void 0) {
2596
+ if (ts3.isImportDeclaration(statement) && statement.importClause !== void 0) {
2515
2597
  const clause = statement.importClause;
2516
2598
  if (clause.name !== void 0) {
2517
2599
  importedNames.add(clause.name.text);
2518
2600
  }
2519
2601
  if (clause.namedBindings !== void 0) {
2520
- if (ts4.isNamedImports(clause.namedBindings)) {
2602
+ if (ts3.isNamedImports(clause.namedBindings)) {
2521
2603
  for (const specifier of clause.namedBindings.elements) {
2522
2604
  importedNames.add(specifier.name.text);
2523
2605
  }
2524
- } else if (ts4.isNamespaceImport(clause.namedBindings)) {
2606
+ } else if (ts3.isNamespaceImport(clause.namedBindings)) {
2525
2607
  importedNames.add(clause.namedBindings.name.text);
2526
2608
  }
2527
2609
  }
2528
2610
  continue;
2529
2611
  }
2530
- if (ts4.isImportEqualsDeclaration(statement)) {
2612
+ if (ts3.isImportEqualsDeclaration(statement)) {
2531
2613
  importedNames.add(statement.name.text);
2532
2614
  }
2533
2615
  }
@@ -2535,13 +2617,13 @@ function collectImportedNames(sourceFile) {
2535
2617
  }
2536
2618
  function isNonReferenceIdentifier(node) {
2537
2619
  const parent = node.parent;
2538
- if ((ts4.isBindingElement(parent) || ts4.isClassDeclaration(parent) || ts4.isEnumDeclaration(parent) || ts4.isEnumMember(parent) || ts4.isFunctionDeclaration(parent) || ts4.isFunctionExpression(parent) || ts4.isImportClause(parent) || ts4.isImportEqualsDeclaration(parent) || ts4.isImportSpecifier(parent) || ts4.isInterfaceDeclaration(parent) || ts4.isMethodDeclaration(parent) || ts4.isMethodSignature(parent) || ts4.isModuleDeclaration(parent) || ts4.isNamespaceExport(parent) || ts4.isNamespaceImport(parent) || ts4.isParameter(parent) || ts4.isPropertyDeclaration(parent) || ts4.isPropertySignature(parent) || ts4.isSetAccessorDeclaration(parent) || ts4.isGetAccessorDeclaration(parent) || ts4.isTypeAliasDeclaration(parent) || ts4.isTypeParameterDeclaration(parent) || ts4.isVariableDeclaration(parent)) && parent.name === node) {
2620
+ 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) {
2539
2621
  return true;
2540
2622
  }
2541
- if ((ts4.isPropertyAssignment(parent) || ts4.isPropertyAccessExpression(parent)) && parent.name === node) {
2623
+ if ((ts3.isPropertyAssignment(parent) || ts3.isPropertyAccessExpression(parent)) && parent.name === node) {
2542
2624
  return true;
2543
2625
  }
2544
- if (ts4.isQualifiedName(parent) && parent.right === node) {
2626
+ if (ts3.isQualifiedName(parent) && parent.right === node) {
2545
2627
  return true;
2546
2628
  }
2547
2629
  return false;
@@ -2553,20 +2635,20 @@ function astReferencesImportedName(root, importedNames) {
2553
2635
  let found = false;
2554
2636
  const visit = (node) => {
2555
2637
  if (found) return;
2556
- if (ts4.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2638
+ if (ts3.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2557
2639
  found = true;
2558
2640
  return;
2559
2641
  }
2560
- ts4.forEachChild(node, visit);
2642
+ ts3.forEachChild(node, visit);
2561
2643
  };
2562
2644
  visit(root);
2563
2645
  return found;
2564
2646
  }
2565
2647
  function getObjectMembers(statement) {
2566
- if (ts4.isInterfaceDeclaration(statement)) {
2648
+ if (ts3.isInterfaceDeclaration(statement)) {
2567
2649
  return statement.members;
2568
2650
  }
2569
- if (ts4.isTypeLiteralNode(statement.type)) {
2651
+ if (ts3.isTypeLiteralNode(statement.type)) {
2570
2652
  return statement.type.members;
2571
2653
  }
2572
2654
  return void 0;
@@ -2578,7 +2660,7 @@ function rewriteImportedMemberTypes(statement, sourceFile, importedNames) {
2578
2660
  }
2579
2661
  const replacements = [];
2580
2662
  for (const member of members) {
2581
- if (!ts4.isPropertySignature(member)) {
2663
+ if (!ts3.isPropertySignature(member)) {
2582
2664
  if (astReferencesImportedName(member, importedNames)) {
2583
2665
  return null;
2584
2666
  }
@@ -2610,14 +2692,14 @@ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2610
2692
  );
2611
2693
  const result = [];
2612
2694
  for (const statement of sourceFile.statements) {
2613
- if (ts4.isImportDeclaration(statement)) continue;
2614
- if (ts4.isImportEqualsDeclaration(statement)) continue;
2615
- if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
2695
+ if (ts3.isImportDeclaration(statement)) continue;
2696
+ if (ts3.isImportEqualsDeclaration(statement)) continue;
2697
+ if (ts3.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
2616
2698
  if (!astReferencesImportedName(statement, importedNamesToSkip)) {
2617
2699
  result.push(statement.getText(sourceFile));
2618
2700
  continue;
2619
2701
  }
2620
- if (ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement)) {
2702
+ if (ts3.isInterfaceDeclaration(statement) || ts3.isTypeAliasDeclaration(statement)) {
2621
2703
  const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
2622
2704
  if (rewritten !== null) {
2623
2705
  result.push(rewritten);
@@ -2642,6 +2724,7 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
2642
2724
  sourceFile,
2643
2725
  tagName,
2644
2726
  parsedTag,
2727
+ text,
2645
2728
  provenance,
2646
2729
  supportingDeclarations,
2647
2730
  options
@@ -2669,6 +2752,9 @@ function renderSyntheticArgumentExpression(valueKind, argumentText) {
2669
2752
  case "number":
2670
2753
  case "integer":
2671
2754
  case "signedInteger":
2755
+ if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
2756
+ return trimmed;
2757
+ }
2672
2758
  return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
2673
2759
  case "string":
2674
2760
  return JSON.stringify(argumentText);
@@ -2714,7 +2800,7 @@ function stripHintNullishUnion(type) {
2714
2800
  return type;
2715
2801
  }
2716
2802
  const nonNullish = type.types.filter(
2717
- (member) => (member.flags & (ts4.TypeFlags.Null | ts4.TypeFlags.Undefined)) === 0
2803
+ (member) => (member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined)) === 0
2718
2804
  );
2719
2805
  if (nonNullish.length === 1 && nonNullish[0] !== void 0) {
2720
2806
  return nonNullish[0];
@@ -2730,10 +2816,10 @@ function isUserEmittableHintProperty(property, declaration) {
2730
2816
  }
2731
2817
  if ("name" in declaration && declaration.name !== void 0) {
2732
2818
  const name = declaration.name;
2733
- if (ts4.isComputedPropertyName(name) || ts4.isPrivateIdentifier(name)) {
2819
+ if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
2734
2820
  return false;
2735
2821
  }
2736
- if (!ts4.isIdentifier(name) && !ts4.isStringLiteral(name) && !ts4.isNumericLiteral(name)) {
2822
+ if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
2737
2823
  return false;
2738
2824
  }
2739
2825
  }
@@ -2878,7 +2964,7 @@ function hasBuiltinConstraintBroadening(tagName, options) {
2878
2964
  const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
2879
2965
  return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
2880
2966
  }
2881
- function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, provenance, supportingDeclarations, options) {
2967
+ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, supportingDeclarations, options) {
2882
2968
  if (!isBuiltinConstraintName(tagName)) {
2883
2969
  return [];
2884
2970
  }
@@ -2899,8 +2985,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2899
2985
  const log2 = getBuildLogger();
2900
2986
  const broadeningLog = getBroadeningLogger();
2901
2987
  const syntheticLog = getSyntheticLogger2();
2988
+ const typedParserLog = getTypedParserLogger();
2902
2989
  const logsEnabled = log2 !== noopLogger4 || broadeningLog !== noopLogger4;
2903
2990
  const syntheticTraceEnabled = syntheticLog !== noopLogger4;
2991
+ const typedParserTraceEnabled = typedParserLog !== noopLogger4;
2904
2992
  const logStart = logsEnabled ? nowMicros() : 0;
2905
2993
  const subjectTypeKind = logsEnabled ? describeTypeKind(subjectType, checker) : "";
2906
2994
  function emit(outcome, result2) {
@@ -2977,7 +3065,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2977
3065
  }
2978
3066
  const hasBroadening = (() => {
2979
3067
  if (target === null) {
2980
- if (isIntegerBrandedType(stripNullishUnion2(subjectType)) && definition.capabilities.includes("numeric-comparable")) {
3068
+ if (_isIntegerBrandedType(stripNullishUnion2(subjectType)) && definition.capabilities.includes("numeric-comparable")) {
2981
3069
  return true;
2982
3070
  }
2983
3071
  return hasBuiltinConstraintBroadening(tagName, options);
@@ -3008,16 +3096,41 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
3008
3096
  ]);
3009
3097
  }
3010
3098
  }
3011
- const argumentExpression = renderSyntheticArgumentExpression(
3012
- definition.valueKind,
3013
- parsedTag?.argumentText ?? ""
3014
- );
3015
- if (definition.requiresArgument && argumentExpression === null) {
3016
- return emit("A-pass", []);
3017
- }
3018
3099
  if (hasBroadening) {
3019
3100
  return emit("bypass", []);
3020
3101
  }
3102
+ const effectiveArgumentText = extractEffectiveArgumentText(tagName, rawText, parsedTag);
3103
+ const typedParseResult = parseTagArgument(tagName, effectiveArgumentText, "build");
3104
+ if (!typedParseResult.ok) {
3105
+ if (typedParserTraceEnabled) {
3106
+ typedParserLog.trace("typed-parser C-reject", {
3107
+ consumer: "build",
3108
+ tag: tagName,
3109
+ placement: nonNullPlacement,
3110
+ subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
3111
+ roleOutcome: "C-reject",
3112
+ diagnosticCode: typedParseResult.diagnostic.code
3113
+ });
3114
+ }
3115
+ const mappedCode = mapTypedParserDiagnosticCode(typedParseResult.diagnostic.code, tagName);
3116
+ return emit("C-reject", [
3117
+ makeDiagnostic(mappedCode, typedParseResult.diagnostic.message, provenance)
3118
+ ]);
3119
+ }
3120
+ if (typedParserTraceEnabled) {
3121
+ typedParserLog.trace("typed-parser C-pass", {
3122
+ consumer: "build",
3123
+ tag: tagName,
3124
+ placement: nonNullPlacement,
3125
+ subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
3126
+ roleOutcome: "C-pass",
3127
+ valueKind: typedParseResult.value.kind
3128
+ });
3129
+ }
3130
+ const argumentExpression = renderSyntheticArgumentExpression(
3131
+ definition.valueKind,
3132
+ effectiveArgumentText
3133
+ );
3021
3134
  const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
3022
3135
  const hostType = options?.hostType ?? subjectType;
3023
3136
  const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
@@ -3056,13 +3169,13 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
3056
3169
  } : {}
3057
3170
  });
3058
3171
  if (result.diagnostics.length === 0) {
3059
- return emit("C-pass", []);
3172
+ return emit("D-pass", []);
3060
3173
  }
3061
3174
  const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
3062
3175
  if (setupDiagnostic !== void 0) {
3063
3176
  return emit("C-reject", [
3064
3177
  makeDiagnostic(
3065
- setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
3178
+ _mapSetupDiagnosticCode(setupDiagnostic.kind),
3066
3179
  setupDiagnostic.message,
3067
3180
  provenance
3068
3181
  )
@@ -3129,6 +3242,16 @@ function parseTSDocTags(node, file = "", options) {
3129
3242
  if (cached !== void 0) {
3130
3243
  return cached;
3131
3244
  }
3245
+ const setupDiags = options?.extensionRegistry?.setupDiagnostics;
3246
+ if (setupDiags !== void 0 && setupDiags.length > 0) {
3247
+ const result2 = {
3248
+ constraints: [],
3249
+ annotations: [],
3250
+ diagnostics: _emitSetupDiagnostics(setupDiags, file)
3251
+ };
3252
+ parseResultCache.set(cacheKey, result2);
3253
+ return result2;
3254
+ }
3132
3255
  const constraints = [];
3133
3256
  const annotations = [];
3134
3257
  const diagnostics = [];
@@ -3140,12 +3263,12 @@ function parseTSDocTags(node, file = "", options) {
3140
3263
  const sourceText = sourceFile.getFullText();
3141
3264
  const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
3142
3265
  const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
3143
- const commentRanges = ts4.getLeadingCommentRanges(sourceText, node.getFullStart());
3266
+ const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
3144
3267
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
3145
3268
  const extensionTagNames = getExtensionTagNames(options);
3146
3269
  if (commentRanges) {
3147
3270
  for (const range of commentRanges) {
3148
- if (range.kind !== ts4.SyntaxKind.MultiLineCommentTrivia) {
3271
+ if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) {
3149
3272
  continue;
3150
3273
  }
3151
3274
  const commentText = sourceText.substring(range.pos, range.end);
@@ -3302,10 +3425,10 @@ function extractDisplayNameMetadata(node) {
3302
3425
  const memberDisplayNames = /* @__PURE__ */ new Map();
3303
3426
  const sourceFile = node.getSourceFile();
3304
3427
  const sourceText = sourceFile.getFullText();
3305
- const commentRanges = ts4.getLeadingCommentRanges(sourceText, node.getFullStart());
3428
+ const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
3306
3429
  if (commentRanges) {
3307
3430
  for (const range of commentRanges) {
3308
- if (range.kind !== ts4.SyntaxKind.MultiLineCommentTrivia) continue;
3431
+ if (range.kind !== ts3.SyntaxKind.MultiLineCommentTrivia) continue;
3309
3432
  const commentText = sourceText.substring(range.pos, range.end);
3310
3433
  if (!commentText.startsWith("/**")) continue;
3311
3434
  const unified = parseUnifiedComment(commentText);
@@ -3330,7 +3453,7 @@ function extractDisplayNameMetadata(node) {
3330
3453
  }
3331
3454
  function collectRawTextFallbacks(node, file) {
3332
3455
  const fallbacks = /* @__PURE__ */ new Map();
3333
- for (const tag of ts4.getJSDocTags(node)) {
3456
+ for (const tag of ts3.getJSDocTags(node)) {
3334
3457
  const tagName = normalizeConstraintTagName2(tag.tagName.text);
3335
3458
  if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
3336
3459
  const commentText = getTagCommentText(tag)?.trim() ?? "";
@@ -3385,7 +3508,7 @@ function getTagCommentText(tag) {
3385
3508
  if (typeof tag.comment === "string") {
3386
3509
  return tag.comment;
3387
3510
  }
3388
- return ts4.getTextOfJSDocComment(tag.comment);
3511
+ return ts3.getTextOfJSDocComment(tag.comment);
3389
3512
  }
3390
3513
  var SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3391
3514
  var init_tsdoc_parser = __esm({
@@ -3393,7 +3516,7 @@ var init_tsdoc_parser = __esm({
3393
3516
  "use strict";
3394
3517
  init_resolve_custom_type();
3395
3518
  init_builtin_brands();
3396
- SYNTHETIC_TYPE_FORMAT_FLAGS = ts4.TypeFormatFlags.NoTruncation | ts4.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3519
+ SYNTHETIC_TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3397
3520
  MAX_HINT_CANDIDATES = 5;
3398
3521
  MAX_HINT_DEPTH = 3;
3399
3522
  parseResultCache = /* @__PURE__ */ new Map();
@@ -3401,7 +3524,7 @@ var init_tsdoc_parser = __esm({
3401
3524
  });
3402
3525
 
3403
3526
  // src/analyzer/jsdoc-constraints.ts
3404
- import * as ts5 from "typescript";
3527
+ import * as ts4 from "typescript";
3405
3528
  function extractJSDocParseResult(node, file = "", options) {
3406
3529
  return parseTSDocTags(node, file, options);
3407
3530
  }
@@ -3416,18 +3539,18 @@ function extractJSDocAnnotationNodes(node, file = "", options) {
3416
3539
  function extractDefaultValueAnnotation(initializer, file = "") {
3417
3540
  if (!initializer) return null;
3418
3541
  let value;
3419
- if (ts5.isStringLiteral(initializer)) {
3542
+ if (ts4.isStringLiteral(initializer)) {
3420
3543
  value = initializer.text;
3421
- } else if (ts5.isNumericLiteral(initializer)) {
3544
+ } else if (ts4.isNumericLiteral(initializer)) {
3422
3545
  value = Number(initializer.text);
3423
- } else if (initializer.kind === ts5.SyntaxKind.TrueKeyword) {
3546
+ } else if (initializer.kind === ts4.SyntaxKind.TrueKeyword) {
3424
3547
  value = true;
3425
- } else if (initializer.kind === ts5.SyntaxKind.FalseKeyword) {
3548
+ } else if (initializer.kind === ts4.SyntaxKind.FalseKeyword) {
3426
3549
  value = false;
3427
- } else if (initializer.kind === ts5.SyntaxKind.NullKeyword) {
3550
+ } else if (initializer.kind === ts4.SyntaxKind.NullKeyword) {
3428
3551
  value = null;
3429
- } else if (ts5.isPrefixUnaryExpression(initializer)) {
3430
- if (initializer.operator === ts5.SyntaxKind.MinusToken && ts5.isNumericLiteral(initializer.operand)) {
3552
+ } else if (ts4.isPrefixUnaryExpression(initializer)) {
3553
+ if (initializer.operator === ts4.SyntaxKind.MinusToken && ts4.isNumericLiteral(initializer.operand)) {
3431
3554
  value = -Number(initializer.operand.text);
3432
3555
  }
3433
3556
  }
@@ -3454,34 +3577,34 @@ var init_jsdoc_constraints = __esm({
3454
3577
  });
3455
3578
 
3456
3579
  // src/analyzer/class-analyzer.ts
3457
- import * as ts6 from "typescript";
3580
+ import * as ts5 from "typescript";
3458
3581
  import {
3459
3582
  analyzeMetadataForNodeWithChecker,
3460
3583
  parseCommentBlock
3461
3584
  } from "@formspec/analysis/internal";
3462
3585
  function isObjectType(type) {
3463
- return !!(type.flags & ts6.TypeFlags.Object);
3586
+ return !!(type.flags & ts5.TypeFlags.Object);
3464
3587
  }
3465
3588
  function isIntersectionType(type) {
3466
- return !!(type.flags & ts6.TypeFlags.Intersection);
3589
+ return !!(type.flags & ts5.TypeFlags.Intersection);
3467
3590
  }
3468
3591
  function isResolvableObjectLikeAliasTypeNode(typeNode) {
3469
- if (ts6.isParenthesizedTypeNode(typeNode)) {
3592
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
3470
3593
  return isResolvableObjectLikeAliasTypeNode(typeNode.type);
3471
3594
  }
3472
- if (ts6.isTypeLiteralNode(typeNode) || ts6.isTypeReferenceNode(typeNode)) {
3595
+ if (ts5.isTypeLiteralNode(typeNode) || ts5.isTypeReferenceNode(typeNode)) {
3473
3596
  return true;
3474
3597
  }
3475
- return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
3598
+ return ts5.isIntersectionTypeNode(typeNode) && typeNode.types.length > 0 && typeNode.types.every((member) => isResolvableObjectLikeAliasTypeNode(member));
3476
3599
  }
3477
3600
  function isSemanticallyPlainObjectLikeType(type, checker) {
3478
3601
  if (isIntersectionType(type)) {
3479
3602
  return type.types.length > 0 && type.types.every((member) => isSemanticallyPlainObjectLikeType(member, checker));
3480
3603
  }
3481
- return isObjectType(type) && checker.getSignaturesOfType(type, ts6.SignatureKind.Call).length === 0 && checker.getSignaturesOfType(type, ts6.SignatureKind.Construct).length === 0 && !checker.isArrayType(type) && !checker.isTupleType(type);
3604
+ 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);
3482
3605
  }
3483
3606
  function isTypeReference(type) {
3484
- return !!(type.flags & ts6.TypeFlags.Object) && !!(type.objectFlags & ts6.ObjectFlags.Reference);
3607
+ return !!(type.flags & ts5.TypeFlags.Object) && !!(type.objectFlags & ts5.ObjectFlags.Reference);
3485
3608
  }
3486
3609
  function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, hostType) {
3487
3610
  if (extensionRegistry === void 0 && fieldType === void 0 && checker === void 0 && subjectType === void 0 && hostType === void 0) {
@@ -3502,6 +3625,17 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
3502
3625
  discriminator
3503
3626
  };
3504
3627
  }
3628
+ function deduplicateDiagnostics(diagnostics) {
3629
+ if (diagnostics.length <= 1) return diagnostics;
3630
+ const seen = /* @__PURE__ */ new Set();
3631
+ return diagnostics.filter((d) => {
3632
+ if (!DEDUPLICATABLE_DIAGNOSTIC_CODES.has(d.code)) return true;
3633
+ const key = `${d.code}\0${d.message}`;
3634
+ if (seen.has(key)) return false;
3635
+ seen.add(key);
3636
+ return true;
3637
+ });
3638
+ }
3505
3639
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
3506
3640
  const analysis = analyzeMetadataForNodeWithChecker({
3507
3641
  checker,
@@ -3538,10 +3672,120 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
3538
3672
  }
3539
3673
  return resolvedMetadata;
3540
3674
  }
3675
+ function getInheritableAnnotationStringValue(annotation) {
3676
+ if (annotation.annotationKind === "format") return annotation.value;
3677
+ return void 0;
3678
+ }
3679
+ function isOverridingInheritableAnnotation(annotation) {
3680
+ const value = getInheritableAnnotationStringValue(annotation);
3681
+ if (value === void 0) return true;
3682
+ return value.trim().length > 0;
3683
+ }
3684
+ function collectInheritedTypeAnnotations(derivedDecl, existingAnnotations, checker, extensionRegistry) {
3685
+ const existingKinds = new Set(
3686
+ existingAnnotations.filter(isOverridingInheritableAnnotation).map((a) => a.annotationKind)
3687
+ );
3688
+ const needed = /* @__PURE__ */ new Set();
3689
+ for (const kind of INHERITABLE_TYPE_ANNOTATION_KINDS) {
3690
+ if (!existingKinds.has(kind)) needed.add(kind);
3691
+ }
3692
+ if (needed.size === 0) return [];
3693
+ const inherited = [];
3694
+ const seen = /* @__PURE__ */ new Set([derivedDecl]);
3695
+ const queue = [];
3696
+ const resolveSymbolTarget = (sym) => {
3697
+ if ((sym.flags & ts5.SymbolFlags.Alias) === 0) return sym;
3698
+ try {
3699
+ return checker.getAliasedSymbol(sym);
3700
+ } catch {
3701
+ return sym;
3702
+ }
3703
+ };
3704
+ const isObjectShapedTypeAlias = (alias) => {
3705
+ const type = checker.getTypeFromTypeNode(alias.type);
3706
+ if ((type.flags & ts5.TypeFlags.Object) !== 0) return true;
3707
+ if (type.isIntersection()) return true;
3708
+ return false;
3709
+ };
3710
+ const enqueueCandidate = (baseDecl, fromTypeAliasRhs) => {
3711
+ if (seen.has(baseDecl)) return;
3712
+ if (ts5.isClassDeclaration(baseDecl) || ts5.isInterfaceDeclaration(baseDecl)) {
3713
+ seen.add(baseDecl);
3714
+ queue.push(baseDecl);
3715
+ return;
3716
+ }
3717
+ if (ts5.isTypeAliasDeclaration(baseDecl)) {
3718
+ if (!fromTypeAliasRhs && !isObjectShapedTypeAlias(baseDecl)) return;
3719
+ seen.add(baseDecl);
3720
+ queue.push(baseDecl);
3721
+ }
3722
+ };
3723
+ const enqueueBasesOf = (decl) => {
3724
+ if (ts5.isTypeAliasDeclaration(decl)) {
3725
+ const rhs = decl.type;
3726
+ if (!ts5.isTypeReferenceNode(rhs)) return;
3727
+ const sym = checker.getSymbolAtLocation(rhs.typeName);
3728
+ if (!sym) return;
3729
+ const target = resolveSymbolTarget(sym);
3730
+ for (const baseDecl of target.declarations ?? []) {
3731
+ enqueueCandidate(
3732
+ baseDecl,
3733
+ /*fromTypeAliasRhs*/
3734
+ true
3735
+ );
3736
+ }
3737
+ return;
3738
+ }
3739
+ const heritageClauses = decl.heritageClauses;
3740
+ if (!heritageClauses) return;
3741
+ for (const clause of heritageClauses) {
3742
+ if (clause.token !== ts5.SyntaxKind.ExtendsKeyword) continue;
3743
+ for (const typeExpr of clause.types) {
3744
+ const sym = checker.getSymbolAtLocation(typeExpr.expression);
3745
+ if (!sym) continue;
3746
+ const target = resolveSymbolTarget(sym);
3747
+ for (const baseDecl of target.declarations ?? []) {
3748
+ enqueueCandidate(
3749
+ baseDecl,
3750
+ /*fromTypeAliasRhs*/
3751
+ false
3752
+ );
3753
+ }
3754
+ }
3755
+ }
3756
+ };
3757
+ enqueueBasesOf(derivedDecl);
3758
+ for (let queueIndex = 0; queueIndex < queue.length && needed.size > 0; queueIndex++) {
3759
+ const baseDecl = queue[queueIndex];
3760
+ if (baseDecl === void 0) continue;
3761
+ const baseFile = baseDecl.getSourceFile().fileName;
3762
+ const baseAnnotations = extractJSDocAnnotationNodes(
3763
+ baseDecl,
3764
+ baseFile,
3765
+ makeParseOptions(extensionRegistry)
3766
+ );
3767
+ for (const annotation of baseAnnotations) {
3768
+ if (!needed.has(annotation.annotationKind)) continue;
3769
+ if (!isOverridingInheritableAnnotation(annotation)) continue;
3770
+ inherited.push(annotation);
3771
+ needed.delete(annotation.annotationKind);
3772
+ }
3773
+ if (needed.size > 0) {
3774
+ enqueueBasesOf(baseDecl);
3775
+ }
3776
+ }
3777
+ return inherited;
3778
+ }
3779
+ function extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) {
3780
+ const local = extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry));
3781
+ const inherited = collectInheritedTypeAnnotations(namedDecl, local, checker, extensionRegistry);
3782
+ if (inherited.length === 0) return [...local];
3783
+ return [...local, ...inherited];
3784
+ }
3541
3785
  function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
3542
3786
  const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3543
3787
  const declarationType = checker.getTypeAtLocation(declaration);
3544
- const logicalName = ts6.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
3788
+ const logicalName = ts5.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
3545
3789
  const docResult = extractJSDocParseResult(
3546
3790
  declaration,
3547
3791
  file,
@@ -3583,13 +3827,19 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3583
3827
  file,
3584
3828
  makeParseOptions(extensionRegistry, void 0, checker, classType, classType)
3585
3829
  );
3586
- const annotations = [...classDoc.annotations];
3830
+ const inheritedClassAnnotations = collectInheritedTypeAnnotations(
3831
+ classDecl,
3832
+ classDoc.annotations,
3833
+ checker,
3834
+ extensionRegistry
3835
+ );
3836
+ const annotations = [...classDoc.annotations, ...inheritedClassAnnotations];
3587
3837
  diagnostics.push(...classDoc.diagnostics);
3588
3838
  const visiting = /* @__PURE__ */ new Set();
3589
3839
  const instanceMethods = [];
3590
3840
  const staticMethods = [];
3591
3841
  for (const member of classDecl.members) {
3592
- if (ts6.isPropertyDeclaration(member)) {
3842
+ if (ts5.isPropertyDeclaration(member)) {
3593
3843
  const fieldNode = analyzeFieldToIR(
3594
3844
  member,
3595
3845
  checker,
@@ -3605,10 +3855,10 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3605
3855
  fields.push(fieldNode);
3606
3856
  fieldLayouts.push({});
3607
3857
  }
3608
- } else if (ts6.isMethodDeclaration(member)) {
3858
+ } else if (ts5.isMethodDeclaration(member)) {
3609
3859
  const methodInfo = analyzeMethod(member, checker);
3610
3860
  if (methodInfo) {
3611
- const isStatic = member.modifiers?.some((m) => m.kind === ts6.SyntaxKind.StaticKeyword);
3861
+ const isStatic = member.modifiers?.some((m) => m.kind === ts5.SyntaxKind.StaticKeyword);
3612
3862
  if (isStatic) {
3613
3863
  staticMethods.push(methodInfo);
3614
3864
  } else {
@@ -3640,6 +3890,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3640
3890
  hostType: classType
3641
3891
  }
3642
3892
  );
3893
+ const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
3643
3894
  return {
3644
3895
  name,
3645
3896
  ...metadata !== void 0 && { metadata },
@@ -3647,7 +3898,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3647
3898
  fieldLayouts,
3648
3899
  typeRegistry,
3649
3900
  ...annotations.length > 0 && { annotations },
3650
- ...diagnostics.length > 0 && { diagnostics },
3901
+ ...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
3651
3902
  instanceMethods,
3652
3903
  staticMethods
3653
3904
  };
@@ -3667,11 +3918,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3667
3918
  file,
3668
3919
  makeParseOptions(extensionRegistry, void 0, checker, interfaceType, interfaceType)
3669
3920
  );
3670
- const annotations = [...interfaceDoc.annotations];
3921
+ const inheritedInterfaceAnnotations = collectInheritedTypeAnnotations(
3922
+ interfaceDecl,
3923
+ interfaceDoc.annotations,
3924
+ checker,
3925
+ extensionRegistry
3926
+ );
3927
+ const annotations = [
3928
+ ...interfaceDoc.annotations,
3929
+ ...inheritedInterfaceAnnotations
3930
+ ];
3671
3931
  diagnostics.push(...interfaceDoc.diagnostics);
3672
3932
  const visiting = /* @__PURE__ */ new Set();
3673
3933
  for (const member of interfaceDecl.members) {
3674
- if (ts6.isPropertySignature(member)) {
3934
+ if (ts5.isPropertySignature(member)) {
3675
3935
  const fieldNode = analyzeInterfacePropertyToIR(
3676
3936
  member,
3677
3937
  checker,
@@ -3712,6 +3972,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3712
3972
  hostType: interfaceType
3713
3973
  }
3714
3974
  );
3975
+ const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
3715
3976
  return {
3716
3977
  name,
3717
3978
  ...metadata !== void 0 && { metadata },
@@ -3719,7 +3980,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3719
3980
  fieldLayouts,
3720
3981
  typeRegistry,
3721
3982
  ...annotations.length > 0 && { annotations },
3722
- ...diagnostics.length > 0 && { diagnostics },
3983
+ ...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
3723
3984
  instanceMethods: [],
3724
3985
  staticMethods: []
3725
3986
  };
@@ -3729,7 +3990,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3729
3990
  if (members === null) {
3730
3991
  const sourceFile = typeAlias.getSourceFile();
3731
3992
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3732
- const kindDesc = ts6.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3993
+ const kindDesc = ts5.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3733
3994
  return {
3734
3995
  ok: false,
3735
3996
  kind: "not-object-like",
@@ -3764,7 +4025,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3764
4025
  diagnostics.push(...typeAliasDoc.diagnostics);
3765
4026
  const visiting = /* @__PURE__ */ new Set();
3766
4027
  for (const member of members) {
3767
- if (ts6.isPropertySignature(member)) {
4028
+ if (ts5.isPropertySignature(member)) {
3768
4029
  const fieldNode = analyzeInterfacePropertyToIR(
3769
4030
  member,
3770
4031
  checker,
@@ -3804,6 +4065,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3804
4065
  hostType: aliasType
3805
4066
  }
3806
4067
  );
4068
+ const deduplicatedDiagnostics = deduplicateDiagnostics(diagnostics);
3807
4069
  return {
3808
4070
  ok: true,
3809
4071
  analysis: {
@@ -3813,7 +4075,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3813
4075
  fieldLayouts: specializedFields.map(() => ({})),
3814
4076
  typeRegistry,
3815
4077
  ...annotations.length > 0 && { annotations },
3816
- ...diagnostics.length > 0 && { diagnostics },
4078
+ ...deduplicatedDiagnostics.length > 0 && { diagnostics: deduplicatedDiagnostics },
3817
4079
  instanceMethods: [],
3818
4080
  staticMethods: []
3819
4081
  }
@@ -3831,13 +4093,13 @@ function makeAnalysisDiagnostic(code, message, primaryLocation, relatedLocations
3831
4093
  function getLeadingParsedTags(node) {
3832
4094
  const sourceFile = node.getSourceFile();
3833
4095
  const sourceText = sourceFile.getFullText();
3834
- const commentRanges = ts6.getLeadingCommentRanges(sourceText, node.getFullStart());
4096
+ const commentRanges = ts5.getLeadingCommentRanges(sourceText, node.getFullStart());
3835
4097
  if (commentRanges === void 0) {
3836
4098
  return [];
3837
4099
  }
3838
4100
  const parsedTags = [];
3839
4101
  for (const range of commentRanges) {
3840
- if (range.kind !== ts6.SyntaxKind.MultiLineCommentTrivia) {
4102
+ if (range.kind !== ts5.SyntaxKind.MultiLineCommentTrivia) {
3841
4103
  continue;
3842
4104
  }
3843
4105
  const commentText = sourceText.slice(range.pos, range.end);
@@ -3855,19 +4117,19 @@ function resolveDiscriminatorProperty(node, checker, fieldName) {
3855
4117
  return null;
3856
4118
  }
3857
4119
  const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
3858
- (candidate) => ts6.isPropertyDeclaration(candidate) || ts6.isPropertySignature(candidate)
4120
+ (candidate) => ts5.isPropertyDeclaration(candidate) || ts5.isPropertySignature(candidate)
3859
4121
  ) ?? propertySymbol.declarations?.[0];
3860
4122
  return {
3861
4123
  declaration,
3862
4124
  type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
3863
- optional: !!(propertySymbol.flags & ts6.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
4125
+ optional: !!(propertySymbol.flags & ts5.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
3864
4126
  };
3865
4127
  }
3866
4128
  function isLocalTypeParameterName(node, typeParameterName) {
3867
4129
  return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
3868
4130
  }
3869
4131
  function isNullishSemanticType(type) {
3870
- if (type.flags & (ts6.TypeFlags.Null | ts6.TypeFlags.Undefined | ts6.TypeFlags.Void | ts6.TypeFlags.Unknown | ts6.TypeFlags.Any)) {
4132
+ if (type.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined | ts5.TypeFlags.Void | ts5.TypeFlags.Unknown | ts5.TypeFlags.Any)) {
3871
4133
  return true;
3872
4134
  }
3873
4135
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
@@ -3877,7 +4139,7 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
3877
4139
  return false;
3878
4140
  }
3879
4141
  seen.add(type);
3880
- if (type.flags & ts6.TypeFlags.StringLike) {
4142
+ if (type.flags & ts5.TypeFlags.StringLike) {
3881
4143
  return true;
3882
4144
  }
3883
4145
  if (type.isUnion()) {
@@ -3890,13 +4152,13 @@ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set(
3890
4152
  return false;
3891
4153
  }
3892
4154
  function getObjectLikeTypeAliasMembers(typeNode) {
3893
- if (ts6.isParenthesizedTypeNode(typeNode)) {
4155
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
3894
4156
  return getObjectLikeTypeAliasMembers(typeNode.type);
3895
4157
  }
3896
- if (ts6.isTypeLiteralNode(typeNode)) {
4158
+ if (ts5.isTypeLiteralNode(typeNode)) {
3897
4159
  return [...typeNode.members];
3898
4160
  }
3899
- if (ts6.isIntersectionTypeNode(typeNode)) {
4161
+ if (ts5.isIntersectionTypeNode(typeNode)) {
3900
4162
  const members = [];
3901
4163
  for (const intersectionMember of typeNode.types) {
3902
4164
  const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
@@ -4059,7 +4321,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, check
4059
4321
  }
4060
4322
  if (propertyType.isUnion()) {
4061
4323
  const nonNullMembers = propertyType.types.filter(
4062
- (member) => !(member.flags & (ts6.TypeFlags.Null | ts6.TypeFlags.Undefined))
4324
+ (member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
4063
4325
  );
4064
4326
  if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
4065
4327
  diagnostics.push(
@@ -4108,13 +4370,13 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
4108
4370
  seen.add(type);
4109
4371
  const symbol = type.aliasSymbol ?? type.getSymbol();
4110
4372
  if (symbol !== void 0) {
4111
- const aliased = symbol.flags & ts6.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
4373
+ const aliased = symbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : void 0;
4112
4374
  const targetSymbol = aliased ?? symbol;
4113
4375
  const declaration = targetSymbol.declarations?.find(
4114
- (candidate) => ts6.isClassDeclaration(candidate) || ts6.isInterfaceDeclaration(candidate) || ts6.isTypeAliasDeclaration(candidate) || ts6.isEnumDeclaration(candidate)
4376
+ (candidate) => ts5.isClassDeclaration(candidate) || ts5.isInterfaceDeclaration(candidate) || ts5.isTypeAliasDeclaration(candidate) || ts5.isEnumDeclaration(candidate)
4115
4377
  );
4116
4378
  if (declaration !== void 0) {
4117
- if (ts6.isTypeAliasDeclaration(declaration) && ts6.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
4379
+ if (ts5.isTypeAliasDeclaration(declaration) && ts5.isTypeReferenceNode(declaration.type) && checker.getTypeFromTypeNode(declaration.type) !== type) {
4118
4380
  return resolveNamedDiscriminatorDeclaration(
4119
4381
  checker.getTypeFromTypeNode(declaration.type),
4120
4382
  checker,
@@ -4142,7 +4404,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
4142
4404
  }
4143
4405
  if (boundType.isUnion()) {
4144
4406
  const nonNullMembers = boundType.types.filter(
4145
- (member) => !(member.flags & (ts6.TypeFlags.Null | ts6.TypeFlags.Undefined))
4407
+ (member) => !(member.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
4146
4408
  );
4147
4409
  if (nonNullMembers.every((member) => member.isStringLiteral())) {
4148
4410
  diagnostics.push(
@@ -4187,7 +4449,7 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
4187
4449
  return null;
4188
4450
  }
4189
4451
  function getDeclarationName(node) {
4190
- if (ts6.isClassDeclaration(node) || ts6.isInterfaceDeclaration(node) || ts6.isTypeAliasDeclaration(node) || ts6.isEnumDeclaration(node)) {
4452
+ if (ts5.isClassDeclaration(node) || ts5.isInterfaceDeclaration(node) || ts5.isTypeAliasDeclaration(node) || ts5.isEnumDeclaration(node)) {
4191
4453
  return node.name?.text ?? "anonymous";
4192
4454
  }
4193
4455
  return "anonymous";
@@ -4242,11 +4504,11 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
4242
4504
  if (sourceTypeNode === void 0) {
4243
4505
  return [];
4244
4506
  }
4245
- const unwrapParentheses = (typeNode) => ts6.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
4507
+ const unwrapParentheses = (typeNode) => ts5.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
4246
4508
  const directTypeNode = unwrapParentheses(sourceTypeNode);
4247
- const referenceTypeNode = ts6.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
4509
+ const referenceTypeNode = ts5.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
4248
4510
  const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
4249
- return ts6.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
4511
+ return ts5.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
4250
4512
  })();
4251
4513
  if (referenceTypeNode?.typeArguments === void 0) {
4252
4514
  return [];
@@ -4254,7 +4516,7 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
4254
4516
  return referenceTypeNode.typeArguments.map((argumentNode) => {
4255
4517
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
4256
4518
  const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
4257
- const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts6.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
4519
+ const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts5.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
4258
4520
  const argumentDecl = argumentSymbol?.declarations?.[0];
4259
4521
  if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
4260
4522
  const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
@@ -4317,7 +4579,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
4317
4579
  );
4318
4580
  }
4319
4581
  function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
4320
- if (!ts6.isIdentifier(prop.name)) {
4582
+ if (!ts5.isIdentifier(prop.name)) {
4321
4583
  return null;
4322
4584
  }
4323
4585
  const name = prop.name.text;
@@ -4444,7 +4706,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
4444
4706
  const seen = /* @__PURE__ */ new Set();
4445
4707
  const duplicates = /* @__PURE__ */ new Set();
4446
4708
  for (const member of members) {
4447
- if (!ts6.isPropertySignature(member)) {
4709
+ if (!ts5.isPropertySignature(member)) {
4448
4710
  continue;
4449
4711
  }
4450
4712
  const name = getAnalyzableObjectLikePropertyName(member.name);
@@ -4460,7 +4722,7 @@ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
4460
4722
  return [...duplicates].sort();
4461
4723
  }
4462
4724
  function getAnalyzableObjectLikePropertyName(name) {
4463
- if (ts6.isIdentifier(name) || ts6.isStringLiteral(name) || ts6.isNumericLiteral(name)) {
4725
+ if (ts5.isIdentifier(name) || ts5.isStringLiteral(name) || ts5.isNumericLiteral(name)) {
4464
4726
  return name.text;
4465
4727
  }
4466
4728
  return null;
@@ -4555,28 +4817,28 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4555
4817
  if (primitiveAlias) {
4556
4818
  return primitiveAlias;
4557
4819
  }
4558
- if (isIntegerBrandedType(type)) {
4820
+ if (_isIntegerBrandedType(type)) {
4559
4821
  return { kind: "primitive", primitiveKind: "integer" };
4560
4822
  }
4561
- if (type.flags & ts6.TypeFlags.String) {
4823
+ if (type.flags & ts5.TypeFlags.String) {
4562
4824
  return { kind: "primitive", primitiveKind: "string" };
4563
4825
  }
4564
- if (type.flags & ts6.TypeFlags.Number) {
4826
+ if (type.flags & ts5.TypeFlags.Number) {
4565
4827
  return { kind: "primitive", primitiveKind: "number" };
4566
4828
  }
4567
- if (type.flags & (ts6.TypeFlags.BigInt | ts6.TypeFlags.BigIntLiteral)) {
4829
+ if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
4568
4830
  return { kind: "primitive", primitiveKind: "bigint" };
4569
4831
  }
4570
- if (type.flags & ts6.TypeFlags.Boolean) {
4832
+ if (type.flags & ts5.TypeFlags.Boolean) {
4571
4833
  return { kind: "primitive", primitiveKind: "boolean" };
4572
4834
  }
4573
- if (type.flags & ts6.TypeFlags.Null) {
4835
+ if (type.flags & ts5.TypeFlags.Null) {
4574
4836
  return { kind: "primitive", primitiveKind: "null" };
4575
4837
  }
4576
- if (type.flags & ts6.TypeFlags.Undefined) {
4838
+ if (type.flags & ts5.TypeFlags.Undefined) {
4577
4839
  return { kind: "primitive", primitiveKind: "null" };
4578
4840
  }
4579
- if (type.flags & ts6.TypeFlags.Void) {
4841
+ if (type.flags & ts5.TypeFlags.Void) {
4580
4842
  return { kind: "primitive", primitiveKind: "null" };
4581
4843
  }
4582
4844
  if (type.isStringLiteral()) {
@@ -4663,10 +4925,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4663
4925
  return { kind: "primitive", primitiveKind: "string" };
4664
4926
  }
4665
4927
  function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4666
- if (!(type.flags & (ts6.TypeFlags.String | ts6.TypeFlags.Number | ts6.TypeFlags.BigInt | ts6.TypeFlags.BigIntLiteral | ts6.TypeFlags.Boolean | ts6.TypeFlags.Null)) && !isIntegerBrandedType(type)) {
4928
+ if (!(type.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null)) && !_isIntegerBrandedType(type)) {
4667
4929
  return null;
4668
4930
  }
4669
- const aliasDecl = type.aliasSymbol?.declarations?.find(ts6.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
4931
+ const aliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
4670
4932
  if (!aliasDecl) {
4671
4933
  return null;
4672
4934
  }
@@ -4677,11 +4939,18 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
4677
4939
  ...extractJSDocConstraintNodes(aliasDecl, file, makeParseOptions(extensionRegistry)),
4678
4940
  ...extractTypeAliasConstraintNodes(aliasDecl.type, checker, file, extensionRegistry)
4679
4941
  ];
4680
- const annotations = extractJSDocAnnotationNodes(
4942
+ const localAnnotations = extractJSDocAnnotationNodes(
4681
4943
  aliasDecl,
4682
4944
  file,
4683
4945
  makeParseOptions(extensionRegistry)
4684
4946
  );
4947
+ const inheritedAnnotations = collectInheritedTypeAnnotations(
4948
+ aliasDecl,
4949
+ localAnnotations,
4950
+ checker,
4951
+ extensionRegistry
4952
+ );
4953
+ const annotations = [...localAnnotations, ...inheritedAnnotations];
4685
4954
  const metadata = resolveNodeMetadata(
4686
4955
  metadataPolicy,
4687
4956
  "type",
@@ -4716,8 +4985,8 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
4716
4985
  return { kind: "reference", name: aliasName, typeArguments: [] };
4717
4986
  }
4718
4987
  function getReferencedTypeAliasDeclaration(sourceNode, checker) {
4719
- const typeNode = sourceNode && (ts6.isPropertyDeclaration(sourceNode) || ts6.isPropertySignature(sourceNode) || ts6.isParameter(sourceNode)) ? sourceNode.type : void 0;
4720
- if (!typeNode || !ts6.isTypeReferenceNode(typeNode)) {
4988
+ const typeNode = sourceNode && (ts5.isPropertyDeclaration(sourceNode) || ts5.isPropertySignature(sourceNode) || ts5.isParameter(sourceNode)) ? sourceNode.type : void 0;
4989
+ if (!typeNode || !ts5.isTypeReferenceNode(typeNode)) {
4721
4990
  return void 0;
4722
4991
  }
4723
4992
  return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
@@ -4738,7 +5007,7 @@ function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
4738
5007
  return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
4739
5008
  }
4740
5009
  function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4741
- if (!ts6.isTypeReferenceNode(typeNode)) {
5010
+ if (!ts5.isTypeReferenceNode(typeNode)) {
4742
5011
  return false;
4743
5012
  }
4744
5013
  const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
@@ -4746,10 +5015,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4746
5015
  return false;
4747
5016
  }
4748
5017
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
4749
- return !!(resolved.flags & (ts6.TypeFlags.String | ts6.TypeFlags.Number | ts6.TypeFlags.BigInt | ts6.TypeFlags.BigIntLiteral | ts6.TypeFlags.Boolean | ts6.TypeFlags.Null));
5018
+ return !!(resolved.flags & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral | ts5.TypeFlags.Boolean | ts5.TypeFlags.Null));
4750
5019
  }
4751
5020
  function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
4752
- const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts6.isTypeAliasDeclaration);
5021
+ const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts5.isTypeAliasDeclaration);
4753
5022
  if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
4754
5023
  visitedAliases.add(nestedAliasDecl);
4755
5024
  return resolveAliasedPrimitiveTarget(
@@ -4764,22 +5033,22 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4764
5033
  visitedAliases
4765
5034
  );
4766
5035
  }
4767
- if (isIntegerBrandedType(type)) {
5036
+ if (_isIntegerBrandedType(type)) {
4768
5037
  return { kind: "primitive", primitiveKind: "integer" };
4769
5038
  }
4770
- if (type.flags & ts6.TypeFlags.String) {
5039
+ if (type.flags & ts5.TypeFlags.String) {
4771
5040
  return { kind: "primitive", primitiveKind: "string" };
4772
5041
  }
4773
- if (type.flags & ts6.TypeFlags.Number) {
5042
+ if (type.flags & ts5.TypeFlags.Number) {
4774
5043
  return { kind: "primitive", primitiveKind: "number" };
4775
5044
  }
4776
- if (type.flags & (ts6.TypeFlags.BigInt | ts6.TypeFlags.BigIntLiteral)) {
5045
+ if (type.flags & (ts5.TypeFlags.BigInt | ts5.TypeFlags.BigIntLiteral)) {
4777
5046
  return { kind: "primitive", primitiveKind: "bigint" };
4778
5047
  }
4779
- if (type.flags & ts6.TypeFlags.Boolean) {
5048
+ if (type.flags & ts5.TypeFlags.Boolean) {
4780
5049
  return { kind: "primitive", primitiveKind: "boolean" };
4781
5050
  }
4782
- if (type.flags & ts6.TypeFlags.Null) {
5051
+ if (type.flags & ts5.TypeFlags.Null) {
4783
5052
  return { kind: "primitive", primitiveKind: "null" };
4784
5053
  }
4785
5054
  return resolveTypeNode(
@@ -4799,7 +5068,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4799
5068
  let typeName = null;
4800
5069
  let namedDecl;
4801
5070
  if (recovered !== null) {
4802
- const recoveredAliasDecl = ts6.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
5071
+ const recoveredAliasDecl = ts5.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
4803
5072
  if (recoveredAliasDecl !== void 0) {
4804
5073
  const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
4805
5074
  const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
@@ -4821,13 +5090,13 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4821
5090
  (memberTypeNode) => !isNullishTypeNode(resolveAliasedTypeNode(memberTypeNode, checker))
4822
5091
  );
4823
5092
  const nonNullTypes = allTypes.filter(
4824
- (memberType) => !(memberType.flags & (ts6.TypeFlags.Null | ts6.TypeFlags.Undefined))
5093
+ (memberType) => !(memberType.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined))
4825
5094
  );
4826
5095
  const nonNullMembers = nonNullTypes.map((memberType, index) => ({
4827
5096
  memberType,
4828
5097
  sourceNode: nonNullSourceNodes.length === nonNullTypes.length ? nonNullSourceNodes[index] : void 0
4829
5098
  }));
4830
- const hasNull = allTypes.some((t) => t.flags & ts6.TypeFlags.Null);
5099
+ const hasNull = allTypes.some((t) => t.flags & ts5.TypeFlags.Null);
4831
5100
  const memberDisplayNames = /* @__PURE__ */ new Map();
4832
5101
  if (namedDecl) {
4833
5102
  for (const [value, label] of extractDisplayNameMetadata(namedDecl).memberDisplayNames) {
@@ -4847,7 +5116,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4847
5116
  if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
4848
5117
  return { kind: "reference", name: typeName, typeArguments: [] };
4849
5118
  }
4850
- const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
5119
+ const annotations = namedDecl ? extractNamedTypeAnnotations(namedDecl, checker, file, extensionRegistry) : void 0;
4851
5120
  const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4852
5121
  metadataPolicy,
4853
5122
  "type",
@@ -4874,7 +5143,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4874
5143
  const displayName = memberDisplayNames.get(String(value));
4875
5144
  return displayName !== void 0 ? { value, displayName } : { value };
4876
5145
  });
4877
- const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts6.TypeFlags.BooleanLiteral);
5146
+ const isBooleanUnion2 = nonNullTypes.length === 2 && nonNullTypes.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
4878
5147
  if (isBooleanUnion2) {
4879
5148
  const boolNode = { kind: "primitive", primitiveKind: "boolean" };
4880
5149
  const result = hasNull ? {
@@ -4966,7 +5235,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metad
4966
5235
  if (type.getProperties().length > 0) {
4967
5236
  return null;
4968
5237
  }
4969
- const indexInfo = checker.getIndexInfoOfType(type, ts6.IndexKind.String);
5238
+ const indexInfo = checker.getIndexInfoOfType(type, ts5.IndexKind.String);
4970
5239
  if (!indexInfo) {
4971
5240
  return null;
4972
5241
  }
@@ -5014,20 +5283,53 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
5014
5283
  }
5015
5284
  if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
5016
5285
  const name = declaration.name;
5017
- if (ts6.isComputedPropertyName(name) || ts6.isPrivateIdentifier(name)) {
5286
+ if (ts5.isComputedPropertyName(name) || ts5.isPrivateIdentifier(name)) {
5018
5287
  return false;
5019
5288
  }
5020
- if (!ts6.isIdentifier(name) && !ts6.isStringLiteral(name) && !ts6.isNumericLiteral(name)) {
5289
+ if (!ts5.isIdentifier(name) && !ts5.isStringLiteral(name) && !ts5.isNumericLiteral(name)) {
5021
5290
  return false;
5022
5291
  }
5023
5292
  }
5024
5293
  return true;
5025
5294
  }
5295
+ function getPassThroughTypeAliasFromSourceNode(sourceNode, checker, extensionRegistry, resolvedTypeName) {
5296
+ const aliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
5297
+ if (!aliasDecl) return void 0;
5298
+ const aliasName = aliasDecl.name.text;
5299
+ if (aliasName === resolvedTypeName) return void 0;
5300
+ if (!ts5.isTypeReferenceNode(aliasDecl.type)) return void 0;
5301
+ if (!hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry)) {
5302
+ return void 0;
5303
+ }
5304
+ return { aliasName, aliasDecl };
5305
+ }
5306
+ function hasInheritableTypeAnnotation(aliasDecl, checker, extensionRegistry) {
5307
+ const file = aliasDecl.getSourceFile().fileName;
5308
+ const local = extractJSDocAnnotationNodes(aliasDecl, file, makeParseOptions(extensionRegistry));
5309
+ for (const annotation of local) {
5310
+ if (!INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) continue;
5311
+ if (!isOverridingInheritableAnnotation(annotation)) continue;
5312
+ return true;
5313
+ }
5314
+ const inherited = collectInheritedTypeAnnotations(aliasDecl, local, checker, extensionRegistry);
5315
+ for (const annotation of inherited) {
5316
+ if (INHERITABLE_TYPE_ANNOTATION_KINDS.has(annotation.annotationKind)) return true;
5317
+ }
5318
+ return false;
5319
+ }
5026
5320
  function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
5027
5321
  const collectedDiagnostics = diagnostics ?? [];
5028
5322
  const typeName = getNamedTypeName(type);
5029
5323
  const namedTypeName = typeName ?? void 0;
5030
5324
  const namedDecl = getNamedTypeDeclaration(type);
5325
+ const passThroughAlias = getPassThroughTypeAliasFromSourceNode(
5326
+ sourceNode,
5327
+ checker,
5328
+ extensionRegistry,
5329
+ namedTypeName
5330
+ );
5331
+ const effectiveTypeName = passThroughAlias?.aliasName ?? namedTypeName;
5332
+ const effectiveNamedDecl = passThroughAlias?.aliasDecl ?? namedDecl;
5031
5333
  const referenceTypeArguments = extractReferenceTypeArguments(
5032
5334
  type,
5033
5335
  checker,
@@ -5039,13 +5341,13 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5039
5341
  extensionRegistry,
5040
5342
  collectedDiagnostics
5041
5343
  );
5042
- const instantiatedTypeName = namedTypeName !== void 0 && referenceTypeArguments.length > 0 ? buildInstantiatedReferenceName(
5043
- namedTypeName,
5344
+ const instantiatedTypeName = effectiveTypeName !== void 0 && referenceTypeArguments.length > 0 ? buildInstantiatedReferenceName(
5345
+ effectiveTypeName,
5044
5346
  referenceTypeArguments.map((argument) => argument.tsType),
5045
5347
  checker
5046
5348
  ) : void 0;
5047
- const registryTypeName = instantiatedTypeName ?? namedTypeName;
5048
- const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" && namedDecl?.getSourceFile().fileName !== file);
5349
+ const registryTypeName = instantiatedTypeName ?? effectiveTypeName;
5350
+ const shouldRegisterNamedType = registryTypeName !== void 0 && !(registryTypeName === "Record" && effectiveNamedDecl?.getSourceFile().fileName !== file);
5049
5351
  const clearNamedTypeRegistration = () => {
5050
5352
  if (registryTypeName === void 0 || !shouldRegisterNamedType) {
5051
5353
  return;
@@ -5066,7 +5368,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5066
5368
  typeRegistry[registryTypeName] = {
5067
5369
  name: registryTypeName,
5068
5370
  type: RESOLVING_TYPE_PLACEHOLDER,
5069
- provenance: provenanceForDeclaration(namedDecl, file)
5371
+ provenance: provenanceForDeclaration(effectiveNamedDecl, file)
5070
5372
  };
5071
5373
  }
5072
5374
  visiting.add(type);
@@ -5098,17 +5400,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5098
5400
  clearNamedTypeRegistration();
5099
5401
  return recordNode;
5100
5402
  }
5101
- const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
5102
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
5403
+ const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
5404
+ const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
5103
5405
  metadataPolicy,
5104
5406
  "type",
5105
5407
  registryTypeName,
5106
- namedDecl,
5408
+ effectiveNamedDecl,
5107
5409
  checker,
5108
5410
  extensionRegistry,
5109
5411
  {
5110
5412
  checker,
5111
- declaration: namedDecl,
5413
+ declaration: effectiveNamedDecl,
5112
5414
  subjectType: type
5113
5415
  }
5114
5416
  ) : void 0;
@@ -5117,7 +5419,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5117
5419
  ...metadata !== void 0 && { metadata },
5118
5420
  type: recordNode,
5119
5421
  ...annotations !== void 0 && annotations.length > 0 && { annotations },
5120
- provenance: provenanceForDeclaration(namedDecl, file)
5422
+ provenance: provenanceForDeclaration(effectiveNamedDecl, file)
5121
5423
  };
5122
5424
  return {
5123
5425
  kind: "reference",
@@ -5143,7 +5445,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5143
5445
  if (!declaration) continue;
5144
5446
  if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
5145
5447
  const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
5146
- const optional = !!(prop.flags & ts6.SymbolFlags.Optional);
5448
+ const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
5147
5449
  const propTypeNode = resolveTypeNode(
5148
5450
  propType,
5149
5451
  checker,
@@ -5156,7 +5458,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5156
5458
  collectedDiagnostics
5157
5459
  );
5158
5460
  const fieldNodeInfo = fieldInfoMap?.get(prop.name);
5159
- const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts6.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
5461
+ const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts5.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
5160
5462
  declaration,
5161
5463
  checker,
5162
5464
  file,
@@ -5166,7 +5468,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5166
5468
  type,
5167
5469
  metadataPolicy,
5168
5470
  extensionRegistry
5169
- ) : ts6.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
5471
+ ) : ts5.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
5170
5472
  declaration,
5171
5473
  checker,
5172
5474
  file,
@@ -5194,9 +5496,9 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5194
5496
  visiting.delete(type);
5195
5497
  const objectNode = {
5196
5498
  kind: "object",
5197
- properties: namedDecl !== void 0 && (ts6.isClassDeclaration(namedDecl) || ts6.isInterfaceDeclaration(namedDecl) || ts6.isTypeAliasDeclaration(namedDecl)) ? applyDiscriminatorToObjectProperties(
5499
+ properties: effectiveNamedDecl !== void 0 && (ts5.isClassDeclaration(effectiveNamedDecl) || ts5.isInterfaceDeclaration(effectiveNamedDecl) || ts5.isTypeAliasDeclaration(effectiveNamedDecl)) ? applyDiscriminatorToObjectProperties(
5198
5500
  properties,
5199
- namedDecl,
5501
+ effectiveNamedDecl,
5200
5502
  type,
5201
5503
  checker,
5202
5504
  file,
@@ -5206,17 +5508,17 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5206
5508
  additionalProperties: true
5207
5509
  };
5208
5510
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
5209
- const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
5210
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
5511
+ const annotations = effectiveNamedDecl ? extractNamedTypeAnnotations(effectiveNamedDecl, checker, file, extensionRegistry) : void 0;
5512
+ const metadata = effectiveNamedDecl !== void 0 ? resolveNodeMetadata(
5211
5513
  metadataPolicy,
5212
5514
  "type",
5213
5515
  registryTypeName,
5214
- namedDecl,
5516
+ effectiveNamedDecl,
5215
5517
  checker,
5216
5518
  extensionRegistry,
5217
5519
  {
5218
5520
  checker,
5219
- declaration: namedDecl,
5521
+ declaration: effectiveNamedDecl,
5220
5522
  subjectType: type
5221
5523
  }
5222
5524
  ) : void 0;
@@ -5225,7 +5527,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
5225
5527
  ...metadata !== void 0 && { metadata },
5226
5528
  type: objectNode,
5227
5529
  ...annotations !== void 0 && annotations.length > 0 && { annotations },
5228
- provenance: provenanceForDeclaration(namedDecl, file)
5530
+ provenance: provenanceForDeclaration(effectiveNamedDecl, file)
5229
5531
  };
5230
5532
  return {
5231
5533
  kind: "reference",
@@ -5242,12 +5544,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5242
5544
  for (const symbol of symbols) {
5243
5545
  const declarations = symbol.declarations;
5244
5546
  if (!declarations) continue;
5245
- const classDecl = declarations.find(ts6.isClassDeclaration);
5547
+ const classDecl = declarations.find(ts5.isClassDeclaration);
5246
5548
  if (classDecl) {
5247
5549
  const map = /* @__PURE__ */ new Map();
5248
5550
  const hostType = checker.getTypeAtLocation(classDecl);
5249
5551
  for (const member of classDecl.members) {
5250
- if (ts6.isPropertyDeclaration(member) && ts6.isIdentifier(member.name)) {
5552
+ if (ts5.isPropertyDeclaration(member) && ts5.isIdentifier(member.name)) {
5251
5553
  const fieldNode = analyzeFieldToIR(
5252
5554
  member,
5253
5555
  checker,
@@ -5271,7 +5573,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5271
5573
  }
5272
5574
  return map;
5273
5575
  }
5274
- const interfaceDecl = declarations.find(ts6.isInterfaceDeclaration);
5576
+ const interfaceDecl = declarations.find(ts5.isInterfaceDeclaration);
5275
5577
  if (interfaceDecl) {
5276
5578
  return buildFieldNodeInfoMap(
5277
5579
  interfaceDecl.members,
@@ -5285,7 +5587,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
5285
5587
  extensionRegistry
5286
5588
  );
5287
5589
  }
5288
- const typeAliasDecl = declarations.find(ts6.isTypeAliasDeclaration);
5590
+ const typeAliasDecl = declarations.find(ts5.isTypeAliasDeclaration);
5289
5591
  const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
5290
5592
  if (typeAliasDecl && typeAliasMembers !== null) {
5291
5593
  return buildFieldNodeInfoMap(
@@ -5309,10 +5611,10 @@ function extractArrayElementTypeNode(sourceNode, checker) {
5309
5611
  return void 0;
5310
5612
  }
5311
5613
  const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
5312
- if (ts6.isArrayTypeNode(resolvedTypeNode)) {
5614
+ if (ts5.isArrayTypeNode(resolvedTypeNode)) {
5313
5615
  return resolvedTypeNode.elementType;
5314
5616
  }
5315
- if (ts6.isTypeReferenceNode(resolvedTypeNode) && ts6.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
5617
+ if (ts5.isTypeReferenceNode(resolvedTypeNode) && ts5.isIdentifier(resolvedTypeNode.typeName) && resolvedTypeNode.typeName.text === "Array" && resolvedTypeNode.typeArguments?.[0]) {
5316
5618
  return resolvedTypeNode.typeArguments[0];
5317
5619
  }
5318
5620
  return void 0;
@@ -5323,13 +5625,13 @@ function extractUnionMemberTypeNodes(sourceNode, checker) {
5323
5625
  return [];
5324
5626
  }
5325
5627
  const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
5326
- return ts6.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
5628
+ return ts5.isUnionTypeNode(resolvedTypeNode) ? [...resolvedTypeNode.types] : [];
5327
5629
  }
5328
5630
  function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
5329
- if (ts6.isParenthesizedTypeNode(typeNode)) {
5631
+ if (ts5.isParenthesizedTypeNode(typeNode)) {
5330
5632
  return resolveAliasedTypeNode(typeNode.type, checker, visited);
5331
5633
  }
5332
- if (!ts6.isTypeReferenceNode(typeNode) || !ts6.isIdentifier(typeNode.typeName)) {
5634
+ if (!ts5.isTypeReferenceNode(typeNode) || !ts5.isIdentifier(typeNode.typeName)) {
5333
5635
  return typeNode;
5334
5636
  }
5335
5637
  const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
@@ -5340,15 +5642,15 @@ function resolveAliasedTypeNode(typeNode, checker, visited = /* @__PURE__ */ new
5340
5642
  return resolveAliasedTypeNode(aliasDecl.type, checker, visited);
5341
5643
  }
5342
5644
  function isNullishTypeNode(typeNode) {
5343
- if (typeNode.kind === ts6.SyntaxKind.NullKeyword || typeNode.kind === ts6.SyntaxKind.UndefinedKeyword) {
5645
+ if (typeNode.kind === ts5.SyntaxKind.NullKeyword || typeNode.kind === ts5.SyntaxKind.UndefinedKeyword) {
5344
5646
  return true;
5345
5647
  }
5346
- return ts6.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts6.SyntaxKind.NullKeyword || typeNode.literal.kind === ts6.SyntaxKind.UndefinedKeyword);
5648
+ return ts5.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts5.SyntaxKind.NullKeyword || typeNode.literal.kind === ts5.SyntaxKind.UndefinedKeyword);
5347
5649
  }
5348
5650
  function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
5349
5651
  const map = /* @__PURE__ */ new Map();
5350
5652
  for (const member of members) {
5351
- if (ts6.isPropertySignature(member)) {
5653
+ if (ts5.isPropertySignature(member)) {
5352
5654
  const fieldNode = analyzeInterfacePropertyToIR(
5353
5655
  member,
5354
5656
  checker,
@@ -5373,7 +5675,7 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, m
5373
5675
  return map;
5374
5676
  }
5375
5677
  function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegistry, depth = 0) {
5376
- if (!ts6.isTypeReferenceNode(typeNode)) return [];
5678
+ if (!ts5.isTypeReferenceNode(typeNode)) return [];
5377
5679
  if (depth >= MAX_ALIAS_CHAIN_DEPTH) {
5378
5680
  const aliasName = typeNode.typeName.getText();
5379
5681
  throw new Error(
@@ -5382,7 +5684,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
5382
5684
  }
5383
5685
  const aliasDecl = getTypeAliasDeclarationFromTypeReference(typeNode, checker);
5384
5686
  if (!aliasDecl) return [];
5385
- if (ts6.isTypeLiteralNode(aliasDecl.type)) return [];
5687
+ if (ts5.isTypeLiteralNode(aliasDecl.type)) return [];
5386
5688
  const aliasFieldType = resolveTypeNode(
5387
5689
  checker.getTypeAtLocation(aliasDecl.type),
5388
5690
  checker,
@@ -5426,14 +5728,14 @@ function getNamedTypeName(type) {
5426
5728
  const symbol = type.getSymbol();
5427
5729
  if (symbol?.declarations) {
5428
5730
  const decl = symbol.declarations[0];
5429
- if (decl && (ts6.isClassDeclaration(decl) || ts6.isInterfaceDeclaration(decl) || ts6.isTypeAliasDeclaration(decl))) {
5430
- const name = ts6.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
5731
+ if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
5732
+ const name = ts5.isClassDeclaration(decl) ? decl.name?.text : decl.name.text;
5431
5733
  if (name) return name;
5432
5734
  }
5433
5735
  }
5434
5736
  const aliasSymbol = type.aliasSymbol;
5435
5737
  if (aliasSymbol?.declarations) {
5436
- const aliasDecl = aliasSymbol.declarations.find(ts6.isTypeAliasDeclaration);
5738
+ const aliasDecl = aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
5437
5739
  if (aliasDecl) {
5438
5740
  return aliasDecl.name.text;
5439
5741
  }
@@ -5444,24 +5746,24 @@ function getNamedTypeDeclaration(type) {
5444
5746
  const symbol = type.getSymbol();
5445
5747
  if (symbol?.declarations) {
5446
5748
  const decl = symbol.declarations[0];
5447
- if (decl && (ts6.isClassDeclaration(decl) || ts6.isInterfaceDeclaration(decl) || ts6.isTypeAliasDeclaration(decl))) {
5749
+ if (decl && (ts5.isClassDeclaration(decl) || ts5.isInterfaceDeclaration(decl) || ts5.isTypeAliasDeclaration(decl))) {
5448
5750
  return decl;
5449
5751
  }
5450
5752
  }
5451
5753
  const aliasSymbol = type.aliasSymbol;
5452
5754
  if (aliasSymbol?.declarations) {
5453
- return aliasSymbol.declarations.find(ts6.isTypeAliasDeclaration);
5755
+ return aliasSymbol.declarations.find(ts5.isTypeAliasDeclaration);
5454
5756
  }
5455
5757
  return void 0;
5456
5758
  }
5457
5759
  function analyzeMethod(method, checker) {
5458
- if (!ts6.isIdentifier(method.name)) {
5760
+ if (!ts5.isIdentifier(method.name)) {
5459
5761
  return null;
5460
5762
  }
5461
5763
  const name = method.name.text;
5462
5764
  const parameters = [];
5463
5765
  for (const param of method.parameters) {
5464
- if (ts6.isIdentifier(param.name)) {
5766
+ if (ts5.isIdentifier(param.name)) {
5465
5767
  const paramInfo = analyzeParameter(param, checker);
5466
5768
  parameters.push(paramInfo);
5467
5769
  }
@@ -5472,7 +5774,7 @@ function analyzeMethod(method, checker) {
5472
5774
  return { name, parameters, returnTypeNode, returnType };
5473
5775
  }
5474
5776
  function analyzeParameter(param, checker) {
5475
- const name = ts6.isIdentifier(param.name) ? param.name.text : "param";
5777
+ const name = ts5.isIdentifier(param.name) ? param.name.text : "param";
5476
5778
  const typeNode = param.type;
5477
5779
  const type = checker.getTypeAtLocation(param);
5478
5780
  const formSpecExportName = detectFormSpecReference(typeNode);
@@ -5481,20 +5783,20 @@ function analyzeParameter(param, checker) {
5481
5783
  }
5482
5784
  function detectFormSpecReference(typeNode) {
5483
5785
  if (!typeNode) return null;
5484
- if (!ts6.isTypeReferenceNode(typeNode)) return null;
5485
- const typeName = ts6.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts6.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
5786
+ if (!ts5.isTypeReferenceNode(typeNode)) return null;
5787
+ const typeName = ts5.isIdentifier(typeNode.typeName) ? typeNode.typeName.text : ts5.isQualifiedName(typeNode.typeName) ? typeNode.typeName.right.text : null;
5486
5788
  if (typeName !== "InferSchema" && typeName !== "InferFormSchema") return null;
5487
5789
  const typeArg = typeNode.typeArguments?.[0];
5488
- if (!typeArg || !ts6.isTypeQueryNode(typeArg)) return null;
5489
- if (ts6.isIdentifier(typeArg.exprName)) {
5790
+ if (!typeArg || !ts5.isTypeQueryNode(typeArg)) return null;
5791
+ if (ts5.isIdentifier(typeArg.exprName)) {
5490
5792
  return typeArg.exprName.text;
5491
5793
  }
5492
- if (ts6.isQualifiedName(typeArg.exprName)) {
5794
+ if (ts5.isQualifiedName(typeArg.exprName)) {
5493
5795
  return typeArg.exprName.right.text;
5494
5796
  }
5495
5797
  return null;
5496
5798
  }
5497
- var RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
5799
+ var RESOLVING_TYPE_PLACEHOLDER, DEDUPLICATABLE_DIAGNOSTIC_CODES, INHERITABLE_TYPE_ANNOTATION_KINDS, MAX_ALIAS_CHAIN_DEPTH;
5498
5800
  var init_class_analyzer = __esm({
5499
5801
  "src/analyzer/class-analyzer.ts"() {
5500
5802
  "use strict";
@@ -5509,12 +5811,17 @@ var init_class_analyzer = __esm({
5509
5811
  properties: [],
5510
5812
  additionalProperties: true
5511
5813
  };
5814
+ DEDUPLICATABLE_DIAGNOSTIC_CODES = /* @__PURE__ */ new Set([
5815
+ "SYNTHETIC_SETUP_FAILURE",
5816
+ "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE"
5817
+ ]);
5818
+ INHERITABLE_TYPE_ANNOTATION_KINDS = /* @__PURE__ */ new Set(["format"]);
5512
5819
  MAX_ALIAS_CHAIN_DEPTH = 8;
5513
5820
  }
5514
5821
  });
5515
5822
 
5516
5823
  // src/analyzer/program.ts
5517
- import * as ts7 from "typescript";
5824
+ import * as ts6 from "typescript";
5518
5825
  import * as path from "path";
5519
5826
  function createProgramContextFromProgram(program, filePath) {
5520
5827
  const absolutePath = path.resolve(filePath);
@@ -5531,23 +5838,23 @@ function createProgramContextFromProgram(program, filePath) {
5531
5838
  function createProgramContext(filePath, additionalFiles) {
5532
5839
  const absolutePath = path.resolve(filePath);
5533
5840
  const fileDir = path.dirname(absolutePath);
5534
- const configPath = ts7.findConfigFile(fileDir, ts7.sys.fileExists.bind(ts7.sys), "tsconfig.json");
5841
+ const configPath = ts6.findConfigFile(fileDir, ts6.sys.fileExists.bind(ts6.sys), "tsconfig.json");
5535
5842
  let compilerOptions;
5536
5843
  let fileNames;
5537
5844
  if (configPath) {
5538
- const configFile = ts7.readConfigFile(configPath, ts7.sys.readFile.bind(ts7.sys));
5845
+ const configFile = ts6.readConfigFile(configPath, ts6.sys.readFile.bind(ts6.sys));
5539
5846
  if (configFile.error) {
5540
5847
  throw new Error(
5541
- `Error reading tsconfig.json: ${ts7.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
5848
+ `Error reading tsconfig.json: ${ts6.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
5542
5849
  );
5543
5850
  }
5544
- const parsed = ts7.parseJsonConfigFileContent(
5851
+ const parsed = ts6.parseJsonConfigFileContent(
5545
5852
  configFile.config,
5546
- ts7.sys,
5853
+ ts6.sys,
5547
5854
  path.dirname(configPath)
5548
5855
  );
5549
5856
  if (parsed.errors.length > 0) {
5550
- const errorMessages = parsed.errors.map((e) => ts7.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
5857
+ const errorMessages = parsed.errors.map((e) => ts6.flattenDiagnosticMessageText(e.messageText, "\n")).join("\n");
5551
5858
  throw new Error(`Error parsing tsconfig.json: ${errorMessages}`);
5552
5859
  }
5553
5860
  compilerOptions = parsed.options;
@@ -5555,9 +5862,9 @@ function createProgramContext(filePath, additionalFiles) {
5555
5862
  fileNames = [.../* @__PURE__ */ new Set([...parsed.fileNames, absolutePath, ...normalizedAdditional])];
5556
5863
  } else {
5557
5864
  compilerOptions = {
5558
- target: ts7.ScriptTarget.ES2022,
5559
- module: ts7.ModuleKind.NodeNext,
5560
- moduleResolution: ts7.ModuleResolutionKind.NodeNext,
5865
+ target: ts6.ScriptTarget.ES2022,
5866
+ module: ts6.ModuleKind.NodeNext,
5867
+ moduleResolution: ts6.ModuleResolutionKind.NodeNext,
5561
5868
  strict: true,
5562
5869
  skipLibCheck: true,
5563
5870
  declaration: true
@@ -5565,7 +5872,7 @@ function createProgramContext(filePath, additionalFiles) {
5565
5872
  const normalizedAdditional = (additionalFiles ?? []).map((f) => path.resolve(f));
5566
5873
  fileNames = [.../* @__PURE__ */ new Set([absolutePath, ...normalizedAdditional])];
5567
5874
  }
5568
- const program = ts7.createProgram(fileNames, compilerOptions);
5875
+ const program = ts6.createProgram(fileNames, compilerOptions);
5569
5876
  const sourceFile = program.getSourceFile(absolutePath);
5570
5877
  if (!sourceFile) {
5571
5878
  throw new Error(`Could not find source file: ${absolutePath}`);
@@ -5584,19 +5891,19 @@ function findNodeByName(sourceFile, name, predicate, getName) {
5584
5891
  result = node;
5585
5892
  return;
5586
5893
  }
5587
- ts7.forEachChild(node, visit);
5894
+ ts6.forEachChild(node, visit);
5588
5895
  }
5589
5896
  visit(sourceFile);
5590
5897
  return result;
5591
5898
  }
5592
5899
  function findClassByName(sourceFile, className) {
5593
- return findNodeByName(sourceFile, className, ts7.isClassDeclaration, (n) => n.name?.text);
5900
+ return findNodeByName(sourceFile, className, ts6.isClassDeclaration, (n) => n.name?.text);
5594
5901
  }
5595
5902
  function findInterfaceByName(sourceFile, interfaceName) {
5596
- return findNodeByName(sourceFile, interfaceName, ts7.isInterfaceDeclaration, (n) => n.name.text);
5903
+ return findNodeByName(sourceFile, interfaceName, ts6.isInterfaceDeclaration, (n) => n.name.text);
5597
5904
  }
5598
5905
  function findTypeAliasByName(sourceFile, aliasName) {
5599
- return findNodeByName(sourceFile, aliasName, ts7.isTypeAliasDeclaration, (n) => n.name.text);
5906
+ return findNodeByName(sourceFile, aliasName, ts6.isTypeAliasDeclaration, (n) => n.name.text);
5600
5907
  }
5601
5908
  function getResolvedObjectRootType(rootType, typeRegistry) {
5602
5909
  if (rootType.kind === "object") {
@@ -5636,22 +5943,22 @@ function createResolvedObjectAliasAnalysis(name, rootType, typeRegistry, rootInf
5636
5943
  };
5637
5944
  }
5638
5945
  function containsTypeReferenceInObjectLikeAlias(typeNode) {
5639
- if (ts7.isParenthesizedTypeNode(typeNode)) {
5946
+ if (ts6.isParenthesizedTypeNode(typeNode)) {
5640
5947
  return containsTypeReferenceInObjectLikeAlias(typeNode.type);
5641
5948
  }
5642
- if (ts7.isTypeReferenceNode(typeNode)) {
5949
+ if (ts6.isTypeReferenceNode(typeNode)) {
5643
5950
  return true;
5644
5951
  }
5645
- return ts7.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
5952
+ return ts6.isIntersectionTypeNode(typeNode) && typeNode.types.some((member) => containsTypeReferenceInObjectLikeAlias(member));
5646
5953
  }
5647
5954
  function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
5648
- if (ts7.isParenthesizedTypeNode(typeNode)) {
5955
+ if (ts6.isParenthesizedTypeNode(typeNode)) {
5649
5956
  return collectFallbackAliasMemberPropertyNames(typeNode.type, checker);
5650
5957
  }
5651
- if (ts7.isTypeLiteralNode(typeNode)) {
5958
+ if (ts6.isTypeLiteralNode(typeNode)) {
5652
5959
  const propertyNames = [];
5653
5960
  for (const member of typeNode.members) {
5654
- if (!ts7.isPropertySignature(member)) {
5961
+ if (!ts6.isPropertySignature(member)) {
5655
5962
  continue;
5656
5963
  }
5657
5964
  const propertyName = getAnalyzableObjectLikePropertyName(member.name);
@@ -5661,13 +5968,13 @@ function collectFallbackAliasMemberPropertyNames(typeNode, checker) {
5661
5968
  }
5662
5969
  return propertyNames;
5663
5970
  }
5664
- if (ts7.isTypeReferenceNode(typeNode)) {
5971
+ if (ts6.isTypeReferenceNode(typeNode)) {
5665
5972
  return checker.getTypeFromTypeNode(typeNode).getProperties().map((property) => property.getName());
5666
5973
  }
5667
5974
  return null;
5668
5975
  }
5669
5976
  function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
5670
- if (!ts7.isIntersectionTypeNode(typeNode)) {
5977
+ if (!ts6.isIntersectionTypeNode(typeNode)) {
5671
5978
  return [];
5672
5979
  }
5673
5980
  const seen = /* @__PURE__ */ new Set();
@@ -5874,7 +6181,7 @@ var init_program = __esm({
5874
6181
  });
5875
6182
 
5876
6183
  // src/extensions/symbol-registry.ts
5877
- import * as ts8 from "typescript";
6184
+ import * as ts7 from "typescript";
5878
6185
  import * as path2 from "path";
5879
6186
  function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistry) {
5880
6187
  const symbolMap = /* @__PURE__ */ new Map();
@@ -5884,10 +6191,10 @@ function buildSymbolMapFromConfig(configPath, program, checker, extensionRegistr
5884
6191
  return symbolMap;
5885
6192
  }
5886
6193
  function visit(node) {
5887
- if (ts8.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
6194
+ if (ts7.isCallExpression(node) && isDefineCustomTypeCall(node, checker)) {
5888
6195
  processDefineCustomTypeCall(node);
5889
6196
  }
5890
- ts8.forEachChild(node, visit);
6197
+ ts7.forEachChild(node, visit);
5891
6198
  }
5892
6199
  function processDefineCustomTypeCall(call) {
5893
6200
  const typeArgNode = call.typeArguments?.[0];
@@ -5924,7 +6231,7 @@ function isDefineCustomTypeCall(node, checker) {
5924
6231
  if (node.typeArguments === void 0 || node.typeArguments.length === 0) return false;
5925
6232
  const callSymbol = checker.getSymbolAtLocation(node.expression);
5926
6233
  if (callSymbol !== void 0) {
5927
- const resolved = callSymbol.flags & ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
6234
+ const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5928
6235
  const decl = resolved.declarations?.[0];
5929
6236
  if (decl !== void 0) {
5930
6237
  const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
@@ -5932,24 +6239,24 @@ function isDefineCustomTypeCall(node, checker) {
5932
6239
  (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5933
6240
  }
5934
6241
  }
5935
- return ts8.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
6242
+ return ts7.isIdentifier(node.expression) && node.expression.text === "defineCustomType";
5936
6243
  }
5937
6244
  function extractTypeNameFromCallArg(call) {
5938
6245
  const arg = call.arguments[0];
5939
- if (arg === void 0 || !ts8.isObjectLiteralExpression(arg)) {
6246
+ if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
5940
6247
  return null;
5941
6248
  }
5942
6249
  const typeNameProp = arg.properties.find(
5943
- (p) => ts8.isPropertyAssignment(p) && ts8.isIdentifier(p.name) && p.name.text === "typeName"
6250
+ (p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "typeName"
5944
6251
  );
5945
- if (typeNameProp === void 0 || !ts8.isStringLiteral(typeNameProp.initializer)) {
6252
+ if (typeNameProp === void 0 || !ts7.isStringLiteral(typeNameProp.initializer)) {
5946
6253
  return null;
5947
6254
  }
5948
6255
  return typeNameProp.initializer.text;
5949
6256
  }
5950
6257
  function extractEnclosingExtensionId(call, checker) {
5951
- for (let node = call.parent; !ts8.isSourceFile(node); node = node.parent) {
5952
- if (ts8.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
6258
+ for (let node = call.parent; !ts7.isSourceFile(node); node = node.parent) {
6259
+ if (ts7.isCallExpression(node) && isDefineExtensionCall(node, checker)) {
5953
6260
  return extractExtensionIdFromCallArg(node);
5954
6261
  }
5955
6262
  }
@@ -5958,24 +6265,24 @@ function extractEnclosingExtensionId(call, checker) {
5958
6265
  function isDefineExtensionCall(node, checker) {
5959
6266
  const callSymbol = checker.getSymbolAtLocation(node.expression);
5960
6267
  if (callSymbol !== void 0) {
5961
- const resolved = callSymbol.flags & ts8.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
6268
+ const resolved = callSymbol.flags & ts7.SymbolFlags.Alias ? checker.getAliasedSymbol(callSymbol) : callSymbol;
5962
6269
  const decl = resolved.declarations?.[0];
5963
6270
  if (decl !== void 0) {
5964
6271
  const sourceFile = decl.getSourceFile().fileName.replace(/\\/g, "/");
5965
6272
  return resolved.name === "defineExtension" && (sourceFile.includes("@formspec/core") || sourceFile.includes("/packages/core/"));
5966
6273
  }
5967
6274
  }
5968
- return ts8.isIdentifier(node.expression) && node.expression.text === "defineExtension";
6275
+ return ts7.isIdentifier(node.expression) && node.expression.text === "defineExtension";
5969
6276
  }
5970
6277
  function extractExtensionIdFromCallArg(call) {
5971
6278
  const arg = call.arguments[0];
5972
- if (arg === void 0 || !ts8.isObjectLiteralExpression(arg)) {
6279
+ if (arg === void 0 || !ts7.isObjectLiteralExpression(arg)) {
5973
6280
  return null;
5974
6281
  }
5975
6282
  const prop = arg.properties.find(
5976
- (p) => ts8.isPropertyAssignment(p) && ts8.isIdentifier(p.name) && p.name.text === "extensionId"
6283
+ (p) => ts7.isPropertyAssignment(p) && ts7.isIdentifier(p.name) && p.name.text === "extensionId"
5977
6284
  );
5978
- if (prop === void 0 || !ts8.isStringLiteral(prop.initializer)) {
6285
+ if (prop === void 0 || !ts7.isStringLiteral(prop.initializer)) {
5979
6286
  return null;
5980
6287
  }
5981
6288
  return prop.initializer.text;
@@ -6087,7 +6394,7 @@ var init_validate = __esm({
6087
6394
  });
6088
6395
 
6089
6396
  // src/generators/class-schema.ts
6090
- import * as ts9 from "typescript";
6397
+ import * as ts8 from "typescript";
6091
6398
  function generateClassSchemas(analysis, source, options) {
6092
6399
  const result = generateClassSchemasDetailed(analysis, source, options);
6093
6400
  if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
@@ -6257,7 +6564,7 @@ function generateSchemasBatch(options) {
6257
6564
  return options.targets.map((target) => {
6258
6565
  let ctx;
6259
6566
  try {
6260
- const cacheKey = ts9.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
6567
+ const cacheKey = ts8.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
6261
6568
  const cachedContext = contextCache.get(cacheKey);
6262
6569
  if (cachedContext === void 0) {
6263
6570
  const additionalFiles = options.configPath !== void 0 ? [options.configPath] : void 0;
@@ -6316,7 +6623,7 @@ function isMutableRegistry(reg) {
6316
6623
  }
6317
6624
  function resolveStaticOptions(options) {
6318
6625
  const legacyRegistry = options.extensionRegistry;
6319
- const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6626
+ const configRegistry = legacyRegistry === void 0 && options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6320
6627
  return {
6321
6628
  extensionRegistry: legacyRegistry ?? configRegistry,
6322
6629
  // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
@@ -6328,7 +6635,7 @@ function resolveStaticOptions(options) {
6328
6635
  };
6329
6636
  }
6330
6637
  function resolveOptions(options) {
6331
- const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6638
+ const configRegistry = options.config?.extensions !== void 0 && options.config.extensions.length > 0 ? createExtensionRegistry(options.config.extensions) : void 0;
6332
6639
  const legacyRegistry = options.extensionRegistry;
6333
6640
  return {
6334
6641
  // When the caller provides the deprecated extensionRegistry field directly,
@@ -6426,7 +6733,7 @@ var init_class_schema = __esm({
6426
6733
  });
6427
6734
 
6428
6735
  // src/static-build.ts
6429
- import * as ts10 from "typescript";
6736
+ import * as ts9 from "typescript";
6430
6737
  function toStaticBuildContext(context) {
6431
6738
  return context;
6432
6739
  }
@@ -6441,7 +6748,7 @@ function getModuleSymbol(context) {
6441
6748
  return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
6442
6749
  }
6443
6750
  function isSchemaSourceDeclaration(declaration) {
6444
- return ts10.isClassDeclaration(declaration) || ts10.isInterfaceDeclaration(declaration) || ts10.isTypeAliasDeclaration(declaration);
6751
+ return ts9.isClassDeclaration(declaration) || ts9.isInterfaceDeclaration(declaration) || ts9.isTypeAliasDeclaration(declaration);
6445
6752
  }
6446
6753
  function resolveModuleExport(context, exportName = "default") {
6447
6754
  const moduleSymbol = getModuleSymbol(context);
@@ -6452,7 +6759,7 @@ function resolveModuleExport(context, exportName = "default") {
6452
6759
  if (exportSymbol === null) {
6453
6760
  return null;
6454
6761
  }
6455
- return exportSymbol.flags & ts10.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
6762
+ return exportSymbol.flags & ts9.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
6456
6763
  }
6457
6764
  function resolveModuleExportDeclaration(context, exportName = "default") {
6458
6765
  return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
@@ -6465,7 +6772,7 @@ var init_static_build = __esm({
6465
6772
  });
6466
6773
 
6467
6774
  // src/generators/discovered-schema.ts
6468
- import * as ts11 from "typescript";
6775
+ import * as ts10 from "typescript";
6469
6776
  import { analyzeMetadataForNodeWithChecker as analyzeMetadataForNodeWithChecker2 } from "@formspec/analysis/internal";
6470
6777
  import { IR_VERSION as IR_VERSION3 } from "@formspec/core/internals";
6471
6778
  function toDiscoveredTypeSchemas(result, resolvedMetadata) {
@@ -6475,17 +6782,17 @@ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
6475
6782
  };
6476
6783
  }
6477
6784
  function isNamedTypeDeclaration(declaration) {
6478
- return ts11.isClassDeclaration(declaration) || ts11.isInterfaceDeclaration(declaration) || ts11.isTypeAliasDeclaration(declaration);
6785
+ return ts10.isClassDeclaration(declaration) || ts10.isInterfaceDeclaration(declaration) || ts10.isTypeAliasDeclaration(declaration);
6479
6786
  }
6480
6787
  function hasConcreteTypeArguments(type, checker) {
6481
6788
  if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
6482
6789
  return true;
6483
6790
  }
6484
- if ((type.flags & ts11.TypeFlags.Object) === 0) {
6791
+ if ((type.flags & ts10.TypeFlags.Object) === 0) {
6485
6792
  return false;
6486
6793
  }
6487
6794
  const objectType = type;
6488
- if ((objectType.objectFlags & ts11.ObjectFlags.Reference) === 0) {
6795
+ if ((objectType.objectFlags & ts10.ObjectFlags.Reference) === 0) {
6489
6796
  return false;
6490
6797
  }
6491
6798
  return checker.getTypeArguments(objectType).length > 0;
@@ -6498,13 +6805,13 @@ function getNamedTypeDeclaration2(type) {
6498
6805
  return declaration;
6499
6806
  }
6500
6807
  }
6501
- const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts11.isTypeAliasDeclaration);
6808
+ const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts10.isTypeAliasDeclaration);
6502
6809
  return aliasDeclaration;
6503
6810
  }
6504
6811
  function getFallbackName(sourceNode, fallback = "AnonymousType") {
6505
6812
  if (sourceNode !== void 0 && "name" in sourceNode) {
6506
6813
  const namedNode = sourceNode;
6507
- if (namedNode.name !== void 0 && ts11.isIdentifier(namedNode.name)) {
6814
+ if (namedNode.name !== void 0 && ts10.isIdentifier(namedNode.name)) {
6508
6815
  return namedNode.name.text;
6509
6816
  }
6510
6817
  }
@@ -6726,7 +7033,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6726
7033
  function generateSchemasFromDeclaration(options) {
6727
7034
  const filePath = options.declaration.getSourceFile().fileName;
6728
7035
  const resolved = resolveStaticOptions(options);
6729
- if (ts11.isClassDeclaration(options.declaration)) {
7036
+ if (ts10.isClassDeclaration(options.declaration)) {
6730
7037
  return generateSchemasFromAnalysis(
6731
7038
  analyzeClassToIR(
6732
7039
  options.declaration,
@@ -6740,7 +7047,7 @@ function generateSchemasFromDeclaration(options) {
6740
7047
  resolved
6741
7048
  );
6742
7049
  }
6743
- if (ts11.isInterfaceDeclaration(options.declaration)) {
7050
+ if (ts10.isInterfaceDeclaration(options.declaration)) {
6744
7051
  return generateSchemasFromAnalysis(
6745
7052
  analyzeInterfaceToIR(
6746
7053
  options.declaration,
@@ -6754,7 +7061,7 @@ function generateSchemasFromDeclaration(options) {
6754
7061
  resolved
6755
7062
  );
6756
7063
  }
6757
- if (ts11.isTypeAliasDeclaration(options.declaration)) {
7064
+ if (ts10.isTypeAliasDeclaration(options.declaration)) {
6758
7065
  const analyzedAlias = analyzeTypeAliasToIR(
6759
7066
  options.declaration,
6760
7067
  options.context.checker,
@@ -6813,7 +7120,7 @@ function generateSchemasFromReturnType(options) {
6813
7120
  const returnType = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
6814
7121
  const type = unwrapPromiseType(options.context.checker, returnType);
6815
7122
  const sourceNode = type !== returnType ? unwrapPromiseTypeNode(options.declaration.type) ?? options.declaration.type ?? options.declaration : options.declaration.type ?? options.declaration;
6816
- const fallbackName = options.declaration.name !== void 0 && ts11.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
7123
+ const fallbackName = options.declaration.name !== void 0 && ts10.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
6817
7124
  return generateSchemasFromResolvedType({
6818
7125
  ...options,
6819
7126
  type,
@@ -6860,14 +7167,14 @@ function unwrapPromiseTypeNode(typeNode) {
6860
7167
  if (typeNode === void 0) {
6861
7168
  return void 0;
6862
7169
  }
6863
- if (ts11.isParenthesizedTypeNode(typeNode)) {
7170
+ if (ts10.isParenthesizedTypeNode(typeNode)) {
6864
7171
  const unwrapped = unwrapPromiseTypeNode(typeNode.type);
6865
7172
  return unwrapped ?? typeNode;
6866
7173
  }
6867
7174
  return isPromiseTypeReferenceNode(typeNode) ? typeNode.typeArguments[0] : typeNode;
6868
7175
  }
6869
7176
  function isPromiseTypeReferenceNode(typeNode) {
6870
- return ts11.isTypeReferenceNode(typeNode) && ts11.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
7177
+ return ts10.isTypeReferenceNode(typeNode) && ts10.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6871
7178
  }
6872
7179
  var init_discovered_schema = __esm({
6873
7180
  "src/generators/discovered-schema.ts"() {