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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -3000,6 +3000,9 @@ var init_jsdoc_constraints = __esm({
3000
3000
  function isObjectType(type) {
3001
3001
  return !!(type.flags & ts3.TypeFlags.Object);
3002
3002
  }
3003
+ function isIntersectionType(type) {
3004
+ return !!(type.flags & ts3.TypeFlags.Intersection);
3005
+ }
3003
3006
  function isTypeReference(type) {
3004
3007
  return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
3005
3008
  }
@@ -3015,10 +3018,11 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
3015
3018
  ...hostType !== void 0 && { hostType }
3016
3019
  };
3017
3020
  }
3018
- function createAnalyzerMetadataPolicy(input) {
3021
+ function createAnalyzerMetadataPolicy(input, discriminator) {
3019
3022
  return {
3020
3023
  raw: input,
3021
- normalized: normalizeMetadataPolicy(input)
3024
+ normalized: normalizeMetadataPolicy(input),
3025
+ discriminator
3022
3026
  };
3023
3027
  }
3024
3028
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
@@ -3086,8 +3090,11 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
3086
3090
  diagnostics: docResult.diagnostics
3087
3091
  };
3088
3092
  }
3089
- function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3090
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3093
+ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3094
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3095
+ metadataPolicy,
3096
+ discriminatorOptions
3097
+ );
3091
3098
  const name = classDecl.name?.text ?? "AnonymousClass";
3092
3099
  const fields = [];
3093
3100
  const fieldLayouts = [];
@@ -3168,8 +3175,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3168
3175
  staticMethods
3169
3176
  };
3170
3177
  }
3171
- function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3172
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3178
+ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3179
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3180
+ metadataPolicy,
3181
+ discriminatorOptions
3182
+ );
3173
3183
  const name = interfaceDecl.name.text;
3174
3184
  const fields = [];
3175
3185
  const typeRegistry = {};
@@ -3237,19 +3247,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3237
3247
  staticMethods: []
3238
3248
  };
3239
3249
  }
3240
- function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
3241
- if (!ts3.isTypeLiteralNode(typeAlias.type)) {
3250
+ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3251
+ const members = getObjectLikeTypeAliasMembers(typeAlias.type);
3252
+ if (members === null) {
3242
3253
  const sourceFile = typeAlias.getSourceFile();
3243
3254
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3244
3255
  const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3245
3256
  return {
3246
3257
  ok: false,
3247
- error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
3258
+ error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
3248
3259
  };
3249
3260
  }
3250
- const typeLiteral = typeAlias.type;
3251
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3261
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3262
+ metadataPolicy,
3263
+ discriminatorOptions
3264
+ );
3252
3265
  const name = typeAlias.name.text;
3266
+ const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
3267
+ if (duplicatePropertyNames.length > 0) {
3268
+ const sourceFile = typeAlias.getSourceFile();
3269
+ const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3270
+ return {
3271
+ ok: false,
3272
+ error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
3273
+ };
3274
+ }
3253
3275
  const fields = [];
3254
3276
  const typeRegistry = {};
3255
3277
  const diagnostics = [];
@@ -3262,7 +3284,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3262
3284
  const annotations = [...typeAliasDoc.annotations];
3263
3285
  diagnostics.push(...typeAliasDoc.diagnostics);
3264
3286
  const visiting = /* @__PURE__ */ new Set();
3265
- for (const member of typeLiteral.members) {
3287
+ for (const member of members) {
3266
3288
  if (ts3.isPropertySignature(member)) {
3267
3289
  const fieldNode = analyzeInterfacePropertyToIR(
3268
3290
  member,
@@ -3371,15 +3393,43 @@ function isNullishSemanticType(type) {
3371
3393
  }
3372
3394
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
3373
3395
  }
3374
- function isStringLikeSemanticType(type) {
3396
+ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
3397
+ if (seen.has(type)) {
3398
+ return false;
3399
+ }
3400
+ seen.add(type);
3375
3401
  if (type.flags & ts3.TypeFlags.StringLike) {
3376
3402
  return true;
3377
3403
  }
3378
3404
  if (type.isUnion()) {
3379
- return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
3405
+ return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
3406
+ }
3407
+ const baseConstraint = checker.getBaseConstraintOfType(type);
3408
+ if (baseConstraint !== void 0 && baseConstraint !== type) {
3409
+ return isStringLikeSemanticType(baseConstraint, checker, seen);
3380
3410
  }
3381
3411
  return false;
3382
3412
  }
3413
+ function getObjectLikeTypeAliasMembers(typeNode) {
3414
+ if (ts3.isParenthesizedTypeNode(typeNode)) {
3415
+ return getObjectLikeTypeAliasMembers(typeNode.type);
3416
+ }
3417
+ if (ts3.isTypeLiteralNode(typeNode)) {
3418
+ return [...typeNode.members];
3419
+ }
3420
+ if (ts3.isIntersectionTypeNode(typeNode)) {
3421
+ const members = [];
3422
+ for (const intersectionMember of typeNode.types) {
3423
+ const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
3424
+ if (resolvedMembers === null) {
3425
+ return null;
3426
+ }
3427
+ members.push(...resolvedMembers);
3428
+ }
3429
+ return members;
3430
+ }
3431
+ return null;
3432
+ }
3383
3433
  function extractDiscriminatorDirective(node, file, diagnostics) {
3384
3434
  const discriminatorTags = getLeadingParsedTags(node).filter(
3385
3435
  (tag) => tag.normalizedTagName === "discriminator"
@@ -3486,7 +3536,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
3486
3536
  );
3487
3537
  return null;
3488
3538
  }
3489
- if (!isStringLikeSemanticType(property.type)) {
3539
+ if (!isStringLikeSemanticType(property.type, checker)) {
3490
3540
  diagnostics.push(
3491
3541
  makeAnalysisDiagnostic(
3492
3542
  "TYPE_MISMATCH",
@@ -3513,8 +3563,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
3513
3563
  const localTypeParameter = node.typeParameters?.[typeParameterIndex];
3514
3564
  return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
3515
3565
  }
3516
- function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
3517
- const propertySymbol = boundType.getProperty(fieldName);
3566
+ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
3567
+ const propertySymbol = boundType.getProperty(propertyName);
3518
3568
  if (propertySymbol === void 0) {
3519
3569
  return void 0;
3520
3570
  }
@@ -3545,6 +3595,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
3545
3595
  }
3546
3596
  return void 0;
3547
3597
  }
3598
+ function getDiscriminatorIdentityPropertyNames(fieldName) {
3599
+ return fieldName === "object" ? ["object"] : [fieldName, "object"];
3600
+ }
3548
3601
  function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3549
3602
  const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
3550
3603
  if (declaration === null) {
@@ -3565,6 +3618,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3565
3618
  );
3566
3619
  return metadata?.apiName;
3567
3620
  }
3621
+ function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
3622
+ const prefix = discriminatorOptions?.apiNamePrefix;
3623
+ return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
3624
+ }
3568
3625
  function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
3569
3626
  if (seen.has(type)) {
3570
3627
  return null;
@@ -3619,22 +3676,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
3619
3676
  return null;
3620
3677
  }
3621
3678
  }
3622
- const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3623
- boundType,
3624
- fieldName,
3625
- checker,
3626
- provenance,
3627
- diagnostics
3628
- );
3629
- if (literalIdentityValue !== void 0) {
3630
- return literalIdentityValue;
3679
+ for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
3680
+ const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3681
+ boundType,
3682
+ identityPropertyName,
3683
+ checker,
3684
+ provenance,
3685
+ diagnostics
3686
+ );
3687
+ if (literalIdentityValue === null) {
3688
+ return null;
3689
+ }
3690
+ if (literalIdentityValue !== void 0) {
3691
+ return literalIdentityValue;
3692
+ }
3631
3693
  }
3632
3694
  const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
3633
3695
  if (apiName?.source === "explicit") {
3634
- return apiName.value;
3696
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3635
3697
  }
3636
3698
  if (apiName?.source === "inferred") {
3637
- return apiName.value;
3699
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3638
3700
  }
3639
3701
  diagnostics.push(
3640
3702
  makeAnalysisDiagnostic(
@@ -3697,15 +3759,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
3697
3759
  return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
3698
3760
  }
3699
3761
  function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
3700
- const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3701
- if (typeNode === void 0) {
3762
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3763
+ if (sourceTypeNode === void 0) {
3702
3764
  return [];
3703
3765
  }
3704
- const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
3705
- if (!ts3.isTypeReferenceNode(resolvedTypeNode) || resolvedTypeNode.typeArguments === void 0) {
3766
+ const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
3767
+ const directTypeNode = unwrapParentheses(sourceTypeNode);
3768
+ const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
3769
+ const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
3770
+ return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
3771
+ })();
3772
+ if (referenceTypeNode?.typeArguments === void 0) {
3706
3773
  return [];
3707
3774
  }
3708
- return resolvedTypeNode.typeArguments.map((argumentNode) => {
3775
+ return referenceTypeNode.typeArguments.map((argumentNode) => {
3709
3776
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
3710
3777
  return {
3711
3778
  tsType: argumentType,
@@ -3819,10 +3886,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
3819
3886
  };
3820
3887
  }
3821
3888
  function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
3822
- if (!ts3.isIdentifier(prop.name)) {
3889
+ const name = getAnalyzableObjectLikePropertyName(prop.name);
3890
+ if (name === null) {
3823
3891
  return null;
3824
3892
  }
3825
- const name = prop.name.text;
3826
3893
  const tsType = checker.getTypeAtLocation(prop);
3827
3894
  const optional = prop.questionToken !== void 0;
3828
3895
  const provenance = provenanceForNode(prop, file);
@@ -3878,6 +3945,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
3878
3945
  provenance
3879
3946
  };
3880
3947
  }
3948
+ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
3949
+ const seen = /* @__PURE__ */ new Set();
3950
+ const duplicates = /* @__PURE__ */ new Set();
3951
+ for (const member of members) {
3952
+ if (!ts3.isPropertySignature(member)) {
3953
+ continue;
3954
+ }
3955
+ const name = getAnalyzableObjectLikePropertyName(member.name);
3956
+ if (name === null) {
3957
+ continue;
3958
+ }
3959
+ if (seen.has(name)) {
3960
+ duplicates.add(name);
3961
+ continue;
3962
+ }
3963
+ seen.add(name);
3964
+ }
3965
+ return [...duplicates].sort();
3966
+ }
3967
+ function getAnalyzableObjectLikePropertyName(name) {
3968
+ if (!ts3.isIdentifier(name)) {
3969
+ return null;
3970
+ }
3971
+ return name.text;
3972
+ }
3881
3973
  function applyEnumMemberDisplayNames(type, annotations) {
3882
3974
  if (!annotations.some(
3883
3975
  (annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
@@ -4070,6 +4162,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4070
4162
  diagnostics
4071
4163
  );
4072
4164
  }
4165
+ if (isIntersectionType(type)) {
4166
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
4167
+ const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
4168
+ if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
4169
+ return resolveObjectType(
4170
+ type,
4171
+ checker,
4172
+ file,
4173
+ typeRegistry,
4174
+ visiting,
4175
+ sourceNode,
4176
+ metadataPolicy,
4177
+ extensionRegistry,
4178
+ diagnostics
4179
+ );
4180
+ }
4181
+ }
4073
4182
  if (isObjectType(type)) {
4074
4183
  return resolveObjectType(
4075
4184
  type,
@@ -4156,9 +4265,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4156
4265
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
4157
4266
  return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
4158
4267
  }
4159
- function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4268
+ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
4160
4269
  const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
4161
- if (nestedAliasDecl !== void 0) {
4270
+ if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
4271
+ visitedAliases.add(nestedAliasDecl);
4162
4272
  return resolveAliasedPrimitiveTarget(
4163
4273
  checker.getTypeFromTypeNode(nestedAliasDecl.type),
4164
4274
  checker,
@@ -4167,9 +4277,25 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4167
4277
  visiting,
4168
4278
  metadataPolicy,
4169
4279
  extensionRegistry,
4170
- diagnostics
4280
+ diagnostics,
4281
+ visitedAliases
4171
4282
  );
4172
4283
  }
4284
+ if (type.flags & ts3.TypeFlags.String) {
4285
+ return { kind: "primitive", primitiveKind: "string" };
4286
+ }
4287
+ if (type.flags & ts3.TypeFlags.Number) {
4288
+ return { kind: "primitive", primitiveKind: "number" };
4289
+ }
4290
+ if (type.flags & (ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral)) {
4291
+ return { kind: "primitive", primitiveKind: "bigint" };
4292
+ }
4293
+ if (type.flags & ts3.TypeFlags.Boolean) {
4294
+ return { kind: "primitive", primitiveKind: "boolean" };
4295
+ }
4296
+ if (type.flags & ts3.TypeFlags.Null) {
4297
+ return { kind: "primitive", primitiveKind: "null" };
4298
+ }
4173
4299
  return resolveTypeNode(
4174
4300
  type,
4175
4301
  checker,
@@ -4449,7 +4575,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4449
4575
  };
4450
4576
  }
4451
4577
  }
4452
- const recordNode = tryResolveRecordType(
4578
+ const recordNode = isObjectType(type) ? tryResolveRecordType(
4453
4579
  type,
4454
4580
  checker,
4455
4581
  file,
@@ -4458,7 +4584,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4458
4584
  metadataPolicy,
4459
4585
  extensionRegistry,
4460
4586
  collectedDiagnostics
4461
- );
4587
+ ) : null;
4462
4588
  if (recordNode) {
4463
4589
  visiting.delete(type);
4464
4590
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
@@ -4655,9 +4781,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
4655
4781
  );
4656
4782
  }
4657
4783
  const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
4658
- if (typeAliasDecl && ts3.isTypeLiteralNode(typeAliasDecl.type)) {
4784
+ const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
4785
+ if (typeAliasDecl && typeAliasMembers !== null) {
4659
4786
  return buildFieldNodeInfoMap(
4660
- typeAliasDecl.type.members,
4787
+ typeAliasMembers,
4661
4788
  checker,
4662
4789
  file,
4663
4790
  typeRegistry,
@@ -4964,17 +5091,18 @@ function findInterfaceByName(sourceFile, interfaceName) {
4964
5091
  function findTypeAliasByName(sourceFile, aliasName) {
4965
5092
  return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
4966
5093
  }
4967
- function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
5094
+ function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4968
5095
  const ctx = createProgramContext(filePath);
4969
5096
  return analyzeNamedTypeToIRFromProgramContext(
4970
5097
  ctx,
4971
5098
  filePath,
4972
5099
  typeName,
4973
5100
  extensionRegistry,
4974
- metadataPolicy
5101
+ metadataPolicy,
5102
+ discriminatorOptions
4975
5103
  );
4976
5104
  }
4977
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
5105
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4978
5106
  const analysisFilePath = path.resolve(filePath);
4979
5107
  const classDecl = findClassByName(ctx.sourceFile, typeName);
4980
5108
  if (classDecl !== null) {
@@ -4983,7 +5111,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4983
5111
  ctx.checker,
4984
5112
  analysisFilePath,
4985
5113
  extensionRegistry,
4986
- metadataPolicy
5114
+ metadataPolicy,
5115
+ discriminatorOptions
4987
5116
  );
4988
5117
  }
4989
5118
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
@@ -4993,7 +5122,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4993
5122
  ctx.checker,
4994
5123
  analysisFilePath,
4995
5124
  extensionRegistry,
4996
- metadataPolicy
5125
+ metadataPolicy,
5126
+ discriminatorOptions
4997
5127
  );
4998
5128
  }
4999
5129
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
@@ -5003,7 +5133,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5003
5133
  ctx.checker,
5004
5134
  analysisFilePath,
5005
5135
  extensionRegistry,
5006
- metadataPolicy
5136
+ metadataPolicy,
5137
+ discriminatorOptions
5007
5138
  );
5008
5139
  if (result.ok) {
5009
5140
  return result.analysis;
@@ -5161,7 +5292,8 @@ function generateSchemasFromClass(options) {
5161
5292
  ctx.checker,
5162
5293
  options.filePath,
5163
5294
  options.extensionRegistry,
5164
- options.metadata
5295
+ options.metadata,
5296
+ options.discriminator
5165
5297
  );
5166
5298
  return generateClassSchemas(
5167
5299
  analysis,
@@ -5187,7 +5319,8 @@ function generateSchemasFromProgram(options) {
5187
5319
  options.filePath,
5188
5320
  options.typeName,
5189
5321
  options.extensionRegistry,
5190
- options.metadata
5322
+ options.metadata,
5323
+ options.discriminator
5191
5324
  );
5192
5325
  return generateClassSchemas(
5193
5326
  analysis,
@@ -5424,7 +5557,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5424
5557
  typeRegistry,
5425
5558
  /* @__PURE__ */ new Set(),
5426
5559
  options.sourceNode,
5427
- createAnalyzerMetadataPolicy(options.metadata),
5560
+ createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
5428
5561
  options.extensionRegistry,
5429
5562
  diagnostics
5430
5563
  );
@@ -5473,7 +5606,8 @@ function generateSchemasFromDeclaration(options) {
5473
5606
  options.context.checker,
5474
5607
  filePath,
5475
5608
  options.extensionRegistry,
5476
- options.metadata
5609
+ options.metadata,
5610
+ options.discriminator
5477
5611
  ),
5478
5612
  filePath,
5479
5613
  options
@@ -5486,7 +5620,8 @@ function generateSchemasFromDeclaration(options) {
5486
5620
  options.context.checker,
5487
5621
  filePath,
5488
5622
  options.extensionRegistry,
5489
- options.metadata
5623
+ options.metadata,
5624
+ options.discriminator
5490
5625
  ),
5491
5626
  filePath,
5492
5627
  options
@@ -5498,7 +5633,8 @@ function generateSchemasFromDeclaration(options) {
5498
5633
  options.context.checker,
5499
5634
  filePath,
5500
5635
  options.extensionRegistry,
5501
- options.metadata
5636
+ options.metadata,
5637
+ options.discriminator
5502
5638
  );
5503
5639
  if (analyzedAlias.ok) {
5504
5640
  return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
@@ -5576,7 +5712,8 @@ function buildMixedAuthoringSchemas(options) {
5576
5712
  filePath,
5577
5713
  typeName,
5578
5714
  schemaOptions.extensionRegistry,
5579
- schemaOptions.metadata
5715
+ schemaOptions.metadata,
5716
+ schemaOptions.discriminator
5580
5717
  );
5581
5718
  const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
5582
5719
  const ir = canonicalizeTSDoc(