@twin.org/tools-core 0.0.3-next.21 → 0.0.3-next.23

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.
@@ -34,81 +34,81 @@ export class JsonSchemaBuilder {
34
34
  * Dictionary of TypeScript utility type names to their schema mapping handlers.
35
35
  */
36
36
  static _utilityTypeHandlers = {
37
- Partial: (context, typeNode) => JsonSchemaBuilder.mapPartialUtilityType(context, typeNode),
38
- Required: (context, typeNode) => JsonSchemaBuilder.mapRequiredUtilityType(context, typeNode),
39
- Pick: (context, typeNode) => JsonSchemaBuilder.mapPickUtilityType(context, typeNode),
40
- Omit: (context, typeNode) => JsonSchemaBuilder.mapOmitUtilityType(context, typeNode),
41
- Exclude: (context, typeNode) => JsonSchemaBuilder.mapExcludeUtilityType(context, typeNode),
42
- Extract: (context, typeNode) => JsonSchemaBuilder.mapExtractUtilityType(context, typeNode),
43
- NonNullable: (context, typeNode) => JsonSchemaBuilder.mapNonNullableUtilityType(context, typeNode),
44
- Record: (context, typeNode) => JsonSchemaBuilder.mapRecordUtilityType(context, typeNode),
45
- JsonLdObjectWithId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
37
+ Partial: (context, typeNode) => UtilityTypeSchemaMapper.mapPartialUtilityType(context, typeNode),
38
+ Required: (context, typeNode) => UtilityTypeSchemaMapper.mapRequiredUtilityType(context, typeNode),
39
+ Pick: (context, typeNode) => UtilityTypeSchemaMapper.mapPickUtilityType(context, typeNode),
40
+ Omit: (context, typeNode) => UtilityTypeSchemaMapper.mapOmitUtilityType(context, typeNode),
41
+ Exclude: (context, typeNode) => UtilityTypeSchemaMapper.mapExcludeUtilityType(context, typeNode),
42
+ Extract: (context, typeNode) => UtilityTypeSchemaMapper.mapExtractUtilityType(context, typeNode),
43
+ NonNullable: (context, typeNode) => UtilityTypeSchemaMapper.mapNonNullableUtilityType(context, typeNode),
44
+ Record: (context, typeNode) => UtilityTypeSchemaMapper.mapRecordUtilityType(context, typeNode),
45
+ JsonLdObjectWithId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
46
46
  keysToRemove: ["id", "@id"],
47
47
  keyToAdd: "id",
48
48
  isAddedKeyRequired: true
49
49
  }),
50
- JsonLdObjectWithAtId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
50
+ JsonLdObjectWithAtId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
51
51
  keysToRemove: ["id", "@id"],
52
52
  keyToAdd: "@id",
53
53
  isAddedKeyRequired: true
54
54
  }),
55
- JsonLdObjectWithOptionalId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
55
+ JsonLdObjectWithOptionalId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
56
56
  keysToRemove: ["id", "@id"],
57
57
  keyToAdd: "id",
58
58
  isAddedKeyRequired: false
59
59
  }),
60
- JsonLdObjectWithOptionalAtId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
60
+ JsonLdObjectWithOptionalAtId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
61
61
  keysToRemove: ["id", "@id"],
62
62
  keyToAdd: "@id",
63
63
  isAddedKeyRequired: false
64
64
  }),
65
- JsonLdObjectWithNoId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
65
+ JsonLdObjectWithNoId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
66
66
  keysToRemove: ["id"]
67
67
  }),
68
- JsonLdObjectWithNoAtId: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
68
+ JsonLdObjectWithNoAtId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
69
69
  keysToRemove: ["@id"]
70
70
  }),
71
- JsonLdObjectWithType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
71
+ JsonLdObjectWithType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
72
72
  keysToRemove: ["type", "@type"],
73
73
  keyToAdd: "type",
74
74
  isAddedKeyRequired: true
75
75
  }),
76
- JsonLdObjectWithAtType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
76
+ JsonLdObjectWithAtType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
77
77
  keysToRemove: ["type", "@type"],
78
78
  keyToAdd: "@type",
79
79
  isAddedKeyRequired: true
80
80
  }),
81
- JsonLdObjectWithOptionalType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
81
+ JsonLdObjectWithOptionalType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
82
82
  keysToRemove: ["type", "@type"],
83
83
  keyToAdd: "type",
84
84
  isAddedKeyRequired: false
85
85
  }),
86
- JsonLdObjectWithOptionalAtType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
86
+ JsonLdObjectWithOptionalAtType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
87
87
  keysToRemove: ["type", "@type"],
88
88
  keyToAdd: "@type",
89
89
  isAddedKeyRequired: false
90
90
  }),
91
- JsonLdObjectWithNoType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
91
+ JsonLdObjectWithNoType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
92
92
  keysToRemove: ["type"]
93
93
  }),
94
- JsonLdObjectWithNoAtType: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
94
+ JsonLdObjectWithNoAtType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
95
95
  keysToRemove: ["@type"]
96
96
  }),
97
- JsonLdObjectWithContext: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
97
+ JsonLdObjectWithContext: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
98
98
  keysToRemove: ["@context"],
99
99
  keyToAdd: "@context",
100
100
  isAddedKeyRequired: true
101
101
  }),
102
- JsonLdObjectWithOptionalContext: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
102
+ JsonLdObjectWithOptionalContext: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
103
103
  keysToRemove: ["@context"],
104
104
  keyToAdd: "@context",
105
105
  isAddedKeyRequired: false
106
106
  }),
107
- JsonLdObjectWithNoContext: (context, typeNode) => JsonSchemaBuilder.mapJsonLdObjectUtilityType(context, typeNode, {
107
+ JsonLdObjectWithNoContext: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
108
108
  keysToRemove: ["@context"]
109
109
  }),
110
- SingleOccurrenceArray: (context, typeNode) => JsonSchemaBuilder.mapSingleOccurrenceArrayUtilityType(context, typeNode),
111
- ObjectOrArray: (context, typeNode) => JsonSchemaBuilder.mapObjectOrArrayUtilityType(context, typeNode)
110
+ SingleOccurrenceArray: (context, typeNode) => UtilityTypeSchemaMapper.mapSingleOccurrenceArrayUtilityType(context, typeNode),
111
+ ObjectOrArray: (context, typeNode) => UtilityTypeSchemaMapper.mapObjectOrArrayUtilityType(context, typeNode)
112
112
  };
113
113
  /**
114
114
  * Parse all object declarations from a source file.
@@ -1337,7 +1337,7 @@ export class JsonSchemaBuilder {
1337
1337
  if (cachedSchemaId) {
1338
1338
  return cachedSchemaId;
1339
1339
  }
1340
- const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, typeName);
1340
+ const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, typeName, context.activeSourceFile?.fileName);
1341
1341
  if (!declarationResult) {
1342
1342
  return mappedReference?.schemaId;
1343
1343
  }
@@ -2107,6 +2107,7 @@ export class JsonSchemaBuilder {
2107
2107
  * @param context The generation context.
2108
2108
  * @param schema The schema to expand.
2109
2109
  * @param declaration The interface declaration.
2110
+ * @throws GeneralError when an extended type cannot be resolved to a schema.
2110
2111
  */
2111
2112
  static applyInterfaceExtendsSchema(context, schema, declaration) {
2112
2113
  const extendsClause = declaration.heritageClauses?.find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword);
@@ -2132,10 +2133,22 @@ export class JsonSchemaBuilder {
2132
2133
  // TypeReferenceNode is constructed here using the same expression + type
2133
2134
  // arguments so the utility handler receives exactly the AST shape it expects.
2134
2135
  if (JsonSchemaBuilder._utilityTypeHandlers[typeName] && ts.isIdentifier(expression)) {
2135
- const syntheticTypeNode = ts.factory.createTypeReferenceNode(expression, extendedType.typeArguments);
2136
- const mappedSchema = JsonSchemaBuilder.mapTypeNodeToSchema(context, syntheticTypeNode);
2137
- if (mappedSchema) {
2138
- allOfRefs.push(mappedSchema);
2136
+ const refinedBaseReference = JsonSchemaBuilder.resolveRefinementUtilityBaseRef(context, declaration, extendedType);
2137
+ if (refinedBaseReference) {
2138
+ allOfRefs.push(refinedBaseReference);
2139
+ }
2140
+ else {
2141
+ const syntheticTypeNode = ts.factory.createTypeReferenceNode(expression, extendedType.typeArguments);
2142
+ const mappedSchema = JsonSchemaBuilder.mapTypeNodeToSchema(context, syntheticTypeNode);
2143
+ if (mappedSchema) {
2144
+ allOfRefs.push(mappedSchema);
2145
+ }
2146
+ else {
2147
+ throw new GeneralError(JsonSchemaBuilder.CLASS_NAME, "missingTypeReferenceSchema", {
2148
+ typeName: extendedType.getText(),
2149
+ importSource: ""
2150
+ });
2151
+ }
2139
2152
  }
2140
2153
  }
2141
2154
  else {
@@ -2149,79 +2162,101 @@ export class JsonSchemaBuilder {
2149
2162
  }
2150
2163
  if (allOfRefs.length > 0) {
2151
2164
  schema.allOf = allOfRefs;
2165
+ // Extract properties defined in the derived interface to avoid duplication with expanded utility bases
2166
+ const derivedPropertyNames = new Set();
2167
+ for (const member of declaration.members) {
2168
+ if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
2169
+ derivedPropertyNames.add(member.name.text);
2170
+ }
2171
+ }
2172
+ // Remove redefined properties from inlined utility base schemas
2173
+ if (derivedPropertyNames.size > 0) {
2174
+ for (const allOfRef of allOfRefs) {
2175
+ if (allOfRef.properties && Is.object(allOfRef.properties)) {
2176
+ for (const propName of derivedPropertyNames) {
2177
+ delete allOfRef.properties[propName];
2178
+ }
2179
+ // Update required array to remove redefined properties
2180
+ if (Is.array(allOfRef.required)) {
2181
+ allOfRef.required = allOfRef.required.filter(req => !derivedPropertyNames.has(req));
2182
+ }
2183
+ }
2184
+ }
2185
+ // Ensure derived interface members are represented at the root schema level.
2186
+ const { properties: derivedProperties, required: derivedRequired } = JsonSchemaBuilder.buildObjectMembersSchema(context, declaration.members);
2187
+ if (Object.keys(derivedProperties).length > 0) {
2188
+ schema.properties = {
2189
+ ...(schema.properties ?? {}),
2190
+ ...derivedProperties
2191
+ };
2192
+ }
2193
+ if (derivedRequired.length > 0) {
2194
+ schema.required = [...new Set([...(schema.required ?? []), ...derivedRequired])];
2195
+ }
2196
+ }
2152
2197
  }
2153
2198
  }
2154
2199
  /**
2155
- * Map Partial<T> to an object schema with no required properties.
2156
- * @param context The generation context.
2157
- * @param typeNode The Partial type reference.
2158
- * @returns The mapped schema.
2159
- */
2160
- static mapPartialUtilityType(context, typeNode) {
2161
- return UtilityTypeSchemaMapper.mapPartialUtilityType(context, typeNode, (ctx, baseTypeNode) => JsonSchemaBuilder.resolveUtilityBaseObjectSchema(ctx, baseTypeNode));
2162
- }
2163
- /**
2164
- * Map Required<T> to an object schema with all properties required.
2165
- * @param context The generation context.
2166
- * @param typeNode The Required type reference.
2167
- * @returns The mapped schema.
2168
- */
2169
- static mapRequiredUtilityType(context, typeNode) {
2170
- return UtilityTypeSchemaMapper.mapRequiredUtilityType(context, typeNode, (ctx, baseTypeNode) => JsonSchemaBuilder.resolveUtilityBaseObjectSchema(ctx, baseTypeNode));
2171
- }
2172
- /**
2173
- * Map Pick<T, K> to an object schema with selected keys preserved.
2200
+ * Resolve a direct base reference for refinement Omit patterns in interface extends clauses.
2174
2201
  * @param context The generation context.
2175
- * @param typeNode The Pick type reference.
2176
- * @returns The mapped schema.
2177
- */
2178
- static mapPickUtilityType(context, typeNode) {
2179
- return UtilityTypeSchemaMapper.mapPickUtilityType(context, typeNode, (ctx, baseTypeNode) => JsonSchemaBuilder.resolveUtilityBaseObjectSchema(ctx, baseTypeNode), (ctx, keysNode) => JsonSchemaBuilder.extractUtilityTypeKeys(ctx, keysNode));
2180
- }
2181
- /**
2182
- * Map Omit<T, K> to an object schema with selected keys removed.
2183
- * @param context The generation context.
2184
- * @param typeNode The Omit type reference.
2185
- * @returns The mapped schema.
2186
- */
2187
- static mapOmitUtilityType(context, typeNode) {
2188
- return UtilityTypeSchemaMapper.mapOmitUtilityType(context, typeNode, (ctx, baseTypeNode) => JsonSchemaBuilder.resolveUtilityBaseObjectSchema(ctx, baseTypeNode), (ctx, keysNode) => JsonSchemaBuilder.extractUtilityTypeKeys(ctx, keysNode));
2189
- }
2190
- /**
2191
- * Map Exclude<T, U> to a schema that removes U members from T.
2192
- * @param context The generation context.
2193
- * @param typeNode The Exclude type reference.
2194
- * @returns The mapped schema.
2195
- */
2196
- static mapExcludeUtilityType(context, typeNode) {
2197
- return UtilityTypeSchemaMapper.mapExcludeUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2198
- }
2199
- /**
2200
- * Map Extract<T, U> to a schema that keeps U members from T.
2201
- * @param context The generation context.
2202
- * @param typeNode The Extract type reference.
2203
- * @returns The mapped schema.
2204
- */
2205
- static mapExtractUtilityType(context, typeNode) {
2206
- return UtilityTypeSchemaMapper.mapExtractUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2207
- }
2208
- /**
2209
- * Map NonNullable<T> by removing null and undefined branches from T.
2210
- * @param context The generation context.
2211
- * @param typeNode The NonNullable type reference.
2212
- * @returns The mapped schema.
2202
+ * @param declaration The interface declaration being mapped.
2203
+ * @param extendedType The heritage type being processed.
2204
+ * @returns A direct base reference when a refinement pattern is detected.
2213
2205
  */
2214
- static mapNonNullableUtilityType(context, typeNode) {
2215
- return UtilityTypeSchemaMapper.mapNonNullableUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2216
- }
2217
- /**
2218
- * Map Record<K, V> to an object schema with key constraints where possible.
2219
- * @param context The generation context.
2220
- * @param typeNode The Record type reference.
2221
- * @returns The mapped schema.
2222
- */
2223
- static mapRecordUtilityType(context, typeNode) {
2224
- return UtilityTypeSchemaMapper.mapRecordUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2206
+ static resolveRefinementUtilityBaseRef(context, declaration, extendedType) {
2207
+ const expression = extendedType.expression;
2208
+ if (!ts.isIdentifier(expression) || expression.text !== "Omit") {
2209
+ return undefined;
2210
+ }
2211
+ const baseTypeNode = extendedType.typeArguments?.[0];
2212
+ if (!baseTypeNode || !ts.isTypeReferenceNode(baseTypeNode) || baseTypeNode.typeArguments) {
2213
+ return undefined;
2214
+ }
2215
+ const omittedKeys = JsonSchemaBuilder.extractUtilityTypeKeys(context, extendedType.typeArguments?.[1]);
2216
+ if (omittedKeys.length === 0) {
2217
+ return undefined;
2218
+ }
2219
+ const propertyNames = new Set();
2220
+ const optionalPropertyNames = new Set();
2221
+ for (const member of declaration.members) {
2222
+ if (ts.isPropertySignature(member) && member.name) {
2223
+ if (ts.isIdentifier(member.name)) {
2224
+ propertyNames.add(member.name.text);
2225
+ if (member.questionToken) {
2226
+ optionalPropertyNames.add(member.name.text);
2227
+ }
2228
+ }
2229
+ else if (ts.isStringLiteral(member.name) || ts.isNumericLiteral(member.name)) {
2230
+ propertyNames.add(member.name.text);
2231
+ if (member.questionToken) {
2232
+ optionalPropertyNames.add(member.name.text);
2233
+ }
2234
+ }
2235
+ }
2236
+ }
2237
+ // Ensure all omitted keys are redefined in the derived interface
2238
+ if (!omittedKeys.every(omittedKey => propertyNames.has(omittedKey))) {
2239
+ return undefined;
2240
+ }
2241
+ // Ensure ONLY omitted keys are being redefined (no extra properties are being added/redefined)
2242
+ const omittedKeySet = new Set(omittedKeys);
2243
+ if (!Array.from(propertyNames).every(propName => omittedKeySet.has(propName))) {
2244
+ return undefined;
2245
+ }
2246
+ const baseTypeName = ts.isIdentifier(baseTypeNode.typeName)
2247
+ ? baseTypeNode.typeName.text
2248
+ : baseTypeNode.typeName.right.text;
2249
+ const baseSchema = JsonSchemaBuilder.resolveObjectTypeSchemaForUtility(context, baseTypeName);
2250
+ const baseRequiredKeys = new Set((Is.array(baseSchema?.required) ? baseSchema.required : []).filter((requiredKey) => Is.string(requiredKey)));
2251
+ const doesReverseOptionalityForRequiredBaseKey = omittedKeys.some(omittedKey => optionalPropertyNames.has(omittedKey) && baseRequiredKeys.has(omittedKey));
2252
+ if (doesReverseOptionalityForRequiredBaseKey) {
2253
+ return undefined;
2254
+ }
2255
+ const title = StringHelper.stripPrefix(baseTypeName);
2256
+ const existingSchemaId = JsonSchemaBuilder.findExistingSchemaIdByTitle(context, title);
2257
+ return {
2258
+ $ref: existingSchemaId ?? `${context.namespace}${title}`
2259
+ };
2225
2260
  }
2226
2261
  /**
2227
2262
  * Determine whether a type node represents null or undefined.
@@ -2266,19 +2301,6 @@ export class JsonSchemaBuilder {
2266
2301
  }
2267
2302
  return [];
2268
2303
  }
2269
- /**
2270
- * Map JsonLdObject utility types using key-removal and optional key-addition rules.
2271
- * @param context The generation context.
2272
- * @param typeNode The JsonLdObject utility type reference.
2273
- * @param options Mapping options.
2274
- * @param options.keysToRemove Keys to remove from the base schema.
2275
- * @param options.keyToAdd Optional key to add to the base schema.
2276
- * @param options.isAddedKeyRequired Whether the added key should be required.
2277
- * @returns The mapped schema.
2278
- */
2279
- static mapJsonLdObjectUtilityType(context, typeNode, options) {
2280
- return UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, options, (ctx, baseTypeNode) => JsonSchemaBuilder.resolveUtilityBaseObjectSchema(ctx, baseTypeNode), (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2281
- }
2282
2304
  /**
2283
2305
  * Resolve a default schema for JsonLdObject utility key additions when the type argument is omitted.
2284
2306
  * @param baseSchema The base object schema.
@@ -2352,24 +2374,6 @@ export class JsonSchemaBuilder {
2352
2374
  }
2353
2375
  return fallbackSchema;
2354
2376
  }
2355
- /**
2356
- * Map ObjectOrArray<T> to a schema accepting T or T[].
2357
- * @param context The generation context.
2358
- * @param typeNode The ObjectOrArray type reference.
2359
- * @returns The mapped schema.
2360
- */
2361
- static mapObjectOrArrayUtilityType(context, typeNode) {
2362
- return UtilityTypeSchemaMapper.mapObjectOrArrayUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2363
- }
2364
- /**
2365
- * Map SingleOccurrenceArray<T, U> to a non-empty array containing exactly one U.
2366
- * @param context The generation context.
2367
- * @param typeNode The SingleOccurrenceArray type reference.
2368
- * @returns The mapped schema.
2369
- */
2370
- static mapSingleOccurrenceArrayUtilityType(context, typeNode) {
2371
- return UtilityTypeSchemaMapper.mapSingleOccurrenceArrayUtilityType(context, typeNode, (ctx, node) => JsonSchemaBuilder.mapTypeNodeToSchema(ctx, node));
2372
- }
2373
2377
  /**
2374
2378
  * Add a comment to schemas inlined for utility type transformations.
2375
2379
  * @param schema The schema to annotate.
@@ -2478,9 +2482,16 @@ export class JsonSchemaBuilder {
2478
2482
  * @returns The resolved object schema.
2479
2483
  */
2480
2484
  static resolveMappedUtilityBaseObjectSchema(context, mappedSchema) {
2481
- if (mappedSchema.type === "object" && mappedSchema.properties) {
2485
+ if (mappedSchema.type === "object") {
2482
2486
  return ObjectHelper.clone(mappedSchema);
2483
2487
  }
2488
+ if (Is.array(mappedSchema.allOf) && mappedSchema.allOf.length > 0) {
2489
+ const expandedSchema = JsonSchemaBuilder.expandAllOfReferences(context, ObjectHelper.clone(mappedSchema), mappedSchema.title);
2490
+ if (expandedSchema.type === "object" || expandedSchema.properties) {
2491
+ expandedSchema.type ??= "object";
2492
+ return expandedSchema;
2493
+ }
2494
+ }
2484
2495
  if (mappedSchema.$ref) {
2485
2496
  for (const packageSchemaEntries of Object.values(context.schemas)) {
2486
2497
  for (const referencedSchema of Object.values(packageSchemaEntries)) {
@@ -2680,7 +2691,7 @@ export class JsonSchemaBuilder {
2680
2691
  const candidateTypeNames = [`I${schemaTitle}`, schemaTitle];
2681
2692
  for (const moduleSpecifier of moduleSpecifiers) {
2682
2693
  for (const candidateTypeName of candidateTypeNames) {
2683
- const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, candidateTypeName);
2694
+ const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, candidateTypeName, context.activeSourceFile?.fileName);
2684
2695
  if (declarationResult) {
2685
2696
  const mappedReference = JsonSchemaBuilder.resolveReferenceMappingTarget(context, moduleSpecifier, candidateTypeName);
2686
2697
  const externalContext = {
@@ -2803,7 +2814,7 @@ export class JsonSchemaBuilder {
2803
2814
  }
2804
2815
  return undefined;
2805
2816
  }
2806
- const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, candidateTypeName);
2817
+ const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, candidateTypeName, context.activeSourceFile?.fileName);
2807
2818
  if (!declarationResult) {
2808
2819
  return undefined;
2809
2820
  }
@@ -3229,7 +3240,7 @@ export class JsonSchemaBuilder {
3229
3240
  return cachedSchemaId;
3230
3241
  }
3231
3242
  const mappedReference = JsonSchemaBuilder.resolveReferenceMappingTarget(context, moduleSpecifier, typeName);
3232
- const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, typeName);
3243
+ const declarationResult = Resolver.resolveTypeDeclarationAst(moduleSpecifier, typeName, context.activeSourceFile?.fileName);
3233
3244
  if (!declarationResult) {
3234
3245
  return mappedReference?.schemaId;
3235
3246
  }