@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/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, undefined);
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
- const schemeTypeNames = new Set<string>();
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 componentDefinitions = Object.entries(components).map(([componentType, componentDefs]) => {
155
- const typeEntries = Object.entries(componentDefs as Record<string, unknown>)
156
- .map(([name, def]) => {
157
- addSchemeTypeName(name);
158
- const typeName = capitalize(camelCase(name));
159
- definedTypeNames.add(typeName);
160
- const typeNode = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(def as OpenAPIV3.SchemaObject));
161
- return factory.createTypeAliasDeclaration(
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
- const enumEntries = [
179
- ...apiGen.enumAliases.filter(e => ts.isEnumDeclaration(e)),
180
- ...apiGen.enumAliases.filter(e => ts.isTypeAliasDeclaration(e)),
181
- ].map(enumDecl => {
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
- alias.name,
211
- alias.typeParameters,
212
- alias.type
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
- if (aliasEntries.length > 0) {
254
- const existingSchemeIndex = allTypeDefinitions.findIndex(def =>
255
- ts.isModuleDeclaration(def) &&
256
- ts.isIdentifier(def.name) &&
257
- def.name.text === 'Scheme'
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
- if (existingSchemeIndex >= 0) {
261
- const existingScheme = allTypeDefinitions[existingSchemeIndex] as ts.ModuleDeclaration;
262
- const mergedMembers = [...(existingScheme.body as ts.ModuleBlock).statements, ...aliasEntries];
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
- const sharedTypesImportPath = sharedTypesFile && outputFile
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
- generateImportNode(sharedTypesImportPath, {
354
- Scheme: 'Scheme',
355
- ...(useEnumType ? { Enum: 'Enum' } : {})
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
- code,
436
- apiGen.resolve(response),
437
- wrapWithSchemeIfComponent(
438
- apiGen.getTypeFromResponse(response, 'readOnly') ||
439
- factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
440
- ),
441
- ] as const
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
- return ts.addSyntheticLeadingComment(
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 = wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema));
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: wrapWithSchemeIfComponent(apiGen.getTypeFromSchema(schema, undefined, 'writeOnly')),
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, undefined))}${
31
+ `use${isLazy ? 'Lazy' : ''}${capitalize(getOperationName(verb, path, operation.operationId))}${
32
32
  isQuery(verb, overrides) ? 'Query' : 'Mutation'
33
33
  }`
34
34
  ),