@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.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -39
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +31 -37
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
79
|
+
proxy: projectProxy,
|
|
84
80
|
security: runtimePolicy.security,
|
|
85
|
-
|
|
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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAGtC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAA;AA0CrB;;;;;;GAMG;AACH,SAAS,oBAAoB,CAC3B,aAAsB,EACtB,cAAqC;
|
|
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
|
+
"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.
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
140
|
+
proxy: projectProxy,
|
|
141
141
|
security: runtimePolicy.security,
|
|
142
|
-
|
|
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(
|
|
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(
|
|
396
|
+
handlerSource: netlifyHandlerSource(
|
|
397
|
+
runtimePolicy,
|
|
398
|
+
functionConfigFor(),
|
|
399
|
+
ctx.deployManifest?.buildId ?? '',
|
|
400
|
+
),
|
|
407
401
|
} satisfies AdapterArtifact,
|
|
408
402
|
{
|
|
409
403
|
kind: 'file',
|