@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.
package/dist/cli.js CHANGED
@@ -3013,6 +3013,9 @@ import {
3013
3013
  function isObjectType(type) {
3014
3014
  return !!(type.flags & ts3.TypeFlags.Object);
3015
3015
  }
3016
+ function isIntersectionType(type) {
3017
+ return !!(type.flags & ts3.TypeFlags.Intersection);
3018
+ }
3016
3019
  function isTypeReference(type) {
3017
3020
  return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
3018
3021
  }
@@ -3028,10 +3031,11 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
3028
3031
  ...hostType !== void 0 && { hostType }
3029
3032
  };
3030
3033
  }
3031
- function createAnalyzerMetadataPolicy(input) {
3034
+ function createAnalyzerMetadataPolicy(input, discriminator) {
3032
3035
  return {
3033
3036
  raw: input,
3034
- normalized: normalizeMetadataPolicy(input)
3037
+ normalized: normalizeMetadataPolicy(input),
3038
+ discriminator
3035
3039
  };
3036
3040
  }
3037
3041
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
@@ -3099,8 +3103,11 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
3099
3103
  diagnostics: docResult.diagnostics
3100
3104
  };
3101
3105
  }
3102
- function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3103
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3106
+ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3107
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3108
+ metadataPolicy,
3109
+ discriminatorOptions
3110
+ );
3104
3111
  const name = classDecl.name?.text ?? "AnonymousClass";
3105
3112
  const fields = [];
3106
3113
  const fieldLayouts = [];
@@ -3181,8 +3188,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3181
3188
  staticMethods
3182
3189
  };
3183
3190
  }
3184
- function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3185
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3191
+ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3192
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3193
+ metadataPolicy,
3194
+ discriminatorOptions
3195
+ );
3186
3196
  const name = interfaceDecl.name.text;
3187
3197
  const fields = [];
3188
3198
  const typeRegistry = {};
@@ -3250,19 +3260,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3250
3260
  staticMethods: []
3251
3261
  };
3252
3262
  }
3253
- function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
3254
- if (!ts3.isTypeLiteralNode(typeAlias.type)) {
3263
+ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3264
+ const members = getObjectLikeTypeAliasMembers(typeAlias.type);
3265
+ if (members === null) {
3255
3266
  const sourceFile = typeAlias.getSourceFile();
3256
3267
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3257
3268
  const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3258
3269
  return {
3259
3270
  ok: false,
3260
- error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
3271
+ error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
3261
3272
  };
3262
3273
  }
3263
- const typeLiteral = typeAlias.type;
3264
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3274
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3275
+ metadataPolicy,
3276
+ discriminatorOptions
3277
+ );
3265
3278
  const name = typeAlias.name.text;
3279
+ const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
3280
+ if (duplicatePropertyNames.length > 0) {
3281
+ const sourceFile = typeAlias.getSourceFile();
3282
+ const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3283
+ return {
3284
+ ok: false,
3285
+ error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
3286
+ };
3287
+ }
3266
3288
  const fields = [];
3267
3289
  const typeRegistry = {};
3268
3290
  const diagnostics = [];
@@ -3275,7 +3297,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3275
3297
  const annotations = [...typeAliasDoc.annotations];
3276
3298
  diagnostics.push(...typeAliasDoc.diagnostics);
3277
3299
  const visiting = /* @__PURE__ */ new Set();
3278
- for (const member of typeLiteral.members) {
3300
+ for (const member of members) {
3279
3301
  if (ts3.isPropertySignature(member)) {
3280
3302
  const fieldNode = analyzeInterfacePropertyToIR(
3281
3303
  member,
@@ -3384,15 +3406,43 @@ function isNullishSemanticType(type) {
3384
3406
  }
3385
3407
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
3386
3408
  }
3387
- function isStringLikeSemanticType(type) {
3409
+ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
3410
+ if (seen.has(type)) {
3411
+ return false;
3412
+ }
3413
+ seen.add(type);
3388
3414
  if (type.flags & ts3.TypeFlags.StringLike) {
3389
3415
  return true;
3390
3416
  }
3391
3417
  if (type.isUnion()) {
3392
- return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
3418
+ return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
3419
+ }
3420
+ const baseConstraint = checker.getBaseConstraintOfType(type);
3421
+ if (baseConstraint !== void 0 && baseConstraint !== type) {
3422
+ return isStringLikeSemanticType(baseConstraint, checker, seen);
3393
3423
  }
3394
3424
  return false;
3395
3425
  }
3426
+ function getObjectLikeTypeAliasMembers(typeNode) {
3427
+ if (ts3.isParenthesizedTypeNode(typeNode)) {
3428
+ return getObjectLikeTypeAliasMembers(typeNode.type);
3429
+ }
3430
+ if (ts3.isTypeLiteralNode(typeNode)) {
3431
+ return [...typeNode.members];
3432
+ }
3433
+ if (ts3.isIntersectionTypeNode(typeNode)) {
3434
+ const members = [];
3435
+ for (const intersectionMember of typeNode.types) {
3436
+ const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
3437
+ if (resolvedMembers === null) {
3438
+ return null;
3439
+ }
3440
+ members.push(...resolvedMembers);
3441
+ }
3442
+ return members;
3443
+ }
3444
+ return null;
3445
+ }
3396
3446
  function extractDiscriminatorDirective(node, file, diagnostics) {
3397
3447
  const discriminatorTags = getLeadingParsedTags(node).filter(
3398
3448
  (tag) => tag.normalizedTagName === "discriminator"
@@ -3499,7 +3549,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
3499
3549
  );
3500
3550
  return null;
3501
3551
  }
3502
- if (!isStringLikeSemanticType(property.type)) {
3552
+ if (!isStringLikeSemanticType(property.type, checker)) {
3503
3553
  diagnostics.push(
3504
3554
  makeAnalysisDiagnostic(
3505
3555
  "TYPE_MISMATCH",
@@ -3526,8 +3576,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
3526
3576
  const localTypeParameter = node.typeParameters?.[typeParameterIndex];
3527
3577
  return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
3528
3578
  }
3529
- function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
3530
- const propertySymbol = boundType.getProperty(fieldName);
3579
+ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
3580
+ const propertySymbol = boundType.getProperty(propertyName);
3531
3581
  if (propertySymbol === void 0) {
3532
3582
  return void 0;
3533
3583
  }
@@ -3558,6 +3608,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
3558
3608
  }
3559
3609
  return void 0;
3560
3610
  }
3611
+ function getDiscriminatorIdentityPropertyNames(fieldName) {
3612
+ return fieldName === "object" ? ["object"] : [fieldName, "object"];
3613
+ }
3561
3614
  function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3562
3615
  const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
3563
3616
  if (declaration === null) {
@@ -3578,6 +3631,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3578
3631
  );
3579
3632
  return metadata?.apiName;
3580
3633
  }
3634
+ function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
3635
+ const prefix = discriminatorOptions?.apiNamePrefix;
3636
+ return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
3637
+ }
3581
3638
  function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
3582
3639
  if (seen.has(type)) {
3583
3640
  return null;
@@ -3632,22 +3689,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
3632
3689
  return null;
3633
3690
  }
3634
3691
  }
3635
- const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3636
- boundType,
3637
- fieldName,
3638
- checker,
3639
- provenance,
3640
- diagnostics
3641
- );
3642
- if (literalIdentityValue !== void 0) {
3643
- return literalIdentityValue;
3692
+ for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
3693
+ const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3694
+ boundType,
3695
+ identityPropertyName,
3696
+ checker,
3697
+ provenance,
3698
+ diagnostics
3699
+ );
3700
+ if (literalIdentityValue === null) {
3701
+ return null;
3702
+ }
3703
+ if (literalIdentityValue !== void 0) {
3704
+ return literalIdentityValue;
3705
+ }
3644
3706
  }
3645
3707
  const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
3646
3708
  if (apiName?.source === "explicit") {
3647
- return apiName.value;
3709
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3648
3710
  }
3649
3711
  if (apiName?.source === "inferred") {
3650
- return apiName.value;
3712
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3651
3713
  }
3652
3714
  diagnostics.push(
3653
3715
  makeAnalysisDiagnostic(
@@ -3710,15 +3772,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
3710
3772
  return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
3711
3773
  }
3712
3774
  function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
3713
- const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3714
- if (typeNode === void 0) {
3775
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3776
+ if (sourceTypeNode === void 0) {
3715
3777
  return [];
3716
3778
  }
3717
- const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
3718
- if (!ts3.isTypeReferenceNode(resolvedTypeNode) || resolvedTypeNode.typeArguments === void 0) {
3779
+ const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
3780
+ const directTypeNode = unwrapParentheses(sourceTypeNode);
3781
+ const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
3782
+ const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
3783
+ return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
3784
+ })();
3785
+ if (referenceTypeNode?.typeArguments === void 0) {
3719
3786
  return [];
3720
3787
  }
3721
- return resolvedTypeNode.typeArguments.map((argumentNode) => {
3788
+ return referenceTypeNode.typeArguments.map((argumentNode) => {
3722
3789
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
3723
3790
  return {
3724
3791
  tsType: argumentType,
@@ -3832,10 +3899,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
3832
3899
  };
3833
3900
  }
3834
3901
  function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
3835
- if (!ts3.isIdentifier(prop.name)) {
3902
+ const name = getAnalyzableObjectLikePropertyName(prop.name);
3903
+ if (name === null) {
3836
3904
  return null;
3837
3905
  }
3838
- const name = prop.name.text;
3839
3906
  const tsType = checker.getTypeAtLocation(prop);
3840
3907
  const optional = prop.questionToken !== void 0;
3841
3908
  const provenance = provenanceForNode(prop, file);
@@ -3891,6 +3958,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
3891
3958
  provenance
3892
3959
  };
3893
3960
  }
3961
+ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
3962
+ const seen = /* @__PURE__ */ new Set();
3963
+ const duplicates = /* @__PURE__ */ new Set();
3964
+ for (const member of members) {
3965
+ if (!ts3.isPropertySignature(member)) {
3966
+ continue;
3967
+ }
3968
+ const name = getAnalyzableObjectLikePropertyName(member.name);
3969
+ if (name === null) {
3970
+ continue;
3971
+ }
3972
+ if (seen.has(name)) {
3973
+ duplicates.add(name);
3974
+ continue;
3975
+ }
3976
+ seen.add(name);
3977
+ }
3978
+ return [...duplicates].sort();
3979
+ }
3980
+ function getAnalyzableObjectLikePropertyName(name) {
3981
+ if (!ts3.isIdentifier(name)) {
3982
+ return null;
3983
+ }
3984
+ return name.text;
3985
+ }
3894
3986
  function applyEnumMemberDisplayNames(type, annotations) {
3895
3987
  if (!annotations.some(
3896
3988
  (annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
@@ -4083,6 +4175,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4083
4175
  diagnostics
4084
4176
  );
4085
4177
  }
4178
+ if (isIntersectionType(type)) {
4179
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
4180
+ const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
4181
+ if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
4182
+ return resolveObjectType(
4183
+ type,
4184
+ checker,
4185
+ file,
4186
+ typeRegistry,
4187
+ visiting,
4188
+ sourceNode,
4189
+ metadataPolicy,
4190
+ extensionRegistry,
4191
+ diagnostics
4192
+ );
4193
+ }
4194
+ }
4086
4195
  if (isObjectType(type)) {
4087
4196
  return resolveObjectType(
4088
4197
  type,
@@ -4462,7 +4571,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4462
4571
  };
4463
4572
  }
4464
4573
  }
4465
- const recordNode = tryResolveRecordType(
4574
+ const recordNode = isObjectType(type) ? tryResolveRecordType(
4466
4575
  type,
4467
4576
  checker,
4468
4577
  file,
@@ -4471,7 +4580,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4471
4580
  metadataPolicy,
4472
4581
  extensionRegistry,
4473
4582
  collectedDiagnostics
4474
- );
4583
+ ) : null;
4475
4584
  if (recordNode) {
4476
4585
  visiting.delete(type);
4477
4586
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
@@ -4668,9 +4777,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
4668
4777
  );
4669
4778
  }
4670
4779
  const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
4671
- if (typeAliasDecl && ts3.isTypeLiteralNode(typeAliasDecl.type)) {
4780
+ const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
4781
+ if (typeAliasDecl && typeAliasMembers !== null) {
4672
4782
  return buildFieldNodeInfoMap(
4673
- typeAliasDecl.type.members,
4783
+ typeAliasMembers,
4674
4784
  checker,
4675
4785
  file,
4676
4786
  typeRegistry,
@@ -4977,17 +5087,18 @@ function findInterfaceByName(sourceFile, interfaceName) {
4977
5087
  function findTypeAliasByName(sourceFile, aliasName) {
4978
5088
  return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
4979
5089
  }
4980
- function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
5090
+ function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4981
5091
  const ctx = createProgramContext(filePath);
4982
5092
  return analyzeNamedTypeToIRFromProgramContext(
4983
5093
  ctx,
4984
5094
  filePath,
4985
5095
  typeName,
4986
5096
  extensionRegistry,
4987
- metadataPolicy
5097
+ metadataPolicy,
5098
+ discriminatorOptions
4988
5099
  );
4989
5100
  }
4990
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
5101
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4991
5102
  const analysisFilePath = path.resolve(filePath);
4992
5103
  const classDecl = findClassByName(ctx.sourceFile, typeName);
4993
5104
  if (classDecl !== null) {
@@ -4996,7 +5107,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4996
5107
  ctx.checker,
4997
5108
  analysisFilePath,
4998
5109
  extensionRegistry,
4999
- metadataPolicy
5110
+ metadataPolicy,
5111
+ discriminatorOptions
5000
5112
  );
5001
5113
  }
5002
5114
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
@@ -5006,7 +5118,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5006
5118
  ctx.checker,
5007
5119
  analysisFilePath,
5008
5120
  extensionRegistry,
5009
- metadataPolicy
5121
+ metadataPolicy,
5122
+ discriminatorOptions
5010
5123
  );
5011
5124
  }
5012
5125
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
@@ -5016,7 +5129,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5016
5129
  ctx.checker,
5017
5130
  analysisFilePath,
5018
5131
  extensionRegistry,
5019
- metadataPolicy
5132
+ metadataPolicy,
5133
+ discriminatorOptions
5020
5134
  );
5021
5135
  if (result.ok) {
5022
5136
  return result.analysis;
@@ -5173,7 +5287,8 @@ function generateSchemasFromClass(options) {
5173
5287
  ctx.checker,
5174
5288
  options.filePath,
5175
5289
  options.extensionRegistry,
5176
- options.metadata
5290
+ options.metadata,
5291
+ options.discriminator
5177
5292
  );
5178
5293
  return generateClassSchemas(
5179
5294
  analysis,
@@ -5199,7 +5314,8 @@ function generateSchemasFromProgram(options) {
5199
5314
  options.filePath,
5200
5315
  options.typeName,
5201
5316
  options.extensionRegistry,
5202
- options.metadata
5317
+ options.metadata,
5318
+ options.discriminator
5203
5319
  );
5204
5320
  return generateClassSchemas(
5205
5321
  analysis,
@@ -5435,7 +5551,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5435
5551
  typeRegistry,
5436
5552
  /* @__PURE__ */ new Set(),
5437
5553
  options.sourceNode,
5438
- createAnalyzerMetadataPolicy(options.metadata),
5554
+ createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
5439
5555
  options.extensionRegistry,
5440
5556
  diagnostics
5441
5557
  );
@@ -5484,7 +5600,8 @@ function generateSchemasFromDeclaration(options) {
5484
5600
  options.context.checker,
5485
5601
  filePath,
5486
5602
  options.extensionRegistry,
5487
- options.metadata
5603
+ options.metadata,
5604
+ options.discriminator
5488
5605
  ),
5489
5606
  filePath,
5490
5607
  options
@@ -5497,7 +5614,8 @@ function generateSchemasFromDeclaration(options) {
5497
5614
  options.context.checker,
5498
5615
  filePath,
5499
5616
  options.extensionRegistry,
5500
- options.metadata
5617
+ options.metadata,
5618
+ options.discriminator
5501
5619
  ),
5502
5620
  filePath,
5503
5621
  options
@@ -5509,7 +5627,8 @@ function generateSchemasFromDeclaration(options) {
5509
5627
  options.context.checker,
5510
5628
  filePath,
5511
5629
  options.extensionRegistry,
5512
- options.metadata
5630
+ options.metadata,
5631
+ options.discriminator
5513
5632
  );
5514
5633
  if (analyzedAlias.ok) {
5515
5634
  return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
@@ -5584,7 +5703,8 @@ function buildMixedAuthoringSchemas(options) {
5584
5703
  filePath,
5585
5704
  typeName,
5586
5705
  schemaOptions.extensionRegistry,
5587
- schemaOptions.metadata
5706
+ schemaOptions.metadata,
5707
+ schemaOptions.discriminator
5588
5708
  );
5589
5709
  const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
5590
5710
  const ir = canonicalizeTSDoc(