@ressjs/vite-router 0.6.0-rc.0 → 0.6.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/codegen.d.ts +10 -1
- package/dist/config/codegen.js +15 -9
- package/dist/config/env.d.ts +2 -0
- package/dist/config/env.js +6 -3
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/load.d.ts +0 -1
- package/dist/config/load.js +2 -1
- package/dist/config/types.d.ts +8 -5
- package/dist/config/validate.js +67 -0
- package/dist/config/watch.d.ts +22 -0
- package/dist/config/watch.js +57 -0
- package/dist/fs/canonical-path.d.ts +12 -0
- package/dist/fs/canonical-path.js +28 -0
- package/dist/fs/shared-modules.d.ts +22 -0
- package/dist/fs/shared-modules.js +44 -0
- package/dist/helpers/request-handler.js +0 -8
- package/dist/index.d.ts +6 -5
- package/dist/index.js +9 -2
- package/dist/isr/handler.d.ts +2 -0
- package/dist/isr/handler.js +1 -1
- package/dist/isr/response.d.ts +3 -1
- package/dist/isr/response.js +4 -2
- package/dist/plugin/index.d.ts +40 -5
- package/dist/plugin/index.js +81 -8
- package/dist/plugin/strip-server-exports.d.ts +39 -0
- package/dist/plugin/strip-server-exports.js +258 -0
- package/dist/render.d.ts +1 -6
- package/dist/render.js +6 -40
- package/dist/router.js +14 -0
- package/dist/routes/scan.d.ts +6 -0
- package/dist/routes/scan.js +16 -4
- package/dist/runtime/dev-server.d.ts +3 -1
- package/dist/runtime/dev-server.js +56 -4
- package/dist/runtime/module-loader.d.ts +16 -1
- package/dist/runtime/module-loader.js +15 -1
- package/dist/runtime/template.js +11 -1
- package/dist/security/client-props.d.ts +9 -17
- package/dist/security/client-props.js +12 -31
- package/dist/security/config.d.ts +6 -9
- package/dist/security/config.js +5 -4
- package/dist/security/errors.d.ts +0 -11
- package/dist/security/errors.js +0 -21
- package/dist/security/index.d.ts +3 -3
- package/dist/security/index.js +2 -4
- package/dist/variants/assets.d.ts +1 -0
- package/dist/variants/assets.js +19 -1
- package/dist/variants/resolve.d.ts +1 -1
- package/dist/variants/resolve.js +3 -37
- package/package.json +4 -4
package/dist/config/codegen.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { PlatformConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Tipos generados a partir de lo que el proyecto declara.
|
|
4
|
+
*
|
|
5
|
+
* Sin esto, declarar un token de plataforma propio en `ress.config.ts` funciona
|
|
6
|
+
* en tiempo de ejecución pero el editor no lo conoce: el desarrollador escribe
|
|
7
|
+
* `'kaios'` y no recibe ni sugerencia ni error si lo escribe mal. Los archivos se
|
|
8
|
+
* generan, no se versionan, y se rehacen cuando cambia la configuración que los
|
|
9
|
+
* origina.
|
|
10
|
+
*/
|
|
2
11
|
/**
|
|
3
12
|
* Amplía `PlatformValueMap` de `@ressjs/platform` con los tokens del proyecto.
|
|
4
13
|
*
|
|
@@ -22,7 +31,7 @@ export declare function generateProjectConfigTypes(values: Record<string, unknow
|
|
|
22
31
|
*/
|
|
23
32
|
export declare function writeGeneratedTypes(root: string, files: Record<string, string>): Promise<string[]>;
|
|
24
33
|
/**
|
|
25
|
-
* Genera `types/` para
|
|
34
|
+
* Genera `types/` sólo para proyectos con `tsconfig.json` cuya configuración se cargó con
|
|
26
35
|
* `loadConfig`. La usan el plugin al arrancar y `ress info`, para que un
|
|
27
36
|
* proyecto recién creado o un clon limpio tengan sus tipos sin levantar nada.
|
|
28
37
|
*/
|
package/dist/config/codegen.js
CHANGED
|
@@ -13,8 +13,6 @@ exports.writeProjectTypes = writeProjectTypes;
|
|
|
13
13
|
* generan, no se versionan, y se rehacen cuando cambia la configuración que los
|
|
14
14
|
* origina.
|
|
15
15
|
*/
|
|
16
|
-
const BANNER = '// Generado por ress.js a partir de la configuración del proyecto.\n' +
|
|
17
|
-
'// No editar a mano ni versionar: se rehace en cada arranque.\n';
|
|
18
16
|
/**
|
|
19
17
|
* Amplía `PlatformValueMap` de `@ressjs/platform` con los tokens del proyecto.
|
|
20
18
|
*
|
|
@@ -34,14 +32,13 @@ function generatePlatformTypes(platform) {
|
|
|
34
32
|
if (byAxis.size === 0) {
|
|
35
33
|
// Un archivo vacío igual se escribe: si el proyecto quitó sus tokens, dejar
|
|
36
34
|
// el anterior mantendría en el autocompletado valores que ya no existen.
|
|
37
|
-
return
|
|
35
|
+
return 'export {}\n';
|
|
38
36
|
}
|
|
39
37
|
const fields = [...byAxis.entries()]
|
|
40
38
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
41
39
|
.map(([axis, tokens]) => ` ${axis}: ${tokens.map(quote).join(' | ')}`)
|
|
42
40
|
.join('\n');
|
|
43
|
-
return (
|
|
44
|
-
"declare module '@ressjs/platform' {\n" +
|
|
41
|
+
return ("declare module '@ressjs/platform' {\n" +
|
|
45
42
|
' interface PlatformValueMap {\n' +
|
|
46
43
|
fields +
|
|
47
44
|
'\n }\n}\n\nexport {}\n');
|
|
@@ -55,10 +52,9 @@ function generatePlatformTypes(platform) {
|
|
|
55
52
|
function generateProjectConfigTypes(values) {
|
|
56
53
|
const keys = Object.keys(values).sort();
|
|
57
54
|
if (keys.length === 0)
|
|
58
|
-
return
|
|
55
|
+
return 'export {}\n';
|
|
59
56
|
const fields = keys.map((key) => ` ${propertyName(key)}: ${typeOf(values[key])}`).join('\n');
|
|
60
|
-
return (
|
|
61
|
-
"declare module '@ressjs/config' {\n" +
|
|
57
|
+
return ("declare module '@ressjs/config' {\n" +
|
|
62
58
|
' interface ProjectConfig {\n' +
|
|
63
59
|
fields +
|
|
64
60
|
'\n }\n}\n\nexport {}\n');
|
|
@@ -118,11 +114,21 @@ async function writeGeneratedTypes(root, files) {
|
|
|
118
114
|
return written;
|
|
119
115
|
}
|
|
120
116
|
/**
|
|
121
|
-
* Genera `types/` para
|
|
117
|
+
* Genera `types/` sólo para proyectos con `tsconfig.json` cuya configuración se cargó con
|
|
122
118
|
* `loadConfig`. La usan el plugin al arrancar y `ress info`, para que un
|
|
123
119
|
* proyecto recién creado o un clon limpio tengan sus tipos sin levantar nada.
|
|
124
120
|
*/
|
|
125
121
|
async function writeProjectTypes(root, platform) {
|
|
122
|
+
const { access } = await import('node:fs/promises');
|
|
123
|
+
const { join } = await import('node:path');
|
|
124
|
+
try {
|
|
125
|
+
await access(join(root, 'tsconfig.json'));
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (error.code === 'ENOENT')
|
|
129
|
+
return [];
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
126
132
|
const { resolved } = await import('@ressjs/config');
|
|
127
133
|
return writeGeneratedTypes(root, {
|
|
128
134
|
'ress-platform.d.ts': generatePlatformTypes(platform),
|
package/dist/config/env.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface PublicEnvOptions {
|
|
|
13
13
|
env?: Record<string, string | undefined>;
|
|
14
14
|
/** Si faltar una variable detiene el arranque. En build, sí. */
|
|
15
15
|
strict?: boolean;
|
|
16
|
+
/** Dónde se informa una variable ausente cuando `strict` es falso. Por defecto, la consola. */
|
|
17
|
+
warn?: (message: string) => void;
|
|
16
18
|
}
|
|
17
19
|
export declare function publicEnvDefines(publicEnv: readonly string[], options?: PublicEnvOptions): Record<string, string>;
|
|
18
20
|
/** Los valores publicados, para inspeccionarlos o serializarlos. */
|
package/dist/config/env.js
CHANGED
|
@@ -20,11 +20,14 @@ function publicEnvDefines(publicEnv, options = {}) {
|
|
|
20
20
|
defines[`process.env.${name}`] = literal;
|
|
21
21
|
defines[`import.meta.env.${name}`] = literal;
|
|
22
22
|
}
|
|
23
|
-
if (missing.length
|
|
24
|
-
|
|
23
|
+
if (missing.length) {
|
|
24
|
+
const message = `[ress] \`publicEnv\` declara ${missing.length === 1 ? 'una variable que no existe' : 'variables que no existen'}: ` +
|
|
25
25
|
missing.join(', ') +
|
|
26
26
|
'. Exponer una variable inexistente es casi siempre un error de tipeo, y ' +
|
|
27
|
-
'el navegador recibiría el nombre sin valor.'
|
|
27
|
+
'el navegador recibiría el nombre sin valor.';
|
|
28
|
+
if (options.strict !== false)
|
|
29
|
+
throw new Error(message);
|
|
30
|
+
(options.warn ?? console.warn)(message);
|
|
28
31
|
}
|
|
29
32
|
return defines;
|
|
30
33
|
}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ export type { CompiledRule, CompiledRules } from './rules';
|
|
|
13
13
|
export { createConfigMiddleware } from './middleware';
|
|
14
14
|
export { publicEnvDefines, publicEnvValues } from './env';
|
|
15
15
|
export { generateProjectConfigTypes, generatePlatformTypes, writeGeneratedTypes, writeProjectTypes } from './codegen';
|
|
16
|
-
export { changedKeys, isConfigLayer, restartReason, watchConfig, HOT_KEYS, RESTART_REASONS } from './watch';
|
|
16
|
+
export { changedKeys, isConfigLayer, restartReason, watchConfig, onConfigReload, HOT_KEYS, RESTART_REASONS } from './watch';
|
|
17
17
|
export { validateConfig, validateRules } from './validate';
|
|
18
18
|
export type { AssetsConfig, IsrConfig, ResolvedIsrConfig, HeaderRule, ModeOverrides, PlatformConfig, RedirectRule, ResolvedConfig, RessConfig, RessServerConfig, RewriteRule, TrailingSlashMode, } from './types';
|
package/dist/config/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* resueltas por el mismo motor, y sólo la primera la lee el router.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.validateRules = exports.validateConfig = exports.RESTART_REASONS = exports.HOT_KEYS = exports.watchConfig = exports.restartReason = exports.isConfigLayer = exports.changedKeys = exports.writeProjectTypes = exports.writeGeneratedTypes = exports.generatePlatformTypes = exports.generateProjectConfigTypes = exports.publicEnvValues = exports.publicEnvDefines = exports.createConfigMiddleware = exports.parseRulePattern = exports.matchRule = exports.compileRules = exports.applyParams = exports.withBasePath = exports.stripBasePath = exports.canonicalTrailingSlash = exports.assetPrefixFor = exports.defineConfig = exports.resolveIsrConfig = exports.normalizeBasePath = exports.loadConfig = void 0;
|
|
10
|
+
exports.validateRules = exports.validateConfig = exports.RESTART_REASONS = exports.HOT_KEYS = exports.onConfigReload = exports.watchConfig = exports.restartReason = exports.isConfigLayer = exports.changedKeys = exports.writeProjectTypes = exports.writeGeneratedTypes = exports.generatePlatformTypes = exports.generateProjectConfigTypes = exports.publicEnvValues = exports.publicEnvDefines = exports.createConfigMiddleware = exports.parseRulePattern = exports.matchRule = exports.compileRules = exports.applyParams = exports.withBasePath = exports.stripBasePath = exports.canonicalTrailingSlash = exports.assetPrefixFor = exports.defineConfig = exports.resolveIsrConfig = exports.normalizeBasePath = exports.loadConfig = void 0;
|
|
11
11
|
var load_1 = require("./load");
|
|
12
12
|
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_1.loadConfig; } });
|
|
13
13
|
Object.defineProperty(exports, "normalizeBasePath", { enumerable: true, get: function () { return load_1.normalizeBasePath; } });
|
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "changedKeys", { enumerable: true, get: function
|
|
|
39
39
|
Object.defineProperty(exports, "isConfigLayer", { enumerable: true, get: function () { return watch_1.isConfigLayer; } });
|
|
40
40
|
Object.defineProperty(exports, "restartReason", { enumerable: true, get: function () { return watch_1.restartReason; } });
|
|
41
41
|
Object.defineProperty(exports, "watchConfig", { enumerable: true, get: function () { return watch_1.watchConfig; } });
|
|
42
|
+
Object.defineProperty(exports, "onConfigReload", { enumerable: true, get: function () { return watch_1.onConfigReload; } });
|
|
42
43
|
Object.defineProperty(exports, "HOT_KEYS", { enumerable: true, get: function () { return watch_1.HOT_KEYS; } });
|
|
43
44
|
Object.defineProperty(exports, "RESTART_REASONS", { enumerable: true, get: function () { return watch_1.RESTART_REASONS; } });
|
|
44
45
|
var validate_1 = require("./validate");
|
package/dist/config/load.d.ts
CHANGED
package/dist/config/load.js
CHANGED
|
@@ -14,7 +14,6 @@ const validate_1 = require("./validate");
|
|
|
14
14
|
* config/default.js ← lo común, opcional
|
|
15
15
|
* config/development.js
|
|
16
16
|
* config/production.js
|
|
17
|
-
* config/test.js
|
|
18
17
|
* config/local.js ← esta máquina; no se sube
|
|
19
18
|
* ```
|
|
20
19
|
*
|
|
@@ -47,6 +46,8 @@ async function resolve(declared) {
|
|
|
47
46
|
// obliga a recordar si ya está en cada concatenación.
|
|
48
47
|
basePath: normalizeBasePath(declared.basePath ?? ''),
|
|
49
48
|
trailingSlash: declared.trailingSlash ?? 'ignore',
|
|
49
|
+
// Sin barra inicial ni final: se compara contra rutas del proyecto.
|
|
50
|
+
shared: (declared.shared ?? []).map((entry) => entry.trim().replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '')),
|
|
50
51
|
// Las tres son funciones para que el proyecto pueda leer un archivo o
|
|
51
52
|
// consultar algo al arrancar. Se invocan una vez, acá.
|
|
52
53
|
redirects: (await declared.redirects?.()) ?? [],
|
package/dist/config/types.d.ts
CHANGED
|
@@ -29,6 +29,13 @@ export interface RessConfig {
|
|
|
29
29
|
basePath?: string;
|
|
30
30
|
/** Qué hacer con la barra final de una URL. */
|
|
31
31
|
trailingSlash?: TrailingSlashMode;
|
|
32
|
+
/**
|
|
33
|
+
* Carpetas cuyo código carga Node una sola vez y comparten tu entrada de servidor
|
|
34
|
+
* (`server.js`, `api/`) y las páginas, relativas a la raíz del proyecto
|
|
35
|
+
* (`['app/services']`). Sin esto, un archivo importado por las dos partes se
|
|
36
|
+
* carga dos veces, y cada copia tiene su propio estado.
|
|
37
|
+
*/
|
|
38
|
+
shared?: string[];
|
|
32
39
|
redirects?: () => RedirectRule[] | Promise<RedirectRule[]>;
|
|
33
40
|
rewrites?: () => RewriteRule[] | Promise<RewriteRule[]>;
|
|
34
41
|
headers?: () => HeaderRule[] | Promise<HeaderRule[]>;
|
|
@@ -143,11 +150,6 @@ export interface PlatformConfig {
|
|
|
143
150
|
}>;
|
|
144
151
|
/** Plataformas para las que se prepara el proyecto generado. F-033. */
|
|
145
152
|
targets?: string[];
|
|
146
|
-
/**
|
|
147
|
-
* Intención declarativa de usar clientes completos forkeables. Las plantillas
|
|
148
|
-
* y sus runtimes pertenecen a F-028 (React Native) y F-029 (Electron).
|
|
149
|
-
*/
|
|
150
|
-
forkedClients?: string[];
|
|
151
153
|
}
|
|
152
154
|
export interface RedirectRule {
|
|
153
155
|
source: string;
|
|
@@ -176,6 +178,7 @@ export interface HeaderRule {
|
|
|
176
178
|
export interface ResolvedConfig {
|
|
177
179
|
basePath: string;
|
|
178
180
|
trailingSlash: TrailingSlashMode;
|
|
181
|
+
shared: string[];
|
|
179
182
|
redirects: RedirectRule[];
|
|
180
183
|
rewrites: RewriteRule[];
|
|
181
184
|
headers: HeaderRule[];
|
package/dist/config/validate.js
CHANGED
|
@@ -16,16 +16,26 @@ function validateConfig(config) {
|
|
|
16
16
|
const problems = [];
|
|
17
17
|
checkBasePath(config, problems);
|
|
18
18
|
checkTrailingSlash(config, problems);
|
|
19
|
+
checkShared(config, problems);
|
|
19
20
|
checkPublicEnv(config, problems);
|
|
20
21
|
checkCallable(config, problems);
|
|
21
22
|
checkAssets(config, problems);
|
|
22
23
|
checkDev(config, problems);
|
|
23
24
|
checkIsr(config, problems);
|
|
25
|
+
checkSecurity(config, problems);
|
|
26
|
+
checkPlatform(config, problems);
|
|
24
27
|
if (problems.length === 0)
|
|
25
28
|
return;
|
|
26
29
|
throw new Error(`[ress] La configuración tiene ${problems.length === 1 ? 'un problema' : `${problems.length} problemas`}:\n` +
|
|
27
30
|
problems.map((p) => ` · ${p}`).join('\n'));
|
|
28
31
|
}
|
|
32
|
+
function checkPlatform({ platform }, problems) {
|
|
33
|
+
if (platform && Object.hasOwn(platform, 'forkedClients')) {
|
|
34
|
+
problems.push('`platform.forkedClients` se retiró en 0.6.0 porque no tenía efecto. ' +
|
|
35
|
+
'Sacá esta clave; los clientes nativos viven en repositorios aparte. ' +
|
|
36
|
+
'`platform.targets` y las cabeceras de plataforma siguen funcionando.');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
29
39
|
function checkBasePath({ basePath }, problems) {
|
|
30
40
|
if (basePath === undefined)
|
|
31
41
|
return;
|
|
@@ -40,6 +50,21 @@ function checkBasePath({ basePath }, problems) {
|
|
|
40
50
|
'otro dominio está `assets.cdnPrefix`.');
|
|
41
51
|
}
|
|
42
52
|
}
|
|
53
|
+
function checkShared({ shared }, problems) {
|
|
54
|
+
if (shared === undefined)
|
|
55
|
+
return;
|
|
56
|
+
if (!Array.isArray(shared)) {
|
|
57
|
+
return void problems.push('`shared` tiene que ser una lista de carpetas del proyecto (`[\'app/services\']`).');
|
|
58
|
+
}
|
|
59
|
+
for (const entry of shared) {
|
|
60
|
+
if (typeof entry !== 'string' || !entry.trim()) {
|
|
61
|
+
problems.push('`shared` sólo admite carpetas como cadenas no vacías.');
|
|
62
|
+
}
|
|
63
|
+
else if (/^([a-zA-Z]:)?[\\/]/.test(entry.trim()) || entry.split(/[\\/]/).includes('..')) {
|
|
64
|
+
problems.push(`\`shared\` lleva rutas relativas a la raíz del proyecto y dentro de ella; "${entry}" no lo es.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
43
68
|
function checkTrailingSlash({ trailingSlash }, problems) {
|
|
44
69
|
const valid = ['always', 'never', 'ignore'];
|
|
45
70
|
if (trailingSlash !== undefined && !valid.includes(trailingSlash)) {
|
|
@@ -78,6 +103,48 @@ function checkAssets({ assets }, problems) {
|
|
|
78
103
|
'los artefactos se sirven desde otro origen.');
|
|
79
104
|
}
|
|
80
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* `security` se resuelve después, con sus valores por defecto, pero un valor de
|
|
108
|
+
* tipo equivocado no tiene que llegar hasta ahí: una cabecera con `undefined`
|
|
109
|
+
* o un límite negativo falla en cada petición en vez de al arrancar.
|
|
110
|
+
*/
|
|
111
|
+
function checkSecurity({ security }, problems) {
|
|
112
|
+
if (security === undefined)
|
|
113
|
+
return;
|
|
114
|
+
if (typeof security !== 'object' || security === null) {
|
|
115
|
+
return void problems.push('`security` tiene que ser un objeto.');
|
|
116
|
+
}
|
|
117
|
+
const s = security;
|
|
118
|
+
const object = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
119
|
+
const isBoolean = (v) => typeof v === 'boolean';
|
|
120
|
+
const isString = (v) => typeof v === 'string';
|
|
121
|
+
const isNonNegativeInteger = (v) => Number.isInteger(v) && v >= 0;
|
|
122
|
+
const isStringList = (v) => Array.isArray(v) && v.every((item) => typeof item === 'string');
|
|
123
|
+
const oneOf = (...values) => (v) => values.includes(v);
|
|
124
|
+
const orFalse = (check) => (v) => v === false || check(v);
|
|
125
|
+
const rules = [
|
|
126
|
+
['security.maxStateBytes', s.maxStateBytes, isNonNegativeInteger, 'un entero no negativo'],
|
|
127
|
+
['security.onStateOverLimit', s.onStateOverLimit, oneOf('warn', 'error'), "'warn' o 'error'"],
|
|
128
|
+
['security.serializePlatform', s.serializePlatform, oneOf('auto', 'always', 'never'), "'auto', 'always' o 'never'"],
|
|
129
|
+
];
|
|
130
|
+
const groups = ['headers', 'cache', 'csp', 'head', 'dev'];
|
|
131
|
+
for (const group of groups) {
|
|
132
|
+
if (s[group] !== undefined && !object(s[group])) {
|
|
133
|
+
problems.push(`\`security.${group}\` tiene que ser un objeto.`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const h = object(s.headers) ? s.headers : {};
|
|
138
|
+
const c = object(s.cache) ? s.cache : {};
|
|
139
|
+
const csp = object(s.csp) ? s.csp : {};
|
|
140
|
+
const head = object(s.head) ? s.head : {};
|
|
141
|
+
const dev = object(s.dev) ? s.dev : {};
|
|
142
|
+
rules.push(['security.headers.contentTypeOptions', h.contentTypeOptions, isBoolean, 'un booleano'], ['security.headers.referrerPolicy', h.referrerPolicy, orFalse(isString), 'una cadena o false'], ['security.headers.frameOptions', h.frameOptions, orFalse(oneOf('DENY', 'SAMEORIGIN')), "'DENY', 'SAMEORIGIN' o false"], ['security.headers.hsts', h.hsts, orFalse((v) => object(v) && isNonNegativeInteger(v.maxAge)), 'false o un objeto con `maxAge` entero'], ['security.cache.html', c.html, isString, 'una cadena'], ['security.cache.immutableMaxAge', c.immutableMaxAge, isNonNegativeInteger, 'un entero no negativo'], ['security.cache.staticMaxAge', c.staticMaxAge, isNonNegativeInteger, 'un entero no negativo'], ['security.csp.enabled', csp.enabled, isBoolean, 'un booleano'], ['security.csp.reportOnly', csp.reportOnly, isBoolean, 'un booleano'], ['security.csp.reportUri', csp.reportUri, isString, 'una cadena'], ['security.csp.directives', csp.directives, (v) => object(v) && Object.values(v).every(orFalse(isStringList)), 'un objeto cuyos valores son listas de cadenas o false'], ['security.head.allowScriptTags', head.allowScriptTags, isBoolean, 'un booleano'], ['security.head.extraTagAllowlist', head.extraTagAllowlist, isStringList, 'una lista de cadenas'], ['security.dev.allowedHosts', dev.allowedHosts, isStringList, 'una lista de cadenas'], ['security.dev.allowedOrigins', dev.allowedOrigins, orFalse(isStringList), 'false o una lista de cadenas']);
|
|
143
|
+
for (const [key, value, valid, expected] of rules) {
|
|
144
|
+
if (value !== undefined && !valid(value))
|
|
145
|
+
problems.push(`\`${key}\` tiene que ser ${expected}.`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
81
148
|
function checkIsr({ isr }, problems) {
|
|
82
149
|
if (isr === undefined)
|
|
83
150
|
return;
|
package/dist/config/watch.d.ts
CHANGED
|
@@ -36,6 +36,21 @@ export declare function changedKeys(previous: ResolvedConfig, next: ResolvedConf
|
|
|
36
36
|
export declare function manualRestartReason(changed: readonly string[]): string | undefined;
|
|
37
37
|
/** El motivo del reinicio, o nada si todo lo que cambió se aplica en caliente. */
|
|
38
38
|
export declare function restartReason(changed: readonly string[]): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Espera a que un archivo deje de cambiar.
|
|
41
|
+
*
|
|
42
|
+
* Guardar es truncar y escribir, y el sistema puede avisar entre un paso y el otro
|
|
43
|
+
* (Windows lo hace, y no siempre vuelve a avisar al terminar). Leer en ese momento
|
|
44
|
+
* da un archivo vacío: la configuración sale por defecto, no hay diferencias ni
|
|
45
|
+
* error, y el cambio se pierde. Se mira el tamaño y la fecha hasta que dos
|
|
46
|
+
* lecturas seguidas coinciden. Un archivo vacío cuenta como «todavía no
|
|
47
|
+
* terminó»: casi siempre es el paso intermedio de una escritura. Si de verdad
|
|
48
|
+
* está vacío, se lo lee igual cuando se agotan los intentos.
|
|
49
|
+
*/
|
|
50
|
+
export declare function settled(file: string, { interval, attempts }?: {
|
|
51
|
+
interval?: number | undefined;
|
|
52
|
+
attempts?: number | undefined;
|
|
53
|
+
}): Promise<void>;
|
|
39
54
|
/** ¿Este archivo es una capa de configuración del proyecto? */
|
|
40
55
|
export declare function isConfigLayer(file: string, root: string): boolean;
|
|
41
56
|
export interface WatchConfigOptions {
|
|
@@ -49,5 +64,12 @@ export interface WatchConfigOptions {
|
|
|
49
64
|
onRestart?: (reason: string) => void;
|
|
50
65
|
log?: (message: string) => void;
|
|
51
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Quien arma el pipeline de petición (el router) se entera acá de una recarga en
|
|
69
|
+
* caliente. El plugin de Vite y el router viven en objetos distintos: sin este
|
|
70
|
+
* aviso, la configuración nueva llegaba al plugin y las peticiones seguían
|
|
71
|
+
* usando las reglas con las que arrancó el servidor. Devuelve la baja.
|
|
72
|
+
*/
|
|
73
|
+
export declare function onConfigReload(listener: (config: ResolvedConfig) => void): () => void;
|
|
52
74
|
/** Conecta el observador de Vite con la carpeta de configuración. */
|
|
53
75
|
export declare function watchConfig(server: any, options: WatchConfigOptions): void;
|
package/dist/config/watch.js
CHANGED
|
@@ -4,9 +4,13 @@ exports.MANUAL_RESTART_KEYS = exports.RESTART_REASONS = exports.HOT_KEYS = void
|
|
|
4
4
|
exports.changedKeys = changedKeys;
|
|
5
5
|
exports.manualRestartReason = manualRestartReason;
|
|
6
6
|
exports.restartReason = restartReason;
|
|
7
|
+
exports.settled = settled;
|
|
7
8
|
exports.isConfigLayer = isConfigLayer;
|
|
9
|
+
exports.onConfigReload = onConfigReload;
|
|
8
10
|
exports.watchConfig = watchConfig;
|
|
11
|
+
const promises_1 = require("node:fs/promises");
|
|
9
12
|
const config_1 = require("@ressjs/config");
|
|
13
|
+
const codegen_1 = require("./codegen");
|
|
10
14
|
const load_1 = require("./load");
|
|
11
15
|
/**
|
|
12
16
|
* Recarga de la configuración en desarrollo.
|
|
@@ -33,6 +37,7 @@ exports.HOT_KEYS = ['redirects', 'rewrites', 'headers', 'trailingSlash'];
|
|
|
33
37
|
*/
|
|
34
38
|
exports.RESTART_REASONS = {
|
|
35
39
|
basePath: 'cambia la URL bajo la que se sirve todo, incluidos los artefactos ya emitidos',
|
|
40
|
+
shared: 'Node carga esas carpetas una sola vez, al arrancar, y las comparten tu entrada de servidor y las páginas',
|
|
36
41
|
extensions: 'cambia qué archivos son páginas, y eso redefine el catálogo de entradas',
|
|
37
42
|
platform: 'redefine los ejes de plataforma, y con ellos las variantes que se construyen',
|
|
38
43
|
publicEnv: 'las variables se reemplazan en tiempo de build, no al atender una petición',
|
|
@@ -55,6 +60,7 @@ exports.RESTART_REASONS = {
|
|
|
55
60
|
*/
|
|
56
61
|
exports.MANUAL_RESTART_KEYS = new Set([
|
|
57
62
|
'basePath',
|
|
63
|
+
'shared',
|
|
58
64
|
'assets',
|
|
59
65
|
'security',
|
|
60
66
|
'isr',
|
|
@@ -110,6 +116,36 @@ function restartReason(changed) {
|
|
|
110
116
|
}
|
|
111
117
|
return undefined;
|
|
112
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Espera a que un archivo deje de cambiar.
|
|
121
|
+
*
|
|
122
|
+
* Guardar es truncar y escribir, y el sistema puede avisar entre un paso y el otro
|
|
123
|
+
* (Windows lo hace, y no siempre vuelve a avisar al terminar). Leer en ese momento
|
|
124
|
+
* da un archivo vacío: la configuración sale por defecto, no hay diferencias ni
|
|
125
|
+
* error, y el cambio se pierde. Se mira el tamaño y la fecha hasta que dos
|
|
126
|
+
* lecturas seguidas coinciden. Un archivo vacío cuenta como «todavía no
|
|
127
|
+
* terminó»: casi siempre es el paso intermedio de una escritura. Si de verdad
|
|
128
|
+
* está vacío, se lo lee igual cuando se agotan los intentos.
|
|
129
|
+
*/
|
|
130
|
+
async function settled(file, { interval = 30, attempts = 30 } = {}) {
|
|
131
|
+
const signature = async () => {
|
|
132
|
+
try {
|
|
133
|
+
const { size, mtimeMs } = await (0, promises_1.stat)(file);
|
|
134
|
+
return `${size}:${mtimeMs}`;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return 'ausente';
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
let previous = await signature();
|
|
141
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
142
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
143
|
+
const current = await signature();
|
|
144
|
+
if (current === previous && !current.startsWith('0:'))
|
|
145
|
+
return;
|
|
146
|
+
previous = current;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
113
149
|
/** ¿Este archivo es una capa de configuración del proyecto? */
|
|
114
150
|
function isConfigLayer(file, root) {
|
|
115
151
|
const normalized = file.replace(/\\/g, '/');
|
|
@@ -119,6 +155,17 @@ function isConfigLayer(file, root) {
|
|
|
119
155
|
const relative = normalized.slice(base.length + 1);
|
|
120
156
|
return /^config\/[^/]+$/.test(relative) || /^config\.[^/]+$/.test(relative);
|
|
121
157
|
}
|
|
158
|
+
const reloadListeners = new Set();
|
|
159
|
+
/**
|
|
160
|
+
* Quien arma el pipeline de petición (el router) se entera acá de una recarga en
|
|
161
|
+
* caliente. El plugin de Vite y el router viven en objetos distintos: sin este
|
|
162
|
+
* aviso, la configuración nueva llegaba al plugin y las peticiones seguían
|
|
163
|
+
* usando las reglas con las que arrancó el servidor. Devuelve la baja.
|
|
164
|
+
*/
|
|
165
|
+
function onConfigReload(listener) {
|
|
166
|
+
reloadListeners.add(listener);
|
|
167
|
+
return () => void reloadListeners.delete(listener);
|
|
168
|
+
}
|
|
122
169
|
/** Conecta el observador de Vite con la carpeta de configuración. */
|
|
123
170
|
function watchConfig(server, options) {
|
|
124
171
|
const log = options.log ?? ((message) => console.log(message));
|
|
@@ -130,6 +177,8 @@ function watchConfig(server, options) {
|
|
|
130
177
|
const onChange = async (file) => {
|
|
131
178
|
if (!isConfigLayer(file, options.root))
|
|
132
179
|
return;
|
|
180
|
+
// Se lee el archivo terminado, no el que se está escribiendo.
|
|
181
|
+
await settled(file);
|
|
133
182
|
// Lo resuelto se descarta entero: la fusión depende de todas las capas, así
|
|
134
183
|
// que un cambio en cualquiera de ellas invalida el resultado.
|
|
135
184
|
(0, config_1.invalidateConfig)();
|
|
@@ -143,6 +192,12 @@ function watchConfig(server, options) {
|
|
|
143
192
|
log(`[ress] La configuración no se pudo cargar: ${error.message}`);
|
|
144
193
|
return;
|
|
145
194
|
}
|
|
195
|
+
// Los tipos de `config.X` salen de lo resuelto, valores propios incluidos, y
|
|
196
|
+
// un valor propio nuevo no figura en `changedKeys` (sólo compara las claves
|
|
197
|
+
// del framework): se regeneran con cada cambio de capa.
|
|
198
|
+
await (0, codegen_1.writeProjectTypes)(options.root, next.platform).catch((error) => {
|
|
199
|
+
log(`[ress] No se pudieron regenerar los tipos de la configuración: ${error.message}`);
|
|
200
|
+
});
|
|
146
201
|
const changed = changedKeys(options.current(), next);
|
|
147
202
|
if (changed.length === 0)
|
|
148
203
|
return;
|
|
@@ -155,6 +210,8 @@ function watchConfig(server, options) {
|
|
|
155
210
|
if (reason)
|
|
156
211
|
return restart(reason);
|
|
157
212
|
options.onReload(next);
|
|
213
|
+
for (const listener of reloadListeners)
|
|
214
|
+
listener(next);
|
|
158
215
|
log(`[ress] Configuración recargada: ${changed.join(', ')}`);
|
|
159
216
|
};
|
|
160
217
|
for (const event of ['add', 'change', 'unlink']) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* La ruta real de un archivo o directorio, sin enlaces simbólicos.
|
|
3
|
+
*
|
|
4
|
+
* El bundler informa cada módulo con su ruta real. Si la raíz del proyecto se
|
|
5
|
+
* toma tal como la escribió el usuario —a través de un enlace, como `/tmp` en
|
|
6
|
+
* macOS—, comparar una ruta con la otra falla sin decir por qué. La raíz se
|
|
7
|
+
* canoniza una vez, donde se resuelve, y todo lo que se derive de ella coincide.
|
|
8
|
+
*
|
|
9
|
+
* Una ruta que no existe se devuelve resuelta pero sin canonizar: el error de
|
|
10
|
+
* que no existe le corresponde a quien la use.
|
|
11
|
+
*/
|
|
12
|
+
export declare function canonicalPath(target: string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.canonicalPath = canonicalPath;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
/**
|
|
10
|
+
* La ruta real de un archivo o directorio, sin enlaces simbólicos.
|
|
11
|
+
*
|
|
12
|
+
* El bundler informa cada módulo con su ruta real. Si la raíz del proyecto se
|
|
13
|
+
* toma tal como la escribió el usuario —a través de un enlace, como `/tmp` en
|
|
14
|
+
* macOS—, comparar una ruta con la otra falla sin decir por qué. La raíz se
|
|
15
|
+
* canoniza una vez, donde se resuelve, y todo lo que se derive de ella coincide.
|
|
16
|
+
*
|
|
17
|
+
* Una ruta que no existe se devuelve resuelta pero sin canonizar: el error de
|
|
18
|
+
* que no existe le corresponde a quien la use.
|
|
19
|
+
*/
|
|
20
|
+
function canonicalPath(target) {
|
|
21
|
+
const absolute = node_path_1.default.resolve(target);
|
|
22
|
+
try {
|
|
23
|
+
return node_fs_1.realpathSync.native(absolute);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return absolute;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carpetas compartidas con Node (`shared` en la config).
|
|
3
|
+
*
|
|
4
|
+
* Un archivo importado por la entrada de servidor (`server.js`, `api/`) y por las
|
|
5
|
+
* páginas se carga dos veces si cada parte lo carga por su cuenta: Node, y el runner
|
|
6
|
+
* de Vite en desarrollo o el bundle compilado en producción. Cada copia tiene su
|
|
7
|
+
* propio estado. Los archivos de estas carpetas los carga siempre Node, así que hay
|
|
8
|
+
* una sola.
|
|
9
|
+
*/
|
|
10
|
+
/** ¿Este archivo cae dentro de una carpeta compartida? `root` es la raíz del proyecto. */
|
|
11
|
+
export declare function isSharedModule(id: string, root: string, shared: readonly string[]): boolean;
|
|
12
|
+
/** Marca con la que el build deja un import compartido hasta que se conoce la ubicación del chunk. */
|
|
13
|
+
export declare const SHARED_PREFIX = "ress-shared:";
|
|
14
|
+
/**
|
|
15
|
+
* Reescribe los marcadores de un chunk por la ruta relativa real al archivo.
|
|
16
|
+
*
|
|
17
|
+
* Se hace al terminar de armar el chunk porque sólo entonces se sabe dónde queda: la
|
|
18
|
+
* ruta «relativa» que calcula el bundler parte de la fuente de la entrada, no del
|
|
19
|
+
* archivo de salida. La app se despliega con `dist/` y las carpetas compartidas
|
|
20
|
+
* lado a lado, así que la ruta relativa sigue valiendo al moverla de lugar.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveSharedMarkers(code: string, chunkFile: string, root: string): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SHARED_PREFIX = void 0;
|
|
7
|
+
exports.isSharedModule = isSharedModule;
|
|
8
|
+
exports.resolveSharedMarkers = resolveSharedMarkers;
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* Carpetas compartidas con Node (`shared` en la config).
|
|
12
|
+
*
|
|
13
|
+
* Un archivo importado por la entrada de servidor (`server.js`, `api/`) y por las
|
|
14
|
+
* páginas se carga dos veces si cada parte lo carga por su cuenta: Node, y el runner
|
|
15
|
+
* de Vite en desarrollo o el bundle compilado en producción. Cada copia tiene su
|
|
16
|
+
* propio estado. Los archivos de estas carpetas los carga siempre Node, así que hay
|
|
17
|
+
* una sola.
|
|
18
|
+
*/
|
|
19
|
+
/** ¿Este archivo cae dentro de una carpeta compartida? `root` es la raíz del proyecto. */
|
|
20
|
+
function isSharedModule(id, root, shared) {
|
|
21
|
+
const file = id.split('?')[0].replace(/\\/g, '/');
|
|
22
|
+
const base = root.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
23
|
+
return shared.some((entry) => file.startsWith(`${base}/${entry}/`));
|
|
24
|
+
}
|
|
25
|
+
/** Marca con la que el build deja un import compartido hasta que se conoce la ubicación del chunk. */
|
|
26
|
+
exports.SHARED_PREFIX = 'ress-shared:';
|
|
27
|
+
/**
|
|
28
|
+
* Reescribe los marcadores de un chunk por la ruta relativa real al archivo.
|
|
29
|
+
*
|
|
30
|
+
* Se hace al terminar de armar el chunk porque sólo entonces se sabe dónde queda: la
|
|
31
|
+
* ruta «relativa» que calcula el bundler parte de la fuente de la entrada, no del
|
|
32
|
+
* archivo de salida. La app se despliega con `dist/` y las carpetas compartidas
|
|
33
|
+
* lado a lado, así que la ruta relativa sigue valiendo al moverla de lugar.
|
|
34
|
+
*/
|
|
35
|
+
function resolveSharedMarkers(code, chunkFile, root) {
|
|
36
|
+
if (!code.includes(exports.SHARED_PREFIX))
|
|
37
|
+
return code;
|
|
38
|
+
return code.replace(new RegExp(`${exports.SHARED_PREFIX}([^"'\`\\s)]+)`, 'g'), (_match, rel) => {
|
|
39
|
+
const relative = node_path_1.default
|
|
40
|
+
.relative(node_path_1.default.dirname(chunkFile), node_path_1.default.join(root, rel))
|
|
41
|
+
.replace(/\\/g, '/');
|
|
42
|
+
return relative.startsWith('.') ? relative : `./${relative}`;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -45,11 +45,8 @@ function buildRenderServer(config) {
|
|
|
45
45
|
const resolvedViteConfig = typeof config.viteConfig === 'function'
|
|
46
46
|
? config.viteConfig()
|
|
47
47
|
: config.viteConfig;
|
|
48
|
-
const options = config.security ?? (0, security_1.resolveSecurityOptions)(config.securityOptions);
|
|
49
48
|
return (0, render_1.createRenderServer)({
|
|
50
49
|
...(resolvedViteConfig.moduleLoader ? { moduleLoader: resolvedViteConfig.moduleLoader } : {}),
|
|
51
|
-
clientProps: options.clientProps,
|
|
52
|
-
isProduction: resolvedViteConfig.isProduction,
|
|
53
50
|
});
|
|
54
51
|
}
|
|
55
52
|
async function processRequest(context, config, renderServer) {
|
|
@@ -112,16 +109,11 @@ async function processRequest(context, config, renderServer) {
|
|
|
112
109
|
if (!res.locals.styles && page?.pageId && viteConfig.catalog && viteConfig.assets) {
|
|
113
110
|
res.locals.styles = (0, assets_1.resolvePageAssets)(page.pageId, platformContext.platformInfo ?? platform_1.DEFAULT_PLATFORM, viteConfig.catalog, viteConfig.assets);
|
|
114
111
|
}
|
|
115
|
-
const pageLocals = { ...res.locals };
|
|
116
|
-
delete pageLocals.styles;
|
|
117
112
|
const rendered = await renderServer({
|
|
118
113
|
url: pathname,
|
|
119
114
|
req,
|
|
120
115
|
res,
|
|
121
116
|
props: res.locals.serverSideProps,
|
|
122
|
-
// `styles` pertenece al pipeline interno de assets; no se mezcla con los
|
|
123
|
-
// locals que la página recibe ni se considera estado serializable.
|
|
124
|
-
locals: pageLocals,
|
|
125
117
|
hydrate,
|
|
126
118
|
// La página ya la resolvió el despachador: buscarla de nuevo por URL sería
|
|
127
119
|
// una segunda resolución con otro criterio.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { getViteSSRInput } from './pages';
|
|
|
3
3
|
export { createRouteManifest, serializeRouteManifest, loadRouteManifest } from './routes/manifest';
|
|
4
4
|
export { resolveServerModule } from './routes/module';
|
|
5
5
|
export type { ResolveServerModuleContext } from './routes/module';
|
|
6
|
-
export { scanRoutes } from './routes/scan';
|
|
6
|
+
export { scanRoutes, RouteConflictError } from './routes/scan';
|
|
7
7
|
export type { PageId, RouteEntry, RouteEntryKind, RouteManifest, RouteManifestData, RouteMatch, RouteSegment, SegmentKind, } from './routes/types';
|
|
8
8
|
export { ROUTE_MANIFEST_VERSION } from './routes/types';
|
|
9
9
|
export { defineEnvironments, OUT_DIR } from './plugin/environments';
|
|
@@ -14,26 +14,27 @@ export type { FetchableEnvironment, ModuleLoader } from './runtime/module-loader
|
|
|
14
14
|
export { createRuntime, resolveServerModulePath, resolveProductionModuleId, } from './runtime/prod-server';
|
|
15
15
|
export { resolveSsrEnvironment } from './runtime/dev-server';
|
|
16
16
|
export type { DevRuntimeOptions, RessRuntime } from './runtime/dev-server';
|
|
17
|
-
export { DEFAULT_EXCLUSIONS, isPageFile, pageExclusionOf, scriptExtensionOf, SCRIPT_EXTENSIONS, } from './fs/module-extensions';
|
|
17
|
+
export { DEFAULT_EXCLUSIONS, DEFAULT_EXTENSION_POLICY, isPageFile, pageExclusionOf, scriptExtensionOf, SCRIPT_EXTENSIONS, setExtensionPolicy, } from './fs/module-extensions';
|
|
18
18
|
export type { PageExclusion } from './fs/module-extensions';
|
|
19
19
|
export { buildVariantCatalog, pageIdFromFile } from './variants/catalog';
|
|
20
20
|
export { resolveVariant, explainResolution } from './variants/resolve';
|
|
21
21
|
export { defaultPlatformRegistry } from './variants/platform-tokens';
|
|
22
22
|
export type { VariantCatalog, BuildEntry, Variant, AssetIndex, PlatformRegistry } from './variants/types';
|
|
23
23
|
export { createRenderServer } from './render';
|
|
24
|
+
export { canonicalPath } from './fs/canonical-path';
|
|
24
25
|
export { detectPlatform } from './platform';
|
|
25
26
|
export type { PlatformInfo } from './platform';
|
|
26
27
|
export type { ViteRouterOptions } from './router';
|
|
27
28
|
export type { PageInfo } from './pages';
|
|
28
29
|
export type { PageConfig, PageConfigVariant, PageHeadConfig, PageRenderingConfig, RenderingMode, RobotsConfig, } from './head/types';
|
|
29
30
|
export type { ServerSideResult } from './helpers/middlewares';
|
|
30
|
-
export {
|
|
31
|
-
export type {
|
|
31
|
+
export { resolveSecurityOptions, serializeState, applySecurityHeaders, } from './security';
|
|
32
|
+
export type { PublicError, ResolvedSecurityOptions, SecurityOptions, } from './security';
|
|
32
33
|
/**
|
|
33
34
|
* @deprecated Usá el manifest de rutas: `runtime.routes.entries`. Devuelve las
|
|
34
35
|
* páginas tal como las enumera el catálogo de variantes, que no conoce grupos ni
|
|
35
36
|
* catch-all. Se elimina cuando F-016 consuma el manifest.
|
|
36
37
|
*/
|
|
37
38
|
export { getPages as listDetectedPages } from './pages';
|
|
38
|
-
export { defineConfig, loadConfig, createConfigMiddleware, compileRules, publicEnvDefines, withBasePath, assetPrefixFor, writeProjectTypes, } from './config';
|
|
39
|
+
export { defineConfig, loadConfig, normalizeBasePath, validateConfig, createConfigMiddleware, compileRules, publicEnvDefines, withBasePath, assetPrefixFor, writeProjectTypes, } from './config';
|
|
39
40
|
export type { RessConfig, ResolvedConfig, TrailingSlashMode, RessServerConfig } from './config';
|