@acrool/rtk-query-codegen-openapi 0.0.2-test.9 → 0.0.2
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/lib/index.d.mts +4 -8
- package/lib/index.d.ts +4 -8
- package/lib/index.js +113 -377
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +113 -377
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/generate.ts +127 -327
- package/src/generators/react-hooks.ts +2 -2
- package/src/index.ts +9 -152
- package/src/types.ts +1 -9
package/src/generate.ts
CHANGED
|
@@ -38,8 +38,8 @@ function defaultIsDataResponse(code: string, includeDefault: boolean) {
|
|
|
38
38
|
return !Number.isNaN(parsedCode) && parsedCode >= 200 && parsedCode < 300;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function getOperationName({ verb, path }: Pick<OperationDefinition, 'verb' | 'path' >) {
|
|
42
|
-
return _getOperationName(verb, path,
|
|
41
|
+
function getOperationName({ verb, path, operation }: Pick<OperationDefinition, 'verb' | 'path' | 'operation'>) {
|
|
42
|
+
return _getOperationName(verb, path, operation.operationId);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function getTags({ verb, pathItem }: Pick<OperationDefinition, 'verb' | 'pathItem'>): string[] {
|
|
@@ -128,176 +128,49 @@ export async function generateApi(
|
|
|
128
128
|
mergeReadWriteOnly,
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
function addSchemeTypeName(name: string) {
|
|
134
|
-
schemeTypeNames.add(name);
|
|
135
|
-
schemeTypeNames.add(camelCase(name));
|
|
136
|
-
schemeTypeNames.add(capitalize(camelCase(name)));
|
|
137
|
-
}
|
|
138
|
-
|
|
131
|
+
// 如果提供了 sharedTypesFile,則將 components 輸出到該文件
|
|
139
132
|
if (sharedTypesFile) {
|
|
140
|
-
const resultFile = ts.createSourceFile(
|
|
141
|
-
'sharedTypes.ts',
|
|
142
|
-
'',
|
|
143
|
-
ts.ScriptTarget.Latest,
|
|
144
|
-
/*setParentNodes*/ false,
|
|
145
|
-
ts.ScriptKind.TS
|
|
146
|
-
);
|
|
147
|
-
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
148
|
-
|
|
149
|
-
const allTypeDefinitions: ts.Statement[] = [];
|
|
150
|
-
const definedTypeNames = new Set<string>();
|
|
151
|
-
|
|
152
133
|
const components = v3Doc.components;
|
|
153
134
|
if (components) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
163
|
-
factory.createIdentifier(typeName),
|
|
164
|
-
undefined,
|
|
165
|
-
typeNode
|
|
166
|
-
);
|
|
167
|
-
});
|
|
168
|
-
return factory.createModuleDeclaration(
|
|
169
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
170
|
-
factory.createIdentifier('Scheme'),
|
|
171
|
-
factory.createModuleBlock(typeEntries),
|
|
172
|
-
ts.NodeFlags.Namespace
|
|
173
|
-
);
|
|
174
|
-
});
|
|
175
|
-
allTypeDefinitions.push(...componentDefinitions);
|
|
176
|
-
}
|
|
135
|
+
const resultFile = ts.createSourceFile(
|
|
136
|
+
'sharedTypes.ts',
|
|
137
|
+
'',
|
|
138
|
+
ts.ScriptTarget.Latest,
|
|
139
|
+
/*setParentNodes*/ false,
|
|
140
|
+
ts.ScriptKind.TS
|
|
141
|
+
);
|
|
142
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
177
143
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (ts.isEnumDeclaration(enumDecl)) {
|
|
183
|
-
return factory.createEnumDeclaration(
|
|
184
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
185
|
-
enumDecl.name,
|
|
186
|
-
enumDecl.members
|
|
187
|
-
);
|
|
188
|
-
} else if (ts.isTypeAliasDeclaration(enumDecl)) {
|
|
189
|
-
return factory.createTypeAliasDeclaration(
|
|
190
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
191
|
-
enumDecl.name,
|
|
192
|
-
enumDecl.typeParameters,
|
|
193
|
-
enumDecl.type
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
return enumDecl;
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
const unionTypeEnums = apiGen.aliases
|
|
200
|
-
.filter(alias => {
|
|
201
|
-
if (ts.isTypeAliasDeclaration(alias) && alias.type) {
|
|
202
|
-
return ts.isUnionTypeNode(alias.type);
|
|
203
|
-
}
|
|
204
|
-
return false;
|
|
205
|
-
})
|
|
206
|
-
.map(alias => {
|
|
207
|
-
if (ts.isTypeAliasDeclaration(alias)) {
|
|
144
|
+
// 將 components 轉換為 TypeScript 類型定義
|
|
145
|
+
const typeDefinitions = Object.entries(components).flatMap(([_, componentDefs]) => {
|
|
146
|
+
return Object.entries(componentDefs as Record<string, unknown>).map(([name, def]) => {
|
|
147
|
+
const typeNode = apiGen.getTypeFromSchema(def as OpenAPIV3.SchemaObject);
|
|
208
148
|
return factory.createTypeAliasDeclaration(
|
|
209
149
|
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
150
|
+
factory.createIdentifier(name),
|
|
151
|
+
undefined,
|
|
152
|
+
typeNode
|
|
213
153
|
);
|
|
214
|
-
}
|
|
215
|
-
return alias;
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
const allEnumEntries = [...enumEntries, ...unionTypeEnums];
|
|
219
|
-
|
|
220
|
-
if (allEnumEntries.length > 0) {
|
|
221
|
-
allTypeDefinitions.push(
|
|
222
|
-
factory.createModuleDeclaration(
|
|
223
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
224
|
-
factory.createIdentifier('Enum'),
|
|
225
|
-
factory.createModuleBlock(allEnumEntries),
|
|
226
|
-
ts.NodeFlags.Namespace
|
|
227
|
-
)
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (apiGen.aliases.length > 0) {
|
|
232
|
-
const aliasEntries = apiGen.aliases
|
|
233
|
-
.filter(alias => {
|
|
234
|
-
if (ts.isTypeAliasDeclaration(alias)) {
|
|
235
|
-
const isDefinedInComponents = definedTypeNames.has(alias.name.text);
|
|
236
|
-
const isUnionTypeEnum = ts.isUnionTypeNode(alias.type);
|
|
237
|
-
return !isDefinedInComponents && !isUnionTypeEnum;
|
|
238
|
-
}
|
|
239
|
-
return false;
|
|
240
|
-
})
|
|
241
|
-
.map(alias => {
|
|
242
|
-
if (ts.isTypeAliasDeclaration(alias)) {
|
|
243
|
-
return factory.createTypeAliasDeclaration(
|
|
244
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
245
|
-
alias.name,
|
|
246
|
-
alias.typeParameters,
|
|
247
|
-
alias.type
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
return alias;
|
|
251
154
|
});
|
|
155
|
+
});
|
|
252
156
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
157
|
+
const output = printer.printNode(
|
|
158
|
+
ts.EmitHint.Unspecified,
|
|
159
|
+
factory.createSourceFile(
|
|
160
|
+
typeDefinitions,
|
|
161
|
+
factory.createToken(ts.SyntaxKind.EndOfFileToken),
|
|
162
|
+
ts.NodeFlags.None
|
|
163
|
+
),
|
|
164
|
+
resultFile
|
|
165
|
+
);
|
|
259
166
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
allTypeDefinitions[existingSchemeIndex] = factory.createModuleDeclaration(
|
|
264
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
265
|
-
factory.createIdentifier('Scheme'),
|
|
266
|
-
factory.createModuleBlock(mergedMembers),
|
|
267
|
-
ts.NodeFlags.Namespace
|
|
268
|
-
);
|
|
269
|
-
} else {
|
|
270
|
-
allTypeDefinitions.push(
|
|
271
|
-
factory.createModuleDeclaration(
|
|
272
|
-
[factory.createModifier(ts.SyntaxKind.ExportKeyword)],
|
|
273
|
-
factory.createIdentifier('Scheme'),
|
|
274
|
-
factory.createModuleBlock(aliasEntries),
|
|
275
|
-
ts.NodeFlags.Namespace
|
|
276
|
-
)
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
167
|
+
// 寫入文件
|
|
168
|
+
const fs = await import('node:fs/promises');
|
|
169
|
+
await fs.writeFile(sharedTypesFile, output, 'utf-8');
|
|
280
170
|
}
|
|
281
|
-
|
|
282
|
-
const fs = await import('node:fs/promises');
|
|
283
|
-
const path = await import('node:path');
|
|
284
|
-
|
|
285
|
-
const sharedTypesDir = path.dirname(sharedTypesFile);
|
|
286
|
-
await fs.mkdir(sharedTypesDir, { recursive: true });
|
|
287
|
-
|
|
288
|
-
const output = printer.printNode(
|
|
289
|
-
ts.EmitHint.Unspecified,
|
|
290
|
-
factory.createSourceFile(
|
|
291
|
-
allTypeDefinitions,
|
|
292
|
-
factory.createToken(ts.SyntaxKind.EndOfFileToken),
|
|
293
|
-
ts.NodeFlags.None
|
|
294
|
-
),
|
|
295
|
-
resultFile
|
|
296
|
-
);
|
|
297
|
-
|
|
298
|
-
await fs.writeFile(sharedTypesFile, output, 'utf-8');
|
|
299
171
|
}
|
|
300
172
|
|
|
173
|
+
// temporary workaround for https://github.com/oazapfts/oazapfts/issues/491
|
|
301
174
|
if (apiGen.spec.components?.schemas) {
|
|
302
175
|
apiGen.preprocessComponents(apiGen.spec.components.schemas);
|
|
303
176
|
}
|
|
@@ -330,18 +203,17 @@ export async function generateApi(
|
|
|
330
203
|
apiFile = apiFile.replace(/\\/g, '/');
|
|
331
204
|
if (!apiFile.startsWith('.')) apiFile = `./${apiFile}`;
|
|
332
205
|
}
|
|
206
|
+
// 處理 sharedTypesFile 的路徑
|
|
207
|
+
if (sharedTypesFile && sharedTypesFile.startsWith('.')) {
|
|
208
|
+
sharedTypesFile = path.relative(path.dirname(outputFile), sharedTypesFile);
|
|
209
|
+
sharedTypesFile = sharedTypesFile.replace(/\\/g, '/');
|
|
210
|
+
if (!sharedTypesFile.startsWith('.')) sharedTypesFile = `./${sharedTypesFile}`;
|
|
211
|
+
}
|
|
333
212
|
}
|
|
334
213
|
apiFile = apiFile.replace(/\.[jt]sx?$/, '');
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
let rel = path.relative(path.dirname(outputFile), sharedTypesFile)
|
|
339
|
-
.replace(/\\/g, '/')
|
|
340
|
-
.replace(/\.[jt]sx?$/, '');
|
|
341
|
-
if (!rel.startsWith('.')) rel = './' + rel;
|
|
342
|
-
return rel;
|
|
343
|
-
})()
|
|
344
|
-
: './shared-types';
|
|
214
|
+
if (sharedTypesFile) {
|
|
215
|
+
sharedTypesFile = sharedTypesFile.replace(/\.[jt]sx?$/, '');
|
|
216
|
+
}
|
|
345
217
|
|
|
346
218
|
return printer.printNode(
|
|
347
219
|
ts.EmitHint.Unspecified,
|
|
@@ -350,10 +222,16 @@ export async function generateApi(
|
|
|
350
222
|
generateImportNode(apiFile, { [apiImport]: 'api' }),
|
|
351
223
|
generateImportNode('@acrool/react-fetcher', { IRestFulEndpointsQueryReturn: 'IRestFulEndpointsQueryReturn' }),
|
|
352
224
|
...(sharedTypesFile ? [
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
225
|
+
factory.createImportDeclaration(
|
|
226
|
+
undefined,
|
|
227
|
+
factory.createImportClause(
|
|
228
|
+
false,
|
|
229
|
+
undefined,
|
|
230
|
+
factory.createNamespaceImport(factory.createIdentifier('SharedTypes'))
|
|
231
|
+
),
|
|
232
|
+
factory.createStringLiteral(sharedTypesFile),
|
|
233
|
+
undefined
|
|
234
|
+
)
|
|
357
235
|
] : []),
|
|
358
236
|
...(tag ? [generateTagTypes({ addTagTypes: extractAllTagTypes({ operationDefinitions }) })] : []),
|
|
359
237
|
generateCreateApiCall({
|
|
@@ -363,7 +241,6 @@ export async function generateApi(
|
|
|
363
241
|
generateEndpoint({
|
|
364
242
|
operationDefinition,
|
|
365
243
|
overrides: getOverrides(operationDefinition, endpointOverrides),
|
|
366
|
-
sharedTypesFile: !!sharedTypesFile,
|
|
367
244
|
})
|
|
368
245
|
),
|
|
369
246
|
true
|
|
@@ -408,11 +285,9 @@ export async function generateApi(
|
|
|
408
285
|
function generateEndpoint({
|
|
409
286
|
operationDefinition,
|
|
410
287
|
overrides,
|
|
411
|
-
sharedTypesFile,
|
|
412
288
|
}: {
|
|
413
289
|
operationDefinition: OperationDefinition;
|
|
414
290
|
overrides?: EndpointOverrides;
|
|
415
|
-
sharedTypesFile: boolean;
|
|
416
291
|
}) {
|
|
417
292
|
const {
|
|
418
293
|
verb,
|
|
@@ -421,37 +296,73 @@ export async function generateApi(
|
|
|
421
296
|
operation,
|
|
422
297
|
operation: { responses, requestBody },
|
|
423
298
|
} = operationDefinition;
|
|
424
|
-
const operationName = getOperationName({ verb, path });
|
|
299
|
+
const operationName = getOperationName({ verb, path, operation });
|
|
425
300
|
const tags = tag ? getTags({ verb, pathItem }) : [];
|
|
426
301
|
const isQuery = testIsQuery(verb, overrides);
|
|
427
302
|
|
|
428
303
|
const returnsJson = apiGen.getResponseType(responses) === 'json';
|
|
429
304
|
let ResponseType: ts.TypeNode = factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
305
|
+
|
|
306
|
+
function replaceReferences(schema: any): ts.TypeNode {
|
|
307
|
+
if (!schema) return factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);
|
|
308
|
+
|
|
309
|
+
const refName = getReferenceName(schema);
|
|
310
|
+
if (refName && sharedTypesFile) {
|
|
311
|
+
return factory.createTypeReferenceNode(
|
|
312
|
+
factory.createQualifiedName(
|
|
313
|
+
factory.createIdentifier('SharedTypes'),
|
|
314
|
+
factory.createIdentifier(refName)
|
|
315
|
+
),
|
|
316
|
+
undefined
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (schema.type === 'object' && schema.properties) {
|
|
321
|
+
const members = Object.entries(schema.properties).map(([key, value]: [string, any]) => {
|
|
322
|
+
return factory.createPropertySignature(
|
|
323
|
+
undefined,
|
|
324
|
+
factory.createIdentifier(key),
|
|
325
|
+
schema.required?.includes(key) ? undefined : factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
326
|
+
replaceReferences(value)
|
|
327
|
+
);
|
|
328
|
+
});
|
|
329
|
+
return factory.createTypeLiteralNode(members);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (schema.type === 'array' && schema.items) {
|
|
333
|
+
return factory.createArrayTypeNode(replaceReferences(schema.items));
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return apiGen.getTypeFromSchema(schema);
|
|
337
|
+
}
|
|
338
|
+
|
|
430
339
|
if (returnsJson) {
|
|
431
340
|
const returnTypes = Object.entries(responses || {})
|
|
432
341
|
.map(
|
|
433
|
-
([code, response]) =>
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
342
|
+
([code, response]) => {
|
|
343
|
+
const resolvedResponse = apiGen.resolve(response);
|
|
344
|
+
if (!resolvedResponse.content?.['application/json']?.schema) {
|
|
345
|
+
return [code, resolvedResponse, factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)] as const;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const schema = resolvedResponse.content['application/json'].schema;
|
|
349
|
+
const type = replaceReferences(schema);
|
|
350
|
+
|
|
351
|
+
return [code, resolvedResponse, type] as const;
|
|
352
|
+
}
|
|
442
353
|
)
|
|
443
354
|
.filter(([status, response]) =>
|
|
444
355
|
isDataResponse(status, includeDefault, apiGen.resolve(response), responses || {})
|
|
445
356
|
)
|
|
446
357
|
.filter(([_1, _2, type]) => type !== keywordType.void)
|
|
447
|
-
.map(([code, response, type]) =>
|
|
448
|
-
|
|
449
|
-
type,
|
|
358
|
+
.map(([code, response, type]) =>
|
|
359
|
+
ts.addSyntheticLeadingComment(
|
|
360
|
+
{ ...type },
|
|
450
361
|
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
451
362
|
`* status ${code} ${response.description} `,
|
|
452
363
|
false
|
|
453
|
-
)
|
|
454
|
-
|
|
364
|
+
)
|
|
365
|
+
);
|
|
455
366
|
if (returnTypes.length > 0) {
|
|
456
367
|
ResponseType = factory.createUnionTypeNode(returnTypes);
|
|
457
368
|
}
|
|
@@ -481,36 +392,28 @@ export async function generateApi(
|
|
|
481
392
|
const queryArg: QueryArgDefinitions = {};
|
|
482
393
|
function generateName(name: string, potentialPrefix: string) {
|
|
483
394
|
const isPureSnakeCase = /^[a-zA-Z][a-zA-Z0-9_]*$/.test(name);
|
|
395
|
+
// prefix with `query`, `path` or `body` if there are multiple paramters with the same name
|
|
484
396
|
const hasNamingConflict = allNames.filter((n) => n === name).length > 1;
|
|
485
397
|
if (hasNamingConflict) {
|
|
486
398
|
name = `${potentialPrefix}_${name}`;
|
|
487
399
|
}
|
|
400
|
+
// convert to camelCase if the name is pure snake_case and there are no naming conflicts
|
|
488
401
|
const camelCaseName = camelCase(name);
|
|
489
402
|
if (isPureSnakeCase && !allNames.includes(camelCaseName)) {
|
|
490
403
|
name = camelCaseName;
|
|
491
404
|
}
|
|
405
|
+
// if there are still any naming conflicts, prepend with underscore
|
|
492
406
|
while (name in queryArg) {
|
|
493
407
|
name = `_${name}`;
|
|
494
408
|
}
|
|
495
409
|
return name;
|
|
496
410
|
}
|
|
497
411
|
|
|
498
|
-
for (const param of parameters) {
|
|
499
|
-
const name = generateName(param.name, param.in);
|
|
500
|
-
queryArg[name] = {
|
|
501
|
-
origin: 'param',
|
|
502
|
-
name,
|
|
503
|
-
originalName: param.name,
|
|
504
|
-
type: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(isReference(param) ? param : param.schema, undefined, 'writeOnly')),
|
|
505
|
-
required: param.required,
|
|
506
|
-
param,
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
|
|
510
412
|
if (requestBody) {
|
|
511
413
|
const body = apiGen.resolve(requestBody);
|
|
512
414
|
const schema = apiGen.getSchemaFromContent(body.content);
|
|
513
|
-
const type =
|
|
415
|
+
const type = replaceReferences(schema);
|
|
416
|
+
|
|
514
417
|
const schemaName = camelCase(
|
|
515
418
|
(type as any).name ||
|
|
516
419
|
getReferenceName(schema) ||
|
|
@@ -523,12 +426,27 @@ export async function generateApi(
|
|
|
523
426
|
origin: 'body',
|
|
524
427
|
name,
|
|
525
428
|
originalName: schemaName,
|
|
526
|
-
type
|
|
429
|
+
type,
|
|
527
430
|
required: true,
|
|
528
431
|
body,
|
|
529
432
|
};
|
|
530
433
|
}
|
|
531
434
|
|
|
435
|
+
for (const param of parameters) {
|
|
436
|
+
const name = generateName(param.name, param.in);
|
|
437
|
+
const paramSchema = isReference(param) ? param : param.schema;
|
|
438
|
+
const type = replaceReferences(paramSchema);
|
|
439
|
+
|
|
440
|
+
queryArg[name] = {
|
|
441
|
+
origin: 'param',
|
|
442
|
+
name,
|
|
443
|
+
originalName: param.name,
|
|
444
|
+
type,
|
|
445
|
+
required: param.required,
|
|
446
|
+
param,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
532
450
|
const propertyName = (name: string | ts.PropertyName): ts.PropertyName => {
|
|
533
451
|
if (typeof name === 'string') {
|
|
534
452
|
return isValidIdentifier(name) ? factory.createIdentifier(name) : factory.createStringLiteral(name);
|
|
@@ -699,132 +617,14 @@ export async function generateApi(
|
|
|
699
617
|
);
|
|
700
618
|
}
|
|
701
619
|
|
|
620
|
+
// eslint-disable-next-line no-empty-pattern
|
|
702
621
|
function generateQueryEndpointProps({}: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
|
|
703
|
-
return {};
|
|
622
|
+
return {}; /* TODO needs implementation - skip for now */
|
|
704
623
|
}
|
|
705
624
|
|
|
625
|
+
// eslint-disable-next-line no-empty-pattern
|
|
706
626
|
function generateMutationEndpointProps({}: { operationDefinition: OperationDefinition }): ObjectPropertyDefinitions {
|
|
707
|
-
return {};
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
function wrapWithSchemeIfComponent(typeNode: ts.TypeNode): ts.TypeNode {
|
|
711
|
-
if (ts.isTypeReferenceNode(typeNode) && ts.isIdentifier(typeNode.typeName)) {
|
|
712
|
-
const typeName = typeNode.typeName.text;
|
|
713
|
-
|
|
714
|
-
// 檢查是否為 enum 類型(包括在 enumAliases 和 aliases 中的)
|
|
715
|
-
const isEnumType = useEnumType && (
|
|
716
|
-
apiGen.enumAliases.some(enumDecl => {
|
|
717
|
-
if (ts.isEnumDeclaration(enumDecl) || ts.isTypeAliasDeclaration(enumDecl)) {
|
|
718
|
-
return enumDecl.name.text === typeName;
|
|
719
|
-
}
|
|
720
|
-
return false;
|
|
721
|
-
}) ||
|
|
722
|
-
apiGen.aliases.some(alias => {
|
|
723
|
-
if (ts.isTypeAliasDeclaration(alias) && alias.type) {
|
|
724
|
-
// 檢查是否為 union type 的 enum
|
|
725
|
-
if (ts.isUnionTypeNode(alias.type)) {
|
|
726
|
-
return alias.name.text === typeName;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
return false;
|
|
730
|
-
})
|
|
731
|
-
);
|
|
732
|
-
|
|
733
|
-
if (isEnumType) {
|
|
734
|
-
return factory.createTypeReferenceNode(
|
|
735
|
-
factory.createQualifiedName(
|
|
736
|
-
factory.createIdentifier('Enum'),
|
|
737
|
-
typeNode.typeName
|
|
738
|
-
),
|
|
739
|
-
typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
|
|
740
|
-
);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
if (schemeTypeNames.has(typeName)) {
|
|
744
|
-
return factory.createTypeReferenceNode(
|
|
745
|
-
factory.createQualifiedName(
|
|
746
|
-
factory.createIdentifier('Scheme'),
|
|
747
|
-
typeNode.typeName
|
|
748
|
-
),
|
|
749
|
-
typeNode.typeArguments?.map(wrapWithSchemeIfComponent)
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
if (typeNode.typeArguments) {
|
|
753
|
-
return factory.createTypeReferenceNode(
|
|
754
|
-
typeNode.typeName,
|
|
755
|
-
typeNode.typeArguments.map(wrapWithSchemeIfComponent)
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
if (ts.isArrayTypeNode(typeNode)) {
|
|
760
|
-
return factory.createArrayTypeNode(wrapWithSchemeIfComponent(typeNode.elementType));
|
|
761
|
-
}
|
|
762
|
-
if (ts.isUnionTypeNode(typeNode)) {
|
|
763
|
-
// 檢查是否為 enum 的 union type
|
|
764
|
-
const unionTypes = typeNode.types;
|
|
765
|
-
if (unionTypes.length > 0 && unionTypes.every(type =>
|
|
766
|
-
ts.isLiteralTypeNode(type) &&
|
|
767
|
-
(ts.isStringLiteral(type.literal) || ts.isNumericLiteral(type.literal))
|
|
768
|
-
)) {
|
|
769
|
-
// 這是一個 enum 的 union type,我們需要找到對應的 enum 類型
|
|
770
|
-
const enumValues = unionTypes.map(type => {
|
|
771
|
-
if (ts.isLiteralTypeNode(type)) {
|
|
772
|
-
if (ts.isStringLiteral(type.literal)) {
|
|
773
|
-
return type.literal.text;
|
|
774
|
-
} else if (ts.isNumericLiteral(type.literal)) {
|
|
775
|
-
return type.literal.text;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return null;
|
|
779
|
-
}).filter(Boolean);
|
|
780
|
-
|
|
781
|
-
// 查找對應的 enum 類型
|
|
782
|
-
const matchingEnum = apiGen.aliases.find(alias => {
|
|
783
|
-
if (ts.isTypeAliasDeclaration(alias) && ts.isUnionTypeNode(alias.type)) {
|
|
784
|
-
const aliasValues = alias.type.types.map(type => {
|
|
785
|
-
if (ts.isLiteralTypeNode(type)) {
|
|
786
|
-
if (ts.isStringLiteral(type.literal)) {
|
|
787
|
-
return type.literal.text;
|
|
788
|
-
} else if (ts.isNumericLiteral(type.literal)) {
|
|
789
|
-
return type.literal.text;
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
return null;
|
|
793
|
-
}).filter(Boolean);
|
|
794
|
-
|
|
795
|
-
return aliasValues.length === enumValues.length &&
|
|
796
|
-
aliasValues.every(val => enumValues.includes(val));
|
|
797
|
-
}
|
|
798
|
-
return false;
|
|
799
|
-
});
|
|
800
|
-
|
|
801
|
-
// 對於所有的 enum 類型,直接使用字串型別,不轉換為 Enum
|
|
802
|
-
// 這樣可以避免自動命名造成的變更問題
|
|
803
|
-
if (matchingEnum && ts.isTypeAliasDeclaration(matchingEnum)) {
|
|
804
|
-
// 直接返回原始的 union type,不轉換為 Enum
|
|
805
|
-
return typeNode;
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
return factory.createUnionTypeNode(typeNode.types.map(wrapWithSchemeIfComponent));
|
|
810
|
-
}
|
|
811
|
-
if (ts.isTypeLiteralNode(typeNode)) {
|
|
812
|
-
return factory.createTypeLiteralNode(
|
|
813
|
-
typeNode.members.map(member => {
|
|
814
|
-
if (ts.isPropertySignature(member) && member.type) {
|
|
815
|
-
return factory.updatePropertySignature(
|
|
816
|
-
member,
|
|
817
|
-
member.modifiers,
|
|
818
|
-
member.name,
|
|
819
|
-
member.questionToken,
|
|
820
|
-
wrapWithSchemeIfComponent(member.type)
|
|
821
|
-
);
|
|
822
|
-
}
|
|
823
|
-
return member;
|
|
824
|
-
})
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
return typeNode;
|
|
627
|
+
return {}; /* TODO needs implementation - skip for now */
|
|
828
628
|
}
|
|
829
629
|
}
|
|
830
630
|
|
|
@@ -20,7 +20,7 @@ type CreateBindingParams = {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
const createBinding = ({
|
|
23
|
-
operationDefinition: { verb, path },
|
|
23
|
+
operationDefinition: { verb, path, operation },
|
|
24
24
|
overrides,
|
|
25
25
|
isLazy = false,
|
|
26
26
|
}: CreateBindingParams) =>
|
|
@@ -28,7 +28,7 @@ const createBinding = ({
|
|
|
28
28
|
undefined,
|
|
29
29
|
undefined,
|
|
30
30
|
factory.createIdentifier(
|
|
31
|
-
`use${isLazy ? 'Lazy' : ''}${capitalize(getOperationName(verb, path,
|
|
31
|
+
`use${isLazy ? 'Lazy' : ''}${capitalize(getOperationName(verb, path, operation.operationId))}${
|
|
32
32
|
isQuery(verb, overrides) ? 'Query' : 'Mutation'
|
|
33
33
|
}`
|
|
34
34
|
),
|