proteum 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -1
- package/README.md +375 -0
- package/agents/framework/AGENTS.md +917 -0
- package/agents/project/AGENTS.md +138 -0
- package/agents/{codex → project}/CODING_STYLE.md +3 -2
- package/agents/project/client/AGENTS.md +108 -0
- package/agents/{codex → project}/client/pages/AGENTS.md +8 -8
- package/agents/{codex → project}/server/routes/AGENTS.md +2 -1
- package/agents/project/server/services/AGENTS.md +170 -0
- package/agents/{codex → project}/tests/AGENTS.md +1 -0
- package/cli/app/config.ts +3 -2
- package/cli/app/index.ts +6 -66
- package/cli/bin.js +7 -2
- package/cli/commands/build.ts +94 -27
- package/cli/commands/check.ts +15 -1
- package/cli/commands/dev.ts +288 -132
- package/cli/commands/doctor.ts +108 -0
- package/cli/commands/explain.ts +226 -0
- package/cli/commands/init.ts +76 -70
- package/cli/commands/lint.ts +18 -1
- package/cli/commands/refresh.ts +16 -6
- package/cli/commands/typecheck.ts +14 -1
- package/cli/compiler/artifacts/controllers.ts +150 -0
- package/cli/compiler/artifacts/discovery.ts +132 -0
- package/cli/compiler/artifacts/manifest.ts +267 -0
- package/cli/compiler/artifacts/routing.ts +315 -0
- package/cli/compiler/artifacts/services.ts +480 -0
- package/cli/compiler/artifacts/shared.ts +12 -0
- package/cli/compiler/client/identite.ts +2 -1
- package/cli/compiler/client/index.ts +13 -3
- package/cli/compiler/common/controllers.ts +23 -28
- package/cli/compiler/common/files/style.ts +3 -4
- package/cli/compiler/common/generatedRouteModules.ts +333 -19
- package/cli/compiler/common/proteumManifest.ts +133 -0
- package/cli/compiler/index.ts +33 -896
- package/cli/compiler/server/index.ts +21 -4
- package/cli/context.ts +71 -0
- package/cli/index.ts +39 -181
- package/cli/presentation/commands.ts +208 -0
- package/cli/presentation/compileReporter.ts +65 -0
- package/cli/presentation/devSession.ts +70 -0
- package/cli/presentation/help.ts +193 -0
- package/cli/presentation/ink.ts +69 -0
- package/cli/presentation/layout.ts +83 -0
- package/cli/runtime/argv.ts +49 -0
- package/cli/runtime/command.ts +25 -0
- package/cli/runtime/commands.ts +221 -0
- package/cli/runtime/importEsm.ts +7 -0
- package/cli/runtime/verbose.ts +15 -0
- package/cli/utils/agents.ts +5 -4
- package/cli/utils/keyboard.ts +12 -6
- package/client/app/index.ts +0 -6
- package/client/services/router/index.tsx +1 -1
- package/client/services/router/response/index.tsx +2 -2
- package/common/dev/serverHotReload.ts +12 -0
- package/common/router/index.ts +3 -2
- package/common/router/layouts.ts +1 -1
- package/common/router/pageSetup.ts +1 -0
- package/package.json +10 -8
- package/prettier/router-registration-plugin.cjs +52 -0
- package/prettier.config.cjs +1 -0
- package/scripts/cleanup-generated-controllers.ts +2 -2
- package/scripts/fix-reference-app-typing.ts +2 -2
- package/scripts/format-router-registrations.ts +119 -0
- package/scripts/migrate-explicit-controllers-and-request.ts +423 -0
- package/scripts/refactor-server-controllers.ts +19 -18
- package/scripts/refactor-server-runtime-aliases.ts +1 -1
- package/server/app/commands.ts +309 -25
- package/server/app/container/config.ts +1 -1
- package/server/app/container/index.ts +2 -2
- package/server/app/controller/index.ts +13 -4
- package/server/app/index.ts +53 -37
- package/server/app/service/container.ts +26 -28
- package/server/app/service/index.ts +10 -20
- package/server/app.tsconfig.json +9 -2
- package/server/index.ts +32 -1
- package/server/services/auth/index.ts +234 -15
- package/server/services/auth/router/index.ts +39 -7
- package/server/services/auth/router/request.ts +40 -8
- package/server/services/disks/index.ts +1 -1
- package/server/services/prisma/Facet.ts +2 -2
- package/server/services/prisma/index.ts +22 -5
- package/server/services/prisma/mariadb.ts +47 -0
- package/server/services/router/http/index.ts +9 -1
- package/server/services/router/index.ts +10 -4
- package/server/services/router/response/index.ts +26 -6
- package/types/auth-check-rules.test.ts +51 -0
- package/types/controller-request-context.test.ts +55 -0
- package/types/service-config.test.ts +39 -0
- package/agents/codex/AGENTS.md +0 -95
- package/agents/codex/client/AGENTS.md +0 -102
- package/agents/codex/server/services/AGENTS.md +0 -137
- package/server/services/models.7z +0 -0
- /package/agents/{codex → project}/agents.md.zip +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
import app from '../../app';
|
|
5
|
+
import cli from '../..';
|
|
6
|
+
import writeIfChanged from '../writeIfChanged';
|
|
7
|
+
import { TProteumManifestLayout, TProteumManifestRoute } from '../common/proteumManifest';
|
|
8
|
+
import {
|
|
9
|
+
getGeneratedRouteModuleFilepath,
|
|
10
|
+
indexRouteDefinitions,
|
|
11
|
+
writeGeneratedRouteModule,
|
|
12
|
+
} from '../common/generatedRouteModules';
|
|
13
|
+
import {
|
|
14
|
+
findClientRouteFiles,
|
|
15
|
+
findLayoutFiles,
|
|
16
|
+
findServerRouteFiles,
|
|
17
|
+
readPreloadedRouteChunks,
|
|
18
|
+
} from './discovery';
|
|
19
|
+
import { getGeneratedImportPath, normalizeAbsolutePath, normalizePath } from './shared';
|
|
20
|
+
|
|
21
|
+
type TClientRouteLoader = { filepath: string; chunkId: string; preload: boolean };
|
|
22
|
+
|
|
23
|
+
const cleanupObsoleteGeneratedArtifacts = () => {
|
|
24
|
+
fs.removeSync(path.join(app.paths.root, 'client', '.generated'));
|
|
25
|
+
fs.removeSync(path.join(app.paths.root, 'common', '.generated'));
|
|
26
|
+
fs.removeSync(path.join(app.paths.root, 'server', '.generated'));
|
|
27
|
+
fs.removeSync(path.join(app.paths.root, 'common', 'generated.d.ts'));
|
|
28
|
+
fs.removeSync(path.join(app.paths.root, '.proteum', 'client', '.generated'));
|
|
29
|
+
fs.removeSync(path.join(app.paths.root, '.proteum', 'common', '.generated'));
|
|
30
|
+
fs.removeSync(path.join(app.paths.root, '.proteum', 'server', '.generated'));
|
|
31
|
+
fs.removeSync(path.join(app.paths.client.generated, 'route-modules'));
|
|
32
|
+
fs.removeSync(path.join(app.paths.server.generated, 'route-modules'));
|
|
33
|
+
fs.removeSync(path.join(app.paths.client.generated, 'index.ts'));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const getGeneratedClientRouteModuleFilepath = (filepath: string) =>
|
|
37
|
+
getGeneratedRouteModuleFilepath(app.paths.client.generated, app.paths.pages, filepath);
|
|
38
|
+
|
|
39
|
+
const getGeneratedServerRouteModuleFilepath = (filepath: string) =>
|
|
40
|
+
getGeneratedRouteModuleFilepath(app.paths.server.generated, app.paths.root, filepath);
|
|
41
|
+
|
|
42
|
+
const buildClientRouteManifestEntry = (filepath: string): TProteumManifestRoute => {
|
|
43
|
+
const [definition] = indexRouteDefinitions({ side: 'client', sourceFilepath: filepath });
|
|
44
|
+
const pageChunk = cli.paths.getPageChunk(app, filepath);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
kind: definition.methodName === 'error' ? 'client-error' : 'client-page',
|
|
48
|
+
methodName: definition.methodName,
|
|
49
|
+
serviceLocalName: definition.serviceLocalName,
|
|
50
|
+
filepath: normalizeAbsolutePath(filepath),
|
|
51
|
+
sourceLocation: definition.sourceLocation,
|
|
52
|
+
targetResolution: definition.targetResolution,
|
|
53
|
+
path: definition.path,
|
|
54
|
+
pathRaw: definition.pathRaw,
|
|
55
|
+
code: definition.code,
|
|
56
|
+
codeRaw: definition.codeRaw,
|
|
57
|
+
optionKeys: definition.optionKeys,
|
|
58
|
+
normalizedOptionKeys: definition.normalizedOptionKeys,
|
|
59
|
+
invalidOptionKeys: definition.invalidOptionKeys,
|
|
60
|
+
reservedOptionKeys: definition.reservedOptionKeys,
|
|
61
|
+
optionsRaw: definition.optionsRaw,
|
|
62
|
+
hasSetup: definition.hasSetup,
|
|
63
|
+
chunkId: pageChunk.chunkId,
|
|
64
|
+
chunkFilepath: normalizePath(pageChunk.filepath),
|
|
65
|
+
scope: 'app',
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const buildServerRouteManifestEntries = (filepath: string) =>
|
|
70
|
+
indexRouteDefinitions({ side: 'server', sourceFilepath: filepath }).map<TProteumManifestRoute>((definition) => ({
|
|
71
|
+
kind: 'server-route',
|
|
72
|
+
methodName: definition.methodName,
|
|
73
|
+
serviceLocalName: definition.serviceLocalName,
|
|
74
|
+
filepath: normalizeAbsolutePath(filepath),
|
|
75
|
+
sourceLocation: definition.sourceLocation,
|
|
76
|
+
targetResolution: definition.targetResolution,
|
|
77
|
+
path: definition.path,
|
|
78
|
+
pathRaw: definition.pathRaw,
|
|
79
|
+
code: definition.code,
|
|
80
|
+
codeRaw: definition.codeRaw,
|
|
81
|
+
optionKeys: definition.optionKeys,
|
|
82
|
+
normalizedOptionKeys: definition.normalizedOptionKeys,
|
|
83
|
+
invalidOptionKeys: definition.invalidOptionKeys,
|
|
84
|
+
reservedOptionKeys: definition.reservedOptionKeys,
|
|
85
|
+
optionsRaw: definition.optionsRaw,
|
|
86
|
+
hasSetup: definition.hasSetup,
|
|
87
|
+
scope: 'app',
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
const generateClientRouteWrapperModules = () => {
|
|
91
|
+
const clientRouteFiles = findClientRouteFiles(app.paths.pages).sort((a, b) => a.localeCompare(b));
|
|
92
|
+
const routeSourceFilepaths = new Set(clientRouteFiles.map((filepath) => normalizePath(path.resolve(filepath))));
|
|
93
|
+
const routes = clientRouteFiles.map((filepath) => buildClientRouteManifestEntry(filepath));
|
|
94
|
+
|
|
95
|
+
for (const filepath of clientRouteFiles) {
|
|
96
|
+
const pageChunk = cli.paths.getPageChunk(app, filepath);
|
|
97
|
+
|
|
98
|
+
writeGeneratedRouteModule({
|
|
99
|
+
outputFilepath: getGeneratedClientRouteModuleFilepath(filepath),
|
|
100
|
+
runtime: 'client',
|
|
101
|
+
side: 'client',
|
|
102
|
+
sourceFilepath: filepath,
|
|
103
|
+
clientRoute: { chunkId: pageChunk.chunkId, filepath: pageChunk.filepath },
|
|
104
|
+
routeSourceFilepaths,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
writeGeneratedRouteModule({
|
|
108
|
+
outputFilepath: getGeneratedServerRouteModuleFilepath(filepath),
|
|
109
|
+
runtime: 'server',
|
|
110
|
+
side: 'client',
|
|
111
|
+
sourceFilepath: filepath,
|
|
112
|
+
clientRoute: { chunkId: pageChunk.chunkId, filepath: pageChunk.filepath },
|
|
113
|
+
routeSourceFilepaths,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return routes;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const generateServerRouteWrapperModules = () => {
|
|
121
|
+
const serverRouteFiles = findServerRouteFiles(path.join(app.paths.root, 'server', 'routes')).sort((a, b) =>
|
|
122
|
+
a.localeCompare(b),
|
|
123
|
+
);
|
|
124
|
+
const routeSourceFilepaths = new Set(serverRouteFiles.map((filepath) => normalizePath(path.resolve(filepath))));
|
|
125
|
+
const routes = serverRouteFiles.flatMap((filepath) => buildServerRouteManifestEntries(filepath));
|
|
126
|
+
|
|
127
|
+
for (const filepath of serverRouteFiles) {
|
|
128
|
+
writeGeneratedRouteModule({
|
|
129
|
+
outputFilepath: getGeneratedServerRouteModuleFilepath(filepath),
|
|
130
|
+
runtime: 'server',
|
|
131
|
+
side: 'server',
|
|
132
|
+
sourceFilepath: filepath,
|
|
133
|
+
routeSourceFilepaths,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return routes;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const generateClientRoutesModule = () => {
|
|
141
|
+
const routeLoadersFile = path.join(app.paths.client.generated, 'routes.ts');
|
|
142
|
+
const preloadedChunks = readPreloadedRouteChunks();
|
|
143
|
+
|
|
144
|
+
const routes = findClientRouteFiles(app.paths.pages)
|
|
145
|
+
.sort((a, b) => a.localeCompare(b))
|
|
146
|
+
.map<TClientRouteLoader>((filepath) => {
|
|
147
|
+
const { chunkId } = cli.paths.getPageChunk(app, filepath);
|
|
148
|
+
|
|
149
|
+
return { filepath, chunkId, preload: preloadedChunks.has(chunkId) };
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const imports: string[] = [];
|
|
153
|
+
const routeEntries: string[] = [];
|
|
154
|
+
|
|
155
|
+
routes.forEach((route, index) => {
|
|
156
|
+
const normalizedImportPath = getGeneratedImportPath(
|
|
157
|
+
app.paths.client.generated,
|
|
158
|
+
getGeneratedClientRouteModuleFilepath(route.filepath),
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
if (route.preload) {
|
|
162
|
+
const localIdentifier = `preloadedRoute${index}`;
|
|
163
|
+
imports.push(`import { __register as ${localIdentifier} } from ${JSON.stringify(normalizedImportPath)};`);
|
|
164
|
+
routeEntries.push(
|
|
165
|
+
` ${JSON.stringify(route.chunkId)}: () => Promise.resolve({ __register: ${localIdentifier} }),`,
|
|
166
|
+
);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
routeEntries.push(
|
|
171
|
+
` ${JSON.stringify(route.chunkId)}: () => import(/* webpackChunkName: ${JSON.stringify(route.chunkId)} */ ${JSON.stringify(normalizedImportPath)}),`,
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const content = `/*----------------------------------
|
|
176
|
+
- GENERATED FILE
|
|
177
|
+
----------------------------------*/
|
|
178
|
+
|
|
179
|
+
// This file is generated by Proteum to avoid rebuilding the page loader map in Babel.
|
|
180
|
+
// Do not edit it manually.
|
|
181
|
+
|
|
182
|
+
${imports.join('\n')}
|
|
183
|
+
${imports.length ? '\n' : ''}const routes = {
|
|
184
|
+
${routeEntries.join('\n')}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export default routes;
|
|
188
|
+
`;
|
|
189
|
+
|
|
190
|
+
writeIfChanged(routeLoadersFile, content);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const generateClientLayoutsModule = () => {
|
|
194
|
+
const layoutsFile = path.join(app.paths.client.generated, 'layouts.ts');
|
|
195
|
+
|
|
196
|
+
const layouts = findLayoutFiles(app.paths.pages)
|
|
197
|
+
.map<TProteumManifestLayout>((filepath) => {
|
|
198
|
+
const { chunkId } = cli.paths.getLayoutChunk(app, filepath);
|
|
199
|
+
const importPath = getGeneratedImportPath(app.paths.client.generated, filepath);
|
|
200
|
+
const relativePath = normalizePath(path.relative(app.paths.root, filepath));
|
|
201
|
+
const depth = relativePath.split('/').filter(Boolean).length;
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
filepath: normalizeAbsolutePath(filepath),
|
|
205
|
+
chunkId,
|
|
206
|
+
depth,
|
|
207
|
+
importPath,
|
|
208
|
+
scope: 'app',
|
|
209
|
+
};
|
|
210
|
+
})
|
|
211
|
+
.sort((a, b) => {
|
|
212
|
+
if (b.depth !== a.depth) return b.depth - a.depth;
|
|
213
|
+
return a.filepath.localeCompare(b.filepath);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const imports = layouts
|
|
217
|
+
.map((layout, index) => `import * as layoutModule${index} from ${JSON.stringify(layout.importPath)};`)
|
|
218
|
+
.join('\n');
|
|
219
|
+
|
|
220
|
+
const layoutEntries = layouts
|
|
221
|
+
.map((layout, index) => ` ${JSON.stringify(layout.chunkId)}: layoutModule${index},`)
|
|
222
|
+
.join('\n');
|
|
223
|
+
|
|
224
|
+
const orderedLayoutIds = layouts.map((layout) => ` ${JSON.stringify(layout.chunkId)},`).join('\n');
|
|
225
|
+
|
|
226
|
+
const content = `/*----------------------------------
|
|
227
|
+
- GENERATED FILE
|
|
228
|
+
----------------------------------*/
|
|
229
|
+
|
|
230
|
+
// This file is generated by Proteum from app layout files.
|
|
231
|
+
// Do not edit it manually.
|
|
232
|
+
|
|
233
|
+
${imports}
|
|
234
|
+
${imports ? '\n' : ''}const layouts = {
|
|
235
|
+
${layoutEntries}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export const layoutOrder = [
|
|
239
|
+
${orderedLayoutIds}
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
export default layouts;
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
writeIfChanged(layoutsFile, content);
|
|
246
|
+
|
|
247
|
+
return layouts;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const generateServerRoutesModule = () => {
|
|
251
|
+
const routeModulesFile = path.join(app.paths.server.generated, 'routes.ts');
|
|
252
|
+
const serverRouteFiles = findServerRouteFiles(path.join(app.paths.root, 'server', 'routes'))
|
|
253
|
+
.sort((a, b) => a.localeCompare(b))
|
|
254
|
+
.map((filepath) => ({
|
|
255
|
+
filepath: normalizePath(path.relative(app.paths.root, filepath)),
|
|
256
|
+
importPath: getGeneratedImportPath(app.paths.server.generated, getGeneratedServerRouteModuleFilepath(filepath)),
|
|
257
|
+
}));
|
|
258
|
+
|
|
259
|
+
const pageRouteFiles = findClientRouteFiles(app.paths.pages)
|
|
260
|
+
.sort((a, b) => a.localeCompare(b))
|
|
261
|
+
.map((filepath) => ({
|
|
262
|
+
filepath: normalizePath(path.relative(app.paths.root, filepath)),
|
|
263
|
+
importPath: getGeneratedImportPath(app.paths.server.generated, getGeneratedServerRouteModuleFilepath(filepath)),
|
|
264
|
+
}));
|
|
265
|
+
|
|
266
|
+
const routeModules = [...serverRouteFiles, ...pageRouteFiles];
|
|
267
|
+
|
|
268
|
+
const imports = routeModules
|
|
269
|
+
.map((routeModule, index) => `const routeModule${index} = require(${JSON.stringify(routeModule.importPath)});`)
|
|
270
|
+
.join('\n');
|
|
271
|
+
|
|
272
|
+
const routeEntries = routeModules
|
|
273
|
+
.map(
|
|
274
|
+
(routeModule, index) => ` {
|
|
275
|
+
filepath: ${JSON.stringify(routeModule.filepath)},
|
|
276
|
+
register: routeModule${index}.__register,
|
|
277
|
+
},`,
|
|
278
|
+
)
|
|
279
|
+
.join('\n');
|
|
280
|
+
|
|
281
|
+
const content = `/*----------------------------------
|
|
282
|
+
- GENERATED FILE
|
|
283
|
+
----------------------------------*/
|
|
284
|
+
|
|
285
|
+
// This file is generated by Proteum from route registration files.
|
|
286
|
+
// Do not edit it manually.
|
|
287
|
+
|
|
288
|
+
import type { TRouteModule } from "@common/router";
|
|
289
|
+
${imports ? '\n' + imports : ''}
|
|
290
|
+
|
|
291
|
+
export type TGeneratedRouteModule = {
|
|
292
|
+
filepath: string,
|
|
293
|
+
register?: TRouteModule["__register"],
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const routeModules: TGeneratedRouteModule[] = [
|
|
297
|
+
${routeEntries}
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
export default routeModules;
|
|
301
|
+
`;
|
|
302
|
+
|
|
303
|
+
writeIfChanged(routeModulesFile, content);
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export const generateRoutingArtifacts = () => {
|
|
307
|
+
cleanupObsoleteGeneratedArtifacts();
|
|
308
|
+
const clientRoutes = generateClientRouteWrapperModules();
|
|
309
|
+
const serverRoutes = generateServerRouteWrapperModules();
|
|
310
|
+
generateServerRoutesModule();
|
|
311
|
+
generateClientRoutesModule();
|
|
312
|
+
const layouts = generateClientLayoutsModule();
|
|
313
|
+
|
|
314
|
+
return { clientRoutes, serverRoutes, layouts };
|
|
315
|
+
};
|