@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/index.d.ts CHANGED
@@ -35,7 +35,7 @@ export type { JSONSchema7, JSONSchemaType, ExtendedJSONSchema7, FormSpecSchemaEx
35
35
  export { createExtensionRegistry } from "./extensions/index.js";
36
36
  export type { ExtensionRegistry } from "./extensions/index.js";
37
37
  export type { UISchema, UISchemaElement, UISchemaElementBase, UISchemaElementType, ControlElement, VerticalLayout, HorizontalLayout, GroupLayout, Categorization, Category, LabelElement, Rule, RuleEffect, RuleConditionSchema, SchemaBasedCondition, } from "./ui-schema/types.js";
38
- export type { GenerateFromClassOptions, GenerateFromClassResult, GenerateSchemasOptions, GenerateSchemasFromProgramOptions, StaticSchemaGenerationOptions, } from "./generators/class-schema.js";
38
+ export type { DiscriminatorResolutionOptions, GenerateFromClassOptions, GenerateFromClassResult, GenerateSchemasOptions, GenerateSchemasFromProgramOptions, StaticSchemaGenerationOptions, } from "./generators/class-schema.js";
39
39
  export type { StaticBuildContext } from "./static-build.js";
40
40
  export type { DiscoveredTypeSchemas, GenerateSchemasFromDeclarationOptions, GenerateSchemasFromParameterOptions, GenerateSchemasFromReturnTypeOptions, GenerateSchemasFromTypeOptions, SchemaSourceDeclaration, } from "./generators/discovered-schema.js";
41
41
  export type { BuildMixedAuthoringSchemasOptions, MixedAuthoringSchemas, } from "./generators/mixed-authoring.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2903,6 +2903,9 @@ function extractDefaultValueAnnotation(initializer, file = "") {
2903
2903
  function isObjectType(type) {
2904
2904
  return !!(type.flags & ts3.TypeFlags.Object);
2905
2905
  }
2906
+ function isIntersectionType(type) {
2907
+ return !!(type.flags & ts3.TypeFlags.Intersection);
2908
+ }
2906
2909
  function isTypeReference(type) {
2907
2910
  return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
2908
2911
  }
@@ -2923,10 +2926,11 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
2923
2926
  ...hostType !== void 0 && { hostType }
2924
2927
  };
2925
2928
  }
2926
- function createAnalyzerMetadataPolicy(input) {
2929
+ function createAnalyzerMetadataPolicy(input, discriminator) {
2927
2930
  return {
2928
2931
  raw: input,
2929
- normalized: normalizeMetadataPolicy(input)
2932
+ normalized: normalizeMetadataPolicy(input),
2933
+ discriminator
2930
2934
  };
2931
2935
  }
2932
2936
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
@@ -2994,8 +2998,11 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
2994
2998
  diagnostics: docResult.diagnostics
2995
2999
  };
2996
3000
  }
2997
- function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
2998
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3001
+ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3002
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3003
+ metadataPolicy,
3004
+ discriminatorOptions
3005
+ );
2999
3006
  const name = classDecl.name?.text ?? "AnonymousClass";
3000
3007
  const fields = [];
3001
3008
  const fieldLayouts = [];
@@ -3076,8 +3083,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3076
3083
  staticMethods
3077
3084
  };
3078
3085
  }
3079
- function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3080
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3086
+ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3087
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3088
+ metadataPolicy,
3089
+ discriminatorOptions
3090
+ );
3081
3091
  const name = interfaceDecl.name.text;
3082
3092
  const fields = [];
3083
3093
  const typeRegistry = {};
@@ -3145,19 +3155,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3145
3155
  staticMethods: []
3146
3156
  };
3147
3157
  }
3148
- function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
3149
- if (!ts3.isTypeLiteralNode(typeAlias.type)) {
3158
+ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
3159
+ const members = getObjectLikeTypeAliasMembers(typeAlias.type);
3160
+ if (members === null) {
3150
3161
  const sourceFile = typeAlias.getSourceFile();
3151
3162
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3152
3163
  const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
3153
3164
  return {
3154
3165
  ok: false,
3155
- error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
3166
+ error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
3156
3167
  };
3157
3168
  }
3158
- const typeLiteral = typeAlias.type;
3159
- const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3169
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
3170
+ metadataPolicy,
3171
+ discriminatorOptions
3172
+ );
3160
3173
  const name = typeAlias.name.text;
3174
+ const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
3175
+ if (duplicatePropertyNames.length > 0) {
3176
+ const sourceFile = typeAlias.getSourceFile();
3177
+ const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3178
+ return {
3179
+ ok: false,
3180
+ error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
3181
+ };
3182
+ }
3161
3183
  const fields = [];
3162
3184
  const typeRegistry = {};
3163
3185
  const diagnostics = [];
@@ -3170,7 +3192,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3170
3192
  const annotations = [...typeAliasDoc.annotations];
3171
3193
  diagnostics.push(...typeAliasDoc.diagnostics);
3172
3194
  const visiting = /* @__PURE__ */ new Set();
3173
- for (const member of typeLiteral.members) {
3195
+ for (const member of members) {
3174
3196
  if (ts3.isPropertySignature(member)) {
3175
3197
  const fieldNode = analyzeInterfacePropertyToIR(
3176
3198
  member,
@@ -3279,15 +3301,43 @@ function isNullishSemanticType(type) {
3279
3301
  }
3280
3302
  return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
3281
3303
  }
3282
- function isStringLikeSemanticType(type) {
3304
+ function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
3305
+ if (seen.has(type)) {
3306
+ return false;
3307
+ }
3308
+ seen.add(type);
3283
3309
  if (type.flags & ts3.TypeFlags.StringLike) {
3284
3310
  return true;
3285
3311
  }
3286
3312
  if (type.isUnion()) {
3287
- return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
3313
+ return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
3314
+ }
3315
+ const baseConstraint = checker.getBaseConstraintOfType(type);
3316
+ if (baseConstraint !== void 0 && baseConstraint !== type) {
3317
+ return isStringLikeSemanticType(baseConstraint, checker, seen);
3288
3318
  }
3289
3319
  return false;
3290
3320
  }
3321
+ function getObjectLikeTypeAliasMembers(typeNode) {
3322
+ if (ts3.isParenthesizedTypeNode(typeNode)) {
3323
+ return getObjectLikeTypeAliasMembers(typeNode.type);
3324
+ }
3325
+ if (ts3.isTypeLiteralNode(typeNode)) {
3326
+ return [...typeNode.members];
3327
+ }
3328
+ if (ts3.isIntersectionTypeNode(typeNode)) {
3329
+ const members = [];
3330
+ for (const intersectionMember of typeNode.types) {
3331
+ const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
3332
+ if (resolvedMembers === null) {
3333
+ return null;
3334
+ }
3335
+ members.push(...resolvedMembers);
3336
+ }
3337
+ return members;
3338
+ }
3339
+ return null;
3340
+ }
3291
3341
  function extractDiscriminatorDirective(node, file, diagnostics) {
3292
3342
  const discriminatorTags = getLeadingParsedTags(node).filter(
3293
3343
  (tag) => tag.normalizedTagName === "discriminator"
@@ -3394,7 +3444,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
3394
3444
  );
3395
3445
  return null;
3396
3446
  }
3397
- if (!isStringLikeSemanticType(property.type)) {
3447
+ if (!isStringLikeSemanticType(property.type, checker)) {
3398
3448
  diagnostics.push(
3399
3449
  makeAnalysisDiagnostic(
3400
3450
  "TYPE_MISMATCH",
@@ -3421,8 +3471,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
3421
3471
  const localTypeParameter = node.typeParameters?.[typeParameterIndex];
3422
3472
  return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
3423
3473
  }
3424
- function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
3425
- const propertySymbol = boundType.getProperty(fieldName);
3474
+ function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
3475
+ const propertySymbol = boundType.getProperty(propertyName);
3426
3476
  if (propertySymbol === void 0) {
3427
3477
  return void 0;
3428
3478
  }
@@ -3453,6 +3503,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
3453
3503
  }
3454
3504
  return void 0;
3455
3505
  }
3506
+ function getDiscriminatorIdentityPropertyNames(fieldName) {
3507
+ return fieldName === "object" ? ["object"] : [fieldName, "object"];
3508
+ }
3456
3509
  function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3457
3510
  const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
3458
3511
  if (declaration === null) {
@@ -3473,6 +3526,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3473
3526
  );
3474
3527
  return metadata?.apiName;
3475
3528
  }
3529
+ function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
3530
+ const prefix = discriminatorOptions?.apiNamePrefix;
3531
+ return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
3532
+ }
3476
3533
  function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
3477
3534
  if (seen.has(type)) {
3478
3535
  return null;
@@ -3527,22 +3584,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
3527
3584
  return null;
3528
3585
  }
3529
3586
  }
3530
- const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3531
- boundType,
3532
- fieldName,
3533
- checker,
3534
- provenance,
3535
- diagnostics
3536
- );
3537
- if (literalIdentityValue !== void 0) {
3538
- return literalIdentityValue;
3587
+ for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
3588
+ const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
3589
+ boundType,
3590
+ identityPropertyName,
3591
+ checker,
3592
+ provenance,
3593
+ diagnostics
3594
+ );
3595
+ if (literalIdentityValue === null) {
3596
+ return null;
3597
+ }
3598
+ if (literalIdentityValue !== void 0) {
3599
+ return literalIdentityValue;
3600
+ }
3539
3601
  }
3540
3602
  const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
3541
3603
  if (apiName?.source === "explicit") {
3542
- return apiName.value;
3604
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3543
3605
  }
3544
3606
  if (apiName?.source === "inferred") {
3545
- return apiName.value;
3607
+ return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
3546
3608
  }
3547
3609
  diagnostics.push(
3548
3610
  makeAnalysisDiagnostic(
@@ -3605,15 +3667,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
3605
3667
  return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
3606
3668
  }
3607
3669
  function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
3608
- const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3609
- if (typeNode === void 0) {
3670
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
3671
+ if (sourceTypeNode === void 0) {
3610
3672
  return [];
3611
3673
  }
3612
- const resolvedTypeNode = resolveAliasedTypeNode(typeNode, checker);
3613
- if (!ts3.isTypeReferenceNode(resolvedTypeNode) || resolvedTypeNode.typeArguments === void 0) {
3674
+ const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
3675
+ const directTypeNode = unwrapParentheses(sourceTypeNode);
3676
+ const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
3677
+ const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
3678
+ return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
3679
+ })();
3680
+ if (referenceTypeNode?.typeArguments === void 0) {
3614
3681
  return [];
3615
3682
  }
3616
- return resolvedTypeNode.typeArguments.map((argumentNode) => {
3683
+ return referenceTypeNode.typeArguments.map((argumentNode) => {
3617
3684
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
3618
3685
  return {
3619
3686
  tsType: argumentType,
@@ -3727,10 +3794,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
3727
3794
  };
3728
3795
  }
3729
3796
  function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
3730
- if (!ts3.isIdentifier(prop.name)) {
3797
+ const name = getAnalyzableObjectLikePropertyName(prop.name);
3798
+ if (name === null) {
3731
3799
  return null;
3732
3800
  }
3733
- const name = prop.name.text;
3734
3801
  const tsType = checker.getTypeAtLocation(prop);
3735
3802
  const optional = prop.questionToken !== void 0;
3736
3803
  const provenance = provenanceForNode(prop, file);
@@ -3786,6 +3853,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
3786
3853
  provenance
3787
3854
  };
3788
3855
  }
3856
+ function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
3857
+ const seen = /* @__PURE__ */ new Set();
3858
+ const duplicates = /* @__PURE__ */ new Set();
3859
+ for (const member of members) {
3860
+ if (!ts3.isPropertySignature(member)) {
3861
+ continue;
3862
+ }
3863
+ const name = getAnalyzableObjectLikePropertyName(member.name);
3864
+ if (name === null) {
3865
+ continue;
3866
+ }
3867
+ if (seen.has(name)) {
3868
+ duplicates.add(name);
3869
+ continue;
3870
+ }
3871
+ seen.add(name);
3872
+ }
3873
+ return [...duplicates].sort();
3874
+ }
3875
+ function getAnalyzableObjectLikePropertyName(name) {
3876
+ if (!ts3.isIdentifier(name)) {
3877
+ return null;
3878
+ }
3879
+ return name.text;
3880
+ }
3789
3881
  function applyEnumMemberDisplayNames(type, annotations) {
3790
3882
  if (!annotations.some(
3791
3883
  (annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
@@ -3978,6 +4070,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
3978
4070
  diagnostics
3979
4071
  );
3980
4072
  }
4073
+ if (isIntersectionType(type)) {
4074
+ const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
4075
+ const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
4076
+ if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
4077
+ return resolveObjectType(
4078
+ type,
4079
+ checker,
4080
+ file,
4081
+ typeRegistry,
4082
+ visiting,
4083
+ sourceNode,
4084
+ metadataPolicy,
4085
+ extensionRegistry,
4086
+ diagnostics
4087
+ );
4088
+ }
4089
+ }
3981
4090
  if (isObjectType(type)) {
3982
4091
  return resolveObjectType(
3983
4092
  type,
@@ -4064,9 +4173,10 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4064
4173
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
4065
4174
  return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
4066
4175
  }
4067
- function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4176
+ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics, visitedAliases = /* @__PURE__ */ new Set()) {
4068
4177
  const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
4069
- if (nestedAliasDecl !== void 0) {
4178
+ if (nestedAliasDecl !== void 0 && !visitedAliases.has(nestedAliasDecl)) {
4179
+ visitedAliases.add(nestedAliasDecl);
4070
4180
  return resolveAliasedPrimitiveTarget(
4071
4181
  checker.getTypeFromTypeNode(nestedAliasDecl.type),
4072
4182
  checker,
@@ -4075,9 +4185,25 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4075
4185
  visiting,
4076
4186
  metadataPolicy,
4077
4187
  extensionRegistry,
4078
- diagnostics
4188
+ diagnostics,
4189
+ visitedAliases
4079
4190
  );
4080
4191
  }
4192
+ if (type.flags & ts3.TypeFlags.String) {
4193
+ return { kind: "primitive", primitiveKind: "string" };
4194
+ }
4195
+ if (type.flags & ts3.TypeFlags.Number) {
4196
+ return { kind: "primitive", primitiveKind: "number" };
4197
+ }
4198
+ if (type.flags & (ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral)) {
4199
+ return { kind: "primitive", primitiveKind: "bigint" };
4200
+ }
4201
+ if (type.flags & ts3.TypeFlags.Boolean) {
4202
+ return { kind: "primitive", primitiveKind: "boolean" };
4203
+ }
4204
+ if (type.flags & ts3.TypeFlags.Null) {
4205
+ return { kind: "primitive", primitiveKind: "null" };
4206
+ }
4081
4207
  return resolveTypeNode(
4082
4208
  type,
4083
4209
  checker,
@@ -4357,7 +4483,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4357
4483
  };
4358
4484
  }
4359
4485
  }
4360
- const recordNode = tryResolveRecordType(
4486
+ const recordNode = isObjectType(type) ? tryResolveRecordType(
4361
4487
  type,
4362
4488
  checker,
4363
4489
  file,
@@ -4366,7 +4492,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4366
4492
  metadataPolicy,
4367
4493
  extensionRegistry,
4368
4494
  collectedDiagnostics
4369
- );
4495
+ ) : null;
4370
4496
  if (recordNode) {
4371
4497
  visiting.delete(type);
4372
4498
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
@@ -4563,9 +4689,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
4563
4689
  );
4564
4690
  }
4565
4691
  const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
4566
- if (typeAliasDecl && ts3.isTypeLiteralNode(typeAliasDecl.type)) {
4692
+ const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
4693
+ if (typeAliasDecl && typeAliasMembers !== null) {
4567
4694
  return buildFieldNodeInfoMap(
4568
- typeAliasDecl.type.members,
4695
+ typeAliasMembers,
4569
4696
  checker,
4570
4697
  file,
4571
4698
  typeRegistry,
@@ -4856,17 +4983,18 @@ function findInterfaceByName(sourceFile, interfaceName) {
4856
4983
  function findTypeAliasByName(sourceFile, aliasName) {
4857
4984
  return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
4858
4985
  }
4859
- function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
4986
+ function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4860
4987
  const ctx = createProgramContext(filePath);
4861
4988
  return analyzeNamedTypeToIRFromProgramContext(
4862
4989
  ctx,
4863
4990
  filePath,
4864
4991
  typeName,
4865
4992
  extensionRegistry,
4866
- metadataPolicy
4993
+ metadataPolicy,
4994
+ discriminatorOptions
4867
4995
  );
4868
4996
  }
4869
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
4997
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4870
4998
  const analysisFilePath = path.resolve(filePath);
4871
4999
  const classDecl = findClassByName(ctx.sourceFile, typeName);
4872
5000
  if (classDecl !== null) {
@@ -4875,7 +5003,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4875
5003
  ctx.checker,
4876
5004
  analysisFilePath,
4877
5005
  extensionRegistry,
4878
- metadataPolicy
5006
+ metadataPolicy,
5007
+ discriminatorOptions
4879
5008
  );
4880
5009
  }
4881
5010
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
@@ -4885,7 +5014,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4885
5014
  ctx.checker,
4886
5015
  analysisFilePath,
4887
5016
  extensionRegistry,
4888
- metadataPolicy
5017
+ metadataPolicy,
5018
+ discriminatorOptions
4889
5019
  );
4890
5020
  }
4891
5021
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
@@ -4895,7 +5025,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
4895
5025
  ctx.checker,
4896
5026
  analysisFilePath,
4897
5027
  extensionRegistry,
4898
- metadataPolicy
5028
+ metadataPolicy,
5029
+ discriminatorOptions
4899
5030
  );
4900
5031
  if (result.ok) {
4901
5032
  return result.analysis;
@@ -5032,7 +5163,8 @@ function generateSchemasFromClass(options) {
5032
5163
  ctx.checker,
5033
5164
  options.filePath,
5034
5165
  options.extensionRegistry,
5035
- options.metadata
5166
+ options.metadata,
5167
+ options.discriminator
5036
5168
  );
5037
5169
  return generateClassSchemas(
5038
5170
  analysis,
@@ -5058,7 +5190,8 @@ function generateSchemasFromProgram(options) {
5058
5190
  options.filePath,
5059
5191
  options.typeName,
5060
5192
  options.extensionRegistry,
5061
- options.metadata
5193
+ options.metadata,
5194
+ options.discriminator
5062
5195
  );
5063
5196
  return generateClassSchemas(
5064
5197
  analysis,
@@ -5277,7 +5410,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5277
5410
  typeRegistry,
5278
5411
  /* @__PURE__ */ new Set(),
5279
5412
  options.sourceNode,
5280
- createAnalyzerMetadataPolicy(options.metadata),
5413
+ createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
5281
5414
  options.extensionRegistry,
5282
5415
  diagnostics
5283
5416
  );
@@ -5326,7 +5459,8 @@ function generateSchemasFromDeclaration(options) {
5326
5459
  options.context.checker,
5327
5460
  filePath,
5328
5461
  options.extensionRegistry,
5329
- options.metadata
5462
+ options.metadata,
5463
+ options.discriminator
5330
5464
  ),
5331
5465
  filePath,
5332
5466
  options
@@ -5339,7 +5473,8 @@ function generateSchemasFromDeclaration(options) {
5339
5473
  options.context.checker,
5340
5474
  filePath,
5341
5475
  options.extensionRegistry,
5342
- options.metadata
5476
+ options.metadata,
5477
+ options.discriminator
5343
5478
  ),
5344
5479
  filePath,
5345
5480
  options
@@ -5351,7 +5486,8 @@ function generateSchemasFromDeclaration(options) {
5351
5486
  options.context.checker,
5352
5487
  filePath,
5353
5488
  options.extensionRegistry,
5354
- options.metadata
5489
+ options.metadata,
5490
+ options.discriminator
5355
5491
  );
5356
5492
  if (analyzedAlias.ok) {
5357
5493
  return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
@@ -5417,7 +5553,8 @@ function buildMixedAuthoringSchemas(options) {
5417
5553
  filePath,
5418
5554
  typeName,
5419
5555
  schemaOptions.extensionRegistry,
5420
- schemaOptions.metadata
5556
+ schemaOptions.metadata,
5557
+ schemaOptions.discriminator
5421
5558
  );
5422
5559
  const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
5423
5560
  const ir = canonicalizeTSDoc(