@ruvyxa/adapter-netlify 1.1.3 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAgD,MAAM,cAAc,CAAA;AAczF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAiND;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAsJpE;eAEc,OAAO"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAgD,MAAM,cAAc,CAAA;AAiBzF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAgMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CA8JpE;eAEc,OAAO"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { CLIENT_BUNDLE_PREFIX, clientBuildOutput, DEFAULT_SECURITY_HEADERS, IMMUTABLE_CACHE_CONTROL, nonPublishableStrategies, projectRelativeOutDir, PUBLIC_ASSET_CACHE_CONTROL, publicAssetGlobs, runtimeBuildPolicy, validateBuildContext, } from '@ruvyxa/core';
2
+ import { CLIENT_BUNDLE_PREFIX, clientBuildOutput, documentCacheOptionsSource, isrTemporaryCacheSource, platformDocumentStoreSource, DEFAULT_SECURITY_HEADERS, IMMUTABLE_CACHE_CONTROL, nonPublishableStrategies, projectRelativeOutDir, PUBLIC_ASSET_CACHE_CONTROL, publicAssetGlobs, runtimeBuildPolicy, validateBuildContext, } from '@ruvyxa/core';
3
3
  /**
4
4
  * Netlify Functions v2 handler source code.
5
5
  *
@@ -7,9 +7,9 @@ import { CLIENT_BUNDLE_PREFIX, clientBuildOutput, DEFAULT_SECURITY_HEADERS, IMMU
7
7
  * handler using the Web-standard Request/Response API. Reads the route
8
8
  * manifest and handles SSR/API/ISR/PPR requests.
9
9
  */
10
- function netlifyHandlerSource(runtimePolicy, functionConfig) {
10
+ function netlifyHandlerSource(runtimePolicy, functionConfig, buildId) {
11
11
  return `import { createHandler, prerenderRelativePath } from './serverless-handler.mjs';
12
- import { applyPluginHttp, loadActionModule, loadRouteModule } from './route-modules.mjs';
12
+ import { projectProxy, documentCacheHandler, loadActionModule, loadRouteModule } from './route-modules.mjs';
13
13
  // Netlify bundles the function with esbuild, so anything the deployed code
14
14
  // needs must be reachable through the module graph. A sibling manifest.json
15
15
  // read from import.meta.dirname is not, and never reaches /var/task.
@@ -27,10 +27,7 @@ const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
27
27
  // serves SSG pages from the publish directory before the function is ever
28
28
  // invoked (config.preferStatic).
29
29
  const prerenderDir = path.join(import.meta.dirname, 'prerender');
30
- // The function bundle directory is read-only at runtime; only the platform
31
- // tmp directory accepts writes. ISR revalidations land there and are read
32
- // back before the bundled deploy-time prerender output.
33
- const isrCacheDir = path.join(os.tmpdir(), 'ruvyxa-isr-cache');
30
+ ${isrTemporaryCacheSource(buildId)}
34
31
 
35
32
  /**
36
33
  * The cache tag a document is stored under, so one path can be dropped from
@@ -67,50 +64,35 @@ async function purgeDurableCache(pathname) {
67
64
  }
68
65
  }
69
66
 
70
- const readEntry = (htmlPath, revalidate) => {
71
- const html = readFileSync(htmlPath, 'utf8');
72
- const stale = Date.now() - statSync(htmlPath).mtimeMs >= revalidate * 1000;
73
- return { html, stale };
74
- };
67
+ ${platformDocumentStoreSource({ onForcedWrite: 'purgeDurableCache' })}
75
68
 
76
69
  const handler = createHandler({
77
70
  routes: manifest.routes,
78
71
  middleware: runtimePolicy.middleware,
72
+ headers: runtimePolicy.headers,
73
+ redirects: runtimePolicy.redirects,
74
+ rewrites: runtimePolicy.rewrites,
79
75
  i18n: manifest.i18n,
80
76
  importPage: loadRouteModule,
81
77
  importApi: loadRouteModule,
82
78
  importAction: loadActionModule,
83
- pluginHttp: applyPluginHttp,
79
+ proxy: projectProxy,
84
80
  security: runtimePolicy.security,
85
- readPrerendered: (pathname, revalidate = 60) => {
86
- // prerenderRelativePath rejects any request path that cannot be mapped to a
87
- // location inside the cache directories, so reads can never escape them.
88
- const relative = prerenderRelativePath(pathname);
89
- if (relative === null) return null;
90
- try {
91
- return readEntry(path.join(isrCacheDir, relative), revalidate);
92
- } catch {
93
- // fall through to the bundled prerender output
94
- }
95
- try {
96
- return readEntry(path.join(prerenderDir, relative), revalidate);
97
- } catch {
98
- return null;
99
- }
100
- },
101
- writePrerendered: (pathname, html, revalidate, forced) => {
102
- const relative = prerenderRelativePath(pathname);
103
- if (relative === null) return;
104
- const htmlPath = path.join(isrCacheDir, relative);
105
- mkdirSync(path.dirname(htmlPath), { recursive: true });
106
- writeFileSync(htmlPath, html, 'utf8');
107
- if (forced === true) return purgeDurableCache(pathname);
108
- },
81
+ ${documentCacheOptionsSource('platformReadPrerendered', 'platformWritePrerendered')}
109
82
  // The project's own not-found page, pre-rendered by the build and carried
110
83
  // inline in the manifest: an unmatched URL is answered with the page the
111
84
  // application actually wrote, on every host.
112
85
  notFoundDocument: manifest.notFoundDocument,
113
86
  supportedStrategies: ['ssr', 'ssg', 'csr', 'isr', 'ppr', 'api'],
87
+ // Netlify's own edge writes \`X-Nf-Client-Connection-IP\` and overwrites any
88
+ // inbound copy of it, so on this platform the header *is* the client.
89
+ // Declared here rather than assumed by the handler: the same handler runs on
90
+ // a self-hosted server where nothing writes it. Without a declaration
91
+ // identity fell through to a right-to-left scan of \`X-Forwarded-For\`, whose
92
+ // rightmost entry here is a fixed platform address — so the built-in \`rate\`
93
+ // middleware, the server-action rate limiter, and the replay quota all
94
+ // counted every visitor into one bucket.
95
+ clientIpHeaders: ['x-nf-client-connection-ip'],
114
96
  });
115
97
 
116
98
  // Netlify Functions v2 — Web-standard Request/Response
@@ -272,7 +254,7 @@ export function netlify(options = {}) {
272
254
  {
273
255
  kind: 'function',
274
256
  path: 'deploy/netlify/functions/ruvyxa-handler',
275
- handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor()),
257
+ handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor(), ctx.deployManifest?.buildId ?? ''),
276
258
  },
277
259
  // Netlify config for the deploy directory
278
260
  {
@@ -289,7 +271,7 @@ export function netlify(options = {}) {
289
271
  kind: 'function',
290
272
  path: '.netlify/v1/functions/ruvyxa-handler',
291
273
  scope: 'project',
292
- handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor()),
274
+ handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor(), ctx.deployManifest?.buildId ?? ''),
293
275
  },
294
276
  {
295
277
  kind: 'file',
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruvyxa/adapter-netlify",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Shape Ruvyxa builds for Netlify functions and assets with a small typed adapter contract.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -56,7 +56,7 @@
56
56
  }
57
57
  },
58
58
  "dependencies": {
59
- "@ruvyxa/core": "^1.1.3"
59
+ "@ruvyxa/core": "^1.1.5"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "24.13.3"
package/src/index.ts CHANGED
@@ -4,6 +4,9 @@ import type { Adapter, AdapterArtifact, AdapterOutput, BuildContext } from '@ruv
4
4
  import {
5
5
  CLIENT_BUNDLE_PREFIX,
6
6
  clientBuildOutput,
7
+ documentCacheOptionsSource,
8
+ isrTemporaryCacheSource,
9
+ platformDocumentStoreSource,
7
10
  DEFAULT_SECURITY_HEADERS,
8
11
  IMMUTABLE_CACHE_CONTROL,
9
12
  nonPublishableStrategies,
@@ -64,9 +67,10 @@ export interface NetlifyAdapterOptions {
64
67
  function netlifyHandlerSource(
65
68
  runtimePolicy: unknown,
66
69
  functionConfig: NetlifyFunctionConfig,
70
+ buildId: string,
67
71
  ): string {
68
72
  return `import { createHandler, prerenderRelativePath } from './serverless-handler.mjs';
69
- import { applyPluginHttp, loadActionModule, loadRouteModule } from './route-modules.mjs';
73
+ import { projectProxy, documentCacheHandler, loadActionModule, loadRouteModule } from './route-modules.mjs';
70
74
  // Netlify bundles the function with esbuild, so anything the deployed code
71
75
  // needs must be reachable through the module graph. A sibling manifest.json
72
76
  // read from import.meta.dirname is not, and never reaches /var/task.
@@ -84,10 +88,7 @@ const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
84
88
  // serves SSG pages from the publish directory before the function is ever
85
89
  // invoked (config.preferStatic).
86
90
  const prerenderDir = path.join(import.meta.dirname, 'prerender');
87
- // The function bundle directory is read-only at runtime; only the platform
88
- // tmp directory accepts writes. ISR revalidations land there and are read
89
- // back before the bundled deploy-time prerender output.
90
- const isrCacheDir = path.join(os.tmpdir(), 'ruvyxa-isr-cache');
91
+ ${isrTemporaryCacheSource(buildId)}
91
92
 
92
93
  /**
93
94
  * The cache tag a document is stored under, so one path can be dropped from
@@ -124,50 +125,35 @@ async function purgeDurableCache(pathname) {
124
125
  }
125
126
  }
126
127
 
127
- const readEntry = (htmlPath, revalidate) => {
128
- const html = readFileSync(htmlPath, 'utf8');
129
- const stale = Date.now() - statSync(htmlPath).mtimeMs >= revalidate * 1000;
130
- return { html, stale };
131
- };
128
+ ${platformDocumentStoreSource({ onForcedWrite: 'purgeDurableCache' })}
132
129
 
133
130
  const handler = createHandler({
134
131
  routes: manifest.routes,
135
132
  middleware: runtimePolicy.middleware,
133
+ headers: runtimePolicy.headers,
134
+ redirects: runtimePolicy.redirects,
135
+ rewrites: runtimePolicy.rewrites,
136
136
  i18n: manifest.i18n,
137
137
  importPage: loadRouteModule,
138
138
  importApi: loadRouteModule,
139
139
  importAction: loadActionModule,
140
- pluginHttp: applyPluginHttp,
140
+ proxy: projectProxy,
141
141
  security: runtimePolicy.security,
142
- readPrerendered: (pathname, revalidate = 60) => {
143
- // prerenderRelativePath rejects any request path that cannot be mapped to a
144
- // location inside the cache directories, so reads can never escape them.
145
- const relative = prerenderRelativePath(pathname);
146
- if (relative === null) return null;
147
- try {
148
- return readEntry(path.join(isrCacheDir, relative), revalidate);
149
- } catch {
150
- // fall through to the bundled prerender output
151
- }
152
- try {
153
- return readEntry(path.join(prerenderDir, relative), revalidate);
154
- } catch {
155
- return null;
156
- }
157
- },
158
- writePrerendered: (pathname, html, revalidate, forced) => {
159
- const relative = prerenderRelativePath(pathname);
160
- if (relative === null) return;
161
- const htmlPath = path.join(isrCacheDir, relative);
162
- mkdirSync(path.dirname(htmlPath), { recursive: true });
163
- writeFileSync(htmlPath, html, 'utf8');
164
- if (forced === true) return purgeDurableCache(pathname);
165
- },
142
+ ${documentCacheOptionsSource('platformReadPrerendered', 'platformWritePrerendered')}
166
143
  // The project's own not-found page, pre-rendered by the build and carried
167
144
  // inline in the manifest: an unmatched URL is answered with the page the
168
145
  // application actually wrote, on every host.
169
146
  notFoundDocument: manifest.notFoundDocument,
170
147
  supportedStrategies: ['ssr', 'ssg', 'csr', 'isr', 'ppr', 'api'],
148
+ // Netlify's own edge writes \`X-Nf-Client-Connection-IP\` and overwrites any
149
+ // inbound copy of it, so on this platform the header *is* the client.
150
+ // Declared here rather than assumed by the handler: the same handler runs on
151
+ // a self-hosted server where nothing writes it. Without a declaration
152
+ // identity fell through to a right-to-left scan of \`X-Forwarded-For\`, whose
153
+ // rightmost entry here is a fixed platform address — so the built-in \`rate\`
154
+ // middleware, the server-action rate limiter, and the replay quota all
155
+ // counted every visitor into one bucket.
156
+ clientIpHeaders: ['x-nf-client-connection-ip'],
171
157
  });
172
158
 
173
159
  // Netlify Functions v2 — Web-standard Request/Response
@@ -386,7 +372,11 @@ export function netlify(options: NetlifyAdapterOptions = {}): Adapter {
386
372
  {
387
373
  kind: 'function',
388
374
  path: 'deploy/netlify/functions/ruvyxa-handler',
389
- handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor()),
375
+ handlerSource: netlifyHandlerSource(
376
+ runtimePolicy,
377
+ functionConfigFor(),
378
+ ctx.deployManifest?.buildId ?? '',
379
+ ),
390
380
  },
391
381
  // Netlify config for the deploy directory
392
382
  {
@@ -403,7 +393,11 @@ export function netlify(options: NetlifyAdapterOptions = {}): Adapter {
403
393
  kind: 'function',
404
394
  path: '.netlify/v1/functions/ruvyxa-handler',
405
395
  scope: 'project',
406
- handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor()),
396
+ handlerSource: netlifyHandlerSource(
397
+ runtimePolicy,
398
+ functionConfigFor(),
399
+ ctx.deployManifest?.buildId ?? '',
400
+ ),
407
401
  } satisfies AdapterArtifact,
408
402
  {
409
403
  kind: 'file',