@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.
- package/dist/es/utils/importTypeQuerySchemaResolver.js +36 -2
- package/dist/es/utils/importTypeQuerySchemaResolver.js.map +1 -1
- package/dist/es/utils/jsDoc.js +1 -1
- package/dist/es/utils/jsDoc.js.map +1 -1
- package/dist/es/utils/jsonSchemaBuilder.js +144 -133
- package/dist/es/utils/jsonSchemaBuilder.js.map +1 -1
- package/dist/es/utils/mappedTypeSchemaResolver.js +35 -1
- package/dist/es/utils/mappedTypeSchemaResolver.js.map +1 -1
- package/dist/es/utils/objectTransformer.js +1 -1
- package/dist/es/utils/objectTransformer.js.map +1 -1
- package/dist/es/utils/resolver.js +22 -9
- package/dist/es/utils/resolver.js.map +1 -1
- package/dist/es/utils/utilityTypeSchemaMapper.js +81 -40
- package/dist/es/utils/utilityTypeSchemaMapper.js.map +1 -1
- package/dist/types/utils/importTypeQuerySchemaResolver.d.ts +35 -0
- package/dist/types/utils/jsonSchemaBuilder.d.ts +6 -82
- package/dist/types/utils/mappedTypeSchemaResolver.d.ts +35 -0
- package/dist/types/utils/resolver.d.ts +7 -1
- package/dist/types/utils/utilityTypeSchemaMapper.d.ts +60 -13
- package/docs/changelog.md +51 -0
- package/docs/reference/classes/ImportTypeQuerySchemaResolver.md +22 -0
- package/docs/reference/classes/JsonSchemaBuilder.md +12 -304
- package/docs/reference/classes/MappedTypeSchemaResolver.md +64 -0
- package/docs/reference/classes/Resolver.md +12 -1
- package/docs/reference/classes/UtilityTypeSchemaMapper.md +64 -62
- package/package.json +2 -2
|
@@ -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) =>
|
|
38
|
-
Required: (context, typeNode) =>
|
|
39
|
-
Pick: (context, typeNode) =>
|
|
40
|
-
Omit: (context, typeNode) =>
|
|
41
|
-
Exclude: (context, typeNode) =>
|
|
42
|
-
Extract: (context, typeNode) =>
|
|
43
|
-
NonNullable: (context, typeNode) =>
|
|
44
|
-
Record: (context, typeNode) =>
|
|
45
|
-
JsonLdObjectWithId: (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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
65
|
+
JsonLdObjectWithNoId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
|
|
66
66
|
keysToRemove: ["id"]
|
|
67
67
|
}),
|
|
68
|
-
JsonLdObjectWithNoAtId: (context, typeNode) =>
|
|
68
|
+
JsonLdObjectWithNoAtId: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
|
|
69
69
|
keysToRemove: ["@id"]
|
|
70
70
|
}),
|
|
71
|
-
JsonLdObjectWithType: (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) =>
|
|
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) =>
|
|
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) =>
|
|
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) =>
|
|
91
|
+
JsonLdObjectWithNoType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
|
|
92
92
|
keysToRemove: ["type"]
|
|
93
93
|
}),
|
|
94
|
-
JsonLdObjectWithNoAtType: (context, typeNode) =>
|
|
94
|
+
JsonLdObjectWithNoAtType: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
|
|
95
95
|
keysToRemove: ["@type"]
|
|
96
96
|
}),
|
|
97
|
-
JsonLdObjectWithContext: (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) =>
|
|
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) =>
|
|
107
|
+
JsonLdObjectWithNoContext: (context, typeNode) => UtilityTypeSchemaMapper.mapJsonLdObjectUtilityType(context, typeNode, {
|
|
108
108
|
keysToRemove: ["@context"]
|
|
109
109
|
}),
|
|
110
|
-
SingleOccurrenceArray: (context, typeNode) =>
|
|
111
|
-
ObjectOrArray: (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
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
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
|
-
*
|
|
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
|
|
2176
|
-
* @
|
|
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
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
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"
|
|
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
|
}
|