proteum 2.1.0 → 2.1.2

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 (95) hide show
  1. package/AGENTS.md +44 -98
  2. package/README.md +143 -10
  3. package/agents/framework/AGENTS.md +146 -886
  4. package/agents/project/AGENTS.md +73 -127
  5. package/agents/project/client/AGENTS.md +22 -93
  6. package/agents/project/client/pages/AGENTS.md +24 -26
  7. package/agents/project/server/routes/AGENTS.md +10 -8
  8. package/agents/project/server/services/AGENTS.md +22 -159
  9. package/agents/project/tests/AGENTS.md +11 -8
  10. package/cli/app/config.ts +7 -20
  11. package/cli/bin.js +8 -0
  12. package/cli/commands/command.ts +243 -0
  13. package/cli/commands/commandLocalRunner.js +198 -0
  14. package/cli/commands/create.ts +5 -0
  15. package/cli/commands/deploy/web.ts +1 -2
  16. package/cli/commands/dev.ts +98 -2
  17. package/cli/commands/doctor.ts +8 -74
  18. package/cli/commands/explain.ts +8 -186
  19. package/cli/commands/init.ts +2 -94
  20. package/cli/commands/trace.ts +228 -0
  21. package/cli/compiler/artifacts/commands.ts +217 -0
  22. package/cli/compiler/artifacts/manifest.ts +35 -21
  23. package/cli/compiler/artifacts/services.ts +300 -1
  24. package/cli/compiler/client/index.ts +43 -8
  25. package/cli/compiler/common/commands.ts +175 -0
  26. package/cli/compiler/common/index.ts +1 -1
  27. package/cli/compiler/common/proteumManifest.ts +15 -114
  28. package/cli/compiler/index.ts +25 -2
  29. package/cli/compiler/server/index.ts +31 -6
  30. package/cli/index.ts +1 -4
  31. package/cli/paths.ts +16 -1
  32. package/cli/presentation/commands.ts +104 -14
  33. package/cli/presentation/devSession.ts +22 -3
  34. package/cli/presentation/proteum_logo_400x400_square_icon.txt +400 -0
  35. package/cli/runtime/commands.ts +121 -4
  36. package/cli/scaffold/index.ts +720 -0
  37. package/cli/scaffold/templates.ts +344 -0
  38. package/cli/scaffold/types.ts +26 -0
  39. package/cli/tsconfig.json +4 -1
  40. package/cli/utils/check.ts +1 -1
  41. package/client/app/component.tsx +13 -9
  42. package/client/dev/profiler/index.tsx +2511 -0
  43. package/client/dev/profiler/noop.tsx +5 -0
  44. package/client/dev/profiler/runtime.noop.ts +116 -0
  45. package/client/dev/profiler/runtime.ts +840 -0
  46. package/client/services/router/components/router.tsx +30 -2
  47. package/client/services/router/index.tsx +27 -3
  48. package/client/services/router/request/api.ts +133 -17
  49. package/commands/proteum/diagnostics.ts +11 -0
  50. package/common/dev/commands.ts +50 -0
  51. package/common/dev/diagnostics.ts +298 -0
  52. package/common/dev/profiler.ts +92 -0
  53. package/common/dev/proteumManifest.ts +135 -0
  54. package/common/dev/requestTrace.ts +115 -0
  55. package/common/env/proteumEnv.ts +284 -0
  56. package/common/router/index.ts +4 -22
  57. package/docs/dev-commands.md +93 -0
  58. package/docs/diagnostics.md +88 -0
  59. package/docs/request-tracing.md +132 -0
  60. package/eslint.js +11 -6
  61. package/package.json +3 -3
  62. package/server/app/commands.ts +35 -370
  63. package/server/app/commandsManager.ts +393 -0
  64. package/server/app/container/config.ts +11 -49
  65. package/server/app/container/console/index.ts +2 -3
  66. package/server/app/container/index.ts +5 -2
  67. package/server/app/container/trace/index.ts +364 -0
  68. package/server/app/devCommands.ts +192 -0
  69. package/server/app/devDiagnostics.ts +53 -0
  70. package/server/app/index.ts +29 -6
  71. package/server/index.ts +0 -1
  72. package/server/services/auth/index.ts +525 -61
  73. package/server/services/auth/router/index.ts +106 -7
  74. package/server/services/cron/CronTask.ts +73 -5
  75. package/server/services/cron/index.ts +34 -11
  76. package/server/services/fetch/index.ts +3 -10
  77. package/server/services/prisma/index.ts +66 -4
  78. package/server/services/router/http/index.ts +173 -6
  79. package/server/services/router/index.ts +200 -12
  80. package/server/services/router/request/api.ts +30 -1
  81. package/server/services/router/response/index.ts +83 -10
  82. package/server/services/router/response/page/document.tsx +16 -0
  83. package/server/services/router/response/page/index.tsx +27 -1
  84. package/skills/clean-project-code/SKILL.md +7 -2
  85. package/test-results/.last-run.json +4 -0
  86. package/types/aliases.d.ts +6 -0
  87. package/types/global/utils.d.ts +7 -14
  88. package/Rte.zip +0 -0
  89. package/agents/project/agents.md.zip +0 -0
  90. package/doc/TODO.md +0 -71
  91. package/doc/front/router.md +0 -27
  92. package/doc/workspace/workspace.png +0 -0
  93. package/doc/workspace/workspace2.png +0 -0
  94. package/doc/workspace/workspace_26.01.22.png +0 -0
  95. package/server/services/router/http/session.ts.old +0 -40
@@ -0,0 +1,298 @@
1
+ import type {
2
+ TProteumManifest,
3
+ TProteumManifestCommand,
4
+ TProteumManifestController,
5
+ TProteumManifestDiagnostic,
6
+ TProteumManifestLayout,
7
+ TProteumManifestRoute,
8
+ TProteumManifestService,
9
+ } from './proteumManifest';
10
+
11
+ export const explainSectionNames = ['app', 'conventions', 'env', 'services', 'controllers', 'commands', 'routes', 'layouts', 'diagnostics'] as const;
12
+
13
+ export type TExplainSectionName = (typeof explainSectionNames)[number];
14
+ export type THumanTextBlock = {
15
+ title: string;
16
+ items: string[];
17
+ empty?: string;
18
+ };
19
+ export type TDoctorResponse = {
20
+ summary: {
21
+ errors: number;
22
+ warnings: number;
23
+ strictFailed: boolean;
24
+ };
25
+ diagnostics: TProteumManifestDiagnostic[];
26
+ };
27
+
28
+ const normalizePath = (value: string) => value.replace(/\\/g, '/');
29
+ const emptyBlock = 'none';
30
+
31
+ export const formatManifestLocation = (line?: number, column?: number) =>
32
+ line && column ? `:${line}:${column}` : line ? `:${line}` : '';
33
+
34
+ export const formatManifestFilepath = (manifest: TProteumManifest, filepath: string) => {
35
+ const normalizedFilepath = normalizePath(filepath);
36
+ const normalizedAppRoot = normalizePath(manifest.app.root);
37
+ const normalizedCoreRoot = normalizePath(manifest.app.coreRoot);
38
+
39
+ if (normalizedFilepath === normalizedAppRoot) return '.';
40
+ if (normalizedFilepath.startsWith(normalizedAppRoot + '/')) return normalizedFilepath.slice(normalizedAppRoot.length + 1) || '.';
41
+
42
+ if (normalizedFilepath === normalizedCoreRoot) return 'node_modules/proteum';
43
+ if (normalizedFilepath.startsWith(normalizedCoreRoot + '/'))
44
+ return `node_modules/proteum/${normalizedFilepath.slice(normalizedCoreRoot.length + 1)}`;
45
+
46
+ return normalizedFilepath;
47
+ };
48
+
49
+ const formatServiceItem = (manifest: TProteumManifest, service: TProteumManifestService) => {
50
+ if (service.kind === 'ref') {
51
+ return `${service.registeredName} -> ref ${service.refTo} [${service.parent}]`;
52
+ }
53
+
54
+ const source = service.metasFilepath ? formatManifestFilepath(manifest, service.metasFilepath) : 'unknown';
55
+ return `${service.registeredName} -> ${service.id} (${service.metaName}) [${service.scope}] priority=${service.priority} source=${source}`;
56
+ };
57
+
58
+ const formatControllerItem = (manifest: TProteumManifest, controller: TProteumManifestController) =>
59
+ `${controller.clientAccessor} -> POST ${controller.httpPath} [${controller.scope}] input=${controller.hasInput ? 'yes' : 'no'} source=${formatManifestFilepath(manifest, controller.filepath)}${formatManifestLocation(controller.sourceLocation.line, controller.sourceLocation.column)}#${controller.methodName}`;
60
+
61
+ const formatCommandItem = (manifest: TProteumManifest, command: TProteumManifestCommand) =>
62
+ `${command.path} -> ${command.className}.${command.methodName} [${command.scope}] source=${formatManifestFilepath(manifest, command.filepath)}${formatManifestLocation(command.sourceLocation.line, command.sourceLocation.column)}`;
63
+
64
+ const formatRouteTarget = (route: TProteumManifestRoute) => {
65
+ if (route.kind === 'client-error') return route.code !== undefined ? String(route.code) : route.codeRaw || '?';
66
+ return route.path || route.pathRaw || '?';
67
+ };
68
+
69
+ const formatRouteItem = (manifest: TProteumManifest, route: TProteumManifestRoute) => {
70
+ const chunk = route.chunkId ? ` chunk=${route.chunkId}` : '';
71
+ const setup = route.hasSetup ? ' setup=yes' : ' setup=no';
72
+ const options = route.normalizedOptionKeys.length > 0 ? ` options=${route.normalizedOptionKeys.join(',')}` : '';
73
+ const resolution = route.targetResolution !== 'literal' ? ` resolution=${route.targetResolution}` : '';
74
+
75
+ return `${route.kind} ${route.methodName} ${formatRouteTarget(route)} [${route.scope}]${chunk}${setup}${options}${resolution} source=${formatManifestFilepath(manifest, route.filepath)}${formatManifestLocation(route.sourceLocation.line, route.sourceLocation.column)}`;
76
+ };
77
+
78
+ const formatLayoutItem = (manifest: TProteumManifest, layout: TProteumManifestLayout) =>
79
+ `${layout.chunkId || 'root'} depth=${layout.depth} [${layout.scope}] source=${formatManifestFilepath(manifest, layout.filepath)}`;
80
+
81
+ const formatDiagnosticItem = (manifest: TProteumManifest, diagnostic: TProteumManifestDiagnostic) => {
82
+ const related =
83
+ diagnostic.relatedFilepaths && diagnostic.relatedFilepaths.length > 0
84
+ ? ` related=${diagnostic.relatedFilepaths.map((filepath) => formatManifestFilepath(manifest, filepath)).join(',')}`
85
+ : '';
86
+
87
+ return `[${diagnostic.level}] ${diagnostic.code} ${diagnostic.message} source=${formatManifestFilepath(manifest, diagnostic.filepath)}${formatManifestLocation(diagnostic.sourceLocation?.line, diagnostic.sourceLocation?.column)}${related}`;
88
+ };
89
+
90
+ export const pickExplainManifestSections = (manifest: TProteumManifest, sectionNames: TExplainSectionName[]) => {
91
+ if (sectionNames.length === 0) return manifest;
92
+
93
+ const selected: Partial<TProteumManifest> = {};
94
+
95
+ for (const sectionName of sectionNames) {
96
+ selected[sectionName] = manifest[sectionName];
97
+ }
98
+
99
+ return selected;
100
+ };
101
+
102
+ export const buildExplainSummaryItems = (manifest: TProteumManifest) => {
103
+ const errorsCount = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'error').length;
104
+ const warningsCount = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'warning').length;
105
+ const providedRequiredEnvVariables = manifest.env.requiredVariables.filter((variable) => variable.provided).length;
106
+
107
+ return [
108
+ `Proteum manifest: ${formatManifestFilepath(manifest, `${normalizePath(manifest.app.root)}/.proteum/manifest.json`)}`,
109
+ `App: ${manifest.app.identity.name} (${manifest.app.identity.identifier})`,
110
+ `Env vars: ${providedRequiredEnvVariables}/${manifest.env.requiredVariables.length} required provided`,
111
+ `Services: ${manifest.services.app.length} app, ${manifest.services.routerPlugins.length} router plugins`,
112
+ `Controllers: ${manifest.controllers.length}`,
113
+ `Commands: ${manifest.commands.length}`,
114
+ `Routes: ${manifest.routes.client.length} client, ${manifest.routes.server.length} server`,
115
+ `Layouts: ${manifest.layouts.length}`,
116
+ `Diagnostics: ${errorsCount} errors, ${warningsCount} warnings`,
117
+ 'Use `proteum explain --json` for the full machine-readable manifest or pass section flags like `routes` and `services`.',
118
+ ];
119
+ };
120
+
121
+ export const buildExplainBlocks = (manifest: TProteumManifest, sectionNames: TExplainSectionName[]): THumanTextBlock[] => {
122
+ const blocks: THumanTextBlock[] = [];
123
+
124
+ for (const sectionName of sectionNames) {
125
+ if (sectionName === 'app') {
126
+ blocks.push({
127
+ title: 'App',
128
+ items: [
129
+ `root=${formatManifestFilepath(manifest, manifest.app.root)}`,
130
+ `coreRoot=${formatManifestFilepath(manifest, manifest.app.coreRoot)}`,
131
+ `identity=${formatManifestFilepath(manifest, manifest.app.identityFilepath)}`,
132
+ `name=${manifest.app.identity.name}`,
133
+ `identifier=${manifest.app.identity.identifier}`,
134
+ `title=${manifest.app.identity.fullTitle || manifest.app.identity.title || manifest.app.identity.name}`,
135
+ ],
136
+ });
137
+ continue;
138
+ }
139
+
140
+ if (sectionName === 'conventions') {
141
+ blocks.push({
142
+ title: 'Conventions',
143
+ items: [
144
+ `routeSetupOptionKeys=${manifest.conventions.routeSetupOptionKeys.join(', ')}`,
145
+ `reservedRouteSetupKeys=${manifest.conventions.reservedRouteSetupKeys.join(', ')}`,
146
+ ],
147
+ });
148
+ continue;
149
+ }
150
+
151
+ if (sectionName === 'env') {
152
+ blocks.push({
153
+ title: 'Env',
154
+ items: [
155
+ `source=${manifest.env.source}`,
156
+ `loadedVariableKeys=${manifest.env.loadedVariableKeys.join(', ') || 'none'}`,
157
+ ...manifest.env.requiredVariables.map(
158
+ (variable) =>
159
+ `${variable.key} possibleValues=${variable.possibleValues.join(' | ')} provided=${variable.provided ? 'yes' : 'no'}`,
160
+ ),
161
+ `resolved.name=${manifest.env.resolved.name}`,
162
+ `resolved.profile=${manifest.env.resolved.profile}`,
163
+ `resolved.routerPort=${manifest.env.resolved.routerPort}`,
164
+ `resolved.routerCurrentDomain=${manifest.env.resolved.routerCurrentDomain}`,
165
+ ],
166
+ });
167
+ continue;
168
+ }
169
+
170
+ if (sectionName === 'services') {
171
+ blocks.push(
172
+ {
173
+ title: 'App Services',
174
+ items: manifest.services.app.map((service) => formatServiceItem(manifest, service)),
175
+ },
176
+ {
177
+ title: 'Router Plugins',
178
+ items: manifest.services.routerPlugins.map((service) => formatServiceItem(manifest, service)),
179
+ },
180
+ );
181
+ continue;
182
+ }
183
+
184
+ if (sectionName === 'controllers') {
185
+ blocks.push({
186
+ title: 'Controllers',
187
+ items: manifest.controllers.map((controller) => formatControllerItem(manifest, controller)),
188
+ });
189
+ continue;
190
+ }
191
+
192
+ if (sectionName === 'commands') {
193
+ blocks.push({
194
+ title: 'Commands',
195
+ items: manifest.commands.map((command) => formatCommandItem(manifest, command)),
196
+ });
197
+ continue;
198
+ }
199
+
200
+ if (sectionName === 'routes') {
201
+ blocks.push(
202
+ {
203
+ title: 'Client Routes',
204
+ items: manifest.routes.client.map((route) => formatRouteItem(manifest, route)),
205
+ },
206
+ {
207
+ title: 'Server Routes',
208
+ items: manifest.routes.server.map((route) => formatRouteItem(manifest, route)),
209
+ },
210
+ );
211
+ continue;
212
+ }
213
+
214
+ if (sectionName === 'layouts') {
215
+ blocks.push({
216
+ title: 'Layouts',
217
+ items: manifest.layouts.map((layout) => formatLayoutItem(manifest, layout)),
218
+ });
219
+ continue;
220
+ }
221
+
222
+ if (sectionName === 'diagnostics') {
223
+ blocks.push({
224
+ title: 'Diagnostics',
225
+ items: manifest.diagnostics.map((diagnostic) => formatDiagnosticItem(manifest, diagnostic)),
226
+ });
227
+ }
228
+ }
229
+
230
+ return blocks;
231
+ };
232
+
233
+ export const renderHumanBlock = (block: THumanTextBlock) => {
234
+ if (block.items.length === 0) return `${block.title}\n- ${block.empty || emptyBlock}`;
235
+ return `${block.title}\n${block.items.map((item) => `- ${item}`).join('\n')}`;
236
+ };
237
+
238
+ export const renderExplainHuman = (manifest: TProteumManifest, sectionNames: TExplainSectionName[]) => {
239
+ if (sectionNames.length === 0) return buildExplainSummaryItems(manifest).join('\n');
240
+ return buildExplainBlocks(manifest, sectionNames).map(renderHumanBlock).join('\n\n');
241
+ };
242
+
243
+ export const buildDoctorResponse = (manifest: TProteumManifest, strict = false): TDoctorResponse => {
244
+ const errors = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'error');
245
+ const warnings = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'warning');
246
+
247
+ return {
248
+ summary: {
249
+ errors: errors.length,
250
+ warnings: warnings.length,
251
+ strictFailed: strict === true && manifest.diagnostics.length > 0,
252
+ },
253
+ diagnostics: manifest.diagnostics,
254
+ };
255
+ };
256
+
257
+ export const buildDoctorBlocks = (manifest: TProteumManifest): THumanTextBlock[] => {
258
+ const errors = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'error');
259
+ const warnings = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'warning');
260
+
261
+ return [
262
+ {
263
+ title: 'Errors',
264
+ items: errors.map((diagnostic) => {
265
+ const related =
266
+ diagnostic.relatedFilepaths && diagnostic.relatedFilepaths.length > 0
267
+ ? ` related=${diagnostic.relatedFilepaths.map((filepath) => formatManifestFilepath(manifest, filepath)).join(',')}`
268
+ : '';
269
+
270
+ return `${diagnostic.code} ${diagnostic.message} source=${formatManifestFilepath(manifest, diagnostic.filepath)}${formatManifestLocation(diagnostic.sourceLocation?.line, diagnostic.sourceLocation?.column)}${related}`;
271
+ }),
272
+ },
273
+ {
274
+ title: 'Warnings',
275
+ items: warnings.map((diagnostic) => {
276
+ const related =
277
+ diagnostic.relatedFilepaths && diagnostic.relatedFilepaths.length > 0
278
+ ? ` related=${diagnostic.relatedFilepaths.map((filepath) => formatManifestFilepath(manifest, filepath)).join(',')}`
279
+ : '';
280
+
281
+ return `${diagnostic.code} ${diagnostic.message} source=${formatManifestFilepath(manifest, diagnostic.filepath)}${formatManifestLocation(diagnostic.sourceLocation?.line, diagnostic.sourceLocation?.column)}${related}`;
282
+ }),
283
+ },
284
+ ];
285
+ };
286
+
287
+ export const renderDoctorHuman = (manifest: TProteumManifest, strict = false) => {
288
+ const response = buildDoctorResponse(manifest, strict);
289
+ if (response.diagnostics.length === 0) return 'Proteum doctor\n- No manifest diagnostics were found.';
290
+
291
+ return [
292
+ 'Proteum doctor',
293
+ `- ${response.summary.errors} errors`,
294
+ `- ${response.summary.warnings} warnings`,
295
+ '',
296
+ ...buildDoctorBlocks(manifest).map(renderHumanBlock),
297
+ ].join('\n');
298
+ };
@@ -0,0 +1,92 @@
1
+ import type { TRequestTrace } from './requestTrace';
2
+
3
+ export const profilerTraceRequestIdHeader = 'x-proteum-trace-request-id';
4
+ export const profilerSessionIdHeader = 'x-proteum-profiler-session-id';
5
+ export const profilerOriginHeader = 'x-proteum-profiler-origin';
6
+ export const profilerParentRequestIdHeader = 'x-proteum-profiler-parent-request-id';
7
+
8
+ export type TProfilerUiState = 'expanded' | 'minimized' | 'pinned-handle';
9
+ export type TProfilerPanel =
10
+ | 'summary'
11
+ | 'timeline'
12
+ | 'auth'
13
+ | 'routing'
14
+ | 'controller'
15
+ | 'ssr'
16
+ | 'api'
17
+ | 'explain'
18
+ | 'doctor'
19
+ | 'commands'
20
+ | 'cron'
21
+ | 'errors';
22
+ export type TProfilerNavigationSessionKind = 'initial-ssr' | 'client-navigation';
23
+ export type TProfilerSessionTraceKind = 'initial-root' | 'navigation-data' | 'async';
24
+ export type TProfilerNavigationStepStatus = 'pending' | 'completed' | 'error';
25
+ export type TProfilerCronTaskTrigger = 'scheduler' | 'manual' | 'autoexec';
26
+ export type TProfilerCronTaskRunStatus = 'completed' | 'error';
27
+
28
+ export type TProfilerCronTaskFrequency =
29
+ | { kind: 'cron'; value: string }
30
+ | { kind: 'date'; value: string };
31
+
32
+ export type TProfilerCronTask = {
33
+ name: string;
34
+ registeredAt: string;
35
+ frequency: TProfilerCronTaskFrequency;
36
+ autoexec: boolean;
37
+ automaticExecution: boolean;
38
+ nextInvocation?: string;
39
+ running: boolean;
40
+ lastTrigger?: TProfilerCronTaskTrigger;
41
+ lastRunStartedAt?: string;
42
+ lastRunFinishedAt?: string;
43
+ lastRunDurationMs?: number;
44
+ lastRunStatus?: TProfilerCronTaskRunStatus;
45
+ lastErrorMessage?: string;
46
+ runCount: number;
47
+ };
48
+
49
+ export type TProfilerNavigationStep = {
50
+ id: string;
51
+ label: string;
52
+ startedAt: string;
53
+ finishedAt?: string;
54
+ durationMs?: number;
55
+ status: TProfilerNavigationStepStatus;
56
+ details?: { [key: string]: string | number | boolean };
57
+ errorMessage?: string;
58
+ };
59
+
60
+ export type TProfilerSessionTrace = {
61
+ id: string;
62
+ kind: TProfilerSessionTraceKind;
63
+ label: string;
64
+ method: string;
65
+ path: string;
66
+ startedAt: string;
67
+ finishedAt?: string;
68
+ durationMs?: number;
69
+ status: 'pending' | 'completed' | 'error';
70
+ requestId?: string;
71
+ fetcherIds?: string[];
72
+ trace?: TRequestTrace;
73
+ errorMessage?: string;
74
+ };
75
+
76
+ export type TProfilerNavigationSession = {
77
+ id: string;
78
+ kind: TProfilerNavigationSessionKind;
79
+ label: string;
80
+ path: string;
81
+ url: string;
82
+ startedAt: string;
83
+ finishedAt?: string;
84
+ durationMs?: number;
85
+ status: 'active' | 'completed' | 'error';
86
+ requestId?: string;
87
+ routeLabel?: string;
88
+ routeChunkId?: string;
89
+ title?: string;
90
+ steps: TProfilerNavigationStep[];
91
+ traces: TProfilerSessionTrace[];
92
+ };
@@ -0,0 +1,135 @@
1
+ export type TProteumManifestScope = 'app' | 'framework';
2
+ export type TProteumManifestSourceLocation = { line: number; column: number };
3
+ export type TProteumManifestRouteTargetResolution = 'literal' | 'static-expression' | 'dynamic-expression';
4
+ export type TProteumManifestDiagnosticLevel = 'warning' | 'error';
5
+
6
+ export type TProteumManifestDiagnostic = {
7
+ level: TProteumManifestDiagnosticLevel;
8
+ code: string;
9
+ message: string;
10
+ filepath: string;
11
+ sourceLocation?: TProteumManifestSourceLocation;
12
+ relatedFilepaths?: string[];
13
+ };
14
+
15
+ export type TProteumManifestService = {
16
+ kind: 'service' | 'ref';
17
+ id?: string;
18
+ registeredName: string;
19
+ metaName?: string;
20
+ parent: string;
21
+ priority: number;
22
+ importPath?: string;
23
+ sourceDir?: string;
24
+ metasFilepath?: string;
25
+ refTo?: string;
26
+ scope: TProteumManifestScope;
27
+ };
28
+
29
+ export type TProteumManifestController = {
30
+ className: string;
31
+ importPath: string;
32
+ filepath: string;
33
+ sourceLocation: TProteumManifestSourceLocation;
34
+ routeBasePath: string;
35
+ methodName: string;
36
+ inputCallsCount: number;
37
+ hasInput: boolean;
38
+ routePath: string;
39
+ httpPath: string;
40
+ clientAccessor: string;
41
+ scope: TProteumManifestScope;
42
+ };
43
+
44
+ export type TProteumManifestCommand = {
45
+ className: string;
46
+ importPath: string;
47
+ filepath: string;
48
+ sourceLocation: TProteumManifestSourceLocation;
49
+ commandBasePath: string;
50
+ methodName: string;
51
+ path: string;
52
+ scope: TProteumManifestScope;
53
+ };
54
+
55
+ export type TProteumManifestRoute = {
56
+ kind: 'client-page' | 'client-error' | 'server-route';
57
+ methodName: string;
58
+ serviceLocalName: string;
59
+ filepath: string;
60
+ sourceLocation: TProteumManifestSourceLocation;
61
+ targetResolution: TProteumManifestRouteTargetResolution;
62
+ path?: string;
63
+ pathRaw?: string;
64
+ code?: number;
65
+ codeRaw?: string;
66
+ optionKeys: string[];
67
+ normalizedOptionKeys: string[];
68
+ invalidOptionKeys: string[];
69
+ reservedOptionKeys: string[];
70
+ optionsRaw?: string;
71
+ hasSetup: boolean;
72
+ chunkId?: string;
73
+ chunkFilepath?: string;
74
+ scope: TProteumManifestScope;
75
+ };
76
+
77
+ export type TProteumManifestLayout = {
78
+ chunkId: string;
79
+ filepath: string;
80
+ importPath: string;
81
+ depth: number;
82
+ scope: TProteumManifestScope;
83
+ };
84
+
85
+ export type TProteumManifest = {
86
+ version: 2;
87
+ app: {
88
+ root: string;
89
+ coreRoot: string;
90
+ identityFilepath: string;
91
+ identity: {
92
+ name: string;
93
+ identifier: string;
94
+ description: string;
95
+ language?: string;
96
+ locale?: string;
97
+ title?: string;
98
+ titleSuffix?: string;
99
+ fullTitle?: string;
100
+ webDescription?: string;
101
+ version?: string;
102
+ };
103
+ };
104
+ conventions: {
105
+ routeSetupOptionKeys: string[];
106
+ reservedRouteSetupKeys: string[];
107
+ };
108
+ env: {
109
+ source: string;
110
+ loadedVariableKeys: string[];
111
+ requiredVariables: {
112
+ key: string;
113
+ possibleValues: string[];
114
+ provided: boolean;
115
+ }[];
116
+ resolved: {
117
+ name: string;
118
+ profile: string;
119
+ routerPort: number;
120
+ routerCurrentDomain: string;
121
+ };
122
+ };
123
+ services: {
124
+ app: TProteumManifestService[];
125
+ routerPlugins: TProteumManifestService[];
126
+ };
127
+ controllers: TProteumManifestController[];
128
+ commands: TProteumManifestCommand[];
129
+ routes: {
130
+ client: TProteumManifestRoute[];
131
+ server: TProteumManifestRoute[];
132
+ };
133
+ layouts: TProteumManifestLayout[];
134
+ diagnostics: TProteumManifestDiagnostic[];
135
+ };
@@ -0,0 +1,115 @@
1
+ export const traceCaptureModes = ['summary', 'resolve', 'deep'] as const;
2
+
3
+ export type TTraceCaptureMode = (typeof traceCaptureModes)[number];
4
+ type TTracePrimitive = string | number | boolean;
5
+
6
+ export const traceCallOrigins = ['ssr-fetcher', 'api-batch-fetcher', 'client-async'] as const;
7
+
8
+ export type TTraceCallOrigin = (typeof traceCallOrigins)[number];
9
+
10
+ export const traceEventTypes = [
11
+ 'request.start',
12
+ 'request.user',
13
+ 'auth.decode',
14
+ 'auth.route',
15
+ 'auth.check.start',
16
+ 'auth.check.rule',
17
+ 'auth.check.result',
18
+ 'auth.session',
19
+ 'resolve.start',
20
+ 'resolve.controller-route',
21
+ 'resolve.routes-evaluated',
22
+ 'resolve.route-skip',
23
+ 'resolve.route-match',
24
+ 'resolve.not-found',
25
+ 'controller.start',
26
+ 'controller.result',
27
+ 'setup.options',
28
+ 'context.create',
29
+ 'page.data',
30
+ 'ssr.payload',
31
+ 'render.start',
32
+ 'render.end',
33
+ 'response.send',
34
+ 'request.finish',
35
+ 'error',
36
+ ] as const;
37
+
38
+ export type TTraceEventType = (typeof traceEventTypes)[number];
39
+
40
+ export type TTraceSummaryValue =
41
+ | TTracePrimitive
42
+ | null
43
+ | { kind: 'undefined' }
44
+ | { kind: 'redacted'; reason: string }
45
+ | { kind: 'bigint'; value: string }
46
+ | { kind: 'symbol'; value: string }
47
+ | { kind: 'function'; name: string }
48
+ | { kind: 'date'; value: string }
49
+ | { kind: 'error'; name: string; message: string; stack?: string }
50
+ | { kind: 'buffer'; byteLength: number }
51
+ | { kind: 'array'; length: number; items: TTraceSummaryValue[]; truncated: boolean }
52
+ | {
53
+ kind: 'object';
54
+ constructorName: string;
55
+ keys: string[];
56
+ entries: { [key: string]: TTraceSummaryValue };
57
+ truncated: boolean;
58
+ }
59
+ | { kind: 'map'; size: number }
60
+ | { kind: 'set'; size: number };
61
+
62
+ export type TTraceEvent = {
63
+ index: number;
64
+ at: string;
65
+ elapsedMs: number;
66
+ type: TTraceEventType;
67
+ details: { [key: string]: TTraceSummaryValue };
68
+ };
69
+
70
+ export type TTraceCall = {
71
+ id: string;
72
+ parentId?: string;
73
+ origin: TTraceCallOrigin;
74
+ label: string;
75
+ method: string;
76
+ path: string;
77
+ fetcherId?: string;
78
+ startedAt: string;
79
+ finishedAt?: string;
80
+ durationMs?: number;
81
+ statusCode?: number;
82
+ errorMessage?: string;
83
+ requestDataKeys: string[];
84
+ requestData?: TTraceSummaryValue;
85
+ resultKeys: string[];
86
+ result?: TTraceSummaryValue;
87
+ };
88
+
89
+ export type TRequestTrace = {
90
+ id: string;
91
+ method: string;
92
+ path: string;
93
+ url: string;
94
+ capture: TTraceCaptureMode;
95
+ profilerSessionId?: string;
96
+ profilerOrigin?: string;
97
+ profilerParentRequestId?: string;
98
+ startedAt: string;
99
+ finishedAt?: string;
100
+ durationMs?: number;
101
+ statusCode?: number;
102
+ user?: string;
103
+ droppedEvents: number;
104
+ persistedFilepath?: string;
105
+ errorMessage?: string;
106
+ calls: TTraceCall[];
107
+ events: TTraceEvent[];
108
+ };
109
+
110
+ export type TRequestTraceListItem = Omit<TRequestTrace, 'events' | 'calls'> & { eventCount: number; callCount: number };
111
+
112
+ export type TRequestTraceListResponse = { requests: TRequestTraceListItem[] };
113
+ export type TRequestTraceResponse = { request: TRequestTrace };
114
+ export type TRequestTraceArmResponse = { armed: true; capture: TTraceCaptureMode };
115
+ export type TRequestTraceErrorResponse = { error: string };