@buildvision/nest-sdk-generator 2.3.0 → 3.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 (94) hide show
  1. package/.eslintrc.js +1 -1
  2. package/.github/workflows/test.yml +35 -0
  3. package/README.md +402 -239
  4. package/build/analyzer/classdeps.js +36 -4
  5. package/build/analyzer/controller.d.ts +2 -14
  6. package/build/analyzer/controller.js +38 -18
  7. package/build/analyzer/controllers.d.ts +2 -2
  8. package/build/analyzer/controllers.js +37 -5
  9. package/build/analyzer/extractor.d.ts +2 -41
  10. package/build/analyzer/extractor.js +63 -66
  11. package/build/analyzer/index.d.ts +2 -6
  12. package/build/analyzer/index.js +107 -86
  13. package/build/analyzer/methods.d.ts +2 -30
  14. package/build/analyzer/methods.js +7 -16
  15. package/build/analyzer/module.js +36 -4
  16. package/build/analyzer/params.d.ts +3 -39
  17. package/build/analyzer/params.js +17 -37
  18. package/build/analyzer/route.js +8 -9
  19. package/build/analyzer/sdk.d.ts +146 -0
  20. package/build/analyzer/sdk.js +120 -0
  21. package/build/analyzer/typedeps.d.ts +15 -0
  22. package/build/analyzer/typedeps.js +62 -10
  23. package/build/bin.js +72 -25
  24. package/build/config.d.ts +13 -0
  25. package/build/config.js +36 -3
  26. package/build/engine/analyze.d.ts +16 -0
  27. package/build/engine/analyze.js +786 -0
  28. package/build/engine/ast.d.ts +24 -0
  29. package/build/engine/ast.js +100 -0
  30. package/build/engine/file-order.d.ts +17 -0
  31. package/build/engine/file-order.js +97 -0
  32. package/build/engine/host.d.ts +63 -0
  33. package/build/engine/host.js +16 -0
  34. package/build/engine/index.d.ts +15 -0
  35. package/build/engine/index.js +93 -0
  36. package/build/engine/ts-morph-compat-host.d.ts +8 -0
  37. package/build/engine/ts-morph-compat-host.js +18 -0
  38. package/build/engine/tsgo-host.d.ts +9 -0
  39. package/build/engine/tsgo-host.js +136 -0
  40. package/build/engine/typescript-host.d.ts +26 -0
  41. package/build/engine/typescript-host.js +142 -0
  42. package/build/generator/genmodules.d.ts +1 -4
  43. package/build/generator/genmodules.js +23 -27
  44. package/build/generator/gentypes.d.ts +1 -1
  45. package/build/generator/gentypes.js +36 -4
  46. package/build/generator/index.d.ts +1 -1
  47. package/build/generator/index.js +91 -69
  48. package/build/generator/prettier.js +43 -9
  49. package/build/generator/sdk-interface.d.ts +1 -1
  50. package/build/generator/sdk-interface.js +5 -5
  51. package/build/logging.d.ts +3 -0
  52. package/build/logging.js +17 -10
  53. package/build/rtk-query-generator/genmodules.d.ts +1 -4
  54. package/build/rtk-query-generator/genmodules.js +31 -33
  55. package/build/rtk-query-generator/index.d.ts +1 -1
  56. package/build/rtk-query-generator/index.js +87 -72
  57. package/build/rtk-query-generator/prettier.js +43 -9
  58. package/build/rtk-query-generator/sdk-interface.js +3 -4
  59. package/build/utils.js +38 -6
  60. package/package.json +29 -11
  61. package/src/analyzer/controller.ts +3 -31
  62. package/src/analyzer/controllers.ts +3 -2
  63. package/src/analyzer/extractor.ts +17 -86
  64. package/src/analyzer/index.ts +5 -11
  65. package/src/analyzer/methods.ts +5 -36
  66. package/src/analyzer/params.ts +13 -55
  67. package/src/analyzer/sdk.ts +247 -0
  68. package/src/analyzer/typedeps.ts +22 -4
  69. package/src/bin.ts +31 -6
  70. package/src/config.ts +15 -0
  71. package/src/engine/analyze.ts +1110 -0
  72. package/src/engine/ast.ts +105 -0
  73. package/src/engine/file-order.ts +104 -0
  74. package/src/engine/host.ts +79 -0
  75. package/src/engine/index.ts +79 -0
  76. package/src/engine/ts-morph-compat-host.ts +20 -0
  77. package/src/engine/tsgo-host.ts +119 -0
  78. package/src/engine/typescript-host.ts +159 -0
  79. package/src/generator/genmodules.ts +9 -4
  80. package/src/generator/gentypes.ts +1 -1
  81. package/src/generator/index.ts +1 -1
  82. package/src/logging.ts +10 -1
  83. package/src/rtk-query-generator/genmodules.ts +17 -9
  84. package/src/rtk-query-generator/index.ts +2 -12
  85. package/src/rtk-query-generator/sdk-interface.ts +2 -3
  86. package/tsconfig.json +7 -6
  87. package/build/analyzer/decorator.d.ts +0 -10
  88. package/build/analyzer/decorator.js +0 -29
  89. package/build/rtk-query-generator/gentypes.d.ts +0 -10
  90. package/build/rtk-query-generator/gentypes.js +0 -62
  91. package/build/tsconfig.tsbuildinfo +0 -1
  92. package/bun.lockb +0 -0
  93. package/src/rtk-query-generator/gentypes.ts +0 -74
  94. package/tsconfig.tsbuildinfo +0 -1
package/build/utils.js CHANGED
@@ -1,8 +1,42 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findFilesRecursive = exports.findFileAbove = void 0;
4
- const fs = require("fs");
5
- const path = require("path");
36
+ exports.findFileAbove = findFileAbove;
37
+ exports.findFilesRecursive = findFilesRecursive;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
6
40
  function findFileAbove(pattern, dir) {
7
41
  if (!path.isAbsolute(dir)) {
8
42
  // Get an absolute path to allow getting its parent using path.dirname()
@@ -27,7 +61,6 @@ function findFileAbove(pattern, dir) {
27
61
  // Success!
28
62
  return path.resolve(dir, items[0]);
29
63
  }
30
- exports.findFileAbove = findFileAbove;
31
64
  /**
32
65
  * Find all files matching a pattern, recursively
33
66
  * @param pattern The pattern to look for
@@ -52,5 +85,4 @@ function findFilesRecursive(pattern, dir, relative = true) {
52
85
  }
53
86
  return find(pattern, dir, dir);
54
87
  }
55
- exports.findFilesRecursive = findFilesRecursive;
56
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUJBQXdCO0FBQ3hCLDZCQUE0QjtBQUU1QixTQUFnQixhQUFhLENBQUMsT0FBd0IsRUFBRSxHQUFXO0lBQ2pFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDMUIsd0VBQXdFO1FBQ3hFLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUN4QyxDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLHVGQUF1RjtJQUN2Riw4QkFBOEI7SUFDOUIsNEdBQTRHO0lBQzVHLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQTtJQUVqQixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUE7SUFFZCx3Q0FBd0M7SUFDeEMsT0FBTyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN4SSxtQ0FBbUM7UUFDbkMsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7UUFFdkIseUZBQXlGO1FBQ3pGLElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzVCLE9BQU8sSUFBSSxDQUFBO1FBQ2IsQ0FBQztRQUVELE9BQU8sR0FBRyxHQUFHLENBQUE7SUFDZixDQUFDO0lBRUQsV0FBVztJQUNYLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDcEMsQ0FBQztBQTdCRCxzQ0E2QkM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxPQUF3QixFQUFFLEdBQVcsRUFBRSxRQUFRLEdBQUcsSUFBSTtJQUN2RixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUE7SUFFekIsU0FBUyxJQUFJLENBQUMsT0FBd0IsRUFBRSxPQUFlLEVBQUUsT0FBZTtRQUN0RSxPQUFPLEVBQUU7YUFDTixXQUFXLENBQUMsT0FBTyxDQUFDO2FBQ3BCLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ1osTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFFNUMsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVcsRUFBRTtnQkFDekMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUMsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNyRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7b0JBQ2xGLENBQUMsQ0FBQyxFQUFFLENBQUE7UUFDVixDQUFDLENBQUM7YUFDRCxJQUFJLEVBQUUsQ0FBQTtJQUNYLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0FBQ2hDLENBQUM7QUFuQkQsZ0RBbUJDIn0=
88
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE1BQVksRUFBRSwrQkFBVTtBQUN4QixNQUFZLElBQUksaUNBQVk7QUFFNUIsdUJBQThCLE9BQXdCLEVBQUUsR0FBVztJQUNqRSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzFCLHdFQUF3RTtRQUN4RSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDeEMsQ0FBQztJQUVELHlCQUF5QjtJQUN6Qix1RkFBdUY7SUFDdkYsOEJBQThCO0lBQzlCLDRHQUE0RztJQUM1RyxJQUFJLE9BQU8sR0FBRyxHQUFHLENBQUE7SUFFakIsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFBO0lBRWQsd0NBQXdDO0lBQ3hDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxZQUFZLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEksbUNBQW1DO1FBQ25DLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBRXZCLHlGQUF5RjtRQUN6RixJQUFJLENBQUMsR0FBRyxJQUFJLE9BQU8sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUM1QixPQUFPLElBQUksQ0FBQTtRQUNiLENBQUM7UUFFRCxPQUFPLEdBQUcsR0FBRyxDQUFBO0lBQ2YsQ0FBQztJQUVELFdBQVc7SUFDWCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ3BDLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCw0QkFBbUMsT0FBd0IsRUFBRSxHQUFXLEVBQUUsUUFBUSxHQUFHLElBQUk7SUFDdkYsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBRXpCLFNBQVMsSUFBSSxDQUFDLE9BQXdCLEVBQUUsT0FBZSxFQUFFLE9BQWU7UUFDdEUsT0FBTyxFQUFFO2FBQ04sV0FBVyxDQUFDLE9BQU8sQ0FBQzthQUNwQixHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNaLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFBO1lBRTVDLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxXQUFXLEVBQUU7Z0JBQ3pDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUM7Z0JBQ2xDLENBQUMsQ0FBQyxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDckUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUNsRixDQUFDLENBQUMsRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDO2FBQ0QsSUFBSSxFQUFFLENBQUE7SUFDWCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUNoQyxDQUFDIn0=
package/package.json CHANGED
@@ -1,36 +1,51 @@
1
1
  {
2
2
  "name": "@buildvision/nest-sdk-generator",
3
3
  "author": "BuildVision <christophe@buildvision.io>",
4
- "version": "2.3.0",
5
- "description": "A full-powered SDK generator for NestJS",
4
+ "version": "3.0.0",
5
+ "description": "Generate fully-typed RTK Query API clients from NestJS controllers",
6
6
  "keywords": [
7
7
  "nest",
8
8
  "nestjs",
9
+ "rtk-query",
10
+ "redux-toolkit",
11
+ "redux",
12
+ "react",
13
+ "api-client",
9
14
  "sdk",
10
15
  "generator",
11
- "typescript",
12
- "frontend",
13
- "api"
16
+ "typescript"
14
17
  ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/build-vision/nest-sdk-generator.git"
21
+ },
22
+ "homepage": "https://github.com/build-vision/nest-sdk-generator#readme",
23
+ "bugs": {
24
+ "url": "https://github.com/build-vision/nest-sdk-generator/issues"
25
+ },
15
26
  "main": "build/bin.js",
16
27
  "scripts": {
17
28
  "prepare": "npm run build",
18
- "build": "tsc -p tsconfig.json --outDir build",
29
+ "build": "rm -rf build && node node_modules/typescript/bin/tsc -p tsconfig.json --outDir build",
30
+ "build:baseline": "./scripts/build-baseline.sh",
19
31
  "start": "npm run build && node build/bin.js",
20
- "typecheck": "bun tsc --project tsconfig.json --noEmit",
21
- "lint": "bun eslint --quiet . --fix"
32
+ "test": "npm run build && node --test 'test/*.test.mjs'",
33
+ "typecheck": "node node_modules/typescript/bin/tsc --project tsconfig.json --noEmit",
34
+ "lint": "node --require ./scripts/eslint-with-typescript-6.cjs node_modules/eslint/bin/eslint.js --quiet . --fix"
22
35
  },
23
36
  "bin": "build/bin.js",
24
37
  "dependencies": {
25
38
  "chalk": "~4.1.2",
26
39
  "minimist": "~1.2.7",
27
40
  "prettier": "^3.2.5",
28
- "ts-morph": "~16.0.0"
41
+ "ts-morph": "~16.0.0",
42
+ "typescript": "7.0.2"
29
43
  },
30
44
  "devDependencies": {
45
+ "@reduxjs/toolkit": "^2.13.0",
31
46
  "@types/minimist": "^1.2.2",
32
47
  "@types/node": "~18.11.9",
33
- "typescript": "^5.2.2",
48
+ "@types/react": "^19.3.0",
34
49
  "@typescript-eslint/eslint-plugin": "^6.13.2",
35
50
  "@typescript-eslint/parser": "^6.13.2",
36
51
  "eslint": "^8.50.0",
@@ -40,6 +55,9 @@
40
55
  "eslint-plugin-import": "^2.27.5",
41
56
  "eslint-plugin-prettier": "^5.0.0",
42
57
  "eslint-plugin-sort-destructure-keys": "^1.5.0",
43
- "eslint-plugin-typescript-sort-keys": "^3.1.0"
58
+ "eslint-plugin-typescript-sort-keys": "^3.1.0",
59
+ "react": "^19.3.0",
60
+ "react-redux": "^9.3.0",
61
+ "typescript-6": "npm:typescript@6.0.3"
44
62
  }
45
63
  }
@@ -8,38 +8,10 @@ import { Node, Project } from 'ts-morph'
8
8
 
9
9
  import { debug, warn } from '../logging'
10
10
 
11
- import { analyzeMethods, SdkMethod } from './methods'
11
+ import { analyzeMethods } from './methods'
12
+ import { camelcase, SdkController } from './sdk'
12
13
 
13
- /**
14
- * Convert a string to camel case
15
- * @param str
16
- */
17
- function camelcase(str: string): string {
18
- return str
19
- .split(/[^a-zA-Z0-9_]/g)
20
- .map((p, i) => {
21
- const f = p.substr(0, 1)
22
- return (i === 0 ? f.toLocaleLowerCase() : f.toLocaleUpperCase()) + p.substr(1)
23
- })
24
- .join('')
25
- }
26
-
27
- /**
28
- * SDK interface of a controller
29
- */
30
- export interface SdkController {
31
- /** Name of the controller's class, camel cased */
32
- readonly className: string
33
-
34
- /** Controller's methods */
35
- readonly methods: SdkMethod[]
36
-
37
- /** Original controller file's path */
38
- readonly path: string
39
-
40
- /** Name the controller is registered under */
41
- readonly registrationName: string
42
- }
14
+ export { SdkController }
43
15
 
44
16
  /**
45
17
  * Generate a SDK interface for a controller
@@ -10,10 +10,11 @@ import { Project } from 'ts-morph'
10
10
  import { debug, format, panic, warn } from '../logging'
11
11
  import { findFileAbove } from '../utils'
12
12
 
13
- import { analyzeController, SdkController } from './controller'
13
+ import { analyzeController } from './controller'
14
14
  import { getModuleName } from './module'
15
+ import { SdkController, SdkModules } from './sdk'
15
16
 
16
- export type SdkModules = Map<string, Map<string, SdkController>>
17
+ export { SdkModules }
17
18
 
18
19
  export function analyzeControllers(controllers: string[], absoluteSrcPath: string, project: Project): SdkModules {
19
20
  /** Hierarchised SDK informations */
@@ -10,45 +10,27 @@ import { MagicType } from '../config'
10
10
  import { debug, format, panic, unreachable, warn } from '../logging'
11
11
 
12
12
  import { analyzeClassDeps } from './classdeps'
13
- import { SdkModules } from './controllers'
14
- import { getParamResolvedTypes } from './params'
13
+ import {
14
+ ExtractedType,
15
+ flattenSdkResolvedTypes,
16
+ locateTypesFile,
17
+ MODULE_EXTENSIONS,
18
+ TypeLocation,
19
+ TypeLocationWithExt,
20
+ TypesExtractorContent,
21
+ } from './sdk'
15
22
  import { getImportResolvedType, ResolvedTypeDeps, resolveTypeDependencies } from './typedeps'
16
23
 
17
- /** Valid extensions for TypeScript module files */
18
- export const MODULE_EXTENSIONS = ['.ts', '.d.ts', '.tsx', '.d.tsx', '.js', '.jsx']
19
-
20
- /**
21
- * Location of an imported type
22
- */
23
- export interface TypeLocation {
24
- readonly relativePathNoExt: string
25
- readonly typename: string
24
+ export {
25
+ ExtractedType,
26
+ flattenSdkResolvedTypes,
27
+ locateTypesFile,
28
+ MODULE_EXTENSIONS,
29
+ TypeLocation,
30
+ TypeLocationWithExt,
31
+ TypesExtractorContent,
26
32
  }
27
33
 
28
- /**
29
- * Location of an imported type after figuring out its extension
30
- */
31
- export interface TypeLocationWithExt extends TypeLocation {
32
- readonly relativePath: string
33
- }
34
-
35
- /**
36
- * Extracted imported type
37
- */
38
- export interface ExtractedType extends TypeLocationWithExt {
39
- /** Type's declaration */
40
- readonly content: string
41
-
42
- /** Types this one depends on */
43
- readonly dependencies: TypeLocationWithExt[]
44
-
45
- /** Type parameters (e.g. <T>) */
46
- readonly typeParams: string[]
47
- }
48
-
49
- // Maps files to records mapping themselves type names to their declaration code
50
- export type TypesExtractorContent = Map<string, Map<string, ExtractedType>>
51
-
52
34
  /**
53
35
  * Types extractor
54
36
  */
@@ -427,54 +409,3 @@ export class TypesExtractor {
427
409
  return extracted
428
410
  }
429
411
  }
430
-
431
- /**
432
- * Locate the files containing a list of a resolved types
433
- * @param resolvedTypes
434
- * @returns
435
- */
436
- export function locateTypesFile(resolvedTypes: Array<ResolvedTypeDeps>): TypeLocation[] {
437
- const out = new Array<TypeLocation>()
438
-
439
- for (const resolved of resolvedTypes) {
440
- for (const [file, types] of resolved.dependencies) {
441
- for (const typename of types) {
442
- if (!out.find((loc) => loc.typename === typename && loc.relativePathNoExt === file)) {
443
- out.push({ typename, relativePathNoExt: file })
444
- }
445
- }
446
- }
447
-
448
- for (const typename of resolved.localTypes) {
449
- if (!out.find((loc) => loc.typename === typename && loc.relativePathNoExt === resolved.relativeFilePath)) {
450
- out.push({ typename, relativePathNoExt: resolved.relativeFilePath })
451
- }
452
- }
453
- }
454
-
455
- return out
456
- }
457
-
458
- /**
459
- * Flatten a tree of resolved type dependencies
460
- * @param sdkModules
461
- * @returns
462
- */
463
- export function flattenSdkResolvedTypes(sdkModules: SdkModules): ResolvedTypeDeps[] {
464
- const flattened = new Array<ResolvedTypeDeps>()
465
-
466
- for (const module of sdkModules.values()) {
467
- for (const controller of module.values()) {
468
- for (const method of controller.methods.values()) {
469
- const { bodyParams, queryParams, routeParams } = method.params
470
-
471
- flattened.push(method.returnType)
472
- flattened.push(...getParamResolvedTypes(routeParams))
473
- flattened.push(...getParamResolvedTypes(queryParams))
474
- flattened.push(...getParamResolvedTypes(bodyParams))
475
- }
476
- }
477
- }
478
-
479
- return flattened
480
- }
@@ -11,13 +11,11 @@ import { Config } from '../config'
11
11
  import { debug, panic } from '../logging'
12
12
 
13
13
  import { builtinMagicTypes } from './builtin'
14
- import { analyzeControllers, SdkModules } from './controllers'
15
- import { flattenSdkResolvedTypes, locateTypesFile, TypesExtractor, TypesExtractorContent } from './extractor'
14
+ import { analyzeControllers } from './controllers'
15
+ import { TypesExtractor } from './extractor'
16
+ import { flattenSdkResolvedTypes, locateTypesFile, SdkContent, serializeSdkContent } from './sdk'
16
17
 
17
- export interface SdkContent {
18
- readonly modules: SdkModules
19
- readonly types: TypesExtractorContent
20
- }
18
+ export { SdkContent }
21
19
 
22
20
  export interface MagicType {
23
21
  readonly content: string
@@ -126,11 +124,7 @@ export async function analyzerCli(config: Config): Promise<SdkContent> {
126
124
  }
127
125
 
128
126
  if (config.jsonOutput) {
129
- fs.writeFileSync(
130
- config.jsonOutput,
131
- JSON.stringify(content, (_, v) => (v instanceof Map ? Object.fromEntries(v) : v), config.jsonPrettyOutput ? 4 : 0),
132
- 'utf8'
133
- )
127
+ fs.writeFileSync(config.jsonOutput, serializeSdkContent(content, !!config.jsonPrettyOutput), 'utf8')
134
128
  }
135
129
 
136
130
  debug('\n===== Done in {green}! ====', ((Date.now() - started) / 1000).toFixed(2) + 's')
@@ -7,43 +7,12 @@ import { ClassDeclaration, MethodDeclaration, Node } from 'ts-morph'
7
7
 
8
8
  import { debug, format } from '../logging'
9
9
 
10
- import { extractParams, SdkMethodParams } from './params'
11
- import { analyzeUri, debugUri, Route } from './route'
12
- import { ResolvedTypeDeps, resolveTypeDependencies } from './typedeps'
10
+ import { extractParams } from './params'
11
+ import { analyzeUri, debugUri } from './route'
12
+ import { SdkHttpMethod, SdkMethod } from './sdk'
13
+ import { resolveTypeDependencies } from './typedeps'
13
14
 
14
- /**
15
- * SDK interface for a single controller's method
16
- */
17
- export interface SdkMethod {
18
- /** Method's HTTP method (e.g. GET / POST) */
19
- readonly httpMethod: SdkHttpMethod
20
-
21
- /** Method's name */
22
- readonly name: string
23
-
24
- /** Method's parameters */
25
- readonly params: SdkMethodParams
26
-
27
- /** Method's return type with resolved dependencies */
28
- readonly returnType: ResolvedTypeDeps
29
-
30
- /** Method's parsed route */
31
- readonly route: Route
32
-
33
- /** Method's URI path */
34
- readonly uriPath: string
35
- }
36
-
37
- /**
38
- * HTTP method of a controller's method
39
- */
40
- export enum SdkHttpMethod {
41
- Delete = 'DELETE',
42
- Get = 'GET',
43
- Patch = 'PATCH',
44
- Post = 'POST',
45
- Put = 'PUT',
46
- }
15
+ export { SdkHttpMethod, SdkMethod }
47
16
 
48
17
  /**
49
18
  * Generate a SDK interface for a controller
@@ -6,61 +6,25 @@ import { ClassDeclaration, Decorator, MethodDeclaration, Node, ParameterDeclarat
6
6
 
7
7
  import { debug, panic } from '../logging'
8
8
 
9
- import { SdkHttpMethod } from './methods'
10
9
  import { paramsFromRoute, Route } from './route'
11
- import { ResolvedTypeDeps, resolveTypeDependencies } from './typedeps'
12
-
13
- /**
14
- * Type of a parameter that must be passed to an SDK method: Body, Query or Route Param
15
- * Supports accessing parameters individually by key or as a whole object
16
- *
17
- * EXAMPLE
18
- *
19
- * Controller Method:
20
- *
21
- * getStuff(@Query('email') email: string, @Query('companyId'): CompanyId)
22
- *
23
- * SDK Method Param:
24
- * { email: string, companyId: CompanyId }
25
- *
26
- * OR
27
- *
28
- * Controller Method:
29
- * type EmailAndCompanyId = { email: string, companyId: CompanyId }
30
- * getStuff(@Query(): EmailAndCompanyId)
31
- *
32
- * SDK Method Param:
33
- * EmailAndCompanyId
34
- */
35
-
36
- export type SdkMethodParam = SdkMethodParamMap | ResolvedTypeDeps | null
37
- export type SdkMethodParamMap = { [key: string]: ResolvedTypeDeps }
38
-
39
- export const isParamResolvedType = (param: SdkMethodParam): param is ResolvedTypeDeps => {
40
- if (param === null) {
41
- return false
42
- }
43
- return 'rawType' in param && 'resolvedType' in param && 'relativeFilePath' in param && 'dependencies' in param && 'localTypes' in param
44
- }
45
-
46
- export const getParamResolvedTypes = (param: SdkMethodParam): ResolvedTypeDeps[] => {
47
- if (param === null) {
48
- return []
49
- }
50
- if (isParamResolvedType(param)) {
51
- return [param]
52
- }
53
- return Object.values(param)
54
- }
10
+ import {
11
+ ArgDecorator,
12
+ SdkMethodParams as BaseSdkMethodParams,
13
+ getParamResolvedTypes,
14
+ isParamResolvedType,
15
+ SdkHttpMethod,
16
+ SdkMethodParam,
17
+ SdkMethodParamMap,
18
+ } from './sdk'
19
+ import { resolveTypeDependencies } from './typedeps'
20
+
21
+ export { ArgDecorator, getParamResolvedTypes, isParamResolvedType, SdkMethodParam, SdkMethodParamMap }
55
22
 
56
23
  /**
57
24
  * SDK interface for a controller's method's parameters
58
25
  */
59
- export interface SdkMethodParams {
60
- bodyParams: SdkMethodParam
26
+ export interface SdkMethodParams extends BaseSdkMethodParams {
61
27
  context: MethodContext
62
- queryParams: SdkMethodParam
63
- routeParams: SdkMethodParam
64
28
  }
65
29
 
66
30
  export type MethodContext = {
@@ -72,12 +36,6 @@ export type MethodContext = {
72
36
  route: Route
73
37
  }
74
38
 
75
- export enum ArgDecorator {
76
- Body = 'Body',
77
- Param = 'Param',
78
- Query = 'Query',
79
- }
80
-
81
39
  export type DecoratedArg = {
82
40
  arg: ParameterDeclaration
83
41
  argParamKey: string | null