@formspec/build 0.1.0-alpha.33 → 0.1.0-alpha.34

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.
@@ -16,7 +16,7 @@ export { canonicalizeTSDoc } from "./canonicalize/index.js";
16
16
  export type { TSDocSource } from "./canonicalize/index.js";
17
17
  export { createProgramContext, createProgramContextFromProgram, findClassByName, findInterfaceByName, findTypeAliasByName, analyzeNamedTypeToIRFromProgramContext, } from "./analyzer/program.js";
18
18
  export { analyzeClassToIR, analyzeInterfaceToIR, analyzeTypeAliasToIR, } from "./analyzer/class-analyzer.js";
19
- export type { IRClassAnalysis, FieldLayoutMetadata, AnalyzeTypeAliasToIRResult, } from "./analyzer/class-analyzer.js";
19
+ export type { DiscriminatorResolutionOptions, IRClassAnalysis, FieldLayoutMetadata, AnalyzeTypeAliasToIRResult, } from "./analyzer/class-analyzer.js";
20
20
  export { generateClassSchemas } from "./generators/class-schema.js";
21
21
  export type { ClassSchemas } from "./generators/class-schema.js";
22
22
  export { generateJsonSchemaFromIR } from "./json-schema/ir-generator.js";
@@ -1 +1 @@
1
- {"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,+BAA+B,EAC/B,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,sCAAsC,GACvC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EACV,+BAA+B,EAC/B,cAAc,GACf,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,+BAA+B,EAC/B,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,sCAAsC,GACvC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,8BAA8B,EAC9B,eAAe,EACf,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EACV,+BAA+B,EAC/B,cAAc,GACf,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
package/dist/internals.js CHANGED
@@ -1653,6 +1653,9 @@ function extractDefaultValueAnnotation(initializer, file = "") {
1653
1653
  function isObjectType(type) {
1654
1654
  return !!(type.flags & ts3.TypeFlags.Object);
1655
1655
  }
1656
+ function isIntersectionType(type) {
1657
+ return !!(type.flags & ts3.TypeFlags.Intersection);
1658
+ }
1656
1659
  function isTypeReference(type) {
1657
1660
  return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
1658
1661
  }
@@ -1673,10 +1676,11 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
1673
1676
  ...hostType !== void 0 && { hostType }
1674
1677
  };
1675
1678
  }
1676
- function createAnalyzerMetadataPolicy(input) {
1679
+ function createAnalyzerMetadataPolicy(input, discriminator) {
1677
1680
  return {
1678
1681
  raw: input,
1679
- normalized: normalizeMetadataPolicy(input)
1682
+ normalized: normalizeMetadataPolicy(input),
1683
+ discriminator
1680
1684
  };
1681
1685
  }
1682
1686
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
@@ -1715,8 +1719,11 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
1715
1719
  }
1716
1720
  return resolvedMetadata;
1717
1721
  }
1718
- function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
1719
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
1722
+ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
1723
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
1724
+ metadataPolicy,
1725
+ discriminatorOptions
1726
+ );
1720
1727
  const name = classDecl.name?.text ?? "AnonymousClass";
1721
1728
  const fields = [];
1722
1729
  const fieldLayouts = [];
@@ -1797,8 +1804,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
1797
1804
  staticMethods
1798
1805
  };
1799
1806
  }
1800
- function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
1801
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
1807
+ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
1808
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
1809
+ metadataPolicy,
1810
+ discriminatorOptions
1811
+ );
1802
1812
  const name = interfaceDecl.name.text;
1803
1813
  const fields = [];
1804
1814
  const typeRegistry = {};
@@ -1866,19 +1876,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
1866
1876
  staticMethods: []
1867
1877
  };
1868
1878
  }
1869
- function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
1870
- if (!ts3.isTypeLiteralNode(typeAlias.type)) {
1879
+ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
1880
+ const members = getObjectLikeTypeAliasMembers(typeAlias.type);
1881
+ if (members === null) {
1871
1882
  const sourceFile = typeAlias.getSourceFile();
1872
1883
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
1873
1884
  const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
1874
1885
  return {
1875
1886
  ok: false,
1876
- error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
1887
+ error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
1877
1888
  };
1878
1889
  }
1879
- const typeLiteral = typeAlias.type;
1880
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
1890
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
1891
+ metadataPolicy,
1892
+ discriminatorOptions
1893
+ );
1881
1894
  const name = typeAlias.name.text;
1895
+ const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
1896
+ if (duplicatePropertyNames.length > 0) {
1897
+ const sourceFile = typeAlias.getSourceFile();
1898
+ const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
1899
+ return {
1900
+ ok: false,
1901
+ error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
1902
+ };
1903
+ }
1882
1904
  const fields = [];
1883
1905
  const typeRegistry = {};
1884
1906
  const diagnostics = [];
@@ -1891,7 +1913,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
1891
1913
  const annotations = [...typeAliasDoc.annotations];
1892
1914
  diagnostics.push(...typeAliasDoc.diagnostics);
1893
1915
  const visiting = /* @__PURE__ */ new Set();
1894
- for (const member of typeLiteral.members) {
1916
+ for (const member of members) {
1895
1917
  if (ts3.isPropertySignature(member)) {
1896
1918
  const fieldNode = analyzeInterfacePropertyToIR(
1897
1919
  member,
@@ -2000,15 +2022,43 @@ function isNullishSemanticType(type) {
2000
2022
  }
2001
2023
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
2002
2024
  }
2003
- function isStringLikeSemanticType(type) {
2025
+ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
2026
+ if (seen.has(type)) {
2027
+ return false;
2028
+ }
2029
+ seen.add(type);
2004
2030
  if (type.flags & ts3.TypeFlags.StringLike) {
2005
2031
  return true;
2006
2032
  }
2007
2033
  if (type.isUnion()) {
2008
- return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
2034
+ return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
2035
+ }
2036
+ const baseConstraint = checker.getBaseConstraintOfType(type);
2037
+ if (baseConstraint !== void 0 && baseConstraint !== type) {
2038
+ return isStringLikeSemanticType(baseConstraint, checker, seen);
2009
2039
  }
2010
2040
  return false;
2011
2041
  }
2042
+ function getObjectLikeTypeAliasMembers(typeNode) {
2043
+ if (ts3.isParenthesizedTypeNode(typeNode)) {
2044
+ return getObjectLikeTypeAliasMembers(typeNode.type);
2045
+ }
2046
+ if (ts3.isTypeLiteralNode(typeNode)) {
2047
+ return [...typeNode.members];
2048
+ }
2049
+ if (ts3.isIntersectionTypeNode(typeNode)) {
2050
+ const members = [];
2051
+ for (const intersectionMember of typeNode.types) {
2052
+ const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
2053
+ if (resolvedMembers === null) {
2054
+ return null;
2055
+ }
2056
+ members.push(...resolvedMembers);
2057
+ }
2058
+ return members;
2059
+ }
2060
+ return null;
2061
+ }
2012
2062
  function extractDiscriminatorDirective(node, file, diagnostics) {
2013
2063
  const discriminatorTags = getLeadingParsedTags(node).filter(
2014
2064
  (tag) => tag.normalizedTagName === "discriminator"
@@ -2115,7 +2165,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
2115
2165
  );
2116
2166
  return null;
2117
2167
  }
2118
- if (!isStringLikeSemanticType(property.type)) {
2168
+ if (!isStringLikeSemanticType(property.type, checker)) {
2119
2169
  diagnostics.push(
2120
2170
  makeAnalysisDiagnostic(
2121
2171
  "TYPE_MISMATCH",
@@ -2142,8 +2192,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
2142
2192
  const localTypeParameter = node.typeParameters?.[typeParameterIndex];
2143
2193
  return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
2144
2194
  }
2145
- function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
2146
- const propertySymbol = boundType.getProperty(fieldName);
2195
+ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
2196
+ const propertySymbol = boundType.getProperty(propertyName);
2147
2197
  if (propertySymbol === void 0) {
2148
2198
  return void 0;
2149
2199
  }
@@ -2174,6 +2224,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
2174
2224
  }
2175
2225
  return void 0;
2176
2226
  }
2227
+ function getDiscriminatorIdentityPropertyNames(fieldName) {
2228
+ return fieldName === "object" ? ["object"] : [fieldName, "object"];
2229
+ }
2177
2230
  function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
2178
2231
  const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
2179
2232
  if (declaration === null) {
@@ -2194,6 +2247,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
2194
2247
  );
2195
2248
  return metadata?.apiName;
2196
2249
  }
2250
+ function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
2251
+ const prefix = discriminatorOptions?.apiNamePrefix;
2252
+ return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
2253
+ }
2197
2254
  function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
2198
2255
  if (seen.has(type)) {
2199
2256
  return null;
@@ -2248,22 +2305,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
2248
2305
  return null;
2249
2306
  }
2250
2307
  }
2251
- const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
2252
- boundType,
2253
- fieldName,
2254
- checker,
2255
- provenance,
2256
- diagnostics
2257
- );
2258
- if (literalIdentityValue !== void 0) {
2259
- return literalIdentityValue;
2308
+ for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
2309
+ const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
2310
+ boundType,
2311
+ identityPropertyName,
2312
+ checker,
2313
+ provenance,
2314
+ diagnostics
2315
+ );
2316
+ if (literalIdentityValue === null) {
2317
+ return null;
2318
+ }
2319
+ if (literalIdentityValue !== void 0) {
2320
+ return literalIdentityValue;
2321
+ }
2260
2322
  }
2261
2323
  const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
2262
2324
  if (apiName?.source === "explicit") {
2263
- return apiName.value;
2325
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
2264
2326
  }
2265
2327
  if (apiName?.source === "inferred") {
2266
- return apiName.value;
2328
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
2267
2329
  }
2268
2330
  diagnostics.push(
2269
2331
  makeAnalysisDiagnostic(
@@ -2326,15 +2388,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
2326
2388
  return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
2327
2389
  }
2328
2390
  function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
2329
- const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
2330
- if (typeNode === void 0) {
2391
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
2392
+ if (sourceTypeNode === void 0) {
2331
2393
  return [];
2332
2394
  }
2333
- const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
2334
- if (!ts3.isTypeReferenceNode(resolvedTypeNode) || resolvedTypeNode.typeArguments === void 0) {
2395
+ const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
2396
+ const directTypeNode = unwrapParentheses(sourceTypeNode);
2397
+ const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
2398
+ const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
2399
+ return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
2400
+ })();
2401
+ if (referenceTypeNode?.typeArguments === void 0) {
2335
2402
  return [];
2336
2403
  }
2337
- return resolvedTypeNode.typeArguments.map((argumentNode) => {
2404
+ return referenceTypeNode.typeArguments.map((argumentNode) => {
2338
2405
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
2339
2406
  return {
2340
2407
  tsType: argumentType,
@@ -2448,10 +2515,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
2448
2515
  };
2449
2516
  }
2450
2517
  function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
2451
- if (!ts3.isIdentifier(prop.name)) {
2518
+ const name = getAnalyzableObjectLikePropertyName(prop.name);
2519
+ if (name === null) {
2452
2520
  return null;
2453
2521
  }
2454
- const name = prop.name.text;
2455
2522
  const tsType = checker.getTypeAtLocation(prop);
2456
2523
  const optional = prop.questionToken !== void 0;
2457
2524
  const provenance = provenanceForNode(prop, file);
@@ -2507,6 +2574,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
2507
2574
  provenance
2508
2575
  };
2509
2576
  }
2577
+ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
2578
+ const seen = /* @__PURE__ */ new Set();
2579
+ const duplicates = /* @__PURE__ */ new Set();
2580
+ for (const member of members) {
2581
+ if (!ts3.isPropertySignature(member)) {
2582
+ continue;
2583
+ }
2584
+ const name = getAnalyzableObjectLikePropertyName(member.name);
2585
+ if (name === null) {
2586
+ continue;
2587
+ }
2588
+ if (seen.has(name)) {
2589
+ duplicates.add(name);
2590
+ continue;
2591
+ }
2592
+ seen.add(name);
2593
+ }
2594
+ return [...duplicates].sort();
2595
+ }
2596
+ function getAnalyzableObjectLikePropertyName(name) {
2597
+ if (!ts3.isIdentifier(name)) {
2598
+ return null;
2599
+ }
2600
+ return name.text;
2601
+ }
2510
2602
  function applyEnumMemberDisplayNames(type, annotations) {
2511
2603
  if (!annotations.some(
2512
2604
  (annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
@@ -2699,6 +2791,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
2699
2791
  diagnostics
2700
2792
  );
2701
2793
  }
2794
+ if (isIntersectionType(type)) {
2795
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
2796
+ const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
2797
+ if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
2798
+ return resolveObjectType(
2799
+ type,
2800
+ checker,
2801
+ file,
2802
+ typeRegistry,
2803
+ visiting,
2804
+ sourceNode,
2805
+ metadataPolicy,
2806
+ extensionRegistry,
2807
+ diagnostics
2808
+ );
2809
+ }
2810
+ }
2702
2811
  if (isObjectType(type)) {
2703
2812
  return resolveObjectType(
2704
2813
  type,
@@ -3078,7 +3187,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
3078
3187
  };
3079
3188
  }
3080
3189
  }
3081
- const recordNode = tryResolveRecordType(
3190
+ const recordNode = isObjectType(type) ? tryResolveRecordType(
3082
3191
  type,
3083
3192
  checker,
3084
3193
  file,
@@ -3087,7 +3196,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
3087
3196
  metadataPolicy,
3088
3197
  extensionRegistry,
3089
3198
  collectedDiagnostics
3090
- );
3199
+ ) : null;
3091
3200
  if (recordNode) {
3092
3201
  visiting.delete(type);
3093
3202
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
@@ -3284,9 +3393,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
3284
3393
  );
3285
3394
  }
3286
3395
  const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
3287
- if (typeAliasDecl && ts3.isTypeLiteralNode(typeAliasDecl.type)) {
3396
+ const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
3397
+ if (typeAliasDecl && typeAliasMembers !== null) {
3288
3398
  return buildFieldNodeInfoMap(
3289
- typeAliasDecl.type.members,
3399
+ typeAliasMembers,
3290
3400
  checker,
3291
3401
  file,
3292
3402
  typeRegistry,
@@ -3577,7 +3687,7 @@ function findInterfaceByName(sourceFile, interfaceName) {
3577
3687
  function findTypeAliasByName(sourceFile, aliasName) {
3578
3688
  return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
3579
3689
  }
3580
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
3690
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
3581
3691
  const analysisFilePath = path.resolve(filePath);
3582
3692
  const classDecl = findClassByName(ctx.sourceFile, typeName);
3583
3693
  if (classDecl !== null) {
@@ -3586,7 +3696,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3586
3696
  ctx.checker,
3587
3697
  analysisFilePath,
3588
3698
  extensionRegistry,
3589
- metadataPolicy
3699
+ metadataPolicy,
3700
+ discriminatorOptions
3590
3701
  );
3591
3702
  }
3592
3703
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
@@ -3596,7 +3707,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3596
3707
  ctx.checker,
3597
3708
  analysisFilePath,
3598
3709
  extensionRegistry,
3599
- metadataPolicy
3710
+ metadataPolicy,
3711
+ discriminatorOptions
3600
3712
  );
3601
3713
  }
3602
3714
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
@@ -3606,7 +3718,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3606
3718
  ctx.checker,
3607
3719
  analysisFilePath,
3608
3720
  extensionRegistry,
3609
- metadataPolicy
3721
+ metadataPolicy,
3722
+ discriminatorOptions
3610
3723
  );
3611
3724
  if (result.ok) {
3612
3725
  return result.analysis;