@openapi-qraft/tanstack-query-react-plugin 2.4.1 → 2.5.0-beta.1

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.
Files changed (120) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/generateCode.d.ts +2 -2
  3. package/dist/generateCode.d.ts.map +1 -1
  4. package/dist/generateCode.js.map +1 -1
  5. package/dist/plugin.d.ts.map +1 -1
  6. package/dist/plugin.js +6 -3
  7. package/dist/plugin.js.map +1 -1
  8. package/dist/ts-factory/getIndexFactory.d.ts +2 -2
  9. package/dist/ts-factory/getIndexFactory.d.ts.map +1 -1
  10. package/dist/ts-factory/getIndexFactory.js.map +1 -1
  11. package/dist/ts-factory/getServiceFactory.d.ts +3 -2
  12. package/dist/ts-factory/getServiceFactory.d.ts.map +1 -1
  13. package/dist/ts-factory/getServiceFactory.js +127 -52
  14. package/dist/ts-factory/getServiceFactory.js.map +1 -1
  15. package/dist/ts-factory/service-operation.generated/ServiceOperationCancelQueries.js +3 -3
  16. package/dist/ts-factory/service-operation.generated/ServiceOperationCancelQueries.js.map +1 -1
  17. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.js +12 -12
  18. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.js.map +1 -1
  19. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchQuery.js +10 -10
  20. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchQuery.js.map +1 -1
  21. package/dist/ts-factory/service-operation.generated/ServiceOperationGetInfiniteQueryData.js +6 -6
  22. package/dist/ts-factory/service-operation.generated/ServiceOperationGetInfiniteQueryData.js.map +1 -1
  23. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueriesData.js +6 -6
  24. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueriesData.js.map +1 -1
  25. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueryData.js +5 -5
  26. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueryData.js.map +1 -1
  27. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueryState.js +11 -11
  28. package/dist/ts-factory/service-operation.generated/ServiceOperationGetQueryState.js.map +1 -1
  29. package/dist/ts-factory/service-operation.generated/ServiceOperationInvalidateQueries.js +2 -2
  30. package/dist/ts-factory/service-operation.generated/ServiceOperationInvalidateQueries.js.map +1 -1
  31. package/dist/ts-factory/service-operation.generated/ServiceOperationIsFetchingQueries.js +3 -3
  32. package/dist/ts-factory/service-operation.generated/ServiceOperationIsFetchingQueries.js.map +1 -1
  33. package/dist/ts-factory/service-operation.generated/ServiceOperationIsMutatingQueries.js +3 -3
  34. package/dist/ts-factory/service-operation.generated/ServiceOperationIsMutatingQueries.js.map +1 -1
  35. package/dist/ts-factory/service-operation.generated/ServiceOperationMutationFn.js +3 -3
  36. package/dist/ts-factory/service-operation.generated/ServiceOperationMutationFn.js.map +1 -1
  37. package/dist/ts-factory/service-operation.generated/ServiceOperationQueryFn.js +6 -6
  38. package/dist/ts-factory/service-operation.generated/ServiceOperationQueryFn.js.map +1 -1
  39. package/dist/ts-factory/service-operation.generated/ServiceOperationRefetchQueries.js +3 -3
  40. package/dist/ts-factory/service-operation.generated/ServiceOperationRefetchQueries.js.map +1 -1
  41. package/dist/ts-factory/service-operation.generated/ServiceOperationRemoveQueries.js +3 -3
  42. package/dist/ts-factory/service-operation.generated/ServiceOperationRemoveQueries.js.map +1 -1
  43. package/dist/ts-factory/service-operation.generated/ServiceOperationResetQueries.js +3 -3
  44. package/dist/ts-factory/service-operation.generated/ServiceOperationResetQueries.js.map +1 -1
  45. package/dist/ts-factory/service-operation.generated/ServiceOperationSetInfiniteQueryData.js +8 -8
  46. package/dist/ts-factory/service-operation.generated/ServiceOperationSetInfiniteQueryData.js.map +1 -1
  47. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueriesData.js +3 -3
  48. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueriesData.js.map +1 -1
  49. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueryData.js +5 -5
  50. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueryData.js.map +1 -1
  51. package/dist/ts-factory/service-operation.generated/ServiceOperationUseInfiniteQuery.js +19 -19
  52. package/dist/ts-factory/service-operation.generated/ServiceOperationUseInfiniteQuery.js.map +1 -1
  53. package/dist/ts-factory/service-operation.generated/ServiceOperationUseIsFetchingQueries.js +3 -3
  54. package/dist/ts-factory/service-operation.generated/ServiceOperationUseIsFetchingQueries.js.map +1 -1
  55. package/dist/ts-factory/service-operation.generated/ServiceOperationUseIsMutating.js +3 -3
  56. package/dist/ts-factory/service-operation.generated/ServiceOperationUseIsMutating.js.map +1 -1
  57. package/dist/ts-factory/service-operation.generated/ServiceOperationUseMutation.js +7 -7
  58. package/dist/ts-factory/service-operation.generated/ServiceOperationUseMutation.js.map +1 -1
  59. package/dist/ts-factory/service-operation.generated/ServiceOperationUseMutationState.js +5 -5
  60. package/dist/ts-factory/service-operation.generated/ServiceOperationUseMutationState.js.map +1 -1
  61. package/dist/ts-factory/service-operation.generated/ServiceOperationUseQueries.js +2 -2
  62. package/dist/ts-factory/service-operation.generated/ServiceOperationUseQueries.js.map +1 -1
  63. package/dist/ts-factory/service-operation.generated/ServiceOperationUseQuery.js +15 -15
  64. package/dist/ts-factory/service-operation.generated/ServiceOperationUseQuery.js.map +1 -1
  65. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseInfiniteQuery.js +9 -9
  66. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseInfiniteQuery.js.map +1 -1
  67. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseQueries.js +2 -2
  68. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseQueries.js.map +1 -1
  69. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseQuery.js +6 -6
  70. package/dist/ts-factory/service-operation.generated/ServiceOperationUseSuspenseQuery.js.map +1 -1
  71. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.d.ts +2 -1
  72. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.d.ts.map +1 -1
  73. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.js +8 -8
  74. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.js.map +1 -1
  75. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.d.ts +2 -1
  76. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.d.ts.map +1 -1
  77. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.js +10 -5
  78. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.js.map +1 -1
  79. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.d.ts +2 -1
  80. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.d.ts.map +1 -1
  81. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.js +9 -3
  82. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.js.map +1 -1
  83. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.d.ts +3 -2
  84. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.d.ts.map +1 -1
  85. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.js +15 -6
  86. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.js.map +1 -1
  87. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.d.ts +2 -1
  88. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.d.ts.map +1 -1
  89. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.js +11 -5
  90. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.js.map +1 -1
  91. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.d.ts +2 -1
  92. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.d.ts.map +1 -1
  93. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.js +10 -5
  94. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.js.map +1 -1
  95. package/dist/ts-factory/tsdoc/createUseSuspenseQueriesOperationTSDocExample.d.ts +2 -1
  96. package/dist/ts-factory/tsdoc/createUseSuspenseQueriesOperationTSDocExample.d.ts.map +1 -1
  97. package/dist/ts-factory/tsdoc/createUseSuspenseQueriesOperationTSDocExample.js +3 -3
  98. package/dist/ts-factory/tsdoc/createUseSuspenseQueriesOperationTSDocExample.js.map +1 -1
  99. package/dist/ts-factory/tsdoc/createUseSuspenseQueryOperationTSDocExample.d.ts +2 -1
  100. package/dist/ts-factory/tsdoc/createUseSuspenseQueryOperationTSDocExample.d.ts.map +1 -1
  101. package/dist/ts-factory/tsdoc/createUseSuspenseQueryOperationTSDocExample.js +11 -5
  102. package/dist/ts-factory/tsdoc/createUseSuspenseQueryOperationTSDocExample.js.map +1 -1
  103. package/dist/ts-factory/tsdoc/lib/createOperationMethodBodyParametersExampleNode.d.ts +3 -0
  104. package/dist/ts-factory/tsdoc/lib/createOperationMethodBodyParametersExampleNode.d.ts.map +1 -0
  105. package/dist/ts-factory/tsdoc/lib/createOperationMethodBodyParametersExampleNode.js +5 -0
  106. package/dist/ts-factory/tsdoc/lib/createOperationMethodBodyParametersExampleNode.js.map +1 -0
  107. package/package.json +3 -3
  108. package/src/generateCode.ts +5 -5
  109. package/src/plugin.ts +11 -3
  110. package/src/ts-factory/getIndexFactory.ts +2 -2
  111. package/src/ts-factory/getServiceFactory.ts +262 -90
  112. package/src/ts-factory/tsdoc/createOperationMethodTSDocExample.ts +17 -8
  113. package/src/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.ts +16 -7
  114. package/src/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.ts +19 -3
  115. package/src/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.ts +40 -10
  116. package/src/ts-factory/tsdoc/createUseQueryOperationTSDocExample.ts +17 -5
  117. package/src/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.ts +16 -7
  118. package/src/ts-factory/tsdoc/createUseSuspenseQueriesOperationTSDocExample.ts +13 -3
  119. package/src/ts-factory/tsdoc/createUseSuspenseQueryOperationTSDocExample.ts +17 -5
  120. package/src/ts-factory/tsdoc/lib/createOperationMethodBodyParametersExampleNode.ts +13 -0
@@ -1,3 +1,4 @@
1
+ import { isReadOnlyOperation } from '@openapi-qraft/plugin/lib/isReadOnlyOperation';
1
2
  import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
2
3
  import camelCase from 'camelcase';
3
4
  import ts from 'typescript';
@@ -35,8 +36,9 @@ import { createOperationMethodTSDocExample } from './tsdoc/createOperationMethod
35
36
 
36
37
  const factory = ts.factory;
37
38
 
38
- export type ServiceImportsFactoryOptions = {
39
+ export type ServiceFactoryOptions = {
39
40
  openapiTypesImportPath: string;
41
+ queryableWriteOperations: boolean;
40
42
  };
41
43
 
42
44
  type Service = { typeName: string; variableName: string };
@@ -44,18 +46,18 @@ type Service = { typeName: string; variableName: string };
44
46
  export const getServiceFactory = (
45
47
  service: Service,
46
48
  operations: ServiceOperation[],
47
- { openapiTypesImportPath }: ServiceImportsFactoryOptions
49
+ options: ServiceFactoryOptions
48
50
  ) => {
49
51
  const mainNodes = [
50
- getServiceInterfaceFactory(service, operations),
52
+ getServiceInterfaceFactory(service, operations, options),
51
53
  getServiceVariableFactory(service, operations),
52
- ...getOperationsTypes(operations),
54
+ ...getOperationsTypes(operations, options),
53
55
  ];
54
56
 
55
57
  const importNodes = [
56
- getOpenAPISchemaImportsFactory(openapiTypesImportPath),
58
+ getOpenAPISchemaImportsFactory(options.openapiTypesImportPath),
57
59
  ...getServiceOperationImportsFactory(
58
- filterUnusedTypes(getModuleTypeImports(operations), mainNodes)
60
+ filterUnusedTypes(getModuleTypeImports(operations, options), mainNodes)
59
61
  ),
60
62
  ];
61
63
 
@@ -112,7 +114,8 @@ const getServiceOperationImportsFactory = (
112
114
 
113
115
  const getServiceInterfaceFactory = (
114
116
  service: Service,
115
- operations: ServiceOperation[]
117
+ operations: ServiceOperation[],
118
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
116
119
  ) => {
117
120
  return factory.createInterfaceDeclaration(
118
121
  [factory.createToken(ts.SyntaxKind.ExportKeyword)],
@@ -120,19 +123,27 @@ const getServiceInterfaceFactory = (
120
123
  undefined,
121
124
  undefined,
122
125
  operations.map((operation) =>
123
- getServiceInterfaceOperationFactory(operation, service)
126
+ getServiceInterfaceOperationFactory(operation, service, options)
124
127
  )
125
128
  );
126
129
  };
127
130
 
128
131
  const getServiceInterfaceOperationFactory = (
129
132
  operation: ServiceOperation,
130
- service: Service
133
+ service: Service,
134
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
131
135
  ) => {
132
136
  const operationMethodNodes = getMethodSignatureNodes(
133
- operation.method === 'get'
134
- ? createServicesQueryOperationNodes()
135
- : createServicesMutationOperationNodes()
137
+ isReadOnlyOperation(operation)
138
+ ? createServicesQueryOperationNodes({ omitOperationQueryFnNodes: false })
139
+ : options.queryableWriteOperations
140
+ ? [
141
+ ...createServicesQueryOperationNodes({
142
+ omitOperationQueryFnNodes: true,
143
+ }),
144
+ ...createServicesMutationOperationNodes(),
145
+ ]
146
+ : createServicesMutationOperationNodes()
136
147
  );
137
148
 
138
149
  operationMethodNodes.forEach((node) => {
@@ -146,7 +157,8 @@ const getServiceInterfaceOperationFactory = (
146
157
  {
147
158
  serviceVariableName: service.variableName,
148
159
  operationMethodName: node.name.text,
149
- }
160
+ },
161
+ options
150
162
  );
151
163
  // Query and Mutation methods (hooks and QueryClient methods)
152
164
  ts.addSyntheticLeadingComment(
@@ -176,11 +188,16 @@ const getServiceInterfaceOperationFactory = (
176
188
  undefined,
177
189
  factory.createTypeLiteralNode([
178
190
  ...replaceGenericTypesWithOperationTypes(
179
- reduceAreAllOptionalConditionalTParamsType(
180
- operationMethodNodes,
191
+ reduceAreAllOptionalConditionalTVariablesType(
192
+ reduceAreAllOptionalConditionalTParamsType(
193
+ operationMethodNodes,
194
+ operation,
195
+ options
196
+ ),
181
197
  operation
182
198
  ),
183
- operation
199
+ operation,
200
+ options
184
201
  ),
185
202
  factory.createPropertySignature(
186
203
  undefined,
@@ -202,7 +219,11 @@ const getServiceInterfaceOperationFactory = (
202
219
  factory.createIdentifier('parameters'),
203
220
  undefined,
204
221
  factory.createTypeReferenceNode(
205
- getOperationParametersTypeName(operation),
222
+ getOperationParametersTypeName(
223
+ operation,
224
+ options,
225
+ isReadOnlyOperation(operation) ? 'query' : 'mutation'
226
+ ),
206
227
  undefined
207
228
  )
208
229
  ),
@@ -224,7 +245,7 @@ const getServiceInterfaceOperationFactory = (
224
245
  undefined
225
246
  )
226
247
  ),
227
- operation.method !== 'get'
248
+ !isReadOnlyOperation(operation) || operation.requestBody
228
249
  ? factory.createPropertySignature(
229
250
  undefined,
230
251
  factory.createIdentifier('body'),
@@ -362,31 +383,36 @@ const getOperationBodyFactory = (operation: ServiceOperation) => {
362
383
  ...mediaTypes.map((mediaType) =>
363
384
  factory.createIndexedAccessTypeNode(
364
385
  factory.createIndexedAccessTypeNode(
365
- factory.createTypeReferenceNode(
366
- factory.createIdentifier('NonNullable'),
367
- [
386
+ (() => {
387
+ const requestBodyNode = factory.createIndexedAccessTypeNode(
368
388
  factory.createIndexedAccessTypeNode(
369
389
  factory.createIndexedAccessTypeNode(
370
- factory.createIndexedAccessTypeNode(
371
- factory.createTypeReferenceNode(
372
- factory.createIdentifier('paths'),
373
- undefined
374
- ),
375
- factory.createLiteralTypeNode(
376
- factory.createStringLiteral(operation.path)
377
- )
390
+ factory.createTypeReferenceNode(
391
+ factory.createIdentifier('paths'),
392
+ undefined
378
393
  ),
379
394
  factory.createLiteralTypeNode(
380
- factory.createStringLiteral(operation.method)
395
+ factory.createStringLiteral(operation.path)
381
396
  )
382
397
  ),
383
398
  factory.createLiteralTypeNode(
384
- factory.createStringLiteral('requestBody')
399
+ factory.createStringLiteral(operation.method)
385
400
  )
386
401
  ),
387
- ]
388
- ),
389
- // todo::Add optional NonNullable inference, see `POST /entities/{entity_id}/documents`
402
+ factory.createLiteralTypeNode(
403
+ factory.createStringLiteral('requestBody')
404
+ )
405
+ );
406
+
407
+ if (!operation.requestBody?.required) {
408
+ return factory.createTypeReferenceNode(
409
+ factory.createIdentifier('NonNullable'),
410
+ [requestBodyNode]
411
+ );
412
+ }
413
+
414
+ return requestBodyNode;
415
+ })(),
390
416
  factory.createLiteralTypeNode(factory.createStringLiteral('content'))
391
417
  ),
392
418
  factory.createLiteralTypeNode(factory.createStringLiteral(mediaType))
@@ -398,39 +424,63 @@ const getOperationBodyFactory = (operation: ServiceOperation) => {
398
424
  ]);
399
425
  };
400
426
 
401
- const createOperationParametersFactory = (operation: ServiceOperation) => {
402
- if (!operation.parameters?.length)
403
- return operation.method === 'get'
404
- ? factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
405
- : // mutation with predefined parameters fallback to an empty object
406
- factory.createTypeLiteralNode(
407
- ['query', 'header', 'path'].map((name) =>
408
- factory.createPropertySignature(
409
- undefined,
410
- factory.createIdentifier(name),
411
- factory.createToken(ts.SyntaxKind.QuestionToken),
412
- factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)
427
+ const createOperationParametersFactory = (
428
+ operation: ServiceOperation,
429
+ withRequestBody: boolean
430
+ ) => {
431
+ if (isReadOnlyOperation(operation) && !operation.parameters?.length) {
432
+ return factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
433
+ }
434
+
435
+ const parametersNodes = operation.parameters?.length
436
+ ? factory.createIndexedAccessTypeNode(
437
+ factory.createIndexedAccessTypeNode(
438
+ factory.createIndexedAccessTypeNode(
439
+ factory.createTypeReferenceNode(
440
+ factory.createIdentifier('paths'),
441
+ undefined
442
+ ),
443
+ factory.createLiteralTypeNode(
444
+ factory.createStringLiteral(operation.path)
413
445
  )
446
+ ),
447
+ factory.createLiteralTypeNode(
448
+ factory.createStringLiteral(operation.method)
414
449
  )
415
- );
450
+ ),
451
+ factory.createLiteralTypeNode(factory.createStringLiteral('parameters'))
452
+ )
453
+ : factory.createTypeLiteralNode(
454
+ ['query', 'header', 'path'].map((name) =>
455
+ factory.createPropertySignature(
456
+ undefined,
457
+ factory.createIdentifier(name),
458
+ factory.createToken(ts.SyntaxKind.QuestionToken),
459
+ factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword)
460
+ )
461
+ )
462
+ );
416
463
 
417
- return factory.createIndexedAccessTypeNode(
418
- factory.createIndexedAccessTypeNode(
419
- factory.createIndexedAccessTypeNode(
464
+ if (!withRequestBody || !operation.requestBody) {
465
+ return parametersNodes;
466
+ }
467
+
468
+ return factory.createIntersectionTypeNode([
469
+ parametersNodes,
470
+ factory.createTypeLiteralNode([
471
+ factory.createPropertySignature(
472
+ undefined,
473
+ factory.createIdentifier('body'),
474
+ operation.requestBody.required
475
+ ? undefined
476
+ : factory.createToken(ts.SyntaxKind.QuestionToken),
420
477
  factory.createTypeReferenceNode(
421
- factory.createIdentifier('paths'),
478
+ factory.createIdentifier(getOperationBodyTypeName(operation)),
422
479
  undefined
423
- ),
424
- factory.createLiteralTypeNode(
425
- factory.createStringLiteral(operation.path)
426
480
  )
427
481
  ),
428
- factory.createLiteralTypeNode(
429
- factory.createStringLiteral(operation.method)
430
- )
431
- ),
432
- factory.createLiteralTypeNode(factory.createStringLiteral('parameters'))
433
- );
482
+ ]),
483
+ ]);
434
484
  };
435
485
 
436
486
  const getServiceVariableFactory = (
@@ -460,7 +510,10 @@ const getServiceVariableFactory = (
460
510
  );
461
511
  };
462
512
 
463
- const getOperationsTypes = (operations: ServiceOperation[]) => {
513
+ const getOperationsTypes = (
514
+ operations: ServiceOperation[],
515
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
516
+ ) => {
464
517
  return operations.flatMap((operation) => {
465
518
  const nodes = [
466
519
  factory.createTypeAliasDeclaration(
@@ -469,12 +522,39 @@ const getOperationsTypes = (operations: ServiceOperation[]) => {
469
522
  undefined,
470
523
  getOperationSchemaFactory(operation)
471
524
  ),
472
- factory.createTypeAliasDeclaration(
473
- undefined,
474
- factory.createIdentifier(getOperationParametersTypeName(operation)),
475
- undefined,
476
- createOperationParametersFactory(operation)
477
- ),
525
+ ...(isSeparateParametersOperation(operation, options)
526
+ ? [
527
+ factory.createTypeAliasDeclaration(
528
+ undefined,
529
+ factory.createIdentifier(
530
+ getOperationParametersTypeName(operation, options, 'query')
531
+ ),
532
+ undefined,
533
+ createOperationParametersFactory(operation, true)
534
+ ),
535
+ factory.createTypeAliasDeclaration(
536
+ undefined,
537
+ factory.createIdentifier(
538
+ getOperationParametersTypeName(operation, options, 'mutation')
539
+ ),
540
+ undefined,
541
+ createOperationParametersFactory(operation, false)
542
+ ),
543
+ ]
544
+ : [
545
+ factory.createTypeAliasDeclaration(
546
+ undefined,
547
+ factory.createIdentifier(
548
+ getOperationParametersTypeName(
549
+ operation,
550
+ options,
551
+ isReadOnlyOperation(operation) ? 'query' : 'mutation'
552
+ )
553
+ ),
554
+ undefined,
555
+ createOperationParametersFactory(operation, false)
556
+ ),
557
+ ]),
478
558
  factory.createTypeAliasDeclaration(
479
559
  undefined,
480
560
  factory.createIdentifier(getOperationDataTypeName(operation)),
@@ -489,7 +569,7 @@ const getOperationsTypes = (operations: ServiceOperation[]) => {
489
569
  ),
490
570
  ];
491
571
 
492
- if (operation.method !== 'get') {
572
+ if (!isReadOnlyOperation(operation) || operation.requestBody) {
493
573
  nodes.push(
494
574
  factory.createTypeAliasDeclaration(
495
575
  undefined,
@@ -507,8 +587,29 @@ const getOperationsTypes = (operations: ServiceOperation[]) => {
507
587
  const getOperationSchemaTypeName = (operation: ServiceOperation) =>
508
588
  camelCase(`${operation.name}-Schema`, { pascalCase: true });
509
589
 
510
- const getOperationParametersTypeName = (operation: ServiceOperation) =>
511
- camelCase(`${operation.name}-Parameters`, { pascalCase: true });
590
+ const getOperationParametersTypeName = (
591
+ operation: ServiceOperation,
592
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>,
593
+ desiredPrefix: 'query' | 'mutation'
594
+ ) => {
595
+ const operationPurpose = isSeparateParametersOperation(operation, options)
596
+ ? `-${desiredPrefix}`
597
+ : '';
598
+
599
+ return camelCase(`${operation.name}${operationPurpose}-Parameters`, {
600
+ pascalCase: true,
601
+ });
602
+ };
603
+
604
+ const isSeparateParametersOperation = (
605
+ operation: ServiceOperation,
606
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
607
+ ) =>
608
+ Boolean(
609
+ options.queryableWriteOperations &&
610
+ operation.requestBody &&
611
+ !isReadOnlyOperation(operation)
612
+ );
512
613
 
513
614
  const getOperationDataTypeName = (operation: ServiceOperation) =>
514
615
  camelCase(`${operation.name}-Data`, { pascalCase: true });
@@ -624,7 +725,11 @@ const getOperationSecuritySchemas = (
624
725
  Object.keys(security).map((securitySchemaName) => securitySchemaName)
625
726
  );
626
727
 
627
- const createServicesQueryOperationNodes = () => [
728
+ const createServicesQueryOperationNodes = ({
729
+ omitOperationQueryFnNodes,
730
+ }: {
731
+ omitOperationQueryFnNodes: boolean;
732
+ }) => [
628
733
  ...createServiceOperationCancelQueriesNodes(),
629
734
  ...createServiceOperationUseQueryNodes(),
630
735
  ...createServiceOperationFetchInfiniteQueryNodes(),
@@ -635,7 +740,7 @@ const createServicesQueryOperationNodes = () => [
635
740
  ...createServiceOperationGetQueryStateNodes(),
636
741
  ...createServiceOperationInvalidateQueriesNodes(),
637
742
  ...createServiceOperationIsFetchingQueriesNodes(),
638
- ...createServiceOperationQueryFnNodes(),
743
+ ...(omitOperationQueryFnNodes ? [] : createServiceOperationQueryFnNodes()),
639
744
  ...createServiceOperationRefetchQueriesNodes(),
640
745
  ...createServiceOperationRemoveQueriesNodes(),
641
746
  ...createServiceOperationResetQueriesNodes(),
@@ -674,18 +779,29 @@ const getMethodSignatureNodes = (
674
779
 
675
780
  /**
676
781
  * Returns a list of all the modules that are imported by the operations.
677
- * @param operations
782
+ * @param operations The list of service operations to analyze
783
+ * @param options Options for controlling module imports generation.Options for controlling module imports generation.
678
784
  * @returns Record<moduleName, importSpecifierNames[]>
679
785
  */
680
- const getModuleTypeImports = (operations: ServiceOperation[]) => {
681
- const nodes = [
682
- ...(operations.some((operation) => operation.method === 'get')
683
- ? createServicesQueryOperationNodes()
684
- : []),
685
- ...(operations.some((operation) => operation.method !== 'get')
686
- ? createServicesMutationOperationNodes()
687
- : []),
688
- ];
786
+ const getModuleTypeImports = (
787
+ operations: ServiceOperation[],
788
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
789
+ ) => {
790
+ const nodes = [];
791
+
792
+ const hasReadOnlyOperations = operations.some(isReadOnlyOperation);
793
+
794
+ if (hasReadOnlyOperations || options.queryableWriteOperations) {
795
+ nodes.push(
796
+ ...createServicesQueryOperationNodes({
797
+ omitOperationQueryFnNodes: !hasReadOnlyOperations,
798
+ })
799
+ );
800
+ }
801
+
802
+ if (operations.some((operation) => !isReadOnlyOperation(operation))) {
803
+ nodes.push(...createServicesMutationOperationNodes());
804
+ }
689
805
 
690
806
  return nodes
691
807
  .map((node) =>
@@ -720,12 +836,13 @@ const getModuleTypeImports = (operations: ServiceOperation[]) => {
720
836
  /**
721
837
  * Replaces generic types with operation types with named types.
722
838
  *
723
- * For example, replaces `TParams` and `TQueryFnData` will be
839
+ * For example, replaces `TQueryParams` and `TQueryFnData` will be
724
840
  * replaced with `GetEntitiesSchemaParameters` and `GetEntitiesSchemaData`.
725
841
  */
726
842
  function replaceGenericTypesWithOperationTypes<T extends ts.Node>(
727
843
  node: T[],
728
- operation: ServiceOperation
844
+ operation: ServiceOperation,
845
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
729
846
  ): T[] {
730
847
  const transformer =
731
848
  (context: ts.TransformationContext) => (rootNode: ts.Node) => {
@@ -735,8 +852,18 @@ function replaceGenericTypesWithOperationTypes<T extends ts.Node>(
735
852
 
736
853
  if (node.typeName.text === 'TSchema')
737
854
  newTypeName = getOperationSchemaTypeName(operation);
738
- else if (node.typeName.text === 'TParams')
739
- newTypeName = getOperationParametersTypeName(operation);
855
+ else if (node.typeName.text === 'TQueryParams')
856
+ newTypeName = getOperationParametersTypeName(
857
+ operation,
858
+ options,
859
+ 'query'
860
+ );
861
+ else if (node.typeName.text === 'TMutationParams')
862
+ newTypeName = getOperationParametersTypeName(
863
+ operation,
864
+ options,
865
+ 'mutation'
866
+ );
740
867
  else if (
741
868
  node.typeName.text === 'TOperationQueryFnData' ||
742
869
  node.typeName.text === 'TMutationData'
@@ -765,10 +892,55 @@ function replaceGenericTypesWithOperationTypes<T extends ts.Node>(
765
892
  }
766
893
 
767
894
  /**
768
- * Replaces `AreAllOptional<TParams>` with `TParams | void` if `TParams` is optional,
769
- * and with `TParams` when at least one parameter is required.
895
+ * Replaces `AreAllOptional<TQueryParams>` with `TQueryParams | void` if `TQueryParams` is optional,
896
+ * and with `TQueryParams` when at least one parameter or `body` (when --queryable-write-operations enabled) is required.
770
897
  */
771
898
  function reduceAreAllOptionalConditionalTParamsType<T extends ts.Node>(
899
+ node: T[],
900
+ operation: ServiceOperation,
901
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
902
+ ): T[] {
903
+ const transformer =
904
+ (context: ts.TransformationContext) => (rootNode: ts.Node) => {
905
+ function visit(node: ts.Node): ts.Node {
906
+ if (
907
+ ts.isConditionalTypeNode(node) &&
908
+ ts.isTypeReferenceNode(node.checkType) &&
909
+ ts.isIdentifier(node.checkType.typeName) &&
910
+ node.checkType.typeName.text === 'AreAllOptional' &&
911
+ node.checkType.typeArguments?.every((node) => {
912
+ return (
913
+ ts.isTypeReferenceNode(node) &&
914
+ ts.isIdentifier(node.typeName) &&
915
+ node.typeName.text === 'TQueryParams'
916
+ );
917
+ })
918
+ ) {
919
+ if (
920
+ operation.parameters?.some((parameter) => parameter.required) ||
921
+ (options.queryableWriteOperations &&
922
+ operation.requestBody?.required)
923
+ ) {
924
+ return node.falseType;
925
+ } else {
926
+ return node.trueType;
927
+ }
928
+ }
929
+ return ts.visitEachChild(node, visit, context);
930
+ }
931
+ return ts.visitNode(rootNode, visit);
932
+ };
933
+
934
+ const result = ts.transform(node, [transformer]);
935
+
936
+ return result.transformed as T[];
937
+ }
938
+
939
+ /**
940
+ * Replaces `AreAllOptional<TVariables>` with `TVariables | void` if `TVariables` is optional,
941
+ * and with `TVariables` when `body` is required.
942
+ */
943
+ function reduceAreAllOptionalConditionalTVariablesType<T extends ts.Node>(
772
944
  node: T[],
773
945
  operation: ServiceOperation
774
946
  ): T[] {
@@ -784,11 +956,11 @@ function reduceAreAllOptionalConditionalTParamsType<T extends ts.Node>(
784
956
  return (
785
957
  ts.isTypeReferenceNode(node) &&
786
958
  ts.isIdentifier(node.typeName) &&
787
- node.typeName.text === 'TParams'
959
+ node.typeName.text === 'TVariables'
788
960
  );
789
961
  })
790
962
  ) {
791
- if (operation.parameters?.some((parameter) => parameter.required)) {
963
+ if (operation.requestBody?.required) {
792
964
  return node.falseType;
793
965
  } else {
794
966
  return node.trueType;
@@ -1,4 +1,5 @@
1
1
  import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
2
+ import { ServiceFactoryOptions } from '../getServiceFactory.js';
2
3
  import { createUseInfiniteQueryOperationTSDocExample } from './createUseInfiniteQueryOperationTSDocExample.js';
3
4
  import { createUseIsFetchingOperationTSDocExample } from './createUseIsFetchingOperationTSDocExample.js';
4
5
  import { createUseIsMutatingOperationTSDocExample } from './createUseIsMutatingOperationTSDocExample.js';
@@ -18,18 +19,21 @@ export const createOperationMethodTSDocExample = (
18
19
  }: {
19
20
  serviceVariableName: string;
20
21
  operationMethodName: string;
21
- }
22
+ },
23
+ options: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
22
24
  ) => {
23
25
  switch (operationMethodName) {
24
26
  case 'useQuery':
25
27
  return createUseQueryOperationTSDocExample(
26
28
  operation,
27
- serviceVariableName
29
+ serviceVariableName,
30
+ options
28
31
  );
29
32
  case 'useSuspenseQuery':
30
33
  return createUseSuspenseQueryOperationTSDocExample(
31
34
  operation,
32
- serviceVariableName
35
+ serviceVariableName,
36
+ options
33
37
  );
34
38
  case 'useMutation':
35
39
  return createUseMutationOperationTSDocExample(
@@ -39,17 +43,20 @@ export const createOperationMethodTSDocExample = (
39
43
  case 'useInfiniteQuery':
40
44
  return createUseInfiniteQueryOperationTSDocExample(
41
45
  operation,
42
- serviceVariableName
46
+ serviceVariableName,
47
+ options
43
48
  );
44
49
  case 'useSuspenseInfiniteQuery':
45
50
  return createUseSuspenseInfiniteQueryOperationTSDocExample(
46
51
  operation,
47
- serviceVariableName
52
+ serviceVariableName,
53
+ options
48
54
  );
49
55
  case 'useIsFetching':
50
56
  return createUseIsFetchingOperationTSDocExample(
51
57
  operation,
52
- serviceVariableName
58
+ serviceVariableName,
59
+ options
53
60
  );
54
61
  case 'useIsMutating':
55
62
  return createUseIsMutatingOperationTSDocExample(
@@ -64,12 +71,14 @@ export const createOperationMethodTSDocExample = (
64
71
  case 'useQueries':
65
72
  return createUseQueriesOperationTSDocExample(
66
73
  operation,
67
- serviceVariableName
74
+ serviceVariableName,
75
+ options
68
76
  );
69
77
  case 'useSuspenseQueries':
70
78
  return createUseSuspenseQueriesOperationTSDocExample(
71
79
  operation,
72
- serviceVariableName
80
+ serviceVariableName,
81
+ options
73
82
  );
74
83
  default:
75
84
  return undefined;
@@ -3,12 +3,17 @@ import camelcase from 'camelcase';
3
3
  import ts from 'typescript';
4
4
  import { createOperationCommonTSDoc } from '../../lib/createOperationCommonTSDoc.js';
5
5
  import { astToString } from '../astToString.js';
6
+ import { ServiceFactoryOptions } from '../getServiceFactory.js';
7
+ import { createOperationMethodBodyParametersExampleNode } from './lib/createOperationMethodBodyParametersExampleNode.js';
6
8
  import { createOperationMethodCallExpressionExampleNode } from './lib/createOperationMethodCallExpressionExampleNode.js';
7
9
  import { createOperationMethodParametersExampleNodes } from './lib/createOperationMethodParametersExampleNodes.js';
8
10
 
9
11
  export const createUseInfiniteQueryOperationTSDocExample = (
10
12
  operation: ServiceOperation,
11
- serviceVariableName: string
13
+ serviceVariableName: string,
14
+ {
15
+ queryableWriteOperations,
16
+ }: Pick<ServiceFactoryOptions, 'queryableWriteOperations'>
12
17
  ): string[] => {
13
18
  const factory = ts.factory;
14
19
 
@@ -36,12 +41,16 @@ export const createUseInfiniteQueryOperationTSDocExample = (
36
41
  },
37
42
  [
38
43
  factory.createObjectLiteralExpression(
39
- createOperationMethodParametersExampleNodes({
40
- ...operation,
41
- parameters: operation.parameters?.filter((parameter) =>
42
- parameter.in === 'query' ? parameter.required : true
43
- ),
44
- }),
44
+ [
45
+ queryableWriteOperations &&
46
+ createOperationMethodBodyParametersExampleNode(operation),
47
+ ...createOperationMethodParametersExampleNodes({
48
+ ...operation,
49
+ parameters: operation.parameters?.filter((parameter) =>
50
+ parameter.in === 'query' ? parameter.required : true
51
+ ),
52
+ }),
53
+ ].filter((node) => !!node),
45
54
  true
46
55
  ),
47
56
  factory.createObjectLiteralExpression(