proteum 2.1.0-3 → 2.1.0-5

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/README.md CHANGED
@@ -36,7 +36,7 @@ Proteum combines:
36
36
  ```text
37
37
  my-app/
38
38
  identity.yaml
39
- env.yaml
39
+ .env # optional file for required local env vars
40
40
  package.json
41
41
  client/
42
42
  pages/
@@ -63,7 +63,7 @@ my-app/
63
63
  Important files:
64
64
 
65
65
  - `identity.yaml`: app identity, naming, locale, and SEO-facing metadata defaults
66
- - `env.yaml`: environment contract loaded by the app
66
+ - `process.env` / optional `.env`: `PORT`, `ENV_*`, `URL`, and `TRACE_*` environment variables loaded by the app
67
67
  - `server/config/*.ts`: plain typed config exports consumed by the explicit app bootstrap
68
68
  - `server/index.ts`: default-exported `Application` subclass that instantiates root services and router plugins
69
69
  - `client/pages/**`: SSR page entrypoints registered through `Router.page(...)`
@@ -71,6 +71,25 @@ Important files:
71
71
  - `server/services/**`: business logic that extends `Service`
72
72
  - `.proteum/**`: framework-owned generated contracts and manifests
73
73
 
74
+ Required Proteum env vars:
75
+
76
+ - `ENV_NAME`: `local` or `server`
77
+ - `ENV_PROFILE`: `dev`, `testing`, or `prod`
78
+ - `PORT`: default router port
79
+ - `URL`: canonical absolute base URL for `Router.url(..., true)`
80
+
81
+ Proteum does not provide defaults for required env vars. They must be defined explicitly in `process.env` or `.env`.
82
+
83
+ Use `proteum explain env` to see the required env vars, their allowed values, and whether each one is currently provided.
84
+
85
+ Optional trace env vars:
86
+
87
+ - `TRACE_ENABLE`
88
+ - `TRACE_REQUESTS_LIMIT`
89
+ - `TRACE_EVENTS_LIMIT`
90
+ - `TRACE_CAPTURE`
91
+ - `TRACE_PERSIST_ON_ERROR`
92
+
74
93
  ## Example: Server Bootstrap
75
94
 
76
95
  Proteum app services are declared explicitly through typed config exports plus a concrete `Application` subclass.
@@ -87,7 +106,7 @@ type RouterBaseConfig = Omit<ServiceConfig<typeof Router>, 'plugins'>;
87
106
  export const usersConfig = Services.config(Users, {});
88
107
 
89
108
  export const routerBaseConfig = {
90
- domains: AppContainer.Environment.router.domains,
109
+ currentDomain: AppContainer.Environment.router.currentDomain,
91
110
  http: {
92
111
  domain: 'example.com',
93
112
  port: AppContainer.Environment.router.port,
@@ -265,6 +284,8 @@ proteum trace latest
265
284
 
266
285
  Proteum includes a dev-only in-memory request trace buffer for routing, controller, context, SSR, and render debugging.
267
286
 
287
+ When diagnosing or testing against an app, first read the default port from `PORT` or `./.proteum/manifest.json` and check whether a server is already running there. If it is, inspect the existing traces before reproducing the issue so you can collect past errors and their context.
288
+
268
289
  - `proteum trace requests`: list the most recent request summaries
269
290
  - `proteum trace latest`: show the latest captured request
270
291
  - `proteum trace show <requestId>`: inspect one trace in detail
@@ -275,19 +296,18 @@ Proteum includes a dev-only in-memory request trace buffer for routing, controll
275
296
  Default behavior:
276
297
 
277
298
  - tracing is enabled only in `profile: dev`
278
- - traces live in memory and are bounded by `trace.requestsLimit` and `trace.eventsLimit`
299
+ - traces live in memory and are bounded by `TRACE_REQUESTS_LIMIT` and `TRACE_EVENTS_LIMIT`
279
300
  - payloads are summarized, long strings are truncated, and sensitive fields such as cookies, passwords, and tokens are redacted
280
- - `persistOnError` can export crashing requests under `var/traces/`
301
+ - `TRACE_PERSIST_ON_ERROR` can export crashing requests under `var/traces/`
281
302
 
282
- `env.yaml` example:
303
+ Trace env example:
283
304
 
284
- ```yaml
285
- trace:
286
- enable: true
287
- requestsLimit: 200
288
- eventsLimit: 800
289
- capture: resolve
290
- persistOnError: true
305
+ ```bash
306
+ export TRACE_ENABLE=true
307
+ export TRACE_REQUESTS_LIMIT=200
308
+ export TRACE_EVENTS_LIMIT=800
309
+ export TRACE_CAPTURE=resolve
310
+ export TRACE_PERSIST_ON_ERROR=true
291
311
  ```
292
312
 
293
313
  Capture modes:
@@ -312,7 +332,7 @@ Proteum is built so an agent can answer these questions quickly and reliably:
312
332
  Proteum answers those questions with explicit artifacts:
313
333
 
314
334
  - `identity.yaml` for app identity
315
- - `env.yaml` for the environment surface
335
+ - `PORT`, `ENV_*`, `URL`, and `TRACE_*` env vars for the environment surface
316
336
  - `server/index.ts` for the explicit root service graph
317
337
  - `.proteum/manifest.json` for machine-readable app structure
318
338
  - `proteum explain --json` for structured framework introspection
@@ -321,7 +341,7 @@ Proteum answers those questions with explicit artifacts:
321
341
  If you are an LLM or automation agent, start here:
322
342
 
323
343
  1. Read `identity.yaml`.
324
- 2. Read `env.yaml`.
344
+ 2. Read `PORT`, the relevant `ENV_*`, `URL`, and `TRACE_*` env vars, or run `proteum explain env`.
325
345
  3. Inspect `server/index.ts` and `server/config/*.ts` for the explicit app bootstrap.
326
346
  4. Read `.proteum/manifest.json` or run `proteum explain --json`.
327
347
  5. Inspect `server/controllers/**` for request entrypoints.
@@ -12,7 +12,8 @@ When you enter a Proteum app, inspect it in this order:
12
12
  2. Inspect `./server/index.ts` and `./server/config/*.ts`.
13
13
  3. Inspect the touched `./server/controllers/**/*.ts`, `./server/services/**`, `./server/routes/**`, and `./client/pages/**` files.
14
14
  4. Run `npx proteum doctor` if routing or generation looks suspicious.
15
- 5. For request-time issues in dev, use `npx proteum trace` before adding temporary logs.
15
+ 5. If you need to diagnose or test against a running app, check the default port in `PORT` or `./.proteum/manifest.json` first.
16
+ 6. If a server is already running on that port, use `npx proteum trace` to inspect past requests, errors, and their context before reproducing the issue or adding temporary logs.
16
17
 
17
18
  ## Non-Negotiable Rules
18
19
 
@@ -37,7 +38,7 @@ Proteum reads these source files directly:
37
38
 
38
39
  - `package.json`
39
40
  - `identity.yaml`
40
- - `env.yaml`
41
+ - `process.env` via the `PORT`, `ENV_*`, `URL`, and `TRACE_*` env contract
41
42
  - `server/config/*.ts`
42
43
  - `server/index.ts`
43
44
  - `server/services/**/service.json`
@@ -238,12 +239,17 @@ Relevant aliases:
238
239
 
239
240
  1. Run `npx proteum explain --json`.
240
241
  2. Run `npx proteum doctor`.
241
- 3. If the issue is request-time behavior in dev, run:
242
- - `npx proteum trace arm --capture deep`
242
+ 3. Read the default port from `PORT` or `./.proteum/manifest.json` and check whether a server is already running there.
243
+ 4. If a server is already running on that default port, inspect existing traces first:
244
+ - `npx proteum trace requests --port <envPort>`
245
+ - `npx proteum trace latest --port <envPort>`
246
+ - `npx proteum trace show <requestId> --port <envPort>` when you need the full context for a past error
247
+ 5. If the issue is request-time behavior in dev and the existing traces are not enough, run:
248
+ - `npx proteum trace arm --capture deep --port <envPort>`
243
249
  - reproduce the failing request once
244
- - `npx proteum trace latest` or `npx proteum trace show <requestId>`
245
- 4. Inspect the touched controller, service, route, or page source.
246
- 5. Only add temporary logging if the trace is insufficient.
250
+ - `npx proteum trace latest --port <envPort>` or `npx proteum trace show <requestId> --port <envPort>`
251
+ 6. Inspect the touched controller, service, route, or page source.
252
+ 7. Only add temporary logging if the trace is insufficient.
247
253
 
248
254
  For the full trace reference, see `node_modules/proteum/docs/request-tracing.md` in installed apps or `docs/request-tracing.md` in the framework repository.
249
255
 
@@ -274,6 +280,12 @@ Verify at the correct layer:
274
280
  - SSR changes: load the real page and inspect rendered HTML plus browser console
275
281
  - router/plugin changes: verify request context, auth, redirects, metrics, and validation on a running app
276
282
 
283
+ When you need to diagnose or test against an app that may already be running:
284
+
285
+ - read the default port from `PORT` or `./.proteum/manifest.json`
286
+ - check whether a server is already running on that port
287
+ - if it is, inspect `proteum trace requests`, `proteum trace latest`, and `proteum trace show <requestId>` before reproducing the issue
288
+
277
289
  Useful app commands:
278
290
 
279
291
  - `proteum dev`
@@ -25,6 +25,12 @@ For request-time issues in dev, inspect traces before adding temporary logs:
25
25
  - `npx proteum trace latest`
26
26
  - `npx proteum trace arm --capture deep`
27
27
 
28
+ If you need to diagnose or test against a running app:
29
+
30
+ - read the default port from `PORT` or `./.proteum/manifest.json`
31
+ - check whether a server is already running on that port
32
+ - if it is, inspect existing traces first to collect past errors and their context before reproducing the issue
33
+
28
34
  ## Project Structure
29
35
 
30
36
  This is a full-stack monolith project using TypeScript, Node.js, Preact, and Proteum.
@@ -77,13 +83,13 @@ When a feature depends on a curated list, keep one canonical catalog or registry
77
83
  1. evaluate or quantify the probability
78
84
  2. explain why
79
85
  3. suggest how to fix it
80
- - When the issue is request-time behavior in dev, prefer `npx proteum trace` over ad hoc logging.
86
+ - When the issue is request-time behavior in dev, first check whether a server is already running on the default port from `PORT` or `./.proteum/manifest.json`. If it is, prefer `npx proteum trace` to inspect past errors and their context before reproducing the issue or adding logs.
81
87
  - When you have finished your work, summarize in one top-level short sentence the changes you made since the beginning of the conversation. Output as `Commit message`.
82
88
 
83
89
  ## High-Impact Files
84
90
 
85
91
  - `tsconfig*.json`
86
- - `env*.yaml`
92
+ - `PORT`, `ENV_*`, `URL`, and `TRACE_*` env setup
87
93
  - Prisma-generated files
88
94
  - symbolic links
89
95
 
package/cli/app/config.ts CHANGED
@@ -2,20 +2,12 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
- /*
6
- NOTE: This is a copy of core/sever/app/config
7
- We can't import core deps here because it will cause the following error:
8
- "Can't use import when not a module"
9
- It will be possible to import core files when the CLI will be compiled as one output file with tsc
10
- And for that, we need to fix the TS errors for the CLI
11
- */
12
-
13
5
  // Npm
14
6
  import fs from 'fs-extra';
15
7
  import yaml from 'yaml';
16
8
 
17
9
  // Types
18
- import type { TEnvConfig } from '../../server/app/container/config';
10
+ import { parseProteumEnvConfig, type TProteumLoadedEnvConfig } from '../../common/env/proteumEnv';
19
11
  import { logVerbose } from '../runtime/verbose';
20
12
 
21
13
  /*----------------------------------
@@ -34,18 +26,13 @@ export default class ConfigParser {
34
26
  return yaml.parse(rawConfig);
35
27
  }
36
28
 
37
- public env(): TEnvConfig {
38
- // We assume that when we run 5htp dev, we're in local
39
- // Otherwise, we're in production environment (docker)
40
- logVerbose('[app] Using environment:', process.env.NODE_ENV);
41
- const envFileName = this.appDir + '/env.yaml';
42
- const envFile = this.loadYaml(envFileName);
29
+ public env(): TProteumLoadedEnvConfig {
30
+ logVerbose('[app] Loading Proteum env vars from process.env');
43
31
  return {
44
- ...envFile,
45
- router:
46
- this.routerPortOverride === undefined
47
- ? envFile.router
48
- : { ...envFile.router, port: this.routerPortOverride },
32
+ ...parseProteumEnvConfig({
33
+ appDir: this.appDir,
34
+ routerPortOverride: this.routerPortOverride,
35
+ }),
49
36
  version: 'CLI',
50
37
  };
51
38
  }
package/cli/bin.js CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  const path = require('path');
4
4
 
5
+ const clearInteractiveConsole = () => {
6
+ if (process.stdout.isTTY !== true || process.env.TERM === 'dumb') return;
7
+
8
+ process.stdout.write('\x1B[2J\x1B[3J\x1B[H');
9
+ };
10
+
5
11
  /*
6
12
  Why this exists (npm i vs npm link difference)
7
13
 
@@ -30,6 +36,8 @@ if (!process.env.TS_NODE_IGNORE) {
30
36
  process.env.TS_NODE_PROJECT = path.join(__dirname, 'tsconfig.json');
31
37
  process.env.TS_NODE_TRANSPILE_ONLY = '1';
32
38
 
39
+ clearInteractiveConsole();
40
+
33
41
  require('ts-node/register/transpile-only');
34
42
 
35
43
  const { runCli } = require('./index.ts');
@@ -45,8 +45,7 @@ export async function run() {
45
45
  { spaces: 4 },
46
46
  );
47
47
 
48
- // Copy config file
49
- fs.copyFileSync(app.paths.root + (simulate ? '/env.yaml' : '/env.server.yaml'), temp + '/env.yaml');
48
+ // Deployment now relies on exported ENV_*, URL, TRACE_*, and PORT variables instead of copied env config files.
50
49
 
51
50
  // Compile & Run Docker
52
51
  await cli.shell(`docker compose up --build`);
@@ -115,10 +115,11 @@ const printSection = (title: string, lines: string[]) => {
115
115
  const renderSummary = (manifest: TProteumManifest) => {
116
116
  const errorsCount = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'error').length;
117
117
  const warningsCount = manifest.diagnostics.filter((diagnostic) => diagnostic.level === 'warning').length;
118
+ const providedRequiredEnvVariables = manifest.env.requiredVariables.filter((variable) => variable.provided).length;
118
119
  const lines = [
119
120
  `Proteum manifest: ${formatFilepath(manifest, path.join(manifest.app.root, '.proteum', 'manifest.json'))}`,
120
121
  `App: ${manifest.app.identity.name} (${manifest.app.identity.identifier})`,
121
- `Env keys: ${manifest.env.loadedTopLevelKeys.join(', ') || 'none'}`,
122
+ `Env vars: ${providedRequiredEnvVariables}/${manifest.env.requiredVariables.length} required provided`,
122
123
  `Services: ${manifest.services.app.length} app, ${manifest.services.routerPlugins.length} router plugins`,
123
124
  `Controllers: ${manifest.controllers.length}`,
124
125
  `Routes: ${manifest.routes.client.length} client, ${manifest.routes.server.length} server`,
@@ -163,9 +164,16 @@ const renderHuman = (manifest: TProteumManifest, sectionNames: TExplainSectionNa
163
164
  if (sectionName === 'env') {
164
165
  sections.push(
165
166
  printSection('Env', [
166
- `- source=${formatFilepath(manifest, manifest.env.sourceFilepath)}`,
167
- `- loadedTopLevelKeys=${manifest.env.loadedTopLevelKeys.join(', ') || 'none'}`,
168
- `- requiredTopLevelKeys=${manifest.env.requiredTopLevelKeys.join(', ')}`,
167
+ `- source=${manifest.env.source}`,
168
+ `- loadedVariableKeys=${manifest.env.loadedVariableKeys.join(', ') || 'none'}`,
169
+ ...manifest.env.requiredVariables.map(
170
+ (variable) =>
171
+ `- ${variable.key} possibleValues=${variable.possibleValues.join(' | ')} provided=${variable.provided ? 'yes' : 'no'}`,
172
+ ),
173
+ `- resolved.name=${manifest.env.resolved.name}`,
174
+ `- resolved.profile=${manifest.env.resolved.profile}`,
175
+ `- resolved.routerPort=${manifest.env.resolved.routerPort}`,
176
+ `- resolved.routerCurrentDomain=${manifest.env.resolved.routerCurrentDomain}`,
169
177
  ]),
170
178
  );
171
179
  continue;
@@ -1,7 +1,6 @@
1
1
  import fs from 'fs-extra';
2
2
  import got from 'got';
3
3
  import path from 'path';
4
- import yaml from 'yaml';
5
4
  import { UsageError } from 'clipanion';
6
5
 
7
6
  import cli from '..';
@@ -12,7 +11,7 @@ import type {
12
11
  TRequestTraceListItem,
13
12
  TRequestTraceListResponse,
14
13
  TRequestTraceResponse,
15
- } from '@common/dev/requestTrace';
14
+ } from '../../common/dev/requestTrace';
16
15
 
17
16
  type TTraceAction = 'latest' | 'show' | 'requests' | 'arm' | 'export';
18
17
 
@@ -31,22 +30,33 @@ const getAction = () => {
31
30
 
32
31
  const normalizeBaseUrl = (value: string) => value.replace(/\/+$/, '');
33
32
 
33
+ const getRouterPortFromManifest = () => {
34
+ const manifestFilepath = path.join(cli.args.workdir as string, '.proteum', 'manifest.json');
35
+ if (!fs.existsSync(manifestFilepath)) return undefined;
36
+
37
+ const manifest = fs.readJsonSync(manifestFilepath, { throws: false }) as
38
+ | { env?: { resolved?: { routerPort?: number } } }
39
+ | undefined;
40
+ const port = manifest?.env?.resolved?.routerPort;
41
+
42
+ if (typeof port !== 'number' || port <= 0) return undefined;
43
+
44
+ return String(port);
45
+ };
46
+
34
47
  const getRouterPort = () => {
35
48
  const overridePort = typeof cli.args.port === 'string' && cli.args.port ? cli.args.port : '';
36
49
  if (overridePort) return overridePort;
37
50
 
38
- const envFilepath = path.join(cli.args.workdir as string, 'env.yaml');
39
- if (!fs.existsSync(envFilepath)) {
40
- throw new UsageError(`Could not find env.yaml in ${cli.args.workdir as string}. Pass --port or --url explicitly.`);
41
- }
51
+ const envPort = process.env.PORT?.trim();
52
+ if (envPort) return envPort;
42
53
 
43
- const envFile = yaml.parse(fs.readFileSync(envFilepath, 'utf8')) as { router?: { port?: number } };
44
- const port = envFile.router?.port;
45
- if (!port) {
46
- throw new UsageError(`Could not determine the router port from ${envFilepath}. Pass --port or --url explicitly.`);
47
- }
54
+ const manifestPort = getRouterPortFromManifest();
55
+ if (manifestPort) return manifestPort;
48
56
 
49
- return String(port);
57
+ throw new UsageError(
58
+ `Could not determine the router port from PORT or .proteum/manifest.json in ${cli.args.workdir as string}. Pass --port or --url explicitly.`,
59
+ );
50
60
  };
51
61
 
52
62
  const getRouterBaseUrls = () => {
@@ -1,9 +1,10 @@
1
1
  import path from 'path';
2
- import fs from 'fs-extra';
3
- import yaml from 'yaml';
4
2
 
5
3
  import app from '../../app';
6
4
  import cli from '../..';
5
+ import {
6
+ inspectProteumEnv,
7
+ } from '../../../common/env/proteumEnv';
7
8
  import { reservedRouteSetupKeys, routeSetupOptionKeys } from '../../../common/router/pageSetup';
8
9
  import {
9
10
  TProteumManifest,
@@ -15,20 +16,6 @@ import {
15
16
  import { writeProteumManifest } from '../common/proteumManifest';
16
17
  import { normalizeAbsolutePath, normalizePath } from './shared';
17
18
 
18
- const envRequiredTopLevelKeys = ['name', 'profile', 'router', 'console'];
19
-
20
- const getEnvTopLevelKeys = () => {
21
- const envFilepath = path.join(app.paths.root, 'env.yaml');
22
-
23
- if (!fs.existsSync(envFilepath)) return [];
24
-
25
- const rawEnv = yaml.parse(fs.readFileSync(envFilepath, 'utf8'));
26
-
27
- if (!rawEnv || typeof rawEnv !== 'object' || Array.isArray(rawEnv)) return [];
28
-
29
- return Object.keys(rawEnv).sort((a, b) => a.localeCompare(b));
30
- };
31
-
32
19
  const collectManifestDiagnostics = ({
33
20
  controllers,
34
21
  routes,
@@ -228,6 +215,8 @@ export const writeCurrentProteumManifest = ({
228
215
  routes: TProteumManifest['routes'];
229
216
  layouts: TProteumManifestLayout[];
230
217
  }) => {
218
+ const envInspection = inspectProteumEnv(app.paths.root);
219
+
231
220
  const manifest: TProteumManifest = {
232
221
  version: 1,
233
222
  app: {
@@ -252,9 +241,19 @@ export const writeCurrentProteumManifest = ({
252
241
  reservedRouteSetupKeys: [...reservedRouteSetupKeys],
253
242
  },
254
243
  env: {
255
- sourceFilepath: normalizeAbsolutePath(path.join(app.paths.root, 'env.yaml')),
256
- loadedTopLevelKeys: getEnvTopLevelKeys(),
257
- requiredTopLevelKeys: [...envRequiredTopLevelKeys],
244
+ source: 'process.env',
245
+ loadedVariableKeys: envInspection.loadedVariableKeys,
246
+ requiredVariables: envInspection.requiredVariables.map((variable) => ({
247
+ key: variable.key,
248
+ possibleValues: [...variable.possibleValues],
249
+ provided: variable.provided,
250
+ })),
251
+ resolved: {
252
+ name: app.env.name,
253
+ profile: app.env.profile,
254
+ routerPort: app.env.router.port,
255
+ routerCurrentDomain: app.env.router.currentDomain,
256
+ },
258
257
  },
259
258
  services,
260
259
  controllers,
@@ -80,7 +80,7 @@ export default function createCommonConfig(
80
80
  APP_NAME: JSON.stringify(app.identity.web.title),
81
81
  APP_OUTPUT_DIR: JSON.stringify(path.basename(app.outputPath(outputTarget))),
82
82
  PROTEUM_DEV_EVENT_PORT: JSON.stringify(dev ? (app.devEventPort ?? null) : null),
83
- PROTEUM_ROUTER_PORT_OVERRIDE: JSON.stringify(app.routerPortOverride ?? null),
83
+ PROTEUM_PORT_OVERRIDE: JSON.stringify(app.routerPortOverride ?? null),
84
84
  }),
85
85
 
86
86
  ...(dev ? [] : []),
@@ -100,9 +100,19 @@ export type TProteumManifest = {
100
100
  reservedRouteSetupKeys: string[];
101
101
  };
102
102
  env: {
103
- sourceFilepath: string;
104
- loadedTopLevelKeys: string[];
105
- requiredTopLevelKeys: string[];
103
+ source: string;
104
+ loadedVariableKeys: string[];
105
+ requiredVariables: {
106
+ key: string;
107
+ possibleValues: string[];
108
+ provided: boolean;
109
+ }[];
110
+ resolved: {
111
+ name: string;
112
+ profile: string;
113
+ routerPort: number;
114
+ routerCurrentDomain: string;
115
+ };
106
116
  };
107
117
  services: {
108
118
  app: TProteumManifestService[];
@@ -202,7 +202,7 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
202
202
  notes: [
203
203
  'This command talks to the running app over the dev-only `__proteum/trace` HTTP endpoints.',
204
204
  'Traces are stored in a bounded in-memory buffer with payload summarization and sensitive-field redaction.',
205
- 'Use `--port` when the app is not running on the router port declared in `env.yaml`, or `--url` when the host itself is non-standard.',
205
+ 'Use `--port` when the app is not running on the router port declared in `PORT`, or `--url` when the host itself is non-standard.',
206
206
  ],
207
207
  status: 'experimental',
208
208
  },
@@ -38,16 +38,9 @@ export default function App({ context }: { context: ClientContext }) {
38
38
  <DialogManager />
39
39
 
40
40
  {!layout ? (
41
- <>
42
- {/* TODO: move to app, because here, we're not aware that the router service has been defined */}
43
- <RouterComponent service={context.Router} />
44
- </>
41
+ <RouterComponent service={context.Router} />
45
42
  ) : (
46
- <>
47
- {' '}
48
- {/* Same as router/components/Page.tsx */}
49
- <layout.Component {...layoutProps} />
50
- </>
43
+ <layout.Component {...layoutProps} />
51
44
  )}
52
45
  </ReactClientContext.Provider>
53
46
  );
@@ -21,7 +21,6 @@ import BaseRouter, {
21
21
  TErrorRoute,
22
22
  TRouteOptions,
23
23
  TRouteModule,
24
- TDomainsList,
25
24
  matchRoute,
26
25
  buildUrl,
27
26
  } from '@common/router';
@@ -136,7 +135,7 @@ export default class ClientRouter<
136
135
  // Context data
137
136
  public ssrRoutes = browserWindow.routes || [];
138
137
  public ssrContext = browserWindow.ssr;
139
- public domains: TDomainsList = browserWindow.ssr?.domains || ({ current: window.location.origin } as TDomainsList);
138
+ public currentDomain = browserWindow.ssr?.currentDomain || window.location.origin;
140
139
  public context!: TRouterContext<this, this['app']>;
141
140
 
142
141
  public setLoading!: React.Dispatch<React.SetStateAction<boolean>>;
@@ -153,7 +152,7 @@ export default class ClientRouter<
153
152
  }
154
153
 
155
154
  public url = (path: string, params: {} = {}, absolute: boolean = true) =>
156
- buildUrl(path, params, this.domains, absolute);
155
+ buildUrl(path, params, this.currentDomain, absolute);
157
156
 
158
157
  public go(url: string | number, data: {} = {}, opt: { newTab?: boolean } = {}) {
159
158
  // Error code
@@ -1,6 +1,7 @@
1
1
  export const traceCaptureModes = ['summary', 'resolve', 'deep'] as const;
2
2
 
3
3
  export type TTraceCaptureMode = (typeof traceCaptureModes)[number];
4
+ type TTracePrimitive = string | number | boolean;
4
5
 
5
6
  export const traceEventTypes = [
6
7
  'request.start',
@@ -27,7 +28,7 @@ export const traceEventTypes = [
27
28
  export type TTraceEventType = (typeof traceEventTypes)[number];
28
29
 
29
30
  export type TTraceSummaryValue =
30
- | PrimitiveValue
31
+ | TTracePrimitive
31
32
  | null
32
33
  | { kind: 'undefined' }
33
34
  | { kind: 'redacted'; reason: string }
@@ -0,0 +1,284 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import dotenv from 'dotenv';
4
+
5
+ export type TProteumEnvName = 'local' | 'server';
6
+ export type TProteumEnvProfile = 'dev' | 'testing' | 'prod';
7
+ export type TProteumTraceCapture = 'summary' | 'resolve' | 'deep';
8
+ export type TProteumRequiredEnvVariable = {
9
+ key: TProteumRequiredEnvVariableKey;
10
+ possibleValues: string[];
11
+ provided: boolean;
12
+ };
13
+ export type TProteumEnvInspection = {
14
+ loadedVariableKeys: string[];
15
+ requiredVariables: TProteumRequiredEnvVariable[];
16
+ };
17
+
18
+ export type TProteumEnvConfig = {
19
+ name: TProteumEnvName;
20
+ profile: TProteumEnvProfile;
21
+ router: {
22
+ port: number;
23
+ currentDomain: string;
24
+ };
25
+ trace: {
26
+ enable: boolean;
27
+ requestsLimit: number;
28
+ eventsLimit: number;
29
+ capture: TProteumTraceCapture;
30
+ persistOnError: boolean;
31
+ };
32
+ };
33
+
34
+ export type TProteumLoadedEnvConfig = TProteumEnvConfig & { version: string };
35
+
36
+ const dotenvFileNames = ['.env'];
37
+ const requiredProteumEnvVariableKeys = ['ENV_NAME', 'ENV_PROFILE', 'PORT', 'URL'] as const;
38
+ const optionalProteumEnvVariablePrefixes = ['TRACE_'] as const;
39
+
40
+ export type TProteumRequiredEnvVariableKey = (typeof requiredProteumEnvVariableKeys)[number];
41
+
42
+ const requiredProteumEnvVariablePossibleValues: Record<TProteumRequiredEnvVariableKey, string[]> = {
43
+ ENV_NAME: ['local', 'server'],
44
+ ENV_PROFILE: ['dev', 'testing', 'prod'],
45
+ PORT: ['integer between 1 and 65535'],
46
+ URL: ['absolute URL'],
47
+ };
48
+
49
+ const envDefinitionHint = (appDir: string) => `Define it in process.env or ${appDir}/.env.`;
50
+ const isProvidedEnvValue = (value: string | undefined) => typeof value === 'string' && value.trim() !== '';
51
+
52
+ const formatRequiredEnvVariableStatus = (variable: TProteumRequiredEnvVariable) =>
53
+ `- ${variable.key} possibleValues=${variable.possibleValues.join(' | ')} provided=${variable.provided ? 'yes' : 'no'}`;
54
+
55
+ const createProteumEnvError = ({
56
+ appDir,
57
+ message,
58
+ }: {
59
+ appDir: string;
60
+ message: string;
61
+ }) => {
62
+ const inspection = inspectProteumEnv(appDir);
63
+
64
+ return new Error(
65
+ [message, envDefinitionHint(appDir), '', 'Required env variables:', ...inspection.requiredVariables.map(formatRequiredEnvVariableStatus)].join(
66
+ '\n',
67
+ ),
68
+ );
69
+ };
70
+
71
+ const parseBooleanEnvValue = ({
72
+ key,
73
+ value,
74
+ appDir,
75
+ }: {
76
+ key: string;
77
+ value: string | undefined;
78
+ appDir: string;
79
+ }) => {
80
+ if (value === undefined || value === '') return undefined;
81
+
82
+ const normalized = value.trim().toLowerCase();
83
+ if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;
84
+ if (['0', 'false', 'no', 'off'].includes(normalized)) return false;
85
+
86
+ throw createProteumEnvError({
87
+ appDir,
88
+ message: `Invalid boolean value for ${key}: "${value}". Expected one of: 1, 0, true, false, yes, no, on, off.`,
89
+ });
90
+ };
91
+
92
+ const parseIntegerEnvValue = ({
93
+ key,
94
+ value,
95
+ appDir,
96
+ min = 1,
97
+ }: {
98
+ key: string;
99
+ value: string;
100
+ appDir: string;
101
+ min?: number;
102
+ }) => {
103
+ const parsed = Number.parseInt(value, 10);
104
+ if (Number.isNaN(parsed) || parsed < min) {
105
+ throw createProteumEnvError({
106
+ appDir,
107
+ message: `Invalid integer value for ${key}: "${value}". Expected an integer greater than or equal to ${min}.`,
108
+ });
109
+ }
110
+
111
+ return parsed;
112
+ };
113
+
114
+ const getRequiredEnvValue = ({ key, appDir }: { key: TProteumRequiredEnvVariableKey; appDir: string }) => {
115
+ const value = process.env[key]?.trim();
116
+ if (value) return value;
117
+
118
+ throw createProteumEnvError({
119
+ appDir,
120
+ message: `Missing required Proteum env variable "${key}".`,
121
+ });
122
+ };
123
+
124
+ const parseEnvName = (value: string, appDir: string): TProteumEnvName => {
125
+ if (value === 'local' || value === 'server') return value;
126
+ throw createProteumEnvError({
127
+ appDir,
128
+ message: `Invalid ENV_NAME "${value}". Expected "local" or "server".`,
129
+ });
130
+ };
131
+
132
+ const parseEnvProfile = (value: string, appDir: string): TProteumEnvProfile => {
133
+ if (value === 'dev' || value === 'testing' || value === 'prod') return value;
134
+ throw createProteumEnvError({
135
+ appDir,
136
+ message: `Invalid ENV_PROFILE "${value}". Expected "dev", "testing", or "prod".`,
137
+ });
138
+ };
139
+
140
+ const parseTraceCapture = ({
141
+ value,
142
+ appDir,
143
+ }: {
144
+ value: string | undefined;
145
+ appDir: string;
146
+ }): TProteumTraceCapture | undefined => {
147
+ if (value === undefined || value === '') return undefined;
148
+ if (value === 'summary' || value === 'resolve' || value === 'deep') return value;
149
+
150
+ throw createProteumEnvError({
151
+ appDir,
152
+ message: `Invalid TRACE_CAPTURE "${value}". Expected "summary", "resolve", or "deep".`,
153
+ });
154
+ };
155
+
156
+ const parseAbsoluteUrl = ({
157
+ key,
158
+ value,
159
+ appDir,
160
+ }: {
161
+ key: string;
162
+ value: string;
163
+ appDir: string;
164
+ }) => {
165
+ let url: URL;
166
+
167
+ try {
168
+ url = new URL(value);
169
+ } catch {
170
+ throw createProteumEnvError({
171
+ appDir,
172
+ message: `Invalid absolute URL for ${key}: "${value}". Expected an absolute http:// or https:// URL.`,
173
+ });
174
+ }
175
+
176
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
177
+ throw createProteumEnvError({
178
+ appDir,
179
+ message: `Invalid absolute URL for ${key}: "${value}". Expected an absolute http:// or https:// URL.`,
180
+ });
181
+ }
182
+
183
+ return value;
184
+ };
185
+
186
+ export const loadOptionalProteumDotenv = (appDir: string) => {
187
+ for (const filename of dotenvFileNames) {
188
+ const filepath = path.join(appDir, filename);
189
+ if (!fs.existsSync(filepath)) continue;
190
+ dotenv.config({ path: filepath, quiet: true });
191
+ }
192
+ };
193
+
194
+ export const getLoadedProteumEnvVariableKeys = () =>
195
+ Object.keys(process.env)
196
+ .filter(
197
+ (key) =>
198
+ requiredProteumEnvVariableKeys.includes(key as TProteumRequiredEnvVariableKey) ||
199
+ optionalProteumEnvVariablePrefixes.some((prefix) => key.startsWith(prefix)),
200
+ )
201
+ .sort((a, b) => a.localeCompare(b));
202
+
203
+ export const inspectProteumEnv = (appDir: string): TProteumEnvInspection => {
204
+ loadOptionalProteumDotenv(appDir);
205
+
206
+ return {
207
+ loadedVariableKeys: getLoadedProteumEnvVariableKeys(),
208
+ requiredVariables: requiredProteumEnvVariableKeys.map((key) => ({
209
+ key,
210
+ possibleValues: [...requiredProteumEnvVariablePossibleValues[key]],
211
+ provided: isProvidedEnvValue(process.env[key]),
212
+ })),
213
+ };
214
+ };
215
+
216
+ export const parseProteumEnvConfig = ({
217
+ appDir,
218
+ routerPortOverride,
219
+ }: {
220
+ appDir: string;
221
+ routerPortOverride?: number;
222
+ }): TProteumEnvConfig => {
223
+ loadOptionalProteumDotenv(appDir);
224
+
225
+ const name = parseEnvName(getRequiredEnvValue({ key: 'ENV_NAME', appDir }), appDir);
226
+ const profile = parseEnvProfile(getRequiredEnvValue({ key: 'ENV_PROFILE', appDir }), appDir);
227
+ const configuredRouterPort = parseIntegerEnvValue({
228
+ key: 'PORT',
229
+ value: getRequiredEnvValue({ key: 'PORT', appDir }),
230
+ appDir,
231
+ });
232
+ const currentDomain = parseAbsoluteUrl({
233
+ key: 'URL',
234
+ value: getRequiredEnvValue({ key: 'URL', appDir }),
235
+ appDir,
236
+ });
237
+
238
+ const traceEnable = parseBooleanEnvValue({
239
+ key: 'TRACE_ENABLE',
240
+ value: process.env.TRACE_ENABLE,
241
+ appDir,
242
+ });
243
+ const tracePersistOnError = parseBooleanEnvValue({
244
+ key: 'TRACE_PERSIST_ON_ERROR',
245
+ value: process.env.TRACE_PERSIST_ON_ERROR,
246
+ appDir,
247
+ });
248
+ const traceRequestsLimit = process.env.TRACE_REQUESTS_LIMIT?.trim();
249
+ const traceEventsLimit = process.env.TRACE_EVENTS_LIMIT?.trim();
250
+ const traceCapture = parseTraceCapture({
251
+ value: process.env.TRACE_CAPTURE?.trim(),
252
+ appDir,
253
+ });
254
+
255
+ return {
256
+ name,
257
+ profile,
258
+ router: {
259
+ port: routerPortOverride === undefined ? configuredRouterPort : routerPortOverride,
260
+ currentDomain,
261
+ },
262
+ trace: {
263
+ enable: traceEnable ?? profile === 'dev',
264
+ requestsLimit:
265
+ traceRequestsLimit === undefined || traceRequestsLimit === ''
266
+ ? 200
267
+ : parseIntegerEnvValue({
268
+ key: 'TRACE_REQUESTS_LIMIT',
269
+ value: traceRequestsLimit,
270
+ appDir,
271
+ }),
272
+ eventsLimit:
273
+ traceEventsLimit === undefined || traceEventsLimit === ''
274
+ ? 800
275
+ : parseIntegerEnvValue({
276
+ key: 'TRACE_EVENTS_LIMIT',
277
+ value: traceEventsLimit,
278
+ appDir,
279
+ }),
280
+ capture: traceCapture ?? 'resolve',
281
+ persistOnError: tracePersistOnError ?? profile === 'dev',
282
+ },
283
+ };
284
+ };
@@ -106,8 +106,6 @@ export type TRouteModule<TRegisteredRoute = any> = {
106
106
  __register: TAppArrowFunction<TRegisteredRoute>;
107
107
  };
108
108
 
109
- export type TDomainsList = { [endpointId: string]: string } & { current: string };
110
-
111
109
  export const defaultOptions: Pick<TRouteOptions, 'priority'> = { priority: 0 };
112
110
 
113
111
  /*----------------------------------
@@ -116,31 +114,15 @@ export const defaultOptions: Pick<TRouteOptions, 'priority'> = { priority: 0 };
116
114
  export const buildUrl = (
117
115
  path: string,
118
116
  params: { [key: string]: any },
119
- domains: { [alias: string]: string },
117
+ currentDomain: string,
120
118
  absolute: boolean,
121
119
  ) => {
122
120
  let prefix: string = '';
123
121
 
124
122
  // Relative to domain
125
- if (path[0] === '/' && absolute) prefix = domains.current;
126
- // Other domains of the project
127
- else if (path[0] === '@') {
128
- // Extract domain ID from path
129
- let domainId: string;
130
- let slackPos = path.indexOf('/');
131
- if (slackPos === -1) slackPos = path.length;
132
- domainId = path.substring(1, slackPos);
133
- path = path.substring(slackPos);
134
-
135
- // Get domain
136
- const domain = domains[domainId];
137
- if (domain === undefined) throw new Error('Unknown API endpoint ID: ' + domainId);
138
-
139
- // Return full url
140
- prefix = domain;
141
-
142
- // Absolute URL
143
- }
123
+ if (path[0] === '/' && absolute) prefix = currentDomain;
124
+ else if (path[0] === '@')
125
+ throw new Error(`Proteum no longer supports Router.url() domain aliases. Use a root-relative path or absolute URL instead: "${path}".`);
144
126
 
145
127
  // Path parapeters
146
128
  const searchParams = new URLSearchParams();
@@ -19,6 +19,12 @@ proteum trace export <requestId>
19
19
  proteum trace latest --url http://127.0.0.1:3010
20
20
  ```
21
21
 
22
+ Before reproducing a bug or starting a new test pass:
23
+
24
+ - read the default port from `PORT` or `./.proteum/manifest.json`
25
+ - check whether a dev server is already running on that port
26
+ - if it is, inspect `proteum trace requests`, `proteum trace latest`, and `proteum trace show <requestId>` first so you can capture past errors and their context
27
+
22
28
  Typical debugging flow:
23
29
 
24
30
  ```bash
@@ -54,15 +60,14 @@ Use `deep` selectively. It is for one-off investigation, not continuous capture.
54
60
 
55
61
  ## Configuration
56
62
 
57
- Add trace settings in `env.yaml`:
63
+ Set trace behavior with env vars:
58
64
 
59
- ```yaml
60
- trace:
61
- enable: true
62
- requestsLimit: 200
63
- eventsLimit: 800
64
- capture: resolve
65
- persistOnError: true
65
+ ```bash
66
+ export TRACE_ENABLE=true
67
+ export TRACE_REQUESTS_LIMIT=200
68
+ export TRACE_EVENTS_LIMIT=800
69
+ export TRACE_CAPTURE=resolve
70
+ export TRACE_PERSIST_ON_ERROR=true
66
71
  ```
67
72
 
68
73
  Notes:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "proteum",
3
3
  "description": "LLM-first Opinionated Typescript Framework for web applications.",
4
- "version": "2.1.0-3",
4
+ "version": "2.1.0-5",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/proteum.git",
7
7
  "license": "MIT",
@@ -12,10 +12,10 @@ import fs from 'fs-extra';
12
12
  import yaml from 'yaml';
13
13
 
14
14
  // Types
15
- import type { TDomainsList } from '@common/router';
16
- import type { TLogProfile } from './console';
15
+ import { parseProteumEnvConfig, type TProteumLoadedEnvConfig } from '../../../common/env/proteumEnv';
17
16
 
18
- declare const PROTEUM_ROUTER_PORT_OVERRIDE: number | null;
17
+ declare const PROTEUM_PORT_OVERRIDE: number | null;
18
+ declare const BUILD_DATE: string;
19
19
 
20
20
  /*----------------------------------
21
21
  - TYPES
@@ -31,50 +31,8 @@ declare global {
31
31
  }
32
32
  }
33
33
 
34
- /*
35
- name: server
36
- profile: prod
37
-
38
- router:
39
- port: 80
40
- domains:
41
- current: 'https://recruiters.becrosspath.com'
42
- recruiters: 'https://recruiters.becrosspath.com'
43
- landing: 'https://becrosspath.com'
44
- employers: 'https://employers.becrosspath.com'
45
- candidates: 'https://candidates.becrosspath.com'
46
- csm: 'https://csm.becrosspath.com'
47
-
48
- database:
49
- name: 'aws'
50
- databases: [railway]
51
- host: 'mysql-z7vp.railway.internal'
52
- port: 3306
53
- login: root
54
- password: "GMnVsczoyYkyzwvVqDkMUOAIjVsumEev"
55
-
56
- console:
57
- enable: false
58
- debug: false
59
- bufferLimit: 10000
60
- level: 'log'
61
- */
62
-
63
34
  export type TEnvName = TEnvConfig['name'];
64
- export type TEnvConfig = {
65
- name: 'local' | 'server';
66
- profile: 'dev' | 'testing' | 'prod';
67
-
68
- router: { port: number; domains: TDomainsList };
69
- console: { enable: boolean; debug: boolean; bufferLimit: number; level: TLogProfile };
70
- trace: {
71
- enable: boolean;
72
- requestsLimit: number;
73
- eventsLimit: number;
74
- capture: 'summary' | 'resolve' | 'deep';
75
- persistOnError: boolean;
76
- };
77
- };
35
+ export type TEnvConfig = TProteumLoadedEnvConfig;
78
36
 
79
37
  type AppIdentityConfig = {
80
38
  name: string;
@@ -105,8 +63,7 @@ export type AppConfig = { env: Config.Env; identity: Config.Identity };
105
63
  const debug = false;
106
64
 
107
65
  const getRouterPortOverride = () => {
108
- if (typeof PROTEUM_ROUTER_PORT_OVERRIDE !== 'undefined' && PROTEUM_ROUTER_PORT_OVERRIDE !== null)
109
- return PROTEUM_ROUTER_PORT_OVERRIDE;
66
+ if (typeof PROTEUM_PORT_OVERRIDE !== 'undefined' && PROTEUM_PORT_OVERRIDE !== null) return PROTEUM_PORT_OVERRIDE;
110
67
 
111
68
  return undefined;
112
69
  };
@@ -127,23 +84,13 @@ export default class ConfigParser {
127
84
  }
128
85
 
129
86
  public env(): TEnvConfig {
130
- // We assume that when we run 5htp dev, we're in local
131
- // Otherwise, we're in production environment (docker)
132
- debug && console.info('[app] Using environment:', process.env.NODE_ENV);
133
- const envFileName = this.appDir + '/env.yaml';
134
- const envFile = this.loadYaml(envFileName);
135
- const routerPortOverride = getRouterPortOverride();
136
- const traceConfig = envFile.trace || {};
87
+ debug && console.info('[app] Loading Proteum env vars from process.env');
88
+
137
89
  return {
138
- ...envFile,
139
- router: routerPortOverride === undefined ? envFile.router : { ...envFile.router, port: routerPortOverride },
140
- trace: {
141
- enable: traceConfig.enable ?? envFile.profile === 'dev',
142
- requestsLimit: traceConfig.requestsLimit ?? 200,
143
- eventsLimit: traceConfig.eventsLimit ?? 800,
144
- capture: traceConfig.capture ?? 'resolve',
145
- persistOnError: traceConfig.persistOnError ?? envFile.profile === 'dev',
146
- },
90
+ ...parseProteumEnvConfig({
91
+ appDir: this.appDir,
92
+ routerPortOverride: getRouterPortOverride(),
93
+ }),
147
94
  version: BUILD_DATE,
148
95
  };
149
96
  }
@@ -23,9 +23,10 @@ import type ServerRequest from '@server/services/router/request';
23
23
  - SERVICE CONFIG
24
24
  ----------------------------------*/
25
25
 
26
- export type TLogProfile = 'silly' | 'info' | 'warn' | 'error';
26
+ export type TLogProfile = 'silly' | 'log' | 'info' | 'warn' | 'error';
27
27
 
28
28
  export type Config = { debug?: boolean; enable: boolean; bufferLimit: number; level: TLogProfile };
29
+ export const defaultConsoleConfig: Config = { enable: false, debug: false, bufferLimit: 10000, level: 'log' };
29
30
 
30
31
  export type Hooks = {};
31
32
 
@@ -14,7 +14,7 @@ import type Application from '..';
14
14
  import type { StartedServicesIndex } from '../service';
15
15
  import Services, { ServicesContainer } from '../service/container';
16
16
  import ConfigParser, { TEnvConfig } from './config';
17
- import Console from './console';
17
+ import Console, { defaultConsoleConfig } from './console';
18
18
  import Trace from './trace';
19
19
  import type ServerRequest from '@server/services/router/request';
20
20
 
@@ -53,7 +53,7 @@ export class ApplicationContainer<TServicesIndex extends StartedServicesIndex =
53
53
  const configParser = new ConfigParser(this.path.root);
54
54
  this.Environment = configParser.env();
55
55
  this.Identity = configParser.identity();
56
- this.Console = new Console(this, this.Environment.console);
56
+ this.Console = new Console(this, defaultConsoleConfig);
57
57
  this.Trace = new Trace(this, this.Environment.trace);
58
58
  }
59
59
 
@@ -32,7 +32,6 @@ import BaseRouter, {
32
32
  defaultOptions,
33
33
  matchRoute,
34
34
  buildUrl,
35
- TDomainsList,
36
35
  } from '@common/router';
37
36
  import type { TSsrUnresolvedRoute, TRegisterPageArgs } from '@common/router/contracts';
38
37
  import { buildRegex, getRegisterPageArgs } from '@common/router/register';
@@ -108,7 +107,7 @@ export type Config<
108
107
 
109
108
  disk?: string; // Disk driver ID
110
109
 
111
- domains: TDomainsList;
110
+ currentDomain: string;
112
111
 
113
112
  http: HttpServiceConfig;
114
113
 
@@ -356,7 +355,7 @@ export default class ServerRouter<
356
355
  }
357
356
 
358
357
  public url = (path: string, params: {} = {}, absolute: boolean = true) =>
359
- buildUrl(path, params, this.config.domains, absolute);
358
+ buildUrl(path, params, this.config.currentDomain, absolute);
360
359
 
361
360
  /*----------------------------------
362
361
  - REGISTER
@@ -14,7 +14,7 @@ import express from 'express';
14
14
  import context from '@server/context';
15
15
  import type { AnyRouterService, default as ServerRouter, TServerRouter, TAnyRouter } from '@server/services/router';
16
16
  import ServerRequest from '@server/services/router/request';
17
- import { TMatchedRoute, TRoute, TAnyRoute, TDomainsList } from '@common/router';
17
+ import { TMatchedRoute, TRoute, TAnyRoute } from '@common/router';
18
18
  import { NotFound, Forbidden, Anomaly } from '@common/errors';
19
19
  import BaseResponse, { TResponseData } from '@common/router/response';
20
20
  import { splitRouteSetupResult } from '@common/router/pageSetup';
@@ -38,7 +38,7 @@ export type TBasicSSrData = {
38
38
  request: { data: TObjetDonnees; id: string };
39
39
  page: { chunkId: string; data?: TObjetDonnees };
40
40
  user: TBasicUser | null;
41
- domains: TDomainsList;
41
+ currentDomain: string;
42
42
  };
43
43
 
44
44
  type TServerRouterApplication<TRouter extends TServerRouter> =
@@ -277,7 +277,7 @@ export default class ServerResponse<
277
277
  request: { id: this.request.id, data: this.request.data },
278
278
  page: { chunkId: page.chunkId || '', data: page.data },
279
279
  user: this.request.user,
280
- domains: this.router.config.domains,
280
+ currentDomain: this.router.config.currentDomain,
281
281
  ...customSsrData,
282
282
  };
283
283
  }
@@ -43,24 +43,17 @@ declare type PrimitiveValue = string | number | boolean;
43
43
  /*type TEnvConfig = {
44
44
  name: 'local' | 'server',
45
45
  profile: 'dev' | 'testing' | 'prod',
46
-
46
+
47
47
  router: {
48
48
  port: number,
49
- domains: TDomainsList
50
- },
51
- database: {
52
- name: string,
53
- databases: string[],
54
- host: string,
55
- port: number,
56
- login: string,
57
- password: string,
49
+ currentDomain: string
58
50
  },
59
- console: {
51
+ trace: {
60
52
  enable: boolean,
61
- debug: boolean,
62
- bufferLimit: number,
63
- level: TLogProfile,
53
+ requestsLimit: number,
54
+ eventsLimit: number,
55
+ capture: 'summary' | 'resolve' | 'deep',
56
+ persistOnError: boolean,
64
57
  },
65
58
  }*/
66
59