proteum 1.0.2 → 2.0.0-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 (185) hide show
  1. package/AGENTS.md +101 -0
  2. package/agents/codex/AGENTS.md +95 -0
  3. package/agents/codex/CODING_STYLE.md +71 -0
  4. package/agents/codex/agents.md.zip +0 -0
  5. package/agents/codex/client/AGENTS.md +102 -0
  6. package/agents/codex/client/pages/AGENTS.md +35 -0
  7. package/agents/codex/server/routes/AGENTS.md +12 -0
  8. package/agents/codex/server/services/AGENTS.md +137 -0
  9. package/agents/codex/tests/AGENTS.md +8 -0
  10. package/cli/app/config.ts +13 -11
  11. package/cli/app/index.ts +74 -82
  12. package/cli/bin.js +1 -1
  13. package/cli/commands/build.ts +51 -14
  14. package/cli/commands/check.ts +19 -0
  15. package/cli/commands/deploy/app.ts +4 -8
  16. package/cli/commands/deploy/web.ts +16 -20
  17. package/cli/commands/dev.ts +189 -64
  18. package/cli/commands/devEvents.ts +106 -0
  19. package/cli/commands/init.ts +63 -57
  20. package/cli/commands/lint.ts +21 -0
  21. package/cli/commands/refresh.ts +18 -0
  22. package/cli/commands/typecheck.ts +18 -0
  23. package/cli/compiler/client/identite.ts +80 -53
  24. package/cli/compiler/client/index.ts +139 -213
  25. package/cli/compiler/common/bundleAnalysis.ts +94 -0
  26. package/cli/compiler/common/clientManifest.ts +67 -0
  27. package/cli/compiler/common/controllers.ts +288 -0
  28. package/cli/compiler/common/files/autres.ts +7 -18
  29. package/cli/compiler/common/files/images.ts +40 -37
  30. package/cli/compiler/common/files/style.ts +11 -22
  31. package/cli/compiler/common/generatedRouteModules.ts +368 -0
  32. package/cli/compiler/common/index.ts +31 -65
  33. package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
  34. package/cli/compiler/common/rspackAliases.ts +13 -0
  35. package/cli/compiler/common/scripts.ts +37 -0
  36. package/cli/compiler/index.ts +781 -230
  37. package/cli/compiler/server/index.ts +59 -75
  38. package/cli/compiler/writeIfChanged.ts +21 -0
  39. package/cli/index.ts +71 -72
  40. package/cli/paths.ts +51 -57
  41. package/cli/print.ts +17 -11
  42. package/cli/tsconfig.json +5 -4
  43. package/cli/utils/agents.ts +100 -0
  44. package/cli/utils/check.ts +71 -0
  45. package/cli/utils/index.ts +1 -3
  46. package/cli/utils/keyboard.ts +8 -25
  47. package/cli/utils/runProcess.ts +30 -0
  48. package/client/app/component.tsx +29 -29
  49. package/client/app/index.ts +36 -57
  50. package/client/app/service.ts +7 -12
  51. package/client/app.tsconfig.json +2 -2
  52. package/client/components/Dialog/Manager.ssr.tsx +40 -0
  53. package/client/components/Dialog/Manager.tsx +119 -150
  54. package/client/components/Dialog/status.tsx +3 -3
  55. package/client/components/index.ts +1 -1
  56. package/client/components/types.d.ts +1 -3
  57. package/client/dev/hmr.ts +65 -0
  58. package/client/global.d.ts +2 -2
  59. package/client/hooks.ts +6 -9
  60. package/client/index.ts +2 -1
  61. package/client/islands/index.ts +7 -0
  62. package/client/islands/useDeferredModule.ts +199 -0
  63. package/client/pages/_layout/index.tsx +4 -12
  64. package/client/pages/useHeader.tsx +14 -21
  65. package/client/router.ts +27 -0
  66. package/client/services/router/components/Link.tsx +34 -27
  67. package/client/services/router/components/Page.tsx +6 -14
  68. package/client/services/router/components/router.ssr.tsx +36 -0
  69. package/client/services/router/components/router.tsx +63 -83
  70. package/client/services/router/index.tsx +185 -220
  71. package/client/services/router/request/api.ts +97 -119
  72. package/client/services/router/request/history.ts +2 -2
  73. package/client/services/router/request/index.ts +13 -12
  74. package/client/services/router/request/multipart.ts +72 -62
  75. package/client/services/router/response/index.tsx +68 -61
  76. package/client/services/router/response/page.ts +28 -32
  77. package/client/utils/dom.ts +17 -33
  78. package/common/app/index.ts +3 -3
  79. package/common/data/chaines/index.ts +22 -23
  80. package/common/data/dates.ts +35 -70
  81. package/common/data/markdown.ts +42 -39
  82. package/common/dev/serverHotReload.ts +26 -0
  83. package/common/errors/index.tsx +110 -142
  84. package/common/router/contracts.ts +29 -0
  85. package/common/router/index.ts +89 -108
  86. package/common/router/layouts.ts +34 -47
  87. package/common/router/pageSetup.ts +50 -0
  88. package/common/router/register.ts +53 -24
  89. package/common/router/request/api.ts +30 -36
  90. package/common/router/request/index.ts +2 -8
  91. package/common/router/response/index.ts +8 -15
  92. package/common/router/response/page.ts +70 -58
  93. package/common/utils.ts +1 -1
  94. package/doc/TODO.md +1 -1
  95. package/eslint.js +62 -0
  96. package/package.json +14 -49
  97. package/prettier.config.cjs +9 -0
  98. package/scripts/cleanup-generated-controllers.ts +62 -0
  99. package/scripts/fix-reference-app-typing.ts +490 -0
  100. package/scripts/refactor-client-app-imports.ts +244 -0
  101. package/scripts/refactor-client-pages.ts +587 -0
  102. package/scripts/refactor-server-controllers.ts +470 -0
  103. package/scripts/refactor-server-runtime-aliases.ts +360 -0
  104. package/scripts/restore-client-app-import-files.ts +41 -0
  105. package/scripts/restore-files-from-git-head.ts +20 -0
  106. package/scripts/update-codex-agents.ts +35 -0
  107. package/server/app/commands.ts +35 -64
  108. package/server/app/container/config.ts +48 -59
  109. package/server/app/container/console/index.ts +202 -248
  110. package/server/app/container/index.ts +33 -71
  111. package/server/app/controller/index.ts +61 -0
  112. package/server/app/index.ts +39 -105
  113. package/server/app/service/container.ts +41 -42
  114. package/server/app/service/index.ts +120 -147
  115. package/server/context.ts +1 -1
  116. package/server/index.ts +25 -1
  117. package/server/services/auth/index.ts +75 -115
  118. package/server/services/auth/router/index.ts +31 -32
  119. package/server/services/auth/router/request.ts +14 -16
  120. package/server/services/cron/CronTask.ts +13 -26
  121. package/server/services/cron/index.ts +14 -36
  122. package/server/services/disks/driver.ts +40 -58
  123. package/server/services/disks/drivers/local/index.ts +79 -90
  124. package/server/services/disks/drivers/s3/index.ts +116 -163
  125. package/server/services/disks/index.ts +23 -38
  126. package/server/services/email/index.ts +45 -104
  127. package/server/services/email/utils.ts +14 -27
  128. package/server/services/fetch/index.ts +53 -85
  129. package/server/services/prisma/Facet.ts +39 -91
  130. package/server/services/prisma/index.ts +74 -110
  131. package/server/services/router/generatedRuntime.ts +29 -0
  132. package/server/services/router/http/index.ts +78 -73
  133. package/server/services/router/http/multipart.ts +19 -42
  134. package/server/services/router/index.ts +378 -365
  135. package/server/services/router/request/api.ts +26 -25
  136. package/server/services/router/request/index.ts +44 -51
  137. package/server/services/router/request/service.ts +7 -11
  138. package/server/services/router/request/validation/zod.ts +111 -148
  139. package/server/services/router/response/index.ts +110 -125
  140. package/server/services/router/response/mask/Filter.ts +31 -72
  141. package/server/services/router/response/mask/index.ts +8 -15
  142. package/server/services/router/response/mask/selecteurs.ts +11 -25
  143. package/server/services/router/response/page/clientManifest.ts +25 -0
  144. package/server/services/router/response/page/document.tsx +199 -127
  145. package/server/services/router/response/page/index.tsx +89 -94
  146. package/server/services/router/service.ts +13 -15
  147. package/server/services/schema/index.ts +17 -26
  148. package/server/services/schema/request.ts +19 -33
  149. package/server/services/schema/router/index.ts +8 -11
  150. package/server/services/security/encrypt/aes/index.ts +15 -35
  151. package/server/utils/slug.ts +29 -35
  152. package/skills/clean-project-code/SKILL.md +63 -0
  153. package/skills/clean-project-code/agents/openai.yaml +4 -0
  154. package/tsconfig.common.json +4 -3
  155. package/tsconfig.json +4 -1
  156. package/types/aliases.d.ts +17 -21
  157. package/types/controller-input.test.ts +48 -0
  158. package/types/express-extra.d.ts +6 -0
  159. package/types/global/constants.d.ts +13 -0
  160. package/types/global/express-extra.d.ts +6 -0
  161. package/types/global/modules.d.ts +13 -16
  162. package/types/global/utils.d.ts +17 -49
  163. package/types/global/vendors.d.ts +62 -0
  164. package/types/icons.d.ts +65 -1
  165. package/types/uuid.d.ts +3 -0
  166. package/types/vendors.d.ts +62 -0
  167. package/cli/compiler/common/babel/index.ts +0 -170
  168. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  169. package/cli/compiler/common/babel/plugins/services.ts +0 -586
  170. package/cli/compiler/common/babel/routes/imports.ts +0 -127
  171. package/cli/compiler/common/babel/routes/routes.ts +0 -1130
  172. package/client/services/captcha/index.ts +0 -67
  173. package/client/services/socket/index.ts +0 -147
  174. package/common/data/rte/nodes.ts +0 -83
  175. package/common/data/stats.ts +0 -90
  176. package/common/utils/rte.ts +0 -183
  177. package/server/services/auth/old.ts +0 -277
  178. package/server/services/cache/commands.ts +0 -41
  179. package/server/services/cache/index.ts +0 -297
  180. package/server/services/cache/service.json +0 -6
  181. package/server/services/socket/index.ts +0 -162
  182. package/server/services/socket/scope.ts +0 -226
  183. package/server/services/socket/service.json +0 -6
  184. package/server/services_old/SocketClient.ts +0 -92
  185. package/server/services_old/Token.old.ts +0 -97
@@ -0,0 +1,360 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import { execFileSync } from 'child_process';
4
+ import { parse } from '@babel/parser';
5
+ import traverse, { NodePath } from '@babel/traverse';
6
+ import generate from '@babel/generator';
7
+ import * as types from '@babel/types';
8
+
9
+ type TRuntimeImportSource = '@app' | '@request' | '@models';
10
+
11
+ type TRuntimeBinding = { local: string; imported: string; source: TRuntimeImportSource };
12
+
13
+ type TClassContext = { hasApp: boolean; hasRequest: boolean };
14
+
15
+ const fallbackBindings = new Map<string, TRuntimeBinding>([
16
+ ['Models', { local: 'Models', imported: 'Models', source: '@app' }],
17
+ ['Disks', { local: 'Disks', imported: 'Disks', source: '@app' }],
18
+ ['Router', { local: 'Router', imported: 'Router', source: '@app' }],
19
+ ['Environment', { local: 'Environment', imported: 'Environment', source: '@app' }],
20
+ ['Identity', { local: 'Identity', imported: 'Identity', source: '@app' }],
21
+ ['auth', { local: 'auth', imported: 'auth', source: '@request' }],
22
+ ['context', { local: 'context', imported: 'context', source: '@request' }],
23
+ ]);
24
+
25
+ const parseCode = (code: string, filename: string) =>
26
+ parse(code, {
27
+ sourceType: 'module',
28
+ sourceFilename: filename,
29
+ plugins: [
30
+ 'typescript',
31
+ 'jsx',
32
+ 'decorators-legacy',
33
+ 'classProperties',
34
+ 'classPrivateProperties',
35
+ 'classPrivateMethods',
36
+ ],
37
+ });
38
+
39
+ const findFiles = (dir: string): string[] => {
40
+ if (!fs.existsSync(dir)) return [];
41
+
42
+ const files: string[] = [];
43
+
44
+ for (const dirent of fs.readdirSync(dir, { withFileTypes: true })) {
45
+ const filepath = path.join(dir, dirent.name);
46
+
47
+ if (dirent.isDirectory()) {
48
+ files.push(...findFiles(filepath));
49
+ continue;
50
+ }
51
+
52
+ if (dirent.isFile() && /\.(tsx?|jsx?)$/.test(filepath) && !filepath.endsWith('.d.ts')) files.push(filepath);
53
+ }
54
+
55
+ return files;
56
+ };
57
+
58
+ const lowerFirst = (value: string) => (value.length ? value[0].toLowerCase() + value.substring(1) : value);
59
+
60
+ const getOriginalFileContent = (repoRoot: string, filepath: string) => {
61
+ const relativeFilepath = path.relative(repoRoot, filepath).replace(/\\/g, '/');
62
+
63
+ try {
64
+ return execFileSync('git', ['-C', repoRoot, 'show', `HEAD:${relativeFilepath}`], { encoding: 'utf8' });
65
+ } catch {
66
+ return null;
67
+ }
68
+ };
69
+
70
+ const extractRuntimeBindings = (code: string, filename: string) => {
71
+ const ast = parseCode(code, filename);
72
+ const runtimeBindings = new Map<string, TRuntimeBinding>();
73
+
74
+ traverse(ast, {
75
+ ImportDeclaration(importPath) {
76
+ const source = importPath.node.source.value;
77
+ if (source !== '@app' && source !== '@request' && source !== '@models') return;
78
+
79
+ for (const specifier of importPath.node.specifiers) {
80
+ if (specifier.type !== 'ImportSpecifier' || specifier.imported.type !== 'Identifier') continue;
81
+
82
+ runtimeBindings.set(specifier.local.name, {
83
+ local: specifier.local.name,
84
+ imported: specifier.imported.name,
85
+ source,
86
+ });
87
+ }
88
+ },
89
+ });
90
+
91
+ return runtimeBindings;
92
+ };
93
+
94
+ const getClassContext = (path: NodePath) => {
95
+ const classPath = path.findParent((parentPath) => parentPath.isClass()) as NodePath<types.Class> | null;
96
+ if (!classPath) return null;
97
+
98
+ const classNode = classPath.node;
99
+ let hasApp = false;
100
+ let hasRequest = false;
101
+
102
+ if (
103
+ types.isIdentifier(classNode.superClass) &&
104
+ (classNode.superClass.name === 'Service' ||
105
+ classNode.superClass.name === 'Controller' ||
106
+ classNode.superClass.name.endsWith('Service') ||
107
+ classNode.superClass.name.endsWith('Controller'))
108
+ ) {
109
+ hasApp = true;
110
+ hasRequest = true;
111
+ }
112
+
113
+ if (classNode.superClass) {
114
+ hasApp = true;
115
+ hasRequest = true;
116
+ }
117
+
118
+ for (const member of classNode.body.body) {
119
+ if (
120
+ (types.isClassProperty(member) || types.isClassAccessorProperty?.(member)) &&
121
+ types.isIdentifier(member.key)
122
+ ) {
123
+ if (member.key.name === 'app') hasApp = true;
124
+ if (member.key.name === 'request') hasRequest = true;
125
+ }
126
+
127
+ if (types.isClassMethod(member) && types.isIdentifier(member.key)) {
128
+ if (member.kind === 'get' && member.key.name === 'request') hasRequest = true;
129
+
130
+ if (member.kind === 'constructor') {
131
+ for (const param of member.params) {
132
+ if (types.isTSParameterProperty(param)) {
133
+ const parameter = param.parameter;
134
+ const identifier = types.isIdentifier(parameter)
135
+ ? parameter
136
+ : types.isAssignmentPattern(parameter) && types.isIdentifier(parameter.left)
137
+ ? parameter.left
138
+ : null;
139
+
140
+ if (!identifier) continue;
141
+
142
+ if (identifier.name === 'app') hasApp = true;
143
+ if (identifier.name === 'request') hasRequest = true;
144
+ } else if (types.isIdentifier(param)) {
145
+ if (param.name === 'app') hasApp = true;
146
+ if (param.name === 'request') hasRequest = true;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ traverse(classPath.node, {
154
+ noScope: true,
155
+ MemberExpression(memberPath) {
156
+ if (!types.isThisExpression(memberPath.node.object)) return;
157
+ if (!types.isIdentifier(memberPath.node.property)) return;
158
+
159
+ if (memberPath.node.property.name === 'app') hasApp = true;
160
+ if (memberPath.node.property.name === 'request') hasRequest = true;
161
+ },
162
+ });
163
+
164
+ if (!hasApp && !hasRequest) return null;
165
+
166
+ return { hasApp, hasRequest } satisfies TClassContext;
167
+ };
168
+
169
+ const isInTypePosition = (path: NodePath<types.Identifier>) => {
170
+ let current: NodePath | null = path;
171
+
172
+ while (current?.parentPath) {
173
+ const parent = current.parentPath;
174
+
175
+ if (
176
+ (parent.isTSAsExpression() ||
177
+ parent.isTSSatisfiesExpression() ||
178
+ parent.isTSNonNullExpression() ||
179
+ parent.isTSInstantiationExpression()) &&
180
+ current.key === 'expression'
181
+ ) {
182
+ current = parent;
183
+ continue;
184
+ }
185
+
186
+ if (parent.node.type.startsWith('TS')) return true;
187
+
188
+ if (
189
+ parent.isExpression() ||
190
+ parent.isStatement() ||
191
+ parent.isProgram() ||
192
+ parent.isClassBody() ||
193
+ parent.isClassMethod() ||
194
+ parent.isClassProperty() ||
195
+ parent.isObjectProperty()
196
+ )
197
+ return false;
198
+
199
+ current = parent;
200
+ }
201
+
202
+ return false;
203
+ };
204
+
205
+ const isSafeImportBinding = (bindingPath: NodePath) => {
206
+ if (
207
+ !bindingPath.isImportSpecifier() &&
208
+ !bindingPath.isImportNamespaceSpecifier() &&
209
+ !bindingPath.isImportDefaultSpecifier()
210
+ )
211
+ return false;
212
+
213
+ const importDeclaration = bindingPath.parentPath;
214
+ if (!importDeclaration?.isImportDeclaration()) return false;
215
+
216
+ if (importDeclaration.node.importKind === 'type') return true;
217
+ if (importDeclaration.node.source.value === '@models/types') return true;
218
+
219
+ return false;
220
+ };
221
+
222
+ const buildReplacementExpression = (binding: TRuntimeBinding, classContext: TClassContext | null) => {
223
+ if (!classContext) return null;
224
+
225
+ if (binding.source === '@request') {
226
+ if (!classContext.hasRequest) return null;
227
+
228
+ if (binding.imported === 'context')
229
+ return types.memberExpression(types.thisExpression(), types.identifier('request'));
230
+
231
+ return types.memberExpression(
232
+ types.memberExpression(types.thisExpression(), types.identifier('request')),
233
+ types.identifier(binding.imported),
234
+ );
235
+ }
236
+
237
+ if (!classContext.hasApp) return null;
238
+
239
+ if (binding.source === '@app') {
240
+ if (binding.imported === 'Environment')
241
+ return types.memberExpression(
242
+ types.memberExpression(types.thisExpression(), types.identifier('app')),
243
+ types.identifier('env'),
244
+ );
245
+
246
+ if (binding.imported === 'Identity')
247
+ return types.memberExpression(
248
+ types.memberExpression(types.thisExpression(), types.identifier('app')),
249
+ types.identifier('identity'),
250
+ );
251
+
252
+ return types.memberExpression(
253
+ types.memberExpression(types.thisExpression(), types.identifier('app')),
254
+ types.identifier(binding.imported),
255
+ );
256
+ }
257
+
258
+ return types.memberExpression(
259
+ types.memberExpression(
260
+ types.memberExpression(
261
+ types.memberExpression(types.thisExpression(), types.identifier('app')),
262
+ types.identifier('Models'),
263
+ ),
264
+ types.identifier('client'),
265
+ ),
266
+ types.identifier(lowerFirst(binding.imported)),
267
+ );
268
+ };
269
+
270
+ const repoRoots = process.argv.slice(2);
271
+ if (!repoRoots.length)
272
+ throw new Error('Usage: ts-node scripts/refactor-server-runtime-aliases.ts <repo-root> [repo-root...]');
273
+
274
+ for (const repoRoot of repoRoots) {
275
+ const serviceRoot = path.join(repoRoot, 'server', 'services');
276
+ const files = findFiles(serviceRoot).filter((filepath) => !filepath.endsWith('.controller.ts'));
277
+
278
+ let changedFiles = 0;
279
+ let replacementCount = 0;
280
+ const skipped: string[] = [];
281
+
282
+ for (const filepath of files) {
283
+ const originalCode = getOriginalFileContent(repoRoot, filepath);
284
+ if (!originalCode) continue;
285
+
286
+ const runtimeBindings = extractRuntimeBindings(originalCode, filepath);
287
+ if (!runtimeBindings.size) continue;
288
+
289
+ const code = fs.readFileSync(filepath, 'utf8');
290
+ const ast = parseCode(code, filepath);
291
+ let fileChanged = false;
292
+
293
+ traverse(ast, {
294
+ MemberExpression(memberPath) {
295
+ if (!types.isMemberExpression(memberPath.node.object)) return;
296
+ if (!types.isThisExpression(memberPath.node.object.object)) return;
297
+ if (!types.isIdentifier(memberPath.node.object.property, { name: 'app' })) return;
298
+ if (!types.isIdentifier(memberPath.node.property)) return;
299
+
300
+ if (memberPath.node.property.name === 'Environment') {
301
+ memberPath.node.property = types.identifier('env');
302
+ fileChanged = true;
303
+ }
304
+
305
+ if (memberPath.node.property.name === 'Identity') {
306
+ memberPath.node.property = types.identifier('identity');
307
+ fileChanged = true;
308
+ }
309
+ },
310
+ Identifier(identifierPath) {
311
+ const binding =
312
+ runtimeBindings.get(identifierPath.node.name) || fallbackBindings.get(identifierPath.node.name);
313
+ if (!binding) return;
314
+ if (!identifierPath.isReferencedIdentifier()) return;
315
+ if (isInTypePosition(identifierPath)) return;
316
+
317
+ const currentBinding = identifierPath.scope.getBinding(identifierPath.node.name);
318
+ if (currentBinding && !isSafeImportBinding(currentBinding.path)) return;
319
+
320
+ const classContext = getClassContext(identifierPath);
321
+ const replacement = buildReplacementExpression(binding, classContext);
322
+ if (!replacement) {
323
+ const location = identifierPath.node.loc?.start;
324
+ skipped.push(
325
+ `${path.relative(repoRoot, filepath)}:${location?.line ?? 0}:${identifierPath.node.name}`,
326
+ );
327
+ return;
328
+ }
329
+
330
+ if (
331
+ identifierPath.parentPath?.isObjectProperty() &&
332
+ identifierPath.parentPath.node.shorthand &&
333
+ identifierPath.parentKey === 'value'
334
+ ) {
335
+ identifierPath.parentPath.node.shorthand = false;
336
+ }
337
+
338
+ identifierPath.replaceWith(types.cloneNode(replacement, true));
339
+ fileChanged = true;
340
+ replacementCount += 1;
341
+ },
342
+ });
343
+
344
+ if (!fileChanged) continue;
345
+
346
+ const output = generate(ast, { retainLines: false, decoratorsBeforeExport: true }, code).code;
347
+
348
+ fs.writeFileSync(filepath, output + '\n');
349
+ changedFiles += 1;
350
+ }
351
+
352
+ console.info(`[runtime-aliases] ${repoRoot}: changed ${changedFiles} files, ${replacementCount} replacements`);
353
+
354
+ if (skipped.length) {
355
+ console.info('[runtime-aliases] skipped references:');
356
+ for (const item of skipped.slice(0, 50)) console.info(' -', item);
357
+
358
+ if (skipped.length > 50) console.info(` - ... ${skipped.length - 50} more`);
359
+ }
360
+ }
@@ -0,0 +1,41 @@
1
+ import { execFileSync } from 'child_process';
2
+ import path from 'path';
3
+ import fs from 'fs-extra';
4
+
5
+ const repoRoots = process.argv.slice(2);
6
+ if (!repoRoots.length)
7
+ throw new Error('Usage: ts-node scripts/restore-client-app-import-files.ts <repo-root> [repo-root...]');
8
+
9
+ for (const repoRoot of repoRoots) {
10
+ const diffOutput = execFileSync(
11
+ 'git',
12
+ ['-C', repoRoot, 'diff', '--name-only', 'HEAD', '--', 'client/components', 'client/hooks'],
13
+ { encoding: 'utf8' },
14
+ );
15
+ const currentDiffFiles = diffOutput
16
+ .split('\n')
17
+ .map((line) => line.trim())
18
+ .filter(Boolean);
19
+
20
+ const grepOutput = execFileSync(
21
+ 'git',
22
+ ['-C', repoRoot, 'grep', '-l', `from '@app'\\|from "@app"`, 'HEAD', '--', 'client'],
23
+ { encoding: 'utf8' },
24
+ );
25
+ const headAppImportFiles = new Set(
26
+ grepOutput
27
+ .split('\n')
28
+ .map((line) => line.trim().replace(/^HEAD:/, ''))
29
+ .filter((line) => line.startsWith('client/components/') || line.startsWith('client/hooks/')),
30
+ );
31
+
32
+ const filesToRestore = currentDiffFiles.filter((filepath) => headAppImportFiles.has(filepath));
33
+
34
+ for (const relativeFile of filesToRestore) {
35
+ const nextContent = execFileSync('git', ['-C', repoRoot, 'show', `HEAD:${relativeFile}`], { encoding: 'utf8' });
36
+ const filepath = path.join(repoRoot, relativeFile);
37
+ fs.ensureDirSync(path.dirname(filepath));
38
+ fs.writeFileSync(filepath, nextContent);
39
+ console.log(`[restore-client-app-import-files] restored ${filepath}`);
40
+ }
41
+ }
@@ -0,0 +1,20 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import { execFileSync } from 'child_process';
4
+
5
+ const args = process.argv.slice(2);
6
+ if (args.length < 2)
7
+ throw new Error(
8
+ 'Usage: ts-node scripts/restore-files-from-git-head.ts <repo-root> <relative-file> [relative-file...]',
9
+ );
10
+
11
+ const [repoRoot, ...relativeFiles] = args;
12
+
13
+ for (const relativeFile of relativeFiles) {
14
+ const nextContent = execFileSync('git', ['-C', repoRoot, 'show', `HEAD:${relativeFile}`], { encoding: 'utf8' });
15
+
16
+ const filepath = path.join(repoRoot, relativeFile);
17
+ fs.ensureDirSync(path.dirname(filepath));
18
+ fs.writeFileSync(filepath, nextContent);
19
+ console.log(`[restore-files-from-git-head] restored ${filepath}`);
20
+ }
@@ -0,0 +1,35 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import path from 'path';
7
+
8
+ // Core
9
+ import { ensureProjectAgentSymlinks } from '../cli/utils/agents';
10
+
11
+ /*----------------------------------
12
+ - TYPES
13
+ ----------------------------------*/
14
+
15
+ type TInputRoot = string | undefined;
16
+
17
+ /*----------------------------------
18
+ - MAIN PROCESS
19
+ ----------------------------------*/
20
+
21
+ const proteumRoot = path.resolve(__dirname, '..');
22
+ const inputRoots = process.argv.slice(2) as TInputRoot[];
23
+ const projectRoots = (inputRoots.length === 0 ? [process.cwd()] : inputRoots).map((inputRoot) =>
24
+ path.resolve(inputRoot || process.cwd()),
25
+ );
26
+
27
+ for (const projectRoot of projectRoots) {
28
+ if (projectRoot === proteumRoot) {
29
+ console.warn(`[update-codex-agents] Skipping Proteum root: ${projectRoot}`);
30
+ continue;
31
+ }
32
+
33
+ console.log(`[update-codex-agents] Syncing project Codex assets in ${projectRoot}`);
34
+ ensureProjectAgentSymlinks({ appRoot: projectRoot, coreRoot: proteumRoot });
35
+ }
@@ -6,7 +6,7 @@
6
6
  import yargsParser from 'yargs-parser';
7
7
 
8
8
  // Core
9
- import type { Application } from '@server/app';
9
+ import type { Application } from './index';
10
10
  import Service from '@server/app/service';
11
11
  import { NotFound } from '@common/errors';
12
12
 
@@ -14,18 +14,16 @@ import { NotFound } from '@common/errors';
14
14
  - TYPES
15
15
  ----------------------------------*/
16
16
 
17
- type CommandCallback<TArgs extends any[]> = (...args: TArgs) => Promise<any>
17
+ type CommandCallback<TArgs extends any[]> = (...args: TArgs) => Promise<any>;
18
18
 
19
- export type CommandsList = {
20
- [commandName: string]: Command
21
- }
19
+ export type CommandsList = { [commandName: string]: Command };
22
20
 
23
21
  export type Command<TArgs extends any[] = any[]> = {
24
- name: string,
25
- description: string,
26
- run?: CommandCallback<TArgs>
27
- childrens: CommandsList
28
- }
22
+ name: string;
23
+ description: string;
24
+ run?: CommandCallback<TArgs>;
25
+ childrens: CommandsList;
26
+ };
29
27
 
30
28
  /*----------------------------------
31
29
  - SERVICE TYPES
@@ -33,59 +31,40 @@ export type Command<TArgs extends any[] = any[]> = {
33
31
 
34
32
  const LogPrefix = `[commands]`;
35
33
 
36
- export type Config = {
37
- debug: boolean
38
- }
34
+ export type Config = { debug: boolean };
39
35
 
40
- export type Hooks = {
41
-
42
- }
36
+ export type Hooks = {};
43
37
 
44
- export type Services = {
45
-
46
- }
38
+ export type Services = {};
47
39
 
48
40
  /*----------------------------------
49
41
  - SERVICE
50
42
  ----------------------------------*/
51
43
  export default class CommandsManager extends Service<Config, Hooks, Application> {
52
-
53
44
  public priority = 2 as 2;
54
45
 
55
- public commandsIndex: CommandsList = {}
56
-
57
- public command<TArgs extends any[]>(
58
- ...args: (
59
- [name: string, description: string, childrens: Command[]]
60
- |
61
- [name: string, description: string, run: CommandCallback<TArgs>, childrens?: Command[]]
62
- )
63
- ): Command {
46
+ public commandsIndex: CommandsList = {};
64
47
 
48
+ public command<TArgs extends any[]>(
49
+ ...args:
50
+ | [name: string, description: string, childrens: Command[]]
51
+ | [name: string, description: string, run: CommandCallback<TArgs>, childrens?: Command[]]
52
+ ): Command {
65
53
  let name: string, description: string;
66
54
  let childrens: Command[] | undefined;
67
55
  let run: CommandCallback<TArgs> | undefined;
68
56
 
69
- if (typeof args[2] === 'object')
70
- ([name, description, childrens] = args)
71
- else
72
- ([name, description, run, childrens] = args)
73
-
74
- const command: Command = {
75
- name,
76
- description,
77
- run,
78
- childrens: childrens ? this.indexFromList(childrens) : {}
79
- }
57
+ if (typeof args[2] === 'object') [name, description, childrens] = args;
58
+ else [name, description, run, childrens] = args;
59
+
60
+ const command: Command = { name, description, run, childrens: childrens ? this.indexFromList(childrens) : {} };
80
61
 
81
62
  return command;
82
63
  }
83
64
 
84
- private indexFromList( list: Command[] ): CommandsList {
85
-
86
- const index: CommandsList = {}
87
- for (const command of list)
88
- index[ command.name ] = command;
65
+ private indexFromList(list: Command[]): CommandsList {
66
+ const index: CommandsList = {};
67
+ for (const command of list) index[command.name] = command;
89
68
 
90
69
  return index;
91
70
  }
@@ -93,49 +72,41 @@ export default class CommandsManager extends Service<Config, Hooks, Application>
93
72
  /*----------------------------------
94
73
  - REGISTER
95
74
  ----------------------------------*/
96
- public fromList( list: Command[] ) {
75
+ public fromList(list: Command[]) {
97
76
  for (const command of list) {
98
-
99
- if (this.commandsIndex[ command.name ] !== undefined)
77
+ if (this.commandsIndex[command.name] !== undefined)
100
78
  throw new Error(`Tried to register command "${command.name}", but it already has been defined.`);
101
79
 
102
- this.commandsIndex[ command.name ] = command;
80
+ this.commandsIndex[command.name] = command;
103
81
  }
104
82
  }
105
83
 
106
84
  /*----------------------------------
107
85
  - RUN
108
86
  ----------------------------------*/
109
- public async run( commandString: string ) {
110
-
87
+ public async run(commandString: string) {
111
88
  const { _, ...args } = yargsParser(commandString);
112
89
 
113
90
  this.config.debug && console.log(LogPrefix, `Run command: ${commandString} | Parsed:`, { _, ...args });
114
91
 
115
92
  let command: Command | undefined;
116
93
  for (const commandName of _) {
117
-
118
- const commandsList: CommandsList = command === undefined
119
- ? this.commandsIndex
120
- : command.childrens;
94
+ const commandsList: CommandsList = command === undefined ? this.commandsIndex : command.childrens;
121
95
 
122
96
  command = commandsList[commandName];
123
97
 
124
- if (command === undefined)
125
- break;
98
+ if (command === undefined) break;
126
99
  }
127
100
 
128
- if (command === undefined)
129
- throw new NotFound(`Command not found.`);
101
+ if (command === undefined) throw new NotFound(`Command not found.`);
130
102
 
131
- if (command.run === undefined)
132
- throw new NotFound(`This command isn't runnable.`);
103
+ if (command.run === undefined) throw new NotFound(`This command isn't runnable.`);
133
104
 
134
105
  // TODO: order correctly & validate type according to injected typescript typedefs (command.run.params)
135
106
  const argsList = Object.values(args);
136
107
 
137
- const result = await command.run(argsList);
108
+ const result = await command.run(...(argsList as Parameters<NonNullable<typeof command.run>>));
138
109
 
139
- return result;
110
+ return result;
140
111
  }
141
- }
112
+ }