@openapi-qraft/tanstack-query-react-plugin 2.0.0-next.9 → 2.0.0

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 (115) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/generateCode.d.ts +3 -3
  3. package/dist/generateCode.d.ts.map +1 -1
  4. package/dist/generateCode.js +3 -3
  5. package/dist/generateCode.js.map +1 -1
  6. package/dist/lib/createOperationCommonTSDoc.d.ts +1 -1
  7. package/dist/lib/createOperationCommonTSDoc.d.ts.map +1 -1
  8. package/dist/plugin.d.ts.map +1 -1
  9. package/dist/plugin.js +4 -1
  10. package/dist/plugin.js.map +1 -1
  11. package/dist/ts-factory/filterUnusedTypes.d.ts +9 -0
  12. package/dist/ts-factory/filterUnusedTypes.d.ts.map +1 -0
  13. package/dist/ts-factory/filterUnusedTypes.js +34 -0
  14. package/dist/ts-factory/filterUnusedTypes.js.map +1 -0
  15. package/dist/ts-factory/getClientFactory.d.ts +1 -1
  16. package/dist/ts-factory/getClientFactory.d.ts.map +1 -1
  17. package/dist/ts-factory/getClientFactory.js +1 -1
  18. package/dist/ts-factory/getClientFactory.js.map +1 -1
  19. package/dist/ts-factory/getIndexFactory.d.ts +1 -1
  20. package/dist/ts-factory/getIndexFactory.d.ts.map +1 -1
  21. package/dist/ts-factory/getIndexFactory.js +2 -2
  22. package/dist/ts-factory/getIndexFactory.js.map +1 -1
  23. package/dist/ts-factory/getServiceFactory.d.ts +1 -1
  24. package/dist/ts-factory/getServiceFactory.d.ts.map +1 -1
  25. package/dist/ts-factory/getServiceFactory.js +54 -42
  26. package/dist/ts-factory/getServiceFactory.js.map +1 -1
  27. package/dist/ts-factory/getServiceIndexFactory.d.ts +3 -3
  28. package/dist/ts-factory/getServiceIndexFactory.d.ts.map +1 -1
  29. package/dist/ts-factory/getServiceIndexFactory.js +1 -1
  30. package/dist/ts-factory/getServiceIndexFactory.js.map +1 -1
  31. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.d.ts.map +1 -1
  32. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.js +26 -67
  33. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.js.map +1 -1
  34. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchQuery.d.ts.map +1 -1
  35. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchQuery.js +16 -1
  36. package/dist/ts-factory/service-operation.generated/ServiceOperationFetchQuery.js.map +1 -1
  37. package/dist/ts-factory/service-operation.generated/ServiceOperationMutationFn.d.ts.map +1 -1
  38. package/dist/ts-factory/service-operation.generated/ServiceOperationMutationFn.js +7 -4
  39. package/dist/ts-factory/service-operation.generated/ServiceOperationMutationFn.js.map +1 -1
  40. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueryData.d.ts.map +1 -1
  41. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueryData.js +9 -3
  42. package/dist/ts-factory/service-operation.generated/ServiceOperationSetQueryData.js.map +1 -1
  43. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.d.ts +1 -1
  44. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.d.ts.map +1 -1
  45. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.js +9 -0
  46. package/dist/ts-factory/tsdoc/createOperationMethodTSDocExample.js.map +1 -1
  47. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.d.ts +3 -1
  48. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.d.ts.map +1 -1
  49. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.js +19 -27
  50. package/dist/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.js.map +1 -1
  51. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.d.ts +1 -1
  52. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.d.ts.map +1 -1
  53. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.js +3 -3
  54. package/dist/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.js.map +1 -1
  55. package/dist/ts-factory/tsdoc/createUseIsMutatingOperationTSDocExample.d.ts +1 -1
  56. package/dist/ts-factory/tsdoc/createUseIsMutatingOperationTSDocExample.d.ts.map +1 -1
  57. package/dist/ts-factory/tsdoc/createUseIsMutatingOperationTSDocExample.js +3 -3
  58. package/dist/ts-factory/tsdoc/createUseIsMutatingOperationTSDocExample.js.map +1 -1
  59. package/dist/ts-factory/tsdoc/createUseMutationOperationTSDocExample.d.ts +1 -1
  60. package/dist/ts-factory/tsdoc/createUseMutationOperationTSDocExample.d.ts.map +1 -1
  61. package/dist/ts-factory/tsdoc/createUseMutationOperationTSDocExample.js +3 -3
  62. package/dist/ts-factory/tsdoc/createUseMutationOperationTSDocExample.js.map +1 -1
  63. package/dist/ts-factory/tsdoc/createUseMutationStateOperationTSDocExample.d.ts +3 -0
  64. package/dist/ts-factory/tsdoc/createUseMutationStateOperationTSDocExample.d.ts.map +1 -0
  65. package/dist/ts-factory/tsdoc/createUseMutationStateOperationTSDocExample.js +55 -0
  66. package/dist/ts-factory/tsdoc/createUseMutationStateOperationTSDocExample.js.map +1 -0
  67. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.d.ts +3 -0
  68. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.d.ts.map +1 -0
  69. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.js +88 -0
  70. package/dist/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.js.map +1 -0
  71. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.d.ts +1 -1
  72. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.d.ts.map +1 -1
  73. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.js +3 -3
  74. package/dist/ts-factory/tsdoc/createUseQueryOperationTSDocExample.js.map +1 -1
  75. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.d.ts +3 -0
  76. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.d.ts.map +1 -0
  77. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.js +39 -0
  78. package/dist/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.js.map +1 -0
  79. package/dist/ts-factory/tsdoc/lib/createOperationMethodCallExpressionExampleNode.d.ts +7 -0
  80. package/dist/ts-factory/tsdoc/lib/createOperationMethodCallExpressionExampleNode.d.ts.map +1 -0
  81. package/dist/ts-factory/tsdoc/lib/createOperationMethodCallExpressionExampleNode.js +6 -0
  82. package/dist/ts-factory/tsdoc/lib/createOperationMethodCallExpressionExampleNode.js.map +1 -0
  83. package/dist/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.d.ts +1 -1
  84. package/dist/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.d.ts.map +1 -1
  85. package/dist/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.js +17 -1
  86. package/dist/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.js.map +1 -1
  87. package/package.json +4 -4
  88. package/src/generateCode.ts +8 -8
  89. package/src/lib/createOperationCommonTSDoc.ts +1 -1
  90. package/src/plugin.ts +8 -3
  91. package/src/ts-factory/filterUnusedTypes.ts +49 -0
  92. package/src/ts-factory/getClientFactory.ts +2 -2
  93. package/src/ts-factory/getIndexFactory.ts +13 -4
  94. package/src/ts-factory/getServiceFactory.ts +98 -69
  95. package/src/ts-factory/getServiceIndexFactory.ts +7 -7
  96. package/src/ts-factory/service-operation.generated/ServiceOperationFetchInfiniteQuery.ts +101 -190
  97. package/src/ts-factory/service-operation.generated/ServiceOperationFetchQuery.ts +80 -0
  98. package/src/ts-factory/service-operation.generated/ServiceOperationMutationFn.ts +23 -22
  99. package/src/ts-factory/service-operation.generated/ServiceOperationSetQueryData.ts +34 -10
  100. package/src/ts-factory/tsdoc/createOperationMethodTSDocExample.ts +19 -1
  101. package/src/ts-factory/tsdoc/createUseInfiniteQueryOperationTSDocExample.ts +84 -95
  102. package/src/ts-factory/tsdoc/createUseIsFetchingOperationTSDocExample.ts +4 -4
  103. package/src/ts-factory/tsdoc/createUseIsMutatingOperationTSDocExample.ts +4 -4
  104. package/src/ts-factory/tsdoc/createUseMutationOperationTSDocExample.ts +4 -4
  105. package/src/ts-factory/tsdoc/createUseMutationStateOperationTSDocExample.ts +154 -0
  106. package/src/ts-factory/tsdoc/createUseQueriesOperationTSDocExample.ts +292 -0
  107. package/src/ts-factory/tsdoc/createUseQueryOperationTSDocExample.ts +4 -4
  108. package/src/ts-factory/tsdoc/createUseSuspenseInfiniteQueryOperationTSDocExample.ts +63 -0
  109. package/src/ts-factory/tsdoc/lib/createOperationMethodCallExpressionExampleNode.ts +28 -0
  110. package/src/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.ts +19 -2
  111. package/dist/ts-factory/tsdoc/lib/createOperationMethodExampleNodes.d.ts +0 -7
  112. package/dist/ts-factory/tsdoc/lib/createOperationMethodExampleNodes.d.ts.map +0 -1
  113. package/dist/ts-factory/tsdoc/lib/createOperationMethodExampleNodes.js +0 -8
  114. package/dist/ts-factory/tsdoc/lib/createOperationMethodExampleNodes.js.map +0 -1
  115. package/src/ts-factory/tsdoc/lib/createOperationMethodExampleNodes.ts +0 -32
@@ -20,7 +20,9 @@ export const createOperationMethodParametersExampleNodes = (operation, transform
20
20
  const factory = ts.factory;
21
21
  return [
22
22
  ...acc,
23
- factory.createPropertyAssignment(factory.createIdentifier(parameterKind), factory.createObjectLiteralExpression(operationParameters.map((parameter) => factory.createPropertyAssignment(factory.createStringLiteral(parameter.name), parameter.example // todo:: add example type inferring
23
+ factory.createPropertyAssignment(factory.createIdentifier(parameterKind), factory.createObjectLiteralExpression(operationParameters.map((parameter) => factory.createPropertyAssignment(isIdentifierCompatibleVariableName(parameter.name)
24
+ ? factory.createIdentifier(parameter.name)
25
+ : factory.createStringLiteral(parameter.name), parameter.example // todo:: add example type inferring
24
26
  ? factory.createStringLiteral(parameter.example)
25
27
  : factory.createIdentifier(transformOperationParameterIdentifier
26
28
  ? transformOperationParameterIdentifier(parameter)
@@ -28,4 +30,18 @@ export const createOperationMethodParametersExampleNodes = (operation, transform
28
30
  ];
29
31
  }, []);
30
32
  };
33
+ /**
34
+ * Checks if the given name is a valid identifier name.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * isIdentifierCompatibleVariableName('foo'); // true
39
+ * isIdentifierCompatibleVariableName('foo-bar'); // false
40
+ * isIdentifierCompatibleVariableName('foo_bar'); // true
41
+ * isIdentifierCompatibleVariableName('foo.bar'); // false
42
+ * ```
43
+ */
44
+ function isIdentifierCompatibleVariableName(name) {
45
+ return !/[^a-zA-Z0-9_$]/.test(name);
46
+ }
31
47
  //# sourceMappingURL=createOperationMethodParametersExampleNodes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createOperationMethodParametersExampleNodes.js","sourceRoot":"","sources":["../../../../src/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,2CAA2C,GAAG,CACzD,SAA2B,EAC3B,qCAEW,EACc,EAAE;IAC3B,IAAI,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,kBAAkB,GAAG,SAAS,CAAC,UAAU;SAC5C,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;SAChC,MAAM,CACL,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,KAAK,CACxE,CAAC;IAEJ,MAAM,2BAA2B,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAC7D,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAClC,CAAC;IAEF,OAAO,kBAAkB,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,aAAa,EAAE,EAAE;QACrB,IAAI,mBAAmB,GAAG,2BAA2B,CAAC,MAAM,CAC1D,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,aAAa,CAC9C,CAAC;QAEF,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,kBAAkB,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,CACnD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,aAAa,CAC9C,CAAC;YACF,IAAI,kBAAkB,EAAE,CAAC;gBACvB,mBAAmB,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QAE5C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC;QAE3B,OAAO;YACL,GAAG,GAAG;YACN,OAAO,CAAC,wBAAwB,CAC9B,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,EACvC,OAAO,CAAC,6BAA6B,CACnC,mBAAmB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CACpC,OAAO,CAAC,wBAAwB,CAC9B,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,EAC3C,SAAS,CAAC,OAAO,CAAC,oCAAoC;gBACpD,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,OAAO,CAAC;gBAChD,CAAC,CAAC,OAAO,CAAC,gBAAgB,CACtB,qCAAqC;oBACnC,CAAC,CAAC,qCAAqC,CAAC,SAAS,CAAC;oBAClD,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAC9B,CACN,CACF,EACD,IAAI,CACL,CACF;SACF,CAAC;IACJ,CAAC,EACD,EAAE,CACH,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"createOperationMethodParametersExampleNodes.js","sourceRoot":"","sources":["../../../../src/ts-factory/tsdoc/lib/createOperationMethodParametersExampleNodes.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,2CAA2C,GAAG,CACzD,SAA2B,EAC3B,qCAEW,EACc,EAAE;IAC3B,IAAI,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,kBAAkB,GAAG,SAAS,CAAC,UAAU;SAC5C,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;SAChC,MAAM,CACL,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,KAAK,CACxE,CAAC;IAEJ,MAAM,2BAA2B,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAC7D,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAClC,CAAC;IAEF,OAAO,kBAAkB,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,aAAa,EAAE,EAAE;QACrB,IAAI,mBAAmB,GAAG,2BAA2B,CAAC,MAAM,CAC1D,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,aAAa,CAC9C,CAAC;QAEF,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,kBAAkB,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,CACnD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,aAAa,CAC9C,CAAC;YACF,IAAI,kBAAkB,EAAE,CAAC;gBACvB,mBAAmB,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC;QAE5C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC;QAE3B,OAAO;YACL,GAAG,GAAG;YACN,OAAO,CAAC,wBAAwB,CAC9B,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,EACvC,OAAO,CAAC,6BAA6B,CACnC,mBAAmB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CACpC,OAAO,CAAC,wBAAwB,CAC9B,kCAAkC,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChD,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1C,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,EAC/C,SAAS,CAAC,OAAO,CAAC,oCAAoC;gBACpD,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,OAAO,CAAC;gBAChD,CAAC,CAAC,OAAO,CAAC,gBAAgB,CACtB,qCAAqC;oBACnC,CAAC,CAAC,qCAAqC,CAAC,SAAS,CAAC;oBAClD,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAC9B,CACN,CACF,EACD,IAAI,CACL,CACF;SACF,CAAC;IACJ,CAAC,EACD,EAAE,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAS,kCAAkC,CAAC,IAAY;IACtD,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-qraft/tanstack-query-react-plugin",
3
- "version": "2.0.0-next.9",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc --project tsconfig.build.json",
@@ -27,7 +27,7 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@openapi-qraft/plugin": "^2.0.0-next.9",
30
+ "@openapi-qraft/plugin": "^2.0.0",
31
31
  "typescript": "^5.6.2"
32
32
  },
33
33
  "devDependencies": {
@@ -35,10 +35,10 @@
35
35
  "@openapi-qraft/test-fixtures": "1.0.0",
36
36
  "@openapi-qraft/ts-factory-code-generator": "1.0.0",
37
37
  "camelcase": "^8.0.0",
38
- "eslint": "^9.10.0",
38
+ "eslint": "^9.16.0",
39
39
  "memfs": "^4.11.1",
40
40
  "rimraf": "^5.0.10",
41
- "vitest": "^1.6.0"
41
+ "vitest": "^2.1.8"
42
42
  },
43
43
  "files": [
44
44
  "dist",
@@ -1,7 +1,7 @@
1
1
  import { URL } from 'node:url';
2
2
  import { formatFileHeader } from '@openapi-qraft/plugin/lib/formatFileHeader';
3
3
  import { GeneratorFile } from '@openapi-qraft/plugin/lib/GeneratorFile';
4
- import { Service } from '@openapi-qraft/plugin/lib/open-api/getServices';
4
+ import { OpenAPIService } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
5
5
  import { OutputOptions as OutputOptionsBase } from '@openapi-qraft/plugin/lib/OutputOptions';
6
6
  import { PredefinedParametersGlob } from '@openapi-qraft/plugin/lib/predefineSchemaParameters';
7
7
  import c from 'ansi-colors';
@@ -19,7 +19,7 @@ import { getServiceIndexFactory } from './ts-factory/getServiceIndexFactory.js';
19
19
  interface OutputOptions extends OutputOptionsBase {
20
20
  fileHeader: string | undefined;
21
21
  servicesDirName: string;
22
- explicitImportExtensions: boolean;
22
+ explicitImportExtensions: '.js' | '.ts' | undefined;
23
23
  exportSchemaTypes: boolean | undefined;
24
24
  operationPredefinedParameters: Array<PredefinedParametersGlob> | undefined;
25
25
  }
@@ -31,7 +31,7 @@ export const generateCode = async ({
31
31
  output,
32
32
  }: {
33
33
  spinner: Ora;
34
- services: Service[];
34
+ services: OpenAPIService[];
35
35
  serviceImports: ServiceImportsFactoryOptions;
36
36
  output: OutputOptions;
37
37
  }) => {
@@ -58,7 +58,7 @@ const composeServicesDirPath = (
58
58
 
59
59
  const generateServices = async (
60
60
  spinner: Ora,
61
- services: Service[],
61
+ services: OpenAPIService[],
62
62
  serviceImports: ServiceImportsFactoryOptions,
63
63
  output: OutputOptions
64
64
  ) => {
@@ -112,7 +112,7 @@ const generateServices = async (
112
112
 
113
113
  const generateServiceIndex = async (
114
114
  spinner: Ora,
115
- services: Service[],
115
+ services: OpenAPIService[],
116
116
  output: OutputOptions
117
117
  ) => {
118
118
  spinner.start('Generating services index');
@@ -127,7 +127,7 @@ const generateServiceIndex = async (
127
127
  try {
128
128
  const code = astToString(
129
129
  getServiceIndexFactory(services, {
130
- explicitImportExtensions: Boolean(output.explicitImportExtensions),
130
+ explicitImportExtensions: output.explicitImportExtensions,
131
131
  })
132
132
  );
133
133
 
@@ -157,7 +157,7 @@ const generateClient = async (spinner: Ora, output: OutputOptions) => {
157
157
  const code = astToString(
158
158
  getClientFactory({
159
159
  servicesDirName: output.servicesDirName,
160
- explicitImportExtensions: Boolean(output.explicitImportExtensions),
160
+ explicitImportExtensions: output.explicitImportExtensions,
161
161
  })
162
162
  );
163
163
 
@@ -228,7 +228,7 @@ const generateIndex = async (
228
228
  const code = astToString(
229
229
  getIndexFactory({
230
230
  servicesDirName: output.servicesDirName,
231
- explicitImportExtensions: Boolean(output.explicitImportExtensions),
231
+ explicitImportExtensions: output.explicitImportExtensions,
232
232
  openapiTypesImportPath: output.exportSchemaTypes
233
233
  ? serviceImports.openapiTypesImportPath
234
234
  : undefined,
@@ -1,4 +1,4 @@
1
- import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/getServices';
1
+ import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
2
2
 
3
3
  export const createOperationCommonTSDoc = (operation: ServiceOperation) => {
4
4
  return [
package/src/plugin.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  } from '@openapi-qraft/plugin/lib/predefineSchemaParameters';
6
6
  import { QraftCommand } from '@openapi-qraft/plugin/lib/QraftCommand';
7
7
  import { QraftCommandPlugin } from '@openapi-qraft/plugin/lib/QraftCommandPlugin';
8
+ import { Option } from 'commander';
8
9
  import { generateCode } from './generateCode.js';
9
10
 
10
11
  export const plugin: QraftCommandPlugin = {
@@ -15,9 +16,13 @@ export const plugin: QraftCommandPlugin = {
15
16
  '--openapi-types-import-path <path>',
16
17
  'Path to schema types file (.d.ts), eg: "../schema.d.ts"'
17
18
  )
18
- .option(
19
- '--explicit-import-extensions',
20
- 'All import statements will include explicit `.js` extensions. Ideal for projects using ECMAScript modules.'
19
+ .addOption(
20
+ new Option(
21
+ '--explicit-import-extensions [extension]',
22
+ 'All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules.'
23
+ )
24
+ .preset('.js')
25
+ .choices(['.js', '.ts'])
21
26
  )
22
27
  .option(
23
28
  '--export-openapi-types [bool]',
@@ -0,0 +1,49 @@
1
+ import ts from 'typescript';
2
+
3
+ /**
4
+ * Checks if a type is used in the given nodes.
5
+ * @param typeImports Record<moduleName, typeName[]>
6
+ * @param nodes
7
+ * @returns Record<moduleName, typeName[]>
8
+ */
9
+ export function filterUnusedTypes(
10
+ typeImports: Record<string, string[]>,
11
+ nodes: ts.Node[]
12
+ ): Record<string, string[]> {
13
+ const usedTypeImports: Record<string, string[]> = {};
14
+ const targetTypeNames = Object.entries(typeImports).reduce<
15
+ Record<string, string>
16
+ >(
17
+ (acc, [moduleName, typeImports]) =>
18
+ typeImports.reduce((acc, typeName) => {
19
+ acc[typeName] = moduleName;
20
+ return acc;
21
+ }, acc),
22
+ {}
23
+ );
24
+
25
+ const transformer =
26
+ (context: ts.TransformationContext) => (rootNode: ts.Node) => {
27
+ function visit(node: ts.Node): ts.Node {
28
+ if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName)) {
29
+ const typeName = node.typeName.text;
30
+ const moduleName = targetTypeNames[typeName];
31
+ if (moduleName) {
32
+ usedTypeImports[moduleName] ??= [];
33
+ if (!usedTypeImports[moduleName].includes(typeName)) {
34
+ usedTypeImports[moduleName].push(typeName);
35
+ usedTypeImports[moduleName].sort();
36
+ }
37
+ }
38
+ }
39
+
40
+ return ts.visitEachChild(node, visit, context);
41
+ }
42
+
43
+ return ts.visitNode(rootNode, visit);
44
+ };
45
+
46
+ ts.transform(nodes, [transformer]).dispose();
47
+
48
+ return usedTypeImports;
49
+ }
@@ -2,7 +2,7 @@ import ts from 'typescript';
2
2
 
3
3
  type Options = {
4
4
  servicesDirName: string;
5
- explicitImportExtensions: boolean;
5
+ explicitImportExtensions: '.js' | '.ts' | undefined;
6
6
  };
7
7
 
8
8
  export const getClientFactory = (options: Options) => {
@@ -79,7 +79,7 @@ const getClientImportsFactory = ({
79
79
  ])
80
80
  ),
81
81
  factory.createStringLiteral(
82
- `./${servicesDirName}/index${explicitImportExtensions ? '.js' : ''}`
82
+ `./${servicesDirName}/index${explicitImportExtensions ?? ''}`
83
83
  ),
84
84
  undefined
85
85
  ),
@@ -8,18 +8,27 @@ export const getIndexFactory = ({
8
8
  explicitImportExtensions,
9
9
  }: {
10
10
  servicesDirName: string;
11
- explicitImportExtensions: boolean;
11
+ explicitImportExtensions: '.js' | '.ts' | undefined;
12
12
  } & Partial<Pick<ServiceImportsFactoryOptions, 'openapiTypesImportPath'>>) => {
13
13
  const factory = ts.factory;
14
- const importExtension = explicitImportExtensions ? '.js' : '';
14
+ const importExtension = explicitImportExtensions ?? '';
15
15
 
16
16
  return [
17
17
  ...(openapiTypesImportPath
18
18
  ? [
19
19
  factory.createExportDeclaration(
20
20
  undefined,
21
- openapiTypesImportPath.endsWith('.d.ts'),
22
- undefined,
21
+ true,
22
+ factory.createNamedExports(
23
+ ['$defs', 'paths', 'components', 'operations', 'webhooks'].map(
24
+ (name) =>
25
+ factory.createExportSpecifier(
26
+ false,
27
+ undefined,
28
+ factory.createIdentifier(name)
29
+ )
30
+ )
31
+ ),
23
32
  factory.createStringLiteral(
24
33
  maybeResolveImport({ openapiTypesImportPath, servicesDirName })
25
34
  ),
@@ -1,7 +1,8 @@
1
- import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/getServices';
1
+ import { ServiceOperation } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
2
2
  import camelCase from 'camelcase';
3
3
  import ts from 'typescript';
4
4
  import { createOperationCommonTSDoc } from '../lib/createOperationCommonTSDoc.js';
5
+ import { filterUnusedTypes } from './filterUnusedTypes.js';
5
6
  import { createServiceOperationCancelQueriesNodes } from './service-operation.generated/ServiceOperationCancelQueries.js';
6
7
  import { createServiceOperationFetchInfiniteQueryNodes } from './service-operation.generated/ServiceOperationFetchInfiniteQuery.js';
7
8
  import { createServiceOperationFetchQueryNodes } from './service-operation.generated/ServiceOperationFetchQuery.js';
@@ -45,13 +46,20 @@ export const getServiceFactory = (
45
46
  operations: ServiceOperation[],
46
47
  { openapiTypesImportPath }: ServiceImportsFactoryOptions
47
48
  ) => {
48
- return [
49
- getOpenAPISchemaImportsFactory(openapiTypesImportPath),
50
- ...getServiceOperationImportsFactory(operations),
49
+ const mainNodes = [
51
50
  getServiceInterfaceFactory(service, operations),
52
51
  getServiceVariableFactory(service, operations),
53
52
  ...getOperationsTypes(operations),
54
53
  ];
54
+
55
+ const importNodes = [
56
+ getOpenAPISchemaImportsFactory(openapiTypesImportPath),
57
+ ...getServiceOperationImportsFactory(
58
+ filterUnusedTypes(getModuleTypeImports(operations), mainNodes)
59
+ ),
60
+ ];
61
+
62
+ return [...importNodes, ...mainNodes];
55
63
  };
56
64
 
57
65
  const getOpenAPISchemaImportsFactory = (schemaTypesPath: string) => {
@@ -74,18 +82,11 @@ const getOpenAPISchemaImportsFactory = (schemaTypesPath: string) => {
74
82
  );
75
83
  };
76
84
 
77
- const getServiceOperationImportsFactory = (operations: ServiceOperation[]) => {
85
+ const getServiceOperationImportsFactory = (
86
+ moduleImports: Record<string, string[]>
87
+ ) => {
78
88
  const factory = ts.factory;
79
89
 
80
- const moduleImports = getModuleTypeImports([
81
- ...(operations.some((operation) => operation.method === 'get')
82
- ? createServicesQueryOperationNodes()
83
- : []),
84
- ...(operations.some((operation) => operation.method !== 'get')
85
- ? createServicesMutationOperationNodes()
86
- : []),
87
- ]);
88
-
89
90
  return Object.entries(moduleImports).map(
90
91
  ([moduleName, importSpecifierNames]) => {
91
92
  return factory.createImportDeclaration(
@@ -266,13 +267,17 @@ const getOperationSchemaFactory = (operation: ServiceOperation) => {
266
267
  )
267
268
  ),
268
269
 
269
- operation.mediaType
270
+ operation.requestBody
270
271
  ? factory.createPropertySignature(
271
272
  undefined,
272
273
  factory.createIdentifier('mediaType'),
273
274
  undefined,
274
- factory.createLiteralTypeNode(
275
- factory.createStringLiteral(operation.mediaType)
275
+ factory.createTupleTypeNode(
276
+ Object.keys(operation.requestBody.content).map((mediaType) =>
277
+ factory.createLiteralTypeNode(
278
+ factory.createStringLiteral(mediaType)
279
+ )
280
+ )
276
281
  )
277
282
  )
278
283
  : null,
@@ -348,39 +353,49 @@ const getOperationResponseFactory = (
348
353
  };
349
354
 
350
355
  const getOperationBodyFactory = (operation: ServiceOperation) => {
351
- if (!operation.mediaType)
356
+ if (!operation.requestBody)
352
357
  return factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
353
358
 
354
- return factory.createIndexedAccessTypeNode(
355
- factory.createIndexedAccessTypeNode(
356
- factory.createTypeReferenceNode(factory.createIdentifier('NonNullable'), [
359
+ const mediaTypes = Object.keys(operation.requestBody.content);
360
+
361
+ return factory.createUnionTypeNode([
362
+ ...mediaTypes.map((mediaType) =>
363
+ factory.createIndexedAccessTypeNode(
357
364
  factory.createIndexedAccessTypeNode(
358
- factory.createIndexedAccessTypeNode(
359
- factory.createIndexedAccessTypeNode(
360
- factory.createTypeReferenceNode(
361
- factory.createIdentifier('paths'),
362
- undefined
365
+ factory.createTypeReferenceNode(
366
+ factory.createIdentifier('NonNullable'),
367
+ [
368
+ factory.createIndexedAccessTypeNode(
369
+ factory.createIndexedAccessTypeNode(
370
+ factory.createIndexedAccessTypeNode(
371
+ factory.createTypeReferenceNode(
372
+ factory.createIdentifier('paths'),
373
+ undefined
374
+ ),
375
+ factory.createLiteralTypeNode(
376
+ factory.createStringLiteral(operation.path)
377
+ )
378
+ ),
379
+ factory.createLiteralTypeNode(
380
+ factory.createStringLiteral(operation.method)
381
+ )
382
+ ),
383
+ factory.createLiteralTypeNode(
384
+ factory.createStringLiteral('requestBody')
385
+ )
363
386
  ),
364
- factory.createLiteralTypeNode(
365
- factory.createStringLiteral(operation.path)
366
- )
367
- ),
368
- factory.createLiteralTypeNode(
369
- factory.createStringLiteral(operation.method)
370
- )
387
+ ]
371
388
  ),
372
- factory.createLiteralTypeNode(
373
- factory.createStringLiteral('requestBody')
374
- )
389
+ // todo::Add optional NonNullable inference, see `POST /entities/{entity_id}/documents`
390
+ factory.createLiteralTypeNode(factory.createStringLiteral('content'))
375
391
  ),
376
- ]),
377
- // todo::Add optional NonNullable inference, see `POST /entities/{entity_id}/documents`
378
- factory.createLiteralTypeNode(factory.createStringLiteral('content'))
392
+ factory.createLiteralTypeNode(factory.createStringLiteral(mediaType))
393
+ )
379
394
  ),
380
- factory.createLiteralTypeNode(
381
- factory.createStringLiteral(operation.mediaType)
382
- )
383
- );
395
+ ...(mediaTypes.some((mediaType) => mediaType.includes('/form-data'))
396
+ ? [factory.createTypeReferenceNode(factory.createIdentifier('FormData'))]
397
+ : []),
398
+ ]);
384
399
  };
385
400
 
386
401
  const createOperationParametersFactory = (operation: ServiceOperation) => {
@@ -532,10 +547,14 @@ const getServiceVariablePropertyFactory = (operation: ServiceOperation) => {
532
547
  factory.createIdentifier('url'),
533
548
  factory.createStringLiteral(operation.path)
534
549
  ),
535
- operation.mediaType
550
+ operation.requestBody
536
551
  ? factory.createPropertyAssignment(
537
552
  factory.createIdentifier('mediaType'),
538
- factory.createStringLiteral(operation.mediaType)
553
+ factory.createArrayLiteralExpression(
554
+ Object.keys(operation.requestBody.content).map(
555
+ (mediaType) => factory.createStringLiteral(mediaType)
556
+ )
557
+ )
539
558
  )
540
559
  : null,
541
560
 
@@ -644,25 +663,36 @@ const getMethodSignatureNodes = (
644
663
  );
645
664
  };
646
665
 
647
- const getModuleTypeImports = (nodes: ts.Node[]) => {
666
+ /**
667
+ * Returns a list of all the modules that are imported by the operations.
668
+ * @param operations
669
+ * @returns Record<moduleName, importSpecifierNames[]>
670
+ */
671
+ const getModuleTypeImports = (operations: ServiceOperation[]) => {
672
+ const nodes = [
673
+ ...(operations.some((operation) => operation.method === 'get')
674
+ ? createServicesQueryOperationNodes()
675
+ : []),
676
+ ...(operations.some((operation) => operation.method !== 'get')
677
+ ? createServicesMutationOperationNodes()
678
+ : []),
679
+ ];
680
+
648
681
  return nodes
649
- .map((node) => {
650
- const foo =
651
- ts.isImportDeclaration(node) &&
652
- ts.isStringLiteral(node.moduleSpecifier) &&
653
- node.importClause?.isTypeOnly &&
654
- node.importClause.namedBindings &&
655
- ts.isNamedImports(node.importClause.namedBindings)
656
- ? {
657
- module: node.moduleSpecifier.text,
658
- imports: node.importClause.namedBindings.elements
659
- .filter(ts.isImportSpecifier)
660
- .map((specifier) => specifier.name.text),
661
- }
662
- : undefined;
663
-
664
- return foo;
665
- })
682
+ .map((node) =>
683
+ ts.isImportDeclaration(node) &&
684
+ ts.isStringLiteral(node.moduleSpecifier) &&
685
+ node.importClause?.isTypeOnly &&
686
+ node.importClause.namedBindings &&
687
+ ts.isNamedImports(node.importClause.namedBindings)
688
+ ? {
689
+ module: node.moduleSpecifier.text,
690
+ imports: node.importClause.namedBindings.elements
691
+ .filter(ts.isImportSpecifier)
692
+ .map((specifier) => specifier.name.text),
693
+ }
694
+ : undefined
695
+ )
666
696
  .reduce<Record<string, string[]>>((acc, item) => {
667
697
  if (!item) return acc;
668
698
  if (!acc[item.module])
@@ -672,6 +702,8 @@ const getModuleTypeImports = (nodes: ts.Node[]) => {
672
702
  arrayFilterUniqueCallback
673
703
  );
674
704
 
705
+ acc[item.module].sort();
706
+
675
707
  return acc;
676
708
  }, {});
677
709
  };
@@ -747,13 +779,10 @@ function reduceAreAllOptionalConditionalTParamsType<T extends ts.Node>(
747
779
  );
748
780
  })
749
781
  ) {
750
- if (
751
- !operation.parameters?.length ||
752
- operation.parameters.every((parameter) => !parameter.required)
753
- ) {
754
- return node.trueType;
755
- } else {
782
+ if (operation.parameters?.some((parameter) => parameter.required)) {
756
783
  return node.falseType;
784
+ } else {
785
+ return node.trueType;
757
786
  }
758
787
  }
759
788
  return ts.visitEachChild(node, visit, context);
@@ -1,10 +1,10 @@
1
- import { Service } from '@openapi-qraft/plugin/lib/open-api/getServices';
1
+ import { OpenAPIService } from '@openapi-qraft/plugin/lib/open-api/OpenAPIService';
2
2
  import ts from 'typescript';
3
3
 
4
- type Options = { explicitImportExtensions: boolean };
4
+ type Options = { explicitImportExtensions: '.js' | '.ts' | undefined };
5
5
 
6
6
  export const getServiceIndexFactory = (
7
- services: Service[],
7
+ services: OpenAPIService[],
8
8
  options: Options
9
9
  ) => {
10
10
  return [
@@ -14,7 +14,7 @@ export const getServiceIndexFactory = (
14
14
  ];
15
15
  };
16
16
 
17
- const getServiceIndexInterfaceFactory = (services: Service[]) => {
17
+ const getServiceIndexInterfaceFactory = (services: OpenAPIService[]) => {
18
18
  const factory = ts.factory;
19
19
 
20
20
  return factory.createTypeAliasDeclaration(
@@ -37,7 +37,7 @@ const getServiceIndexInterfaceFactory = (services: Service[]) => {
37
37
  );
38
38
  };
39
39
 
40
- const getServiceIndexVariableFactory = (services: Service[]) => {
40
+ const getServiceIndexVariableFactory = (services: OpenAPIService[]) => {
41
41
  const factory = ts.factory;
42
42
 
43
43
  return factory.createVariableStatement(
@@ -71,7 +71,7 @@ const getServiceIndexVariableFactory = (services: Service[]) => {
71
71
  };
72
72
 
73
73
  const getServicesImportsFactory = (
74
- services: Service[],
74
+ services: OpenAPIService[],
75
75
  { explicitImportExtensions }: Options
76
76
  ) => {
77
77
  const factory = ts.factory;
@@ -96,7 +96,7 @@ const getServicesImportsFactory = (
96
96
  ])
97
97
  ),
98
98
  factory.createStringLiteral(
99
- `./${fileBaseName}${explicitImportExtensions ? '.js' : ''}`
99
+ `./${fileBaseName}${explicitImportExtensions ?? ''}`
100
100
  )
101
101
  )
102
102
  );