@redonvn/redai-backend-api-sdk 0.1.17 → 0.1.20

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 (153) hide show
  1. package/dist/core/auth.d.ts +19 -0
  2. package/dist/core/auth.js +47 -0
  3. package/dist/core/http-client.d.ts +9 -0
  4. package/dist/core/http-client.js +41 -0
  5. package/dist/core/types.d.ts +19 -0
  6. package/dist/core/types.js +2 -0
  7. package/{src/generated/dynamic-table/index.ts → dist/generated/dynamic-table/index.d.ts} +0 -1
  8. package/dist/generated/dynamic-table/index.js +19 -0
  9. package/dist/generated/dynamic-table/services/api-docs.service.d.ts +9 -0
  10. package/dist/generated/dynamic-table/services/api-docs.service.js +36 -0
  11. package/dist/generated/dynamic-table/services/api-tokens.service.d.ts +10 -0
  12. package/dist/generated/dynamic-table/services/api-tokens.service.js +45 -0
  13. package/dist/generated/dynamic-table/services/attachments-secure.service.d.ts +8 -0
  14. package/dist/generated/dynamic-table/services/attachments-secure.service.js +27 -0
  15. package/dist/generated/dynamic-table/services/attachments.service.d.ts +10 -0
  16. package/dist/generated/dynamic-table/services/attachments.service.js +45 -0
  17. package/dist/generated/dynamic-table/services/base-members.service.d.ts +10 -0
  18. package/dist/generated/dynamic-table/services/base-members.service.js +45 -0
  19. package/dist/generated/dynamic-table/services/bases.service.d.ts +11 -0
  20. package/dist/generated/dynamic-table/services/bases.service.js +54 -0
  21. package/dist/generated/dynamic-table/services/caches.service.d.ts +9 -0
  22. package/dist/generated/dynamic-table/services/caches.service.js +36 -0
  23. package/dist/generated/dynamic-table/services/calendar-data.service.d.ts +14 -0
  24. package/dist/generated/dynamic-table/services/calendar-data.service.js +36 -0
  25. package/dist/generated/dynamic-table/services/calendars.service.d.ts +9 -0
  26. package/dist/generated/dynamic-table/services/calendars.service.js +36 -0
  27. package/dist/generated/dynamic-table/services/columns.service.d.ts +17 -0
  28. package/dist/generated/dynamic-table/services/columns.service.js +81 -0
  29. package/dist/generated/dynamic-table/services/command-palette.service.d.ts +9 -0
  30. package/dist/generated/dynamic-table/services/command-palette.service.js +36 -0
  31. package/dist/generated/dynamic-table/services/comments.service.d.ts +13 -0
  32. package/dist/generated/dynamic-table/services/comments.service.js +72 -0
  33. package/dist/generated/dynamic-table/services/data-imports.service.d.ts +15 -0
  34. package/dist/generated/dynamic-table/services/data-imports.service.js +63 -0
  35. package/dist/generated/dynamic-table/services/data-table.service.d.ts +33 -0
  36. package/dist/generated/dynamic-table/services/data-table.service.js +162 -0
  37. package/dist/generated/dynamic-table/services/dynamic-table-auth.service.d.ts +7 -0
  38. package/dist/generated/dynamic-table/services/dynamic-table-auth.service.js +18 -0
  39. package/dist/generated/dynamic-table/services/filters.service.d.ts +12 -0
  40. package/dist/generated/dynamic-table/services/filters.service.js +63 -0
  41. package/dist/generated/dynamic-table/services/forms.service.d.ts +9 -0
  42. package/dist/generated/dynamic-table/services/forms.service.js +36 -0
  43. package/dist/generated/dynamic-table/services/galleries.service.d.ts +9 -0
  44. package/dist/generated/dynamic-table/services/galleries.service.js +36 -0
  45. package/dist/generated/dynamic-table/services/grids.service.d.ts +8 -0
  46. package/dist/generated/dynamic-table/services/grids.service.js +27 -0
  47. package/dist/generated/dynamic-table/services/hooks.service.d.ts +18 -0
  48. package/dist/generated/dynamic-table/services/hooks.service.js +117 -0
  49. package/{src/generated/dynamic-table/services/index.ts → dist/generated/dynamic-table/services/index.d.ts} +4 -1
  50. package/dist/generated/dynamic-table/services/index.js +84 -0
  51. package/dist/generated/dynamic-table/services/internal.service.d.ts +9 -0
  52. package/dist/generated/dynamic-table/services/internal.service.js +36 -0
  53. package/dist/generated/dynamic-table/services/jobs-meta.service.d.ts +16 -0
  54. package/dist/generated/dynamic-table/services/jobs-meta.service.js +45 -0
  55. package/dist/generated/dynamic-table/services/jobs.service.d.ts +7 -0
  56. package/dist/generated/dynamic-table/services/jobs.service.js +18 -0
  57. package/dist/generated/dynamic-table/services/kanban-data.service.d.ts +7 -0
  58. package/dist/generated/dynamic-table/services/kanban-data.service.js +18 -0
  59. package/dist/generated/dynamic-table/services/kanbans.service.d.ts +9 -0
  60. package/dist/generated/dynamic-table/services/kanbans.service.js +36 -0
  61. package/dist/generated/dynamic-table/services/maps.service.d.ts +9 -0
  62. package/dist/generated/dynamic-table/services/maps.service.js +36 -0
  63. package/dist/generated/dynamic-table/services/row-color.service.d.ts +12 -0
  64. package/dist/generated/dynamic-table/services/row-color.service.js +63 -0
  65. package/dist/generated/dynamic-table/services/sorts.service.d.ts +12 -0
  66. package/dist/generated/dynamic-table/services/sorts.service.js +63 -0
  67. package/dist/generated/dynamic-table/services/sources.service.d.ts +11 -0
  68. package/dist/generated/dynamic-table/services/sources.service.js +54 -0
  69. package/dist/generated/dynamic-table/services/tables.service.d.ts +12 -0
  70. package/dist/generated/dynamic-table/services/tables.service.js +63 -0
  71. package/dist/generated/dynamic-table/services/user-ui-preferences.service.d.ts +8 -0
  72. package/dist/generated/dynamic-table/services/user-ui-preferences.service.js +27 -0
  73. package/dist/generated/dynamic-table/services/utils.service.d.ts +10 -0
  74. package/dist/generated/dynamic-table/services/utils.service.js +45 -0
  75. package/dist/generated/dynamic-table/services/view-columns.service.d.ts +13 -0
  76. package/dist/generated/dynamic-table/services/view-columns.service.js +72 -0
  77. package/dist/generated/dynamic-table/services/views.service.d.ts +15 -0
  78. package/dist/generated/dynamic-table/services/views.service.js +90 -0
  79. package/dist/generated/dynamic-table/services/workspace-invite-link-settings.service.d.ts +9 -0
  80. package/dist/generated/dynamic-table/services/workspace-invite-link-settings.service.js +36 -0
  81. package/dist/generated/dynamic-table/services/workspace-invite-links.service.d.ts +10 -0
  82. package/dist/generated/dynamic-table/services/workspace-invite-links.service.js +45 -0
  83. package/dist/generated/dynamic-table/services/workspace-invites.service.d.ts +7 -0
  84. package/dist/generated/dynamic-table/services/workspace-invites.service.js +18 -0
  85. package/dist/generated/dynamic-table/services/workspace-join-requests.service.d.ts +9 -0
  86. package/dist/generated/dynamic-table/services/workspace-join-requests.service.js +36 -0
  87. package/dist/generated/dynamic-table/services/workspace-members.service.d.ts +10 -0
  88. package/dist/generated/dynamic-table/services/workspace-members.service.js +45 -0
  89. package/dist/generated/dynamic-table/services/workspaces.service.d.ts +12 -0
  90. package/dist/generated/dynamic-table/services/workspaces.service.js +63 -0
  91. package/dist/generated/dynamic-table/types.d.ts +2539 -0
  92. package/dist/generated/dynamic-table/types.js +488 -0
  93. package/{src/generated/index.ts → dist/generated/index.d.ts} +0 -1
  94. package/dist/generated/index.js +43 -0
  95. package/{src/generated/services/index.ts → dist/generated/services/index.d.ts} +0 -1
  96. package/dist/generated/services/index.js +18 -0
  97. package/{src/generated/types.ts → dist/generated/types.d.ts} +0 -1
  98. package/dist/generated/types.js +18 -0
  99. package/dist/index.d.ts +58 -0
  100. package/dist/index.js +98 -0
  101. package/package.json +19 -13
  102. package/.npm-cache/_cacache/content-v2/sha512/86/70/40787d3ad4c6bb74f182be681858c7e22dc44bd5679779bfe4f3aa562f18810e6b8e80144a539402fe397be24c37e2555f351176e49d8bd1ddff114d5e04 +0 -0
  103. package/.npm-cache/_cacache/tmp/6303939d +0 -0
  104. package/.npm-cache/_update-notifier-last-checked +0 -0
  105. package/src/core/auth.ts +0 -62
  106. package/src/core/http-client.ts +0 -41
  107. package/src/core/types.ts +0 -23
  108. package/src/generated/dynamic-table/services/api-docs.service.ts +0 -42
  109. package/src/generated/dynamic-table/services/api-tokens.service.ts +0 -53
  110. package/src/generated/dynamic-table/services/attachments-secure.service.ts +0 -31
  111. package/src/generated/dynamic-table/services/attachments.service.ts +0 -53
  112. package/src/generated/dynamic-table/services/base-members.service.ts +0 -55
  113. package/src/generated/dynamic-table/services/bases.service.ts +0 -66
  114. package/src/generated/dynamic-table/services/caches.service.ts +0 -42
  115. package/src/generated/dynamic-table/services/calendar-data.service.ts +0 -44
  116. package/src/generated/dynamic-table/services/calendars.service.ts +0 -45
  117. package/src/generated/dynamic-table/services/columns.service.ts +0 -98
  118. package/src/generated/dynamic-table/services/command-palette.service.ts +0 -42
  119. package/src/generated/dynamic-table/services/data-table.service.ts +0 -199
  120. package/src/generated/dynamic-table/services/dynamic-table-auth.service.ts +0 -21
  121. package/src/generated/dynamic-table/services/filters.service.ts +0 -76
  122. package/src/generated/dynamic-table/services/forms.service.ts +0 -45
  123. package/src/generated/dynamic-table/services/galleries.service.ts +0 -45
  124. package/src/generated/dynamic-table/services/grids.service.ts +0 -33
  125. package/src/generated/dynamic-table/services/hooks.service.ts +0 -145
  126. package/src/generated/dynamic-table/services/internal.service.ts +0 -42
  127. package/src/generated/dynamic-table/services/kanban-data.service.ts +0 -21
  128. package/src/generated/dynamic-table/services/kanbans.service.ts +0 -45
  129. package/src/generated/dynamic-table/services/maps.service.ts +0 -45
  130. package/src/generated/dynamic-table/services/row-color.service.ts +0 -77
  131. package/src/generated/dynamic-table/services/sorts.service.ts +0 -76
  132. package/src/generated/dynamic-table/services/sources.service.ts +0 -66
  133. package/src/generated/dynamic-table/services/tables.service.ts +0 -77
  134. package/src/generated/dynamic-table/services/user-ui-preferences.service.ts +0 -32
  135. package/src/generated/dynamic-table/services/utils.service.ts +0 -53
  136. package/src/generated/dynamic-table/services/view-columns.service.ts +0 -87
  137. package/src/generated/dynamic-table/services/views.service.ts +0 -109
  138. package/src/generated/dynamic-table/services/workspace-invite-link-settings.service.ts +0 -43
  139. package/src/generated/dynamic-table/services/workspace-invite-links.service.ts +0 -55
  140. package/src/generated/dynamic-table/services/workspace-invites.service.ts +0 -21
  141. package/src/generated/dynamic-table/services/workspace-join-requests.service.ts +0 -45
  142. package/src/generated/dynamic-table/services/workspace-members.service.ts +0 -56
  143. package/src/generated/dynamic-table/services/workspaces.service.ts +0 -77
  144. package/src/generated/dynamic-table/types.ts +0 -2326
  145. package/src/index.ts +0 -79
  146. package/tools/.reports/dynamic-table-sdk-report.json +0 -9
  147. package/tools/generate-dynamic-table-sdk.ts +0 -31
  148. package/tools/generate-sdk.ts +0 -13
  149. package/tools/generator/openapi-resolver.ts +0 -77
  150. package/tools/generator/shared.ts +0 -162
  151. package/tools/generator/ts-resolver.ts +0 -439
  152. package/tools/verify-generated.ts +0 -23
  153. package/tsconfig.json +0 -19
@@ -1,439 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import ts from 'typescript';
4
- import { HttpMethod, TsRouteInfo, extractTypeIdentifiers, joinPaths, normalizeApiPath } from './shared';
5
-
6
- const unwrapGeneric = (typeName: string, wrapper: string): string | null => {
7
- const t = typeName.trim();
8
- const h = `${wrapper}<`;
9
- if (!t.startsWith(h) || !t.endsWith('>')) return null;
10
- return t.slice(h.length, -1).trim();
11
- };
12
-
13
- const cleanTypeString = (raw: string): string => {
14
- let value = raw.replace(/import\([^)]*\)\./g, '').replace(/\s+/g, ' ').trim();
15
- while (true) {
16
- const inner = unwrapGeneric(value, 'Promise') || unwrapGeneric(value, 'globalThis.Promise') || unwrapGeneric(value, 'Observable');
17
- if (!inner) break;
18
- value = inner;
19
- }
20
- return value;
21
- };
22
-
23
- const ensureApiResponseWrapper = (typeString: string): string => {
24
- if (!typeString || typeString === 'unknown') return 'unknown';
25
- if (typeString === 'void' || typeString === 'never') return 'void';
26
- if (typeString.startsWith('ApiResponseDto<')) return typeString;
27
- return `ApiResponseDto<${typeString}>`;
28
- };
29
-
30
- const getDecoratorName = (decorator: ts.Decorator): string | null => {
31
- const e = decorator.expression;
32
- if (ts.isCallExpression(e)) {
33
- if (ts.isIdentifier(e.expression)) return e.expression.text;
34
- if (ts.isPropertyAccessExpression(e.expression) && ts.isIdentifier(e.expression.name)) return e.expression.name.text;
35
- }
36
- if (ts.isIdentifier(e)) return e.text;
37
- return null;
38
- };
39
-
40
- const resolveExpressionToString = (expr: ts.Expression, checker: ts.TypeChecker, depth = 0): string | null => {
41
- if (depth > 6) return null;
42
- if (ts.isStringLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) return expr.text;
43
- if (ts.isParenthesizedExpression(expr)) return resolveExpressionToString(expr.expression, checker, depth + 1);
44
-
45
- const type = checker.getTypeAtLocation(expr);
46
- if ((type.flags & ts.TypeFlags.StringLiteral) !== 0) return (type as ts.StringLiteralType).value;
47
-
48
- const symbol = checker.getSymbolAtLocation(expr);
49
- if (!symbol) return null;
50
- for (const d of symbol.declarations ?? []) {
51
- if (ts.isEnumMember(d) && d.initializer) {
52
- const value = resolveExpressionToString(d.initializer, checker, depth + 1);
53
- if (value !== null) return value;
54
- }
55
- if (ts.isVariableDeclaration(d) && d.initializer) {
56
- const value = resolveExpressionToString(d.initializer, checker, depth + 1);
57
- if (value !== null) return value;
58
- }
59
- if (ts.isPropertyAssignment(d) && d.initializer) {
60
- const value = resolveExpressionToString(d.initializer, checker, depth + 1);
61
- if (value !== null) return value;
62
- }
63
- }
64
- return null;
65
- };
66
-
67
- const getDecoratorFirstStringArg = (decorator: ts.Decorator, checker: ts.TypeChecker): string | null => {
68
- const e = decorator.expression;
69
- if (!ts.isCallExpression(e) || e.arguments.length === 0) return '';
70
- return resolveExpressionToString(e.arguments[0], checker);
71
- };
72
-
73
- const collectControllerFiles = (root: string): string[] => {
74
- if (!fs.existsSync(root)) return [];
75
- const out: string[] = [];
76
- const stack = [root];
77
- while (stack.length > 0) {
78
- const cur = stack.pop() as string;
79
- for (const e of fs.readdirSync(cur, { withFileTypes: true })) {
80
- const abs = path.join(cur, e.name);
81
- if (e.isDirectory()) stack.push(abs);
82
- else if (e.isFile() && e.name.endsWith('.controller.ts')) out.push(abs);
83
- }
84
- }
85
- return out.sort((a, b) => a.localeCompare(b));
86
- };
87
-
88
- const collectModuleFiles = (root: string): string[] => {
89
- if (!fs.existsSync(root)) return [];
90
- const out: string[] = [];
91
- const stack = [root];
92
- while (stack.length > 0) {
93
- const cur = stack.pop() as string;
94
- for (const e of fs.readdirSync(cur, { withFileTypes: true })) {
95
- const abs = path.join(cur, e.name);
96
- if (e.isDirectory()) {
97
- if (e.name === 'node_modules' || e.name === 'dist') continue;
98
- stack.push(abs);
99
- } else if (e.isFile() && e.name.endsWith('.ts') && !e.name.endsWith('.d.ts')) {
100
- out.push(abs);
101
- }
102
- }
103
- }
104
- return out.sort((a, b) => a.localeCompare(b));
105
- };
106
-
107
- const createProgram = (backendRoot: string, files: string[]): ts.Program =>
108
- ts.createProgram(files, {
109
- target: ts.ScriptTarget.ES2020,
110
- module: ts.ModuleKind.CommonJS,
111
- moduleResolution: ts.ModuleResolutionKind.NodeJs,
112
- skipLibCheck: true,
113
- strict: false,
114
- esModuleInterop: true,
115
- experimentalDecorators: true,
116
- emitDecoratorMetadata: true,
117
- baseUrl: backendRoot,
118
- });
119
-
120
- const getTypeText = (checker: ts.TypeChecker, node: ts.Node): string =>
121
- cleanTypeString(
122
- checker.typeToString(
123
- checker.getTypeAtLocation(node),
124
- node,
125
- ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope,
126
- ),
127
- );
128
-
129
- export const resolveTsOperations = (params: {
130
- backendRoot: string;
131
- controllersDir: string;
132
- moduleName: string;
133
- pathPrefix: string;
134
- }): Array<{
135
- method: HttpMethod;
136
- path: string;
137
- actionName: string;
138
- responseType: string;
139
- pathParams: Array<{ name: string; typeName: string }>;
140
- queryTypeName?: string;
141
- bodyTypeName?: string;
142
- bodyRequired: boolean;
143
- headerParams: Array<{ name: string; typeName: string; required: boolean }>;
144
- }> => {
145
- const { backendRoot, controllersDir, moduleName, pathPrefix } = params;
146
- const files = collectControllerFiles(path.join(backendRoot, controllersDir));
147
- if (files.length === 0) return [];
148
-
149
- const program = createProgram(backendRoot, files);
150
-
151
- const checker = program.getTypeChecker();
152
- const result: Array<{
153
- method: HttpMethod;
154
- path: string;
155
- actionName: string;
156
- responseType: string;
157
- pathParams: Array<{ name: string; typeName: string }>;
158
- queryTypeName?: string;
159
- bodyTypeName?: string;
160
- bodyRequired: boolean;
161
- headerParams: Array<{ name: string; typeName: string; required: boolean }>;
162
- }> = [];
163
-
164
- for (const sf of program.getSourceFiles()) {
165
- if (!sf.fileName.endsWith('.controller.ts')) continue;
166
- const norm = sf.fileName.replace(/\\/g, '/').toLowerCase();
167
- if (!norm.includes(`/modules/${moduleName}/controllers/`)) continue;
168
-
169
- for (const st of sf.statements) {
170
- if (!ts.isClassDeclaration(st) || !st.name) continue;
171
- const ctrlDec = (ts.getDecorators(st) ?? []).find((d) => getDecoratorName(d) === 'Controller');
172
- if (!ctrlDec) continue;
173
- const basePathArg = getDecoratorFirstStringArg(ctrlDec, checker);
174
- if (basePathArg === null) continue;
175
- const basePath = normalizeApiPath(basePathArg || '', moduleName);
176
-
177
- for (const m of st.members) {
178
- if (!ts.isMethodDeclaration(m) || !m.name || !ts.isIdentifier(m.name)) continue;
179
- const routeDec = (ts.getDecorators(m) ?? []).find((d) => {
180
- const n = getDecoratorName(d);
181
- return Boolean(n && ['Get', 'Post', 'Put', 'Patch', 'Delete', 'Options', 'Head'].includes(n));
182
- });
183
- if (!routeDec) continue;
184
-
185
- const method = getDecoratorName(routeDec)!.toLowerCase() as HttpMethod;
186
- const routePathArg = getDecoratorFirstStringArg(routeDec, checker);
187
- if (routePathArg === null) continue;
188
- const fullPath = normalizeApiPath(joinPaths(basePath, routePathArg || '', moduleName), moduleName);
189
- if (!fullPath.startsWith(pathPrefix)) continue;
190
-
191
- const sig = checker.getSignatureFromDeclaration(m);
192
- if (!sig) continue;
193
- const type = checker.getReturnTypeOfSignature(sig);
194
- const raw = checker.typeToString(
195
- type,
196
- m,
197
- ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope,
198
- );
199
- const responseType = ensureApiResponseWrapper(cleanTypeString(raw));
200
-
201
- const pathTokens = [...fullPath.matchAll(/\{([^}]+)\}/g)].map((x) => x[1]);
202
- const explicitPathParamTypes = new Map<string, string>();
203
- let queryTypeName: string | undefined;
204
- let bodyTypeName: string | undefined;
205
- let bodyRequired = false;
206
- const headerParams: Array<{ name: string; typeName: string; required: boolean }> = [];
207
-
208
- for (const parameter of m.parameters) {
209
- const decorators = ts.getDecorators(parameter) ?? [];
210
- for (const dec of decorators) {
211
- const decName = getDecoratorName(dec);
212
- if (!decName) continue;
213
- if (!['Param', 'Query', 'Body', 'Headers'].includes(decName)) continue;
214
- const arg = getDecoratorFirstStringArg(dec, checker);
215
- const typeName = getTypeText(checker, parameter);
216
-
217
- if (decName === 'Param' && arg) {
218
- explicitPathParamTypes.set(arg, typeName || 'string');
219
- }
220
- if (decName === 'Query') {
221
- queryTypeName = typeName || 'Record<string, unknown>';
222
- }
223
- if (decName === 'Body') {
224
- bodyTypeName = typeName || 'unknown';
225
- bodyRequired = !parameter.questionToken;
226
- }
227
- if (decName === 'Headers' && arg) {
228
- headerParams.push({
229
- name: arg,
230
- typeName: typeName || 'string',
231
- required: !parameter.questionToken,
232
- });
233
- }
234
- }
235
- }
236
-
237
- const pathParams = pathTokens.map((token) => ({
238
- name: token,
239
- typeName: explicitPathParamTypes.get(token) || 'string',
240
- }));
241
-
242
- result.push({
243
- method,
244
- path: fullPath,
245
- actionName: m.name.text,
246
- responseType,
247
- pathParams,
248
- queryTypeName,
249
- bodyTypeName,
250
- bodyRequired,
251
- headerParams,
252
- });
253
- }
254
- }
255
- }
256
-
257
- return result;
258
- };
259
-
260
- export const resolveTsRoutes = (params: {
261
- backendRoot: string;
262
- controllersDir: string;
263
- moduleName: string;
264
- pathPrefix: string;
265
- }): Map<string, TsRouteInfo> => {
266
- const ops = resolveTsOperations(params);
267
- const result = new Map<string, TsRouteInfo>();
268
- for (const op of ops) {
269
- result.set(`${op.method.toUpperCase()} ${op.path}`, {
270
- method: op.method,
271
- path: op.path,
272
- responseType: op.responseType,
273
- });
274
- }
275
- return result;
276
- };
277
-
278
- const getTypeParameterText = (node: ts.NodeArray<ts.TypeParameterDeclaration> | undefined, sf: ts.SourceFile): string => {
279
- if (!node || node.length === 0) return '';
280
- return `<${node.map((t) => t.getText(sf)).join(', ')}>`;
281
- };
282
-
283
- const getKeysUnionFromMappedArg = (expr: ts.Expression, sf: ts.SourceFile): string => {
284
- if (!ts.isArrayLiteralExpression(expr)) return expr.getText(sf);
285
- const keys = expr.elements
286
- .map((e) => {
287
- if (ts.isStringLiteral(e) || ts.isNoSubstitutionTemplateLiteral(e)) return `'${e.text.replace(/'/g, "\\'")}'`;
288
- if (ts.isIdentifier(e)) return `'${e.text}'`;
289
- return null;
290
- })
291
- .filter((x): x is string => Boolean(x));
292
- if (keys.length === 0) return 'never';
293
- return keys.join(' | ');
294
- };
295
-
296
- const mapMappedTypeCall = (call: ts.CallExpression, sf: ts.SourceFile): string | null => {
297
- if (!ts.isIdentifier(call.expression)) return null;
298
- const helper = call.expression.text;
299
- const args = call.arguments;
300
- if (helper === 'PartialType' && args.length >= 1) return `Partial<${args[0].getText(sf)}>`;
301
- if (helper === 'PickType' && args.length >= 2) {
302
- return `Pick<${args[0].getText(sf)}, ${getKeysUnionFromMappedArg(args[1], sf)}>`;
303
- }
304
- if (helper === 'OmitType' && args.length >= 2) {
305
- return `Omit<${args[0].getText(sf)}, ${getKeysUnionFromMappedArg(args[1], sf)}>`;
306
- }
307
- if (helper === 'IntersectionType' && args.length >= 2) {
308
- return `${args[0].getText(sf)} & ${args[1].getText(sf)}`;
309
- }
310
- return null;
311
- };
312
-
313
- const getClassBaseType = (node: ts.ClassDeclaration, sf: ts.SourceFile): string | null => {
314
- const extendsClause = node.heritageClauses?.find((x) => x.token === ts.SyntaxKind.ExtendsKeyword);
315
- const base = extendsClause?.types?.[0];
316
- if (!base) return null;
317
- const expr = base.expression;
318
- if (ts.isCallExpression(expr)) {
319
- const mapped = mapMappedTypeCall(expr, sf);
320
- if (mapped) return mapped;
321
- }
322
- return expr.getText(sf);
323
- };
324
-
325
- const emitClassAsInterface = (
326
- node: ts.ClassDeclaration,
327
- checker: ts.TypeChecker,
328
- sf: ts.SourceFile,
329
- ): string | null => {
330
- if (!node.name) return null;
331
- const typeParams = getTypeParameterText(node.typeParameters, sf);
332
- const members: string[] = [];
333
- const baseType = getClassBaseType(node, sf);
334
-
335
- for (const m of node.members) {
336
- if (!ts.isPropertyDeclaration(m) || !m.name) continue;
337
- const readonly = m.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.ReadonlyKeyword) ? 'readonly ' : '';
338
- let nameText = '';
339
- if (ts.isIdentifier(m.name)) nameText = m.name.text;
340
- else if (ts.isStringLiteral(m.name)) nameText = `'${m.name.text.replace(/'/g, "\\'")}'`;
341
- else continue;
342
- const optional = m.questionToken ? '?' : '';
343
- const typeText = m.type
344
- ? m.type.getText(sf)
345
- : checker.typeToString(checker.getTypeAtLocation(m), m, ts.TypeFormatFlags.NoTruncation);
346
- members.push(` ${readonly}${nameText}${optional}: ${typeText};`);
347
- }
348
-
349
- if (members.length === 0) {
350
- if (baseType) return `export type ${node.name.text}${typeParams} = ${baseType};`;
351
- return `export interface ${node.name.text}${typeParams} {\n}`;
352
- }
353
-
354
- if (baseType) {
355
- return `export type ${node.name.text}${typeParams} = ${baseType} & {\n${members.join('\n')}\n};`;
356
- }
357
-
358
- return `export interface ${node.name.text}${typeParams} {\n${members.join('\n')}\n}`;
359
- };
360
-
361
- const emitDeclaration = (node: ts.Node, checker: ts.TypeChecker, sf: ts.SourceFile): string | null => {
362
- if (ts.isTypeAliasDeclaration(node)) {
363
- const typeParams = getTypeParameterText(node.typeParameters, sf);
364
- return `export type ${node.name.text}${typeParams} = ${node.type.getText(sf)};`;
365
- }
366
- if (ts.isInterfaceDeclaration(node)) {
367
- const typeParams = getTypeParameterText(node.typeParameters, sf);
368
- const heritage = node.heritageClauses?.map((h) => h.getText(sf)).join(' ') ?? '';
369
- const members = node.members.map((m) => ` ${m.getText(sf).trim()}`).join('\n');
370
- return `export interface ${node.name.text}${typeParams}${heritage ? ` ${heritage}` : ''} {\n${members}\n}`;
371
- }
372
- if (ts.isEnumDeclaration(node)) {
373
- const members = node.members
374
- .map((m) => {
375
- const name = m.name.getText(sf);
376
- const value = m.initializer ? ` = ${m.initializer.getText(sf)}` : '';
377
- return ` ${name}${value},`;
378
- })
379
- .join('\n');
380
- return `export enum ${node.name.text} {\n${members}\n}`;
381
- }
382
- if (ts.isClassDeclaration(node)) {
383
- return emitClassAsInterface(node, checker, sf);
384
- }
385
- return null;
386
- };
387
-
388
- export const resolveTsTypeDeclarations = (params: {
389
- backendRoot: string;
390
- moduleName: string;
391
- requestedTypeNames: Set<string>;
392
- }): Map<string, string> => {
393
- const { backendRoot, requestedTypeNames } = params;
394
- if (requestedTypeNames.size === 0) return new Map();
395
-
396
- const sourceRoot = path.join(backendRoot, 'src');
397
- const files = collectModuleFiles(sourceRoot);
398
- if (files.length === 0) return new Map();
399
-
400
- const program = createProgram(backendRoot, files);
401
- const checker = program.getTypeChecker();
402
- const declMap = new Map<string, { node: ts.Node; sourceFile: ts.SourceFile }>();
403
-
404
- for (const sf of program.getSourceFiles()) {
405
- const norm = sf.fileName.replace(/\\/g, '/').toLowerCase();
406
- if (!norm.includes('/src/')) continue;
407
- for (const st of sf.statements) {
408
- if (
409
- (ts.isTypeAliasDeclaration(st) || ts.isInterfaceDeclaration(st) || ts.isEnumDeclaration(st) || ts.isClassDeclaration(st)) &&
410
- st.name
411
- ) {
412
- if (!declMap.has(st.name.text)) {
413
- declMap.set(st.name.text, { node: st, sourceFile: sf });
414
- }
415
- }
416
- }
417
- }
418
-
419
- const result = new Map<string, string>();
420
- const queue = [...requestedTypeNames];
421
- const seen = new Set<string>();
422
-
423
- while (queue.length > 0) {
424
- const name = queue.shift() as string;
425
- if (seen.has(name)) continue;
426
- seen.add(name);
427
- const target = declMap.get(name);
428
- if (!target) continue;
429
- const emitted = emitDeclaration(target.node, checker, target.sourceFile);
430
- if (!emitted) continue;
431
- result.set(name, emitted);
432
-
433
- for (const dep of extractTypeIdentifiers(emitted)) {
434
- if (!seen.has(dep)) queue.push(dep);
435
- }
436
- }
437
-
438
- return result;
439
- };
@@ -1,23 +0,0 @@
1
- import { spawnSync } from 'child_process';
2
- import * as path from 'path';
3
-
4
- const toolRoot = 'F:/Redon/sdk/generic-sdk-api';
5
- const cliPath = path.join(toolRoot, 'src', 'cli.ts');
6
-
7
- const args = process.argv.slice(2);
8
- const defaults = [
9
- '--module=dynamic-table',
10
- `--backendRoot=${process.env.BACKEND_ROOT ?? 'F:/Redon/DuAn/project01/true'}`,
11
- `--controllersDir=${process.env.CONTROLLERS_GLOB ?? 'src/modules/dynamic-table/controllers'}`,
12
- `--pathPrefix=${process.env.PATH_PREFIX ?? '/v1/dynamic-table'}`,
13
- `--outDir=${process.cwd()}`,
14
- ];
15
-
16
- const result = spawnSync('npx', ['tsx', cliPath, 'verify', ...defaults, ...args], {
17
- stdio: 'inherit',
18
- shell: process.platform === 'win32',
19
- });
20
-
21
- if (result.status !== 0) {
22
- process.exit(result.status ?? 1);
23
- }
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "CommonJS",
5
- "lib": ["ES2020"],
6
- "declaration": true,
7
- "outDir": "dist",
8
- "rootDir": "src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true,
12
- "forceConsistentCasingInFileNames": true,
13
- "moduleResolution": "node",
14
- "resolveJsonModule": true,
15
- "types": ["node"]
16
- },
17
- "include": ["src/**/*.ts"],
18
- "exclude": ["dist", "node_modules"]
19
- }