@ressjs/vite-router 0.5.2 → 0.6.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/LICENSE +69 -0
  2. package/README.md +9 -515
  3. package/dist/client/entry.d.mts +2 -0
  4. package/dist/client/entry.mjs +1 -0
  5. package/dist/client/index.d.ts +2 -0
  6. package/dist/client/index.js +8 -0
  7. package/dist/config/base-path.d.ts +44 -0
  8. package/dist/config/base-path.js +100 -0
  9. package/dist/config/codegen.d.ts +29 -0
  10. package/dist/config/codegen.js +131 -0
  11. package/dist/config/define.d.ts +8 -0
  12. package/dist/config/define.js +12 -0
  13. package/dist/config/env.d.ts +19 -0
  14. package/dist/config/env.js +40 -0
  15. package/dist/config/index.d.ts +18 -0
  16. package/dist/config/index.js +46 -0
  17. package/dist/config/load.d.ts +28 -0
  18. package/dist/config/load.js +82 -0
  19. package/dist/config/middleware.d.ts +18 -0
  20. package/dist/config/middleware.js +79 -0
  21. package/dist/config/rules.d.ts +59 -0
  22. package/dist/config/rules.js +162 -0
  23. package/dist/config/types.d.ts +189 -0
  24. package/dist/config/types.js +2 -0
  25. package/dist/config/validate.d.ts +19 -0
  26. package/dist/config/validate.js +143 -0
  27. package/dist/config/watch.d.ts +53 -0
  28. package/dist/config/watch.js +163 -0
  29. package/dist/fs/module-extensions.d.ts +105 -0
  30. package/dist/fs/module-extensions.js +213 -0
  31. package/dist/head/resolve.d.ts +5 -0
  32. package/dist/head/resolve.js +166 -0
  33. package/dist/head/types.d.ts +44 -0
  34. package/dist/head/types.js +2 -0
  35. package/dist/helpers/html-generator.d.ts +26 -6
  36. package/dist/helpers/html-generator.js +96 -138
  37. package/dist/helpers/middlewares.d.ts +32 -21
  38. package/dist/helpers/middlewares.js +181 -159
  39. package/dist/helpers/page-config-merge.d.ts +11 -0
  40. package/dist/helpers/page-config-merge.js +84 -0
  41. package/dist/helpers/request-handler.d.ts +15 -2
  42. package/dist/helpers/request-handler.js +164 -27
  43. package/dist/index.d.ts +35 -3
  44. package/dist/index.js +77 -8
  45. package/dist/isr/capture.d.ts +79 -0
  46. package/dist/isr/capture.js +222 -0
  47. package/dist/isr/handler.d.ts +49 -0
  48. package/dist/isr/handler.js +207 -0
  49. package/dist/isr/key.d.ts +26 -0
  50. package/dist/isr/key.js +59 -0
  51. package/dist/isr/page-config.d.ts +17 -0
  52. package/dist/isr/page-config.js +71 -0
  53. package/dist/isr/preview.d.ts +5 -0
  54. package/dist/isr/preview.js +38 -0
  55. package/dist/isr/public-request.d.ts +50 -0
  56. package/dist/isr/public-request.js +108 -0
  57. package/dist/isr/response.d.ts +41 -0
  58. package/dist/isr/response.js +128 -0
  59. package/dist/isr/store.d.ts +42 -0
  60. package/dist/isr/store.js +108 -0
  61. package/dist/isr/types.d.ts +62 -0
  62. package/dist/isr/types.js +2 -0
  63. package/dist/pages.d.ts +10 -9
  64. package/dist/pages.js +42 -261
  65. package/dist/platform.d.ts +11 -14
  66. package/dist/platform.js +18 -102
  67. package/dist/plugin/environments.d.ts +68 -0
  68. package/dist/plugin/environments.js +74 -0
  69. package/dist/plugin/index.d.ts +59 -0
  70. package/dist/plugin/index.js +195 -0
  71. package/dist/plugin/route-manifest.d.ts +19 -0
  72. package/dist/plugin/route-manifest.js +55 -0
  73. package/dist/plugin/virtual-entries.d.ts +26 -0
  74. package/dist/plugin/virtual-entries.js +80 -0
  75. package/dist/render.d.ts +39 -2
  76. package/dist/render.js +75 -77
  77. package/dist/router.d.ts +32 -13
  78. package/dist/router.js +180 -146
  79. package/dist/routes/dispatcher.d.ts +58 -0
  80. package/dist/routes/dispatcher.js +70 -0
  81. package/dist/routes/manifest.d.ts +17 -0
  82. package/dist/routes/manifest.js +62 -0
  83. package/dist/routes/match.d.ts +20 -0
  84. package/dist/routes/match.js +75 -0
  85. package/dist/routes/module.d.ts +14 -0
  86. package/dist/routes/module.js +30 -0
  87. package/dist/routes/parse.d.ts +31 -0
  88. package/dist/routes/parse.js +114 -0
  89. package/dist/routes/rank.d.ts +12 -0
  90. package/dist/routes/rank.js +49 -0
  91. package/dist/routes/router.d.ts +54 -0
  92. package/dist/routes/router.js +153 -0
  93. package/dist/routes/scan.d.ts +26 -0
  94. package/dist/routes/scan.js +98 -0
  95. package/dist/routes/types.d.ts +114 -0
  96. package/dist/routes/types.js +17 -0
  97. package/dist/runtime/dev-server.d.ts +64 -0
  98. package/dist/runtime/dev-server.js +94 -0
  99. package/dist/runtime/dev-styles.d.ts +13 -0
  100. package/dist/runtime/dev-styles.js +50 -0
  101. package/dist/runtime/module-loader.d.ts +55 -0
  102. package/dist/runtime/module-loader.js +122 -0
  103. package/dist/runtime/prod-server.d.ts +55 -0
  104. package/dist/runtime/prod-server.js +188 -0
  105. package/dist/runtime/template.d.ts +10 -0
  106. package/dist/runtime/template.js +33 -0
  107. package/dist/security/client-props.d.ts +25 -0
  108. package/dist/security/client-props.js +51 -0
  109. package/dist/security/config.d.ts +121 -0
  110. package/dist/security/config.js +77 -0
  111. package/dist/security/csp.d.ts +53 -0
  112. package/dist/security/csp.js +118 -0
  113. package/dist/security/dev-hardening.d.ts +46 -0
  114. package/dist/security/dev-hardening.js +65 -0
  115. package/dist/security/errors.d.ts +37 -0
  116. package/dist/security/errors.js +84 -0
  117. package/dist/security/escape.d.ts +40 -0
  118. package/dist/security/escape.js +90 -0
  119. package/dist/security/head-tags.d.ts +32 -0
  120. package/dist/security/head-tags.js +156 -0
  121. package/dist/security/headers.d.ts +76 -0
  122. package/dist/security/headers.js +278 -0
  123. package/dist/security/index.d.ts +24 -0
  124. package/dist/security/index.js +49 -0
  125. package/dist/security/serialize.d.ts +48 -0
  126. package/dist/security/serialize.js +146 -0
  127. package/dist/variants/assets.d.ts +33 -0
  128. package/dist/variants/assets.js +144 -0
  129. package/dist/variants/catalog.d.ts +33 -0
  130. package/dist/variants/catalog.js +79 -0
  131. package/dist/variants/platform-tokens.d.ts +9 -0
  132. package/dist/variants/platform-tokens.js +15 -0
  133. package/dist/variants/resolve.d.ts +40 -0
  134. package/dist/variants/resolve.js +90 -0
  135. package/dist/variants/suffix.d.ts +8 -0
  136. package/dist/variants/suffix.js +12 -0
  137. package/dist/variants/types.d.ts +72 -0
  138. package/dist/variants/types.js +2 -0
  139. package/package.json +23 -11
  140. package/dist/helpers/vite-config.d.ts +0 -10
  141. package/dist/helpers/vite-config.js +0 -90
@@ -1,52 +1,102 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRequestPlatform = resolveRequestPlatform;
4
+ exports.buildRenderServer = buildRenderServer;
6
5
  exports.processRequest = processRequest;
7
- const promises_1 = __importDefault(require("node:fs/promises"));
8
- const pages_1 = require("../pages");
9
6
  const render_1 = require("../render");
10
7
  const platform_1 = require("../platform");
11
8
  const html_generator_1 = require("./html-generator");
12
- async function preparePlatform(req, enablePlatformDetection = true, isProduction = false) {
9
+ const assets_1 = require("@ressjs/assets");
10
+ const resolve_1 = require("../variants/resolve");
11
+ const platform_tokens_1 = require("../variants/platform-tokens");
12
+ const security_1 = require("../security");
13
+ const template_1 = require("../runtime/template");
14
+ const resolve_2 = require("../head/resolve");
15
+ const page_config_merge_1 = require("./page-config-merge");
16
+ const dev_styles_1 = require("../runtime/dev-styles");
17
+ function resolveRequestPlatform(req, enablePlatformDetection = true) {
13
18
  if (!enablePlatformDetection) {
14
19
  return {
15
20
  platform: 'desktop',
16
21
  platformInfo: null
17
22
  };
18
23
  }
19
- const userAgent = req.headers['user-agent'] || '';
20
- const platformInfo = (0, platform_1.detectPlatform)(userAgent, req.headers);
24
+ // R-10: la detección usa siempre el User-Agent. Es la única señal disponible
25
+ // para un cliente que no manda cabeceras propias ni pistas del navegador —un
26
+ // Safari de iPhone o un televisor Tizen sin app nativa detrás—, y no se
27
+ // declara en `Vary` (ver `security/headers.ts`), así que no hay nada que
28
+ // apagar por cacheabilidad.
29
+ const platformInfo = (0, platform_1.detect)({
30
+ userAgent: req.headers['user-agent'] || '',
31
+ headers: req.headers,
32
+ });
21
33
  const platform = (platformInfo.device === 'phone' || platformInfo.device === 'tablet') ? 'mobile' : 'desktop';
22
- if (!isProduction && platformInfo) {
23
- await (0, pages_1.generateTempEntries)('dist', platformInfo);
24
- }
25
34
  return { platform, platformInfo };
26
35
  }
36
+ /**
37
+ * Arma el render server a partir de la config de la ruta.
38
+ *
39
+ * `viteConfig` puede llegar como thunk (modo automático: el runtime se
40
+ * resuelve después de crear el router), por eso se resuelve acá y no al
41
+ * armar `RouterConfig`. Se llama una sola vez por middleware: quien la usa
42
+ * cachea el resultado en su propio closure.
43
+ */
44
+ function buildRenderServer(config) {
45
+ const resolvedViteConfig = typeof config.viteConfig === 'function'
46
+ ? config.viteConfig()
47
+ : config.viteConfig;
48
+ const options = config.security ?? (0, security_1.resolveSecurityOptions)(config.securityOptions);
49
+ return (0, render_1.createRenderServer)({
50
+ ...(resolvedViteConfig.moduleLoader ? { moduleLoader: resolvedViteConfig.moduleLoader } : {}),
51
+ clientProps: options.clientProps,
52
+ isProduction: resolvedViteConfig.isProduction,
53
+ });
54
+ }
27
55
  async function processRequest(context, config, renderServer) {
28
56
  const { req, res, page, next } = context;
29
- // config.viteConfig can be a ViteConfig or a thunk returning it (auto mode)
57
+ // En modo automático el runtime llega como thunk, porque se resuelve después de crear el router.
30
58
  const resolvedViteConfig = typeof config.viteConfig === 'function'
31
59
  ? config.viteConfig()
32
60
  : config.viteConfig;
33
61
  const { enablePlatformDetection, renderFunction } = config;
34
62
  const viteConfig = resolvedViteConfig;
63
+ const options = config.security ?? (0, security_1.resolveSecurityOptions)(config.securityOptions);
64
+ // El nonce se genera una vez por petición, antes del render, y viaja hasta el
65
+ // documento y hasta la cabecera: así el valor del atributo y el de la política
66
+ // son el mismo por construcción y no por coincidencia.
67
+ // Por qué ejes varía esta página. Decide dos cosas que tienen que coincidir:
68
+ // qué se declara en `Vary` y qué del cliente puede escribirse en el documento.
69
+ const pageVariants = page?.pageId
70
+ ? (viteConfig.catalog?.variantsByPage.get(page.pageId) ?? [])
71
+ : [];
72
+ const varyBy = (0, resolve_1.varyingAxes)(pageVariants);
73
+ const security = {
74
+ isProduction: viteConfig.isProduction,
75
+ options,
76
+ route: page?.route ?? req.url ?? '',
77
+ varyBy,
78
+ ...(options.csp.enabled ? { nonce: (0, security_1.createNonce)() } : {}),
79
+ };
35
80
  try {
36
- const platformContext = await preparePlatform(req, enablePlatformDetection, viteConfig.isProduction);
81
+ // La caché incremental ya la resolvió para armar su clave: volver a
82
+ // detectarla podría dar otra respuesta y guardar un documento bajo la
83
+ // plataforma equivocada.
84
+ const platformContext = req.ressPlatform
85
+ ?? resolveRequestPlatform(req, enablePlatformDetection);
86
+ // Lo que devolvió `getServerSideProps` gana sobre el export estático.
87
+ const hydrate = req.ressPageRendering?.hydrate ?? page?.config?.hydrate !== false;
37
88
  if (renderFunction) {
38
89
  const html = await renderFunction({
39
90
  url: req.url,
40
91
  platform: platformContext.platform,
41
92
  req
42
93
  });
43
- res.setHeader('Content-Type', 'text/html');
94
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
44
95
  res.send(html);
45
96
  return;
46
97
  }
47
98
  if (!renderServer) {
48
- const renderOptions = viteConfig.vite ? { vite: viteConfig.vite } : {};
49
- renderServer = (0, render_1.createRenderServer)(renderOptions);
99
+ renderServer = buildRenderServer(config);
50
100
  }
51
101
  const protocol = req.headers['x-forwarded-proto'] || (req.connection?.encrypted ? 'https' : 'http');
52
102
  const host = req.headers.host || 'localhost';
@@ -56,38 +106,125 @@ async function processRequest(context, config, renderServer) {
56
106
  if (!res.locals) {
57
107
  res.locals = {};
58
108
  }
109
+ // El catálogo se resolvió al arrancar. Dejamos los enlaces en el scope de
110
+ // esta petición para que middlewares puedan inspeccionarlos o ajustarlos,
111
+ // sin volver a consultar el filesystem durante el render.
112
+ if (!res.locals.styles && page?.pageId && viteConfig.catalog && viteConfig.assets) {
113
+ res.locals.styles = (0, assets_1.resolvePageAssets)(page.pageId, platformContext.platformInfo ?? platform_1.DEFAULT_PLATFORM, viteConfig.catalog, viteConfig.assets);
114
+ }
115
+ const pageLocals = { ...res.locals };
116
+ delete pageLocals.styles;
59
117
  const rendered = await renderServer({
60
118
  url: pathname,
61
119
  req,
62
120
  res,
63
- props: res.locals.serverSideProps
121
+ 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
+ hydrate,
126
+ // La página ya la resolvió el despachador: buscarla de nuevo por URL sería
127
+ // una segunda resolución con otro criterio.
128
+ page,
64
129
  });
65
130
  const template = await getTemplate(req, viteConfig);
131
+ const pageHead = (0, resolve_2.resolvePageHead)((0, page_config_merge_1.mergePageConfig)(page?.config, res.locals?.pageConfig), rendered.head, platformContext.platformInfo);
66
132
  const html = await (0, html_generator_1.generateCompleteHTML)({
67
133
  template,
68
134
  rendered,
69
135
  page,
70
- manifest: viteConfig.manifest,
71
136
  platform: platformContext.platform,
72
137
  isProduction: viteConfig.isProduction,
73
138
  platformInfo: platformContext.platformInfo,
74
- // pasar solo la config segura
75
- ...(res.locals?.htmlConfig ? { serverSideResult: res.locals.htmlConfig } : {})
139
+ catalog: viteConfig.catalog,
140
+ assets: viteConfig.assets,
141
+ styles: hydrate || viteConfig.isProduction
142
+ ? res.locals.styles
143
+ : withDevStyles(res.locals.styles, viteConfig.vite, page?.file),
144
+ pageHead,
145
+ hydrate,
146
+ }, security);
147
+ warnIfStateTooLarge(rendered.props, security);
148
+ // Las cabeceras van antes del cuerpo: después de la primera escritura ya no
149
+ // se pueden cambiar, y el intento lanza una excepción que tapa el error real.
150
+ (0, security_1.applySecurityHeaders)(res, options, {
151
+ isProduction: viteConfig.isProduction,
152
+ varyBy: platformContext.platformInfo ? varyBy : null,
153
+ edge: platform_tokens_1.defaultPlatformRegistry.edge,
154
+ nonce: security.nonce,
155
+ kind: 'html',
76
156
  });
77
- res.setHeader('Content-Type', 'text/html');
157
+ if (pageHead.robots)
158
+ res.setHeader('X-Robots-Tag', pageHead.robots);
159
+ if (options.csp.enabled && security.nonce) {
160
+ const header = (0, security_1.cspHeaderName)(options.csp);
161
+ const existing = res.getHeader(header);
162
+ // Una política que escribió la aplicación se respeta: sus dominios y sus
163
+ // proveedores son decisión suya. Lo único que se le agrega es el nonce,
164
+ // sin el cual el bloque de estado no se ejecuta y la página no hidrata.
165
+ res.setHeader(header, existing
166
+ ? (0, security_1.injectNonce)(String(existing), security.nonce)
167
+ : (0, security_1.buildCsp)(options.csp, security.nonce, viteConfig.isProduction));
168
+ // `report-to` nombra un grupo: sin la cabecera que lo define, los informes
169
+ // de violación no llegan a ningún lado.
170
+ if (options.csp.reportUri && res.getHeader('Reporting-Endpoints') === undefined) {
171
+ res.setHeader('Reporting-Endpoints', (0, security_1.reportingEndpointsHeader)(options.csp.reportUri));
172
+ }
173
+ }
78
174
  res.send(html);
79
175
  }
80
176
  catch (error) {
81
- console.error(`Error handling ${req.url}:`, error);
82
- if (viteConfig.vite?.ssrFixStacktrace) {
83
- viteConfig.vite.ssrFixStacktrace(error);
84
- }
85
- next(error);
177
+ const publicError = (0, security_1.sanitizeError)(error, viteConfig.isProduction);
178
+ (0, security_1.logServerError)(error, { method: req.method, url: req.url, statusCode: publicError.statusCode });
179
+ (0, security_1.applySecurityHeaders)(res, options, {
180
+ isProduction: viteConfig.isProduction,
181
+ kind: 'error',
182
+ });
183
+ next(Object.assign(new Error(publicError.message), publicError));
86
184
  }
87
185
  }
186
+ /**
187
+ * Avisa cuando el estado que viaja es grande.
188
+ *
189
+ * En desarrollo, en cada petición y con las claves más pesadas —eso es lo que
190
+ * hace accionable el aviso—. En producción, una sola vez por ruta: un aviso por
191
+ * petición inunda los logs y deja de leerse.
192
+ */
193
+ const warnedOversizeRoutes = new Set();
194
+ function warnIfStateTooLarge(props, security) {
195
+ const { options, isProduction, route } = security;
196
+ const check = (0, security_1.checkStateSize)((0, security_1.serializeState)(props ?? {}), options.maxStateBytes, props);
197
+ if (!check.overLimit)
198
+ return;
199
+ const kib = (n) => `${(n / 1024).toFixed(1)} KiB`;
200
+ const detail = check.heaviest.length
201
+ ? ` Lo más pesado: ${check.heaviest.map((h) => `${h.key} (${kib(h.bytes)})`).join(', ')}.`
202
+ : '';
203
+ const message = `[ress] ${route}: el estado que viaja al cliente pesa ${kib(check.bytes)}, ` +
204
+ `sobre un límite de ${kib(options.maxStateBytes)}.${detail}`;
205
+ if (options.onStateOverLimit === 'error')
206
+ throw new Error(message);
207
+ if (isProduction) {
208
+ if (warnedOversizeRoutes.has(route))
209
+ return;
210
+ warnedOversizeRoutes.add(route);
211
+ }
212
+ console.warn(message);
213
+ }
214
+ /**
215
+ * Una página que no hidrata, en desarrollo, enlaza sus hojas directamente: el
216
+ * módulo que normalmente las inyecta no se carga.
217
+ */
218
+ function withDevStyles(styles, vite, pageFile) {
219
+ if (!styles)
220
+ return styles;
221
+ const prefix = styles.js.includes('/@id/') ? styles.js.slice(0, styles.js.indexOf('/@id/')) : '';
222
+ const css = [...new Set([...styles.css, ...(styles.devStyles ?? []), ...(0, dev_styles_1.devModuleStyles)(vite, pageFile, prefix)])];
223
+ return { ...styles, css };
224
+ }
88
225
  async function getTemplate(req, viteConfig) {
89
226
  if (!viteConfig.isProduction) {
90
- const template = await promises_1.default.readFile('./index.html', 'utf-8');
227
+ const template = await (0, template_1.readTemplateHtml)();
91
228
  return viteConfig.vite ? await viteConfig.vite.transformIndexHtml(req.url, template) : template;
92
229
  }
93
230
  else {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,39 @@
1
- export { createViteRouter, createAutoViteServer, listDetectedPages, getPages } from './router';
2
- export { getViteInput, getViteSSRInput, getClientEntriesInput, generateTempEntries, resolvePlatformCSS } from './pages';
1
+ export { createViteRouter, waitForViteRouter, getPages } from './router';
2
+ export { getViteSSRInput } from './pages';
3
+ export { createRouteManifest, serializeRouteManifest, loadRouteManifest } from './routes/manifest';
4
+ export { resolveServerModule } from './routes/module';
5
+ export type { ResolveServerModuleContext } from './routes/module';
6
+ export { scanRoutes } from './routes/scan';
7
+ export type { PageId, RouteEntry, RouteEntryKind, RouteManifest, RouteManifestData, RouteMatch, RouteSegment, SegmentKind, } from './routes/types';
8
+ export { ROUTE_MANIFEST_VERSION } from './routes/types';
9
+ export { defineEnvironments, OUT_DIR } from './plugin/environments';
10
+ export { ressPlugin, ressCorePlugin, refreshVariantCatalog, getVariantCatalog } from './plugin/index';
11
+ export type { RessPlugin, RessPluginOptions } from './plugin/index';
12
+ export { createDevModuleLoader, createProdModuleLoader, } from './runtime/module-loader';
13
+ export type { FetchableEnvironment, ModuleLoader } from './runtime/module-loader';
14
+ export { createRuntime, resolveServerModulePath, resolveProductionModuleId, } from './runtime/prod-server';
15
+ export { resolveSsrEnvironment } from './runtime/dev-server';
16
+ export type { DevRuntimeOptions, RessRuntime } from './runtime/dev-server';
17
+ export { DEFAULT_EXCLUSIONS, isPageFile, pageExclusionOf, scriptExtensionOf, SCRIPT_EXTENSIONS, } from './fs/module-extensions';
18
+ export type { PageExclusion } from './fs/module-extensions';
19
+ export { buildVariantCatalog, pageIdFromFile } from './variants/catalog';
20
+ export { resolveVariant, explainResolution } from './variants/resolve';
21
+ export { defaultPlatformRegistry } from './variants/platform-tokens';
22
+ export type { VariantCatalog, BuildEntry, Variant, AssetIndex, PlatformRegistry } from './variants/types';
3
23
  export { createRenderServer } from './render';
4
24
  export { detectPlatform } from './platform';
5
25
  export type { PlatformInfo } from './platform';
6
- export type { ViteRouterOptions, AutoViteServerOptions } from './router';
26
+ export type { ViteRouterOptions } from './router';
7
27
  export type { PageInfo } from './pages';
28
+ export type { PageConfig, PageConfigVariant, PageHeadConfig, PageRenderingConfig, RenderingMode, RobotsConfig, } from './head/types';
29
+ export type { ServerSideResult } from './helpers/middlewares';
30
+ export { PublicFacingError, resolveSecurityOptions, serializeState, applySecurityHeaders, } from './security';
31
+ export type { ClientPropsPolicy, PublicError, ResolvedSecurityOptions, SecurityOptions, } from './security';
32
+ /**
33
+ * @deprecated Usá el manifest de rutas: `runtime.routes.entries`. Devuelve las
34
+ * páginas tal como las enumera el catálogo de variantes, que no conoce grupos ni
35
+ * catch-all. Se elimina cuando F-016 consuma el manifest.
36
+ */
37
+ export { getPages as listDetectedPages } from './pages';
38
+ export { defineConfig, loadConfig, createConfigMiddleware, compileRules, publicEnvDefines, withBasePath, assetPrefixFor, writeProjectTypes, } from './config';
39
+ export type { RessConfig, ResolvedConfig, TrailingSlashMode, RessServerConfig } from './config';
package/dist/index.js CHANGED
@@ -1,22 +1,91 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.detectPlatform = exports.createRenderServer = exports.resolvePlatformCSS = exports.generateTempEntries = exports.getClientEntriesInput = exports.getViteSSRInput = exports.getViteInput = exports.getPages = exports.listDetectedPages = exports.createAutoViteServer = exports.createViteRouter = void 0;
3
+ exports.writeProjectTypes = exports.assetPrefixFor = exports.withBasePath = exports.publicEnvDefines = exports.compileRules = exports.createConfigMiddleware = exports.loadConfig = exports.defineConfig = exports.listDetectedPages = exports.applySecurityHeaders = exports.serializeState = exports.resolveSecurityOptions = exports.PublicFacingError = exports.detectPlatform = exports.createRenderServer = exports.defaultPlatformRegistry = exports.explainResolution = exports.resolveVariant = exports.pageIdFromFile = exports.buildVariantCatalog = exports.SCRIPT_EXTENSIONS = exports.scriptExtensionOf = exports.pageExclusionOf = exports.isPageFile = exports.DEFAULT_EXCLUSIONS = exports.resolveSsrEnvironment = exports.resolveProductionModuleId = exports.resolveServerModulePath = exports.createRuntime = exports.createProdModuleLoader = exports.createDevModuleLoader = exports.getVariantCatalog = exports.refreshVariantCatalog = exports.ressCorePlugin = exports.ressPlugin = exports.OUT_DIR = exports.defineEnvironments = exports.ROUTE_MANIFEST_VERSION = exports.scanRoutes = exports.resolveServerModule = exports.loadRouteManifest = exports.serializeRouteManifest = exports.createRouteManifest = exports.getViteSSRInput = exports.getPages = exports.waitForViteRouter = exports.createViteRouter = void 0;
4
4
  // Main API
5
5
  var router_1 = require("./router");
6
6
  Object.defineProperty(exports, "createViteRouter", { enumerable: true, get: function () { return router_1.createViteRouter; } });
7
- Object.defineProperty(exports, "createAutoViteServer", { enumerable: true, get: function () { return router_1.createAutoViteServer; } });
8
- Object.defineProperty(exports, "listDetectedPages", { enumerable: true, get: function () { return router_1.listDetectedPages; } });
7
+ Object.defineProperty(exports, "waitForViteRouter", { enumerable: true, get: function () { return router_1.waitForViteRouter; } });
9
8
  Object.defineProperty(exports, "getPages", { enumerable: true, get: function () { return router_1.getPages; } });
10
- // Core functions for Vite config
9
+ // Entradas de build del entorno de servidor
11
10
  var pages_1 = require("./pages");
12
- Object.defineProperty(exports, "getViteInput", { enumerable: true, get: function () { return pages_1.getViteInput; } });
13
11
  Object.defineProperty(exports, "getViteSSRInput", { enumerable: true, get: function () { return pages_1.getViteSSRInput; } });
14
- Object.defineProperty(exports, "getClientEntriesInput", { enumerable: true, get: function () { return pages_1.getClientEntriesInput; } });
15
- Object.defineProperty(exports, "generateTempEntries", { enumerable: true, get: function () { return pages_1.generateTempEntries; } });
16
- Object.defineProperty(exports, "resolvePlatformCSS", { enumerable: true, get: function () { return pages_1.resolvePlatformCSS; } });
12
+ // Rutas: manifest, escaneo y tipos (F-018). Superficie que F-033 (la CLI)
13
+ // necesita para construir la aplicación y para `ress info`, sin duplicar la
14
+ // enumeración que ya hace el framework.
15
+ var manifest_1 = require("./routes/manifest");
16
+ Object.defineProperty(exports, "createRouteManifest", { enumerable: true, get: function () { return manifest_1.createRouteManifest; } });
17
+ Object.defineProperty(exports, "serializeRouteManifest", { enumerable: true, get: function () { return manifest_1.serializeRouteManifest; } });
18
+ Object.defineProperty(exports, "loadRouteManifest", { enumerable: true, get: function () { return manifest_1.loadRouteManifest; } });
19
+ var module_1 = require("./routes/module");
20
+ Object.defineProperty(exports, "resolveServerModule", { enumerable: true, get: function () { return module_1.resolveServerModule; } });
21
+ var scan_1 = require("./routes/scan");
22
+ Object.defineProperty(exports, "scanRoutes", { enumerable: true, get: function () { return scan_1.scanRoutes; } });
23
+ var types_1 = require("./routes/types");
24
+ Object.defineProperty(exports, "ROUTE_MANIFEST_VERSION", { enumerable: true, get: function () { return types_1.ROUTE_MANIFEST_VERSION; } });
25
+ // Runtime: entornos de build y directorios de salida (F-015/F-016). La CLI los
26
+ // usa para `ress build` y para resolver dónde quedó el build en `ress info`.
27
+ var environments_1 = require("./plugin/environments");
28
+ Object.defineProperty(exports, "defineEnvironments", { enumerable: true, get: function () { return environments_1.defineEnvironments; } });
29
+ Object.defineProperty(exports, "OUT_DIR", { enumerable: true, get: function () { return environments_1.OUT_DIR; } });
30
+ var index_1 = require("./plugin/index");
31
+ Object.defineProperty(exports, "ressPlugin", { enumerable: true, get: function () { return index_1.ressPlugin; } });
32
+ Object.defineProperty(exports, "ressCorePlugin", { enumerable: true, get: function () { return index_1.ressCorePlugin; } });
33
+ Object.defineProperty(exports, "refreshVariantCatalog", { enumerable: true, get: function () { return index_1.refreshVariantCatalog; } });
34
+ Object.defineProperty(exports, "getVariantCatalog", { enumerable: true, get: function () { return index_1.getVariantCatalog; } });
35
+ // Cargador de módulos: la vía de escape nivel 2 de F-033 carga el archivo de
36
+ // servidor del proyecto con el mismo mecanismo que las páginas.
37
+ var module_loader_1 = require("./runtime/module-loader");
38
+ Object.defineProperty(exports, "createDevModuleLoader", { enumerable: true, get: function () { return module_loader_1.createDevModuleLoader; } });
39
+ Object.defineProperty(exports, "createProdModuleLoader", { enumerable: true, get: function () { return module_loader_1.createProdModuleLoader; } });
40
+ var prod_server_1 = require("./runtime/prod-server");
41
+ Object.defineProperty(exports, "createRuntime", { enumerable: true, get: function () { return prod_server_1.createRuntime; } });
42
+ Object.defineProperty(exports, "resolveServerModulePath", { enumerable: true, get: function () { return prod_server_1.resolveServerModulePath; } });
43
+ Object.defineProperty(exports, "resolveProductionModuleId", { enumerable: true, get: function () { return prod_server_1.resolveProductionModuleId; } });
44
+ var dev_server_1 = require("./runtime/dev-server");
45
+ Object.defineProperty(exports, "resolveSsrEnvironment", { enumerable: true, get: function () { return dev_server_1.resolveSsrEnvironment; } });
46
+ // Extensiones reconocidas (F-017), para quien necesita autodetectar un archivo
47
+ // de servidor del proyecto con la misma política que las páginas.
48
+ var module_extensions_1 = require("./fs/module-extensions");
49
+ Object.defineProperty(exports, "DEFAULT_EXCLUSIONS", { enumerable: true, get: function () { return module_extensions_1.DEFAULT_EXCLUSIONS; } });
50
+ Object.defineProperty(exports, "isPageFile", { enumerable: true, get: function () { return module_extensions_1.isPageFile; } });
51
+ Object.defineProperty(exports, "pageExclusionOf", { enumerable: true, get: function () { return module_extensions_1.pageExclusionOf; } });
52
+ Object.defineProperty(exports, "scriptExtensionOf", { enumerable: true, get: function () { return module_extensions_1.scriptExtensionOf; } });
53
+ Object.defineProperty(exports, "SCRIPT_EXTENSIONS", { enumerable: true, get: function () { return module_extensions_1.SCRIPT_EXTENSIONS; } });
54
+ // Catálogo de variantes de plataforma
55
+ var catalog_1 = require("./variants/catalog");
56
+ Object.defineProperty(exports, "buildVariantCatalog", { enumerable: true, get: function () { return catalog_1.buildVariantCatalog; } });
57
+ Object.defineProperty(exports, "pageIdFromFile", { enumerable: true, get: function () { return catalog_1.pageIdFromFile; } });
58
+ var resolve_1 = require("./variants/resolve");
59
+ Object.defineProperty(exports, "resolveVariant", { enumerable: true, get: function () { return resolve_1.resolveVariant; } });
60
+ Object.defineProperty(exports, "explainResolution", { enumerable: true, get: function () { return resolve_1.explainResolution; } });
61
+ var platform_tokens_1 = require("./variants/platform-tokens");
62
+ Object.defineProperty(exports, "defaultPlatformRegistry", { enumerable: true, get: function () { return platform_tokens_1.defaultPlatformRegistry; } });
17
63
  // Render functions
18
64
  var render_1 = require("./render");
19
65
  Object.defineProperty(exports, "createRenderServer", { enumerable: true, get: function () { return render_1.createRenderServer; } });
20
66
  // Platform detection
21
67
  var platform_1 = require("./platform");
22
68
  Object.defineProperty(exports, "detectPlatform", { enumerable: true, get: function () { return platform_1.detectPlatform; } });
69
+ // Endurecimiento del renderizado en el servidor (F-019)
70
+ var security_1 = require("./security");
71
+ Object.defineProperty(exports, "PublicFacingError", { enumerable: true, get: function () { return security_1.PublicFacingError; } });
72
+ Object.defineProperty(exports, "resolveSecurityOptions", { enumerable: true, get: function () { return security_1.resolveSecurityOptions; } });
73
+ Object.defineProperty(exports, "serializeState", { enumerable: true, get: function () { return security_1.serializeState; } });
74
+ Object.defineProperty(exports, "applySecurityHeaders", { enumerable: true, get: function () { return security_1.applySecurityHeaders; } });
75
+ /**
76
+ * @deprecated Usá el manifest de rutas: `runtime.routes.entries`. Devuelve las
77
+ * páginas tal como las enumera el catálogo de variantes, que no conoce grupos ni
78
+ * catch-all. Se elimina cuando F-016 consuma el manifest.
79
+ */
80
+ var pages_2 = require("./pages");
81
+ Object.defineProperty(exports, "listDetectedPages", { enumerable: true, get: function () { return pages_2.getPages; } });
82
+ // Configuración del proyecto (F-008)
83
+ var config_1 = require("./config");
84
+ Object.defineProperty(exports, "defineConfig", { enumerable: true, get: function () { return config_1.defineConfig; } });
85
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
86
+ Object.defineProperty(exports, "createConfigMiddleware", { enumerable: true, get: function () { return config_1.createConfigMiddleware; } });
87
+ Object.defineProperty(exports, "compileRules", { enumerable: true, get: function () { return config_1.compileRules; } });
88
+ Object.defineProperty(exports, "publicEnvDefines", { enumerable: true, get: function () { return config_1.publicEnvDefines; } });
89
+ Object.defineProperty(exports, "withBasePath", { enumerable: true, get: function () { return config_1.withBasePath; } });
90
+ Object.defineProperty(exports, "assetPrefixFor", { enumerable: true, get: function () { return config_1.assetPrefixFor; } });
91
+ Object.defineProperty(exports, "writeProjectTypes", { enumerable: true, get: function () { return config_1.writeProjectTypes; } });
@@ -0,0 +1,79 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { Request, RequestHandler, Response } from 'express';
3
+ import type { CapturedResponse, HeaderValue } from './types';
4
+ type Headers = Record<string, HeaderValue>;
5
+ /**
6
+ * Una respuesta sin socket.
7
+ *
8
+ * Implementa la parte de `express.Response` que usan el pipeline de render y
9
+ * `getServerSideProps`, y nada la conecta con la respuesta real: una generación
10
+ * en segundo plano no puede escribirle a un cliente que ya recibió su documento.
11
+ * La compresión tampoco la toca, así que lo que queda capturado es el HTML tal
12
+ * como lo produjo la página.
13
+ */
14
+ export declare class CaptureResponse extends EventEmitter {
15
+ #private;
16
+ readonly req: Request;
17
+ private readonly onEnd?;
18
+ statusCode: number;
19
+ statusMessage: string;
20
+ locals: Record<string, unknown>;
21
+ constructor(req: Request, seed?: Headers, onEnd?: ((res: CaptureResponse) => void) | undefined);
22
+ get headersSent(): boolean;
23
+ get writableEnded(): boolean;
24
+ get finished(): boolean;
25
+ setHeader(name: string, value: unknown): this;
26
+ getHeader(name: string): HeaderValue | undefined;
27
+ getHeaders(): Headers;
28
+ getHeaderNames(): string[];
29
+ hasHeader(name: string): boolean;
30
+ removeHeader(name: string): void;
31
+ set(field: string | Record<string, unknown>, value?: unknown): this;
32
+ header(field: string | Record<string, unknown>, value?: unknown): this;
33
+ get(name: string): HeaderValue | undefined;
34
+ append(name: string, value: unknown): this;
35
+ vary(field: string): this;
36
+ status(code: number): this;
37
+ sendStatus(code: number): this;
38
+ type(value: string): this;
39
+ contentType(value: string): this;
40
+ location(url: string): this;
41
+ redirect(statusOrUrl: number | string, maybeUrl?: string): void;
42
+ cookie(name: string, value: unknown, options?: {
43
+ path?: string;
44
+ maxAge?: number;
45
+ httpOnly?: boolean;
46
+ secure?: boolean;
47
+ sameSite?: string;
48
+ }): this;
49
+ clearCookie(name: string, options?: {
50
+ path?: string;
51
+ }): this;
52
+ writeHead(status: number, headers?: Record<string, unknown>): this;
53
+ flushHeaders(): void;
54
+ write(chunk: unknown): boolean;
55
+ end(chunk?: unknown): this;
56
+ send(body?: unknown): this;
57
+ json(body: unknown): this;
58
+ /** Lo que se escribió, sin las cabeceras de transporte. */
59
+ snapshot(): CapturedResponse;
60
+ }
61
+ /**
62
+ * Ejecuta la cadena de render contra una respuesta sintética.
63
+ *
64
+ * Resuelve con lo capturado; con `null` si la cadena terminó sin responder
65
+ * (la ruta la atiende otro); rechaza con el error que la cadena propagó.
66
+ */
67
+ export declare function runCaptured(chain: readonly RequestHandler[], req: Request, seed: Headers): Promise<CapturedResponse | null>;
68
+ /**
69
+ * Lo que la generación agregó o cambió respecto de la semilla.
70
+ *
71
+ * La semilla son las cabeceras que la respuesta real ya tenía —las de los
72
+ * middlewares—, y esas se recalculan en cada petición: guardarlas congelaría las
73
+ * de un visitante para todos. De `Vary` se guardan sólo los campos nuevos.
74
+ */
75
+ export declare function headerDelta(seed: Headers, produced: Headers): Headers;
76
+ export declare function varyFields(value: HeaderValue | undefined): string[];
77
+ /** Las cabeceras de la respuesta real, normalizadas, sin cookies. */
78
+ export declare function seedFrom(res: Response): Headers;
79
+ export {};