tspace-spear 1.2.7 → 1.2.9-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 (99) hide show
  1. package/README.md +347 -155
  2. package/dist/cli/generators/app/index.d.ts +1 -0
  3. package/dist/cli/generators/app/index.js +124 -0
  4. package/dist/cli/generators/app/index.js.map +1 -0
  5. package/dist/cli/generators/app/template.d.ts +1 -0
  6. package/dist/cli/generators/app/template.js +42 -0
  7. package/dist/cli/generators/app/template.js.map +1 -0
  8. package/dist/cli/generators/client/template.d.ts +1 -0
  9. package/dist/cli/generators/client/template.js +30 -0
  10. package/dist/cli/generators/client/template.js.map +1 -0
  11. package/dist/cli/generators/controller/index.d.ts +1 -0
  12. package/dist/cli/generators/controller/index.js +78 -0
  13. package/dist/cli/generators/controller/index.js.map +1 -0
  14. package/dist/cli/generators/controller/template.d.ts +1 -0
  15. package/dist/cli/generators/controller/template.js +108 -0
  16. package/dist/cli/generators/controller/template.js.map +1 -0
  17. package/dist/cli/generators/dto/index.d.ts +1 -0
  18. package/dist/cli/generators/dto/index.js +57 -0
  19. package/dist/cli/generators/dto/index.js.map +1 -0
  20. package/dist/cli/generators/dto/template.d.ts +1 -0
  21. package/dist/cli/generators/dto/template.js +32 -0
  22. package/dist/cli/generators/dto/template.js.map +1 -0
  23. package/dist/cli/generators/middleware/index.d.ts +1 -0
  24. package/dist/cli/generators/middleware/index.js +38 -0
  25. package/dist/cli/generators/middleware/index.js.map +1 -0
  26. package/dist/cli/generators/middleware/template.d.ts +1 -0
  27. package/dist/cli/generators/middleware/template.js +16 -0
  28. package/dist/cli/generators/middleware/template.js.map +1 -0
  29. package/dist/cli/generators/module/index.d.ts +1 -0
  30. package/dist/cli/generators/module/index.js +173 -0
  31. package/dist/cli/generators/module/index.js.map +1 -0
  32. package/dist/cli/generators/service/index.d.ts +1 -0
  33. package/dist/cli/generators/service/index.js +53 -0
  34. package/dist/cli/generators/service/index.js.map +1 -0
  35. package/dist/cli/generators/service/template.d.ts +1 -0
  36. package/dist/cli/generators/service/template.js +74 -0
  37. package/dist/cli/generators/service/template.js.map +1 -0
  38. package/dist/cli/generators/shared/index.d.ts +3 -0
  39. package/dist/cli/generators/shared/index.js +22 -0
  40. package/dist/cli/generators/shared/index.js.map +1 -0
  41. package/dist/cli/index.js +55 -96
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/lib/core/client/index.d.ts +13 -43
  44. package/dist/lib/core/client/index.js +70 -33
  45. package/dist/lib/core/client/index.js.map +1 -1
  46. package/dist/lib/core/client/types.d.ts +43 -0
  47. package/dist/lib/core/client/types.js +3 -0
  48. package/dist/lib/core/client/types.js.map +1 -0
  49. package/dist/lib/core/compiler/generator.d.ts +4 -6
  50. package/dist/lib/core/compiler/generator.js +190 -39
  51. package/dist/lib/core/compiler/generator.js.map +1 -1
  52. package/dist/lib/core/compiler/index.d.ts +2 -2
  53. package/dist/lib/core/compiler/index.js +2 -2
  54. package/dist/lib/core/compiler/index.js.map +1 -1
  55. package/dist/lib/core/compiler/pre-routes.d.ts +12 -130
  56. package/dist/lib/core/compiler/pre-routes.js +13 -35
  57. package/dist/lib/core/compiler/pre-routes.js.map +1 -1
  58. package/dist/lib/core/compiler/types.d.ts +25 -0
  59. package/dist/lib/core/decorators/context.d.ts +78 -8
  60. package/dist/lib/core/decorators/context.js +84 -9
  61. package/dist/lib/core/decorators/context.js.map +1 -1
  62. package/dist/lib/core/decorators/controller.js +2 -1
  63. package/dist/lib/core/decorators/controller.js.map +1 -1
  64. package/dist/lib/core/decorators/index.d.ts +1 -0
  65. package/dist/lib/core/decorators/index.js +1 -0
  66. package/dist/lib/core/decorators/index.js.map +1 -1
  67. package/dist/lib/core/decorators/methods.js +4 -3
  68. package/dist/lib/core/decorators/methods.js.map +1 -1
  69. package/dist/lib/core/decorators/middleware.d.ts +40 -2
  70. package/dist/lib/core/decorators/middleware.js +54 -9
  71. package/dist/lib/core/decorators/middleware.js.map +1 -1
  72. package/dist/lib/core/decorators/service.d.ts +28 -0
  73. package/dist/lib/core/decorators/service.js +36 -0
  74. package/dist/lib/core/decorators/service.js.map +1 -0
  75. package/dist/lib/core/decorators/statusCode.js +3 -1
  76. package/dist/lib/core/decorators/statusCode.js.map +1 -1
  77. package/dist/lib/core/decorators/swagger.js +4 -3
  78. package/dist/lib/core/decorators/swagger.js.map +1 -1
  79. package/dist/lib/core/exception/index.d.ts +68 -0
  80. package/dist/lib/core/exception/index.js +123 -0
  81. package/dist/lib/core/exception/index.js.map +1 -0
  82. package/dist/lib/core/metadata/index.d.ts +6 -0
  83. package/dist/lib/core/metadata/index.js +13 -0
  84. package/dist/lib/core/metadata/index.js.map +1 -0
  85. package/dist/lib/core/package/index.d.ts +11 -0
  86. package/dist/lib/core/package/index.js +42 -0
  87. package/dist/lib/core/package/index.js.map +1 -0
  88. package/dist/lib/core/server/fast-router.d.ts +2 -2
  89. package/dist/lib/core/server/fast-router.js +17 -3
  90. package/dist/lib/core/server/fast-router.js.map +1 -1
  91. package/dist/lib/core/server/index.d.ts +32 -5
  92. package/dist/lib/core/server/index.js +188 -45
  93. package/dist/lib/core/server/index.js.map +1 -1
  94. package/dist/lib/core/server/parser-factory.js +59 -10
  95. package/dist/lib/core/server/parser-factory.js.map +1 -1
  96. package/dist/lib/core/server/response.js +21 -1
  97. package/dist/lib/core/server/response.js.map +1 -1
  98. package/dist/lib/core/types/index.d.ts +42 -29
  99. package/package.json +15 -6
@@ -15,27 +15,51 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
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
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.ApiClient = void 0;
27
37
  let fetchFn = null;
28
- async function getFetch() {
38
+ const getFetch = async () => {
29
39
  if (fetchFn)
30
40
  return fetchFn;
31
- if (globalThis.fetch) {
32
- fetchFn = globalThis.fetch;
41
+ // Browser OR modern Node v18+ (preferred)
42
+ if (typeof globalThis.fetch === "function") {
43
+ fetchFn = globalThis.fetch.bind(globalThis);
33
44
  return fetchFn;
34
45
  }
46
+ // Legacy Node fallback
35
47
  const mod = await Promise.resolve().then(() => __importStar(require("node-fetch")));
36
48
  fetchFn = mod.default;
37
49
  return fetchFn;
38
- }
50
+ };
51
+ const isFormData = (value) => {
52
+ // In Node.js 18+ it is compatible with the browser implementation.
53
+ if (typeof globalThis.FormData !== "undefined") {
54
+ return value instanceof globalThis.FormData;
55
+ }
56
+ // In Node.js below 18-, FormData is not the same as in the browser
57
+ // using from pkg form-data
58
+ return (value != null &&
59
+ typeof value === "object" &&
60
+ typeof value.append === "function" &&
61
+ typeof value.getHeaders === "function");
62
+ };
39
63
  /**
40
64
  * Type-safe HTTP client built on top of the native Fetch API.
41
65
  *
@@ -67,7 +91,8 @@ async function getFetch() {
67
91
  * })
68
92
  *
69
93
  * // fully typed response
70
- * console.log(res.cats)
94
+ * if(res.ok)
95
+ * console.log(res.cats)
71
96
  * ```
72
97
  */
73
98
  class ApiClient {
@@ -92,50 +117,62 @@ class ApiClient {
92
117
  if (!fetchFn) {
93
118
  throw new Error("Fetch is not available. Use Node 18+ or polyfill.");
94
119
  }
120
+ let body = input?.body
121
+ ? JSON.stringify(input.body)
122
+ : undefined;
123
+ let headers = {
124
+ "Content-Type": "application/json",
125
+ };
126
+ const isFileUpload = isFormData(input?.body);
127
+ if (isFileUpload) {
128
+ body = input?.body;
129
+ headers = undefined;
130
+ }
95
131
  const res = await fetchFn(url, {
96
132
  method: method,
97
- headers: {
98
- "Content-Type": "application/json",
99
- },
100
- body: input?.body
101
- ? JSON.stringify(input.body)
102
- : undefined,
133
+ headers,
134
+ body
103
135
  });
104
136
  const contentType = res.headers.get("content-type");
105
137
  const isJson = contentType?.includes("application/json");
106
138
  const data = isJson
107
139
  ? await res.json()
108
140
  : await res.text();
109
- // if (!res.ok) {
110
- // throw new Error(
111
- // data?.message ||
112
- // data?.error ||
113
- // (typeof data === "string"
114
- // ? data
115
- // : `HTTP ${res.status}`),
116
- // );
117
- // }
118
141
  return {
119
142
  ok: res.ok,
143
+ headers: res.headers,
120
144
  status: res.status,
121
- data,
145
+ data: data,
122
146
  };
123
147
  }
124
- async get(path, input) {
148
+ async get(path, ...args) {
149
+ const input = args[0];
125
150
  return this.request("GET", path, input);
126
151
  }
127
- async post(path, input) {
152
+ async post(path, ...args) {
153
+ const input = args[0];
128
154
  return this.request("POST", path, input);
129
155
  }
130
- async put(path, input) {
156
+ async put(path, ...args) {
157
+ const input = args[0];
131
158
  return this.request("PUT", path, input);
132
159
  }
133
- async patch(path, input) {
160
+ async patch(path, ...args) {
161
+ const input = args[0];
134
162
  return this.request("PATCH", path, input);
135
163
  }
136
- async delete(path, input) {
164
+ async delete(path, ...args) {
165
+ const input = args[0];
137
166
  return this.request("DELETE", path, input);
138
167
  }
168
+ async upload(path, options) {
169
+ const { method = "POST", formdata } = options;
170
+ return this.request(method, path,
171
+ //@ts-ignore
172
+ {
173
+ body: formdata
174
+ });
175
+ }
139
176
  }
140
177
  exports.ApiClient = ApiClient;
141
178
  exports.default = ApiClient;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/core/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAI,OAAO,GAAwB,IAAI,CAAC;AAExC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IAC1B,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,0CAA0C;IAC1C,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC3C,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,uBAAuB;IACvB,MAAM,GAAG,GAAG,wDAAa,YAAY,GAAC,CAAC;IACvC,OAAO,GAAG,GAAG,CAAC,OAAkC,CAAC;IAEjD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAW,EAAE;IAE7C,mEAAmE;IACnE,IAAG,OAAO,UAAU,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC9C,OAAO,KAAK,YAAY,UAAU,CAAC,QAAQ,CAAC;IAC9C,CAAC;IAED,mEAAmE;IACnE,2BAA2B;IAC3B,OAAO,CACL,KAAK,IAAI,IAAI;QACb,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAQ,KAAa,CAAC,MAAM,KAAK,UAAU;QAC3C,OAAQ,KAAa,CAAC,UAAU,KAAK,UAAU,CAChD,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,SAAS;IAGL,OAAO,CAAS;IAExB,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,OAAO,CAInB,MAAe,EACf,IAAW,EACX,KAIC;QAWC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAI,IAAe,CAAA;QAGzC,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;YAClB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC/B,GAAG,GAAG,GAAG,CAAC,OAAO,CACf,IAAI,GAAG,EAAE,EACT,kBAAkB,CAAE,KAAK,CAAC,MAAc,CAAC,GAAG,CAAC,CAAC,CAC/C,CAAA;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC;YACjB,MAAM,WAAW,GAAG,IAAI,eAAe,CACrC,KAAK,CAAC,KAAY,CACnB,CAAC,QAAQ,EAAE,CAAA;YAEZ,IAAI,WAAW,EAAE,CAAC;gBAChB,GAAG,IAAI,IAAI,WAAW,EAAE,CAAA;YAC1B,CAAC;QACH,CAAC;QAEH,OAAO,GAAG,MAAM,QAAQ,EAAE,CAAC;QAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,IAAI,GAAQ,KAAK,EAAE,IAAI;YACzB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAC5B,CAAC,CAAC,SAAS,CAAA;QAEb,IAAI,OAAO,GAAQ;YACjB,cAAc,EACZ,kBAAkB;SACrB,CAAA;QAED,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAE7C,IAAG,YAAY,EAAE,CAAC;YAChB,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC;YACnB,OAAO,GAAG,SAAS,CAAC;QACtB,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;YAC7B,MAAM,EAAE,MAAgB;YACxB,OAAO;YACP,IAAI;SACL,CAAC,CAAC;QAEH,MAAM,WAAW,GACf,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAElC,MAAM,MAAM,GACV,WAAW,EAAE,QAAQ,CACnB,kBAAkB,CACnB,CAAC;QAEJ,MAAM,IAAI,GAAG,MAAM;YACjB,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE;YAClB,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAErB,OAAO;YACL,EAAE,EAAQ,GAAG,CAAC,EAAE;YAChB,OAAO,EAAG,GAAG,CAAC,OAAO;YACrB,MAAM,EAAI,GAAG,CAAC,MAAa;YAC3B,IAAI,EAAM,IAAI;SACf,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,GAAG,CAMd,IAAW,EACX,GAAG,IAA0D;QAE7D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC,OAAO,CACjB,KAAK,EACL,IAAI,EACJ,KAAK,CACN,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAMf,IAAW,EACX,GAAG,IAA2D;QAE9D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,OAAO,IAAI,CAAC,OAAO,CACjB,MAAM,EACN,IAAI,EACJ,KAAK,CACN,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,GAAG,CAMd,IAAW,EACX,GAAG,IAA0D;QAE7D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,OAAO,IAAI,CAAC,OAAO,CACjB,KAAK,EACL,IAAI,EACJ,KAAK,CACN,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,KAAK,CAMhB,IAAW,EACX,GAAG,IAA4D;QAE/D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,OAAO,IAAI,CAAC,OAAO,CACjB,OAAO,EACP,IAAI,EACJ,KAAK,CACN,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,MAAM,CAMjB,IAAW,EACX,GAAG,IAA6D;QAEhE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtB,OAAO,IAAI,CAAC,OAAO,CACjB,QAAQ,EACR,IAAI,EACJ,KAAK,CACN,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,MAAM,CAIjB,IAAW,EACX,OAGC;QAED,MAAM,EAAE,MAAM,GAAG,MAAiB,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAEzD,OAAO,IAAI,CAAC,OAAO,CACjB,MAAM,EACN,IAAI;QACJ,YAAY;QACZ;YACE,IAAI,EAAG,QAAQ;SAChB,CACF,CAAC;IACJ,CAAC;CAEF;AAEQ,8BAAS;AAClB,kBAAe,SAAS,CAAC"}
@@ -0,0 +1,43 @@
1
+ export type AnyRoutes = {
2
+ [key: string]: any;
3
+ };
4
+ export type RoutesWithMethod<TRoutes extends AnyRoutes, TMethod extends string> = {
5
+ [K in keyof TRoutes]: TMethod extends keyof TRoutes[K] ? K : never;
6
+ }[keyof TRoutes];
7
+ export type ExtractFrom<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath], Key extends string> = TRoutes[TPath][TMethod] extends Record<Key, infer R> ? R : never;
8
+ export type RequestBody<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = ExtractFrom<TRoutes, TPath, TMethod, "body">;
9
+ export type RequestQuery<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = ExtractFrom<TRoutes, TPath, TMethod, "query">;
10
+ export type RequestParams<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = ExtractFrom<TRoutes, TPath, TMethod, "params">;
11
+ export type RequestFiles<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = ExtractFrom<TRoutes, TPath, TMethod, "files">;
12
+ export type ResponseType<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = TRoutes[TPath][TMethod] extends {
13
+ response: infer R;
14
+ } ? Awaited<R> : never;
15
+ export type Prettify<T> = {
16
+ [K in keyof T]: T[K];
17
+ } & {};
18
+ export type ExactProperty<Key extends string, T> = [
19
+ T
20
+ ] extends [never] ? {
21
+ [K in Key]?: never;
22
+ } : undefined extends T ? {
23
+ [K in Key]?: T;
24
+ } : {} extends T ? {
25
+ [K in Key]?: T;
26
+ } : {
27
+ [K in Key]: T;
28
+ };
29
+ export type OptionalIfEmpty<T> = {} extends T ? [input?: T] : [input: T];
30
+ export type RequestInput<TRoutes extends AnyRoutes, TPath extends keyof TRoutes, TMethod extends keyof TRoutes[TPath]> = Prettify<ExactProperty<"params", RequestParams<TRoutes, TPath, TMethod>> & ExactProperty<"query", RequestQuery<TRoutes, TPath, TMethod>> & ExactProperty<"body", RequestBody<TRoutes, TPath, TMethod>> & ExactProperty<"files", RequestFiles<TRoutes, TPath, TMethod>>>;
31
+ export type SuccessStatus = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226;
32
+ export type ErrorStatus = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511;
33
+ export type ApiResponse<T, E = any> = {
34
+ ok: true;
35
+ status: SuccessStatus;
36
+ headers: Headers;
37
+ data: T;
38
+ } | {
39
+ ok: false;
40
+ status: ErrorStatus;
41
+ headers: Headers;
42
+ data: E;
43
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/core/client/types.ts"],"names":[],"mappings":""}
@@ -1,18 +1,16 @@
1
1
  type Route = {
2
2
  method: string;
3
3
  path: string;
4
- response: string;
5
4
  body: string;
6
5
  params: string;
7
6
  query: string;
8
7
  files: string;
8
+ response: string;
9
9
  };
10
10
  type Options = {
11
- controllers: {
12
- folder: string;
13
- name: RegExp;
14
- };
11
+ folder: string;
12
+ name: RegExp;
15
13
  output?: string;
16
14
  };
17
- export declare function generateRoutes(options: Options): Promise<Route[] | undefined>;
15
+ export declare const generateRoutes: (globalPrefix: string, options: Options) => Promise<Route[] | undefined>;
18
16
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateRoutes = generateRoutes;
6
+ exports.generateRoutes = void 0;
7
7
  const ts_morph_1 = require("ts-morph");
8
8
  const typescript_1 = __importDefault(require("typescript"));
9
9
  const fs_1 = __importDefault(require("fs"));
@@ -17,15 +17,30 @@ const HTTP_METHODS = {
17
17
  Options: "OPTIONS",
18
18
  Head: "HEAD",
19
19
  };
20
- function normalizePath(p) {
20
+ const normalizeType = (t) => {
21
+ return t
22
+ .split("|")
23
+ .map(v => v.trim())
24
+ .filter(v => v !== "null" &&
25
+ v !== "undefined")[0] || "string";
26
+ };
27
+ const maybeObject = (v) => {
28
+ const s = v.trim();
29
+ return s.startsWith("{") && s.endsWith("}");
30
+ };
31
+ const maybeArrayObject = (v) => {
32
+ const s = v.trim();
33
+ return s.endsWith("}[]");
34
+ };
35
+ const normalizePath = (p) => {
21
36
  return ("/" +
22
37
  p
23
38
  .replace(/['"`]/g, "")
24
39
  .replace(/\/+/g, "/")
25
40
  .replace(/\/$/, "")
26
41
  .replace(/^\//, ""));
27
- }
28
- function splitTopLevel(input) {
42
+ };
43
+ const splitTopLevel = (input) => {
29
44
  const parts = [];
30
45
  let current = "";
31
46
  let depth = 0;
@@ -45,11 +60,11 @@ function splitTopLevel(input) {
45
60
  parts.push(current.trim());
46
61
  }
47
62
  return parts;
48
- }
49
- function parseType(type) {
63
+ };
64
+ const parseType = (type) => {
50
65
  type = type.trim();
51
66
  if (type === "never") {
52
- return null;
67
+ return undefined;
53
68
  }
54
69
  if (type.startsWith("Record<")) {
55
70
  return {};
@@ -121,6 +136,8 @@ function parseType(type) {
121
136
  return "boolean";
122
137
  if (type === "date")
123
138
  return "date";
139
+ if (type === "Date")
140
+ return "Date";
124
141
  if (type === "string | undefined")
125
142
  return "string";
126
143
  if (type === "number | undefined")
@@ -129,6 +146,8 @@ function parseType(type) {
129
146
  return "boolean";
130
147
  if (type === "date | undefined")
131
148
  return "date";
149
+ if (type === "Date | undefined")
150
+ return "Date";
132
151
  if (type.includes("| undefined")) {
133
152
  return type;
134
153
  }
@@ -139,11 +158,9 @@ function parseType(type) {
139
158
  return type.replace(/"/g, "");
140
159
  }
141
160
  // fallback
142
- return {
143
- $ref: type
144
- };
145
- }
146
- function resolveType(type) {
161
+ return "string";
162
+ };
163
+ const resolveType = (type) => {
147
164
  if (type.getSymbol()?.getName() === "Promise") {
148
165
  type = type.getTypeArguments()[0];
149
166
  }
@@ -161,14 +178,52 @@ function resolveType(type) {
161
178
  return "any";
162
179
  if (type.isUnknown())
163
180
  return "unknown";
164
- if (type.isUnion())
181
+ if (type.isStringLiteral() ||
182
+ type.isBooleanLiteral() ||
183
+ type.isNumberLiteral())
165
184
  return type.getText();
185
+ if (type.getText() === 'Date' &&
186
+ type.getSymbol()?.getName() === 'Date') {
187
+ return "Date";
188
+ }
189
+ if (type.getText().includes("ServerResponse") &&
190
+ type.getText().includes("THttpResponder")) {
191
+ const filtered = type
192
+ .getIntersectionTypes()
193
+ .filter((t) => {
194
+ const text = t.getText();
195
+ return (!text.includes("ServerResponse") &&
196
+ !text.includes("THttpResponder"));
197
+ });
198
+ const t = filtered[0];
199
+ if (t == null)
200
+ return 'never';
201
+ return resolveType(t);
202
+ }
203
+ if (type.isUnion()) {
204
+ const text = type.getText();
205
+ if (text.includes('| null') || text.includes('| undefined')) {
206
+ const types = type.getUnionTypes();
207
+ if (types.length > 1) {
208
+ const nonSpecial = types.filter(t => !t.isNull() && !t.isUndefined());
209
+ const hasNull = types.some(t => t.isNull());
210
+ const hasUndefined = types.some(t => t.isUndefined());
211
+ const sorted = [
212
+ ...nonSpecial,
213
+ ...(hasNull ? [types.find(t => t.isNull())] : []),
214
+ ...(hasUndefined ? [types.find(t => t.isUndefined())] : []),
215
+ ];
216
+ return sorted.map(t => resolveType(t)).join(" | ");
217
+ }
218
+ }
219
+ return text;
220
+ }
166
221
  if (type.isArray()) {
167
222
  const el = type.getArrayElementTypeOrThrow();
168
223
  return `${resolveType(el)}[]`;
169
224
  }
170
- const props = type.getProperties();
171
- if (props.length) {
225
+ if (type.getProperties().length) {
226
+ const props = type.getProperties();
172
227
  const obj = [];
173
228
  for (const prop of props) {
174
229
  const decl = prop.getDeclarations()[0];
@@ -196,8 +251,8 @@ function resolveType(type) {
196
251
  return `{ ${obj.join("; ")} }`;
197
252
  }
198
253
  return type.getText();
199
- }
200
- function extractPropertyType(type, key, node) {
254
+ };
255
+ const extractPropertyType = (type, key, node) => {
201
256
  const prop = type.getProperty(key);
202
257
  if (!prop)
203
258
  return "never";
@@ -208,12 +263,12 @@ function extractPropertyType(type, key, node) {
208
263
  if (!text || text.includes("undefined"))
209
264
  return "never";
210
265
  return resolveType(t) ?? "never";
211
- }
212
- async function generateRoutes(options) {
266
+ };
267
+ const generateRoutes = async (globalPrefix, options) => {
213
268
  const project = new ts_morph_1.Project({
214
269
  tsConfigFilePath: path_1.default.resolve(process.cwd(), "tsconfig.json"),
215
270
  });
216
- project.addSourceFilesAtPaths(path_1.default.join(options.controllers.folder, "**/*"));
271
+ project.addSourceFilesAtPaths(path_1.default.join(options.folder, "**/*"));
217
272
  const files = project.getSourceFiles();
218
273
  if (!files.length) {
219
274
  console.log("No controller files found");
@@ -222,7 +277,7 @@ async function generateRoutes(options) {
222
277
  const routes = [];
223
278
  for (const file of files) {
224
279
  const filename = file.getBaseName();
225
- if (!options.controllers.name.test(filename))
280
+ if (!options.name.test(filename))
226
281
  continue;
227
282
  for (const cls of file.getClasses()) {
228
283
  const controller = cls.getDecorator("Controller");
@@ -249,10 +304,12 @@ async function generateRoutes(options) {
249
304
  const firstParam = method.getParameters()[0];
250
305
  if (firstParam) {
251
306
  const type = firstParam.getType();
252
- body = extractPropertyType(type, "body", firstParam);
253
307
  params = extractPropertyType(type, "params", firstParam);
254
308
  query = extractPropertyType(type, "query", firstParam);
309
+ body = extractPropertyType(type, "body", firstParam);
255
310
  files = extractPropertyType(type, "files", firstParam);
311
+ if (body === 'Record<string, any>')
312
+ body = "never";
256
313
  }
257
314
  routes.push({
258
315
  method: http,
@@ -261,7 +318,7 @@ async function generateRoutes(options) {
261
318
  body,
262
319
  params,
263
320
  query,
264
- files,
321
+ files
265
322
  });
266
323
  }
267
324
  }
@@ -295,9 +352,97 @@ async function generateRoutes(options) {
295
352
  }`;
296
353
  })
297
354
  .join("\n");
298
- const formatValue = (v) => {
299
- if (typeof v === "string")
300
- return v;
355
+ const formatExampleValue = (v) => {
356
+ if (v === null) {
357
+ return "null";
358
+ }
359
+ if (v === undefined) {
360
+ return "undefined";
361
+ }
362
+ if (typeof v === "string") {
363
+ const t = normalizeType(v.trim());
364
+ if (maybeObject(t)) {
365
+ const inner = t.trim().slice(1, -1);
366
+ const result = Object.fromEntries(splitTopLevel(inner)
367
+ .map(s => s.trim())
368
+ .filter(Boolean)
369
+ .map(pair => {
370
+ const idx = pair.indexOf(":");
371
+ const key = pair.slice(0, idx).trim();
372
+ const type = pair.slice(idx + 1).trim();
373
+ return [key.replace(/\?/g, ''), type];
374
+ }));
375
+ return formatExampleValue(result);
376
+ }
377
+ if (maybeArrayObject(t)) {
378
+ const s = v.trim();
379
+ const output = s.replace(/(\w+):\s*(\{[^}]+\})\[\]/, '$1: [$2]').match(/\{(.*)\}/)?.[1];
380
+ if (!output)
381
+ return `[]`;
382
+ const result = Object.fromEntries(splitTopLevel(output)
383
+ .map(s => s.trim())
384
+ .filter(Boolean)
385
+ .map(pair => {
386
+ const idx = pair.indexOf(":");
387
+ const key = pair.slice(0, idx).trim();
388
+ const type = pair.slice(idx + 1).trim();
389
+ return [key, type];
390
+ }));
391
+ return formatExampleValue(result);
392
+ }
393
+ switch (t) {
394
+ case "string":
395
+ return `"example"`;
396
+ case "string[]":
397
+ return `["example1", "example2", "example3"]`;
398
+ case "number":
399
+ return "123";
400
+ case "number[]":
401
+ return "[1 ,2, 3]";
402
+ case "boolean":
403
+ return "true";
404
+ case "boolean[]":
405
+ return "[true, false, true]";
406
+ case "null":
407
+ return "null";
408
+ case "null[]":
409
+ return "[null, null, null]";
410
+ case "undefined":
411
+ return "undefined";
412
+ case "undefined[]":
413
+ return "[undefined, undefined, undefined]";
414
+ case "date":
415
+ case "Date":
416
+ return `"2000-01-01T00:00:00.000Z"`;
417
+ case "date[]":
418
+ case "Date[]":
419
+ return `["2000-01-01T00:00:00.000Z","2000-01-02T00:00:00.000Z","2000-01-03T00:00:00.000Z"]`;
420
+ default:
421
+ return `"${t.replace(/"/g, "")}"`;
422
+ }
423
+ }
424
+ if (Array.isArray(v)) {
425
+ if (!v.length) {
426
+ return "[]";
427
+ }
428
+ return `[
429
+ ${formatExampleValue(v[0])},
430
+ ${formatExampleValue(v[0])},
431
+ ${formatExampleValue(v[0])}
432
+ ]`;
433
+ }
434
+ if (typeof v === "object") {
435
+ const entries = Object.entries(v).map(([key, value]) => {
436
+ if (key.includes("uuid")) {
437
+ return `${key}: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"`;
438
+ }
439
+ if (key === "id" || key.endsWith("id")) {
440
+ return `${key}: 123`;
441
+ }
442
+ return `${key}: ${formatExampleValue(value)}`;
443
+ });
444
+ return `{ ${entries.map(v => `${v}`).join(", ")} }`;
445
+ }
301
446
  return JSON.stringify(v);
302
447
  };
303
448
  const groupedValues = routes.reduce((acc, route) => {
@@ -318,11 +463,11 @@ async function generateRoutes(options) {
318
463
  const methodBlock = Object.entries(methods)
319
464
  .map(([method, c]) => `
320
465
  ${method}: {
321
- params: ${formatValue(c.params)},
322
- query: ${formatValue(c.query)},
323
- body: ${formatValue(c.body)},
324
- files: ${formatValue(c.files)},
325
- response: ${formatValue(c.response)}
466
+ params: ${formatExampleValue(c.params)},
467
+ query: ${formatExampleValue(c.query)},
468
+ body: ${formatExampleValue(c.body)},
469
+ files: ${formatExampleValue(c.files)},
470
+ response: ${formatExampleValue(c.response)}
326
471
  }`).join(",\n");
327
472
  return `
328
473
  "${path}": {
@@ -334,16 +479,20 @@ async function generateRoutes(options) {
334
479
  // @ts-nocheck
335
480
  // AUTO GENERATED FILE
336
481
  // DO NOT EDIT
482
+ // **Response values shown here are examples only.
483
+ ${globalPrefix ?
484
+ `// **The App is using the configuration:
485
+ // globalPrefix: '${globalPrefix}'` : ''}
337
486
 
338
487
  export const appRoutes = {
339
488
  ${routerMapValues}
340
- }
489
+ };
341
490
 
342
491
  export interface AppRoutes {
343
492
  ${routeMapTypes}
344
- }
493
+ };
345
494
 
346
- export type AppRoute = keyof AppRoutes
495
+ export type AppRoute = keyof AppRoutes;
347
496
  `;
348
497
  const outPath = options.output
349
498
  ? `${__dirname}/${options.output}/pre-routes.ts`
@@ -351,15 +500,17 @@ export type AppRoute = keyof AppRoutes
351
500
  await fs_1.default.promises.mkdir(path_1.default.dirname(outPath), {
352
501
  recursive: true,
353
502
  });
354
- await fs_1.default.promises.writeFile(outPath, output);
355
503
  const compiled = typescript_1.default.transpileModule(output, {
356
504
  compilerOptions: {
357
505
  module: typescript_1.default.ModuleKind.CommonJS,
358
- target: typescript_1.default.ScriptTarget.ES2020,
506
+ target: typescript_1.default.ScriptTarget.ESNext
359
507
  },
360
508
  });
361
- const jsPath = outPath.replace(/\.ts$/, ".js");
362
- await fs_1.default.promises.writeFile(jsPath, compiled.outputText, "utf8");
509
+ await Promise.all([
510
+ fs_1.default.promises.writeFile(outPath, output),
511
+ fs_1.default.promises.writeFile(outPath.replace(/\.ts$/, ".js"), compiled.outputText)
512
+ ]);
363
513
  return routes;
364
- }
514
+ };
515
+ exports.generateRoutes = generateRoutes;
365
516
  //# sourceMappingURL=generator.js.map