@ruvyxa/adapter-netlify 1.0.30 → 1.1.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.
- package/README.md +18 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -12
- package/dist/index.js.map +1 -1
- package/package.json +27 -7
- package/src/index.ts +68 -12
package/README.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/thirawat27/Ruvyxa">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/thirawat27/Ruvyxa/main/assets/branding/ruvyxa.png" alt="Ruvyxa" width="140" height="140" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<h1 align="center">@ruvyxa/adapter-netlify</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Netlify deployment adapter for Ruvyxa production builds.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://www.npmjs.com/package/@ruvyxa/adapter-netlify"><img src="https://img.shields.io/npm/v/@ruvyxa/adapter-netlify?style=flat-square" alt="npm version" /></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/@ruvyxa/adapter-netlify"><img src="https://img.shields.io/node/v/@ruvyxa/adapter-netlify?style=flat-square&label=node" alt="Supported Node version" /></a>
|
|
16
|
+
<img src="https://img.shields.io/badge/license-Apache%202.0-green?style=flat-square" alt="License" />
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
4
20
|
|
|
5
21
|
## Install
|
|
6
22
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAgD,MAAM,cAAc,CAAA;AAYzF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAmID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CA+IpE;eAEc,OAAO"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import { CLIENT_BUNDLE_PREFIX, clientBuildOutput, IMMUTABLE_CACHE_CONTROL, projectRelativeOutDir, PUBLIC_ASSET_CACHE_CONTROL, publicAssetGlobs, runtimeBuildPolicy, validateBuildContext, } from '@ruvyxa/core';
|
|
2
3
|
/**
|
|
3
4
|
* Netlify Functions v2 handler source code.
|
|
@@ -6,9 +7,9 @@ import { CLIENT_BUNDLE_PREFIX, clientBuildOutput, IMMUTABLE_CACHE_CONTROL, proje
|
|
|
6
7
|
* handler using the Web-standard Request/Response API. Reads the route
|
|
7
8
|
* manifest and handles SSR/API/ISR/PPR requests.
|
|
8
9
|
*/
|
|
9
|
-
function netlifyHandlerSource(runtimePolicy) {
|
|
10
|
+
function netlifyHandlerSource(runtimePolicy, functionConfig) {
|
|
10
11
|
return `import { createHandler, prerenderRelativePath } from './serverless-handler.mjs';
|
|
11
|
-
import { loadRouteModule } from './route-modules.mjs';
|
|
12
|
+
import { applyPluginHttp, loadActionModule, loadRouteModule } from './route-modules.mjs';
|
|
12
13
|
// Netlify bundles the function with esbuild, so anything the deployed code
|
|
13
14
|
// needs must be reachable through the module graph. A sibling manifest.json
|
|
14
15
|
// read from import.meta.dirname is not, and never reaches /var/task.
|
|
@@ -19,10 +20,11 @@ import path from 'node:path';
|
|
|
19
20
|
|
|
20
21
|
const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
|
|
21
22
|
|
|
22
|
-
// Deploy-time prerender output is
|
|
23
|
-
//
|
|
24
|
-
// an on-demand render, and Netlify
|
|
25
|
-
// before the function is ever
|
|
23
|
+
// Deploy-time prerender output is not part of the module graph, so it reaches
|
|
24
|
+
// the bundle through the includedFiles glob in the config below. Reads stay
|
|
25
|
+
// best-effort anyway: a miss falls through to an on-demand render, and Netlify
|
|
26
|
+
// serves SSG pages from the publish directory before the function is ever
|
|
27
|
+
// invoked (config.preferStatic).
|
|
26
28
|
const prerenderDir = path.join(import.meta.dirname, 'prerender');
|
|
27
29
|
// The function bundle directory is read-only at runtime; only the platform
|
|
28
30
|
// tmp directory accepts writes. ISR revalidations land there and are read
|
|
@@ -41,6 +43,9 @@ const handler = createHandler({
|
|
|
41
43
|
i18n: manifest.i18n,
|
|
42
44
|
importPage: loadRouteModule,
|
|
43
45
|
importApi: loadRouteModule,
|
|
46
|
+
importAction: loadActionModule,
|
|
47
|
+
pluginHttp: applyPluginHttp,
|
|
48
|
+
security: runtimePolicy.security,
|
|
44
49
|
readPrerendered: (pathname, revalidate = 60) => {
|
|
45
50
|
// prerenderRelativePath rejects any request path that cannot be mapped to a
|
|
46
51
|
// location inside the cache directories, so reads can never escape them.
|
|
@@ -73,12 +78,26 @@ export default async function(request, context) {
|
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
// Netlify Functions v2 config
|
|
76
|
-
export const config = {
|
|
77
|
-
path: '/*',
|
|
78
|
-
preferStatic: true,
|
|
79
|
-
};
|
|
81
|
+
export const config = ${JSON.stringify(functionConfig, null, 2)};
|
|
80
82
|
`;
|
|
81
83
|
}
|
|
84
|
+
/** Read the adapter package version so `generator` carries real semver. */
|
|
85
|
+
function packageVersion() {
|
|
86
|
+
const metadata = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
87
|
+
if (typeof metadata.version !== 'string' || !/^\d+\.\d+\.\d+/.test(metadata.version)) {
|
|
88
|
+
throw new Error('[RUV2001] netlifyAdapter: package version must be valid semver metadata');
|
|
89
|
+
}
|
|
90
|
+
return metadata.version;
|
|
91
|
+
}
|
|
92
|
+
function functionConfigFor(functionRoot) {
|
|
93
|
+
return {
|
|
94
|
+
path: '/*',
|
|
95
|
+
preferStatic: true,
|
|
96
|
+
name: 'Ruvyxa SSR',
|
|
97
|
+
generator: `ruvyxa/${packageVersion()}`,
|
|
98
|
+
includedFiles: [`${functionRoot}/prerender/**`],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
82
101
|
/**
|
|
83
102
|
* Create a Netlify deployment adapter for Ruvyxa.
|
|
84
103
|
*
|
|
@@ -172,7 +191,7 @@ export function netlify(options = {}) {
|
|
|
172
191
|
{
|
|
173
192
|
kind: 'function',
|
|
174
193
|
path: 'deploy/netlify/functions/ruvyxa-handler',
|
|
175
|
-
handlerSource: netlifyHandlerSource(runtimePolicy),
|
|
194
|
+
handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor('functions/ruvyxa-handler')),
|
|
176
195
|
},
|
|
177
196
|
// Netlify config for the deploy directory
|
|
178
197
|
{
|
|
@@ -190,7 +209,7 @@ export function netlify(options = {}) {
|
|
|
190
209
|
kind: 'function',
|
|
191
210
|
path: '.netlify/v1/functions/ruvyxa-handler',
|
|
192
211
|
scope: 'project',
|
|
193
|
-
handlerSource: netlifyHandlerSource(runtimePolicy),
|
|
212
|
+
handlerSource: netlifyHandlerSource(runtimePolicy, functionConfigFor('.netlify/v1/functions/ruvyxa-handler')),
|
|
194
213
|
},
|
|
195
214
|
{
|
|
196
215
|
kind: 'file',
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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.0
|
|
3
|
+
"version": "1.1.0",
|
|
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",
|
|
@@ -14,20 +14,37 @@
|
|
|
14
14
|
"keywords": [
|
|
15
15
|
"ruvyxa",
|
|
16
16
|
"adapter",
|
|
17
|
+
"deploy",
|
|
18
|
+
"deployment",
|
|
19
|
+
"hosting",
|
|
20
|
+
"build",
|
|
17
21
|
"netlify",
|
|
18
|
-
"
|
|
22
|
+
"netlify-functions",
|
|
23
|
+
"functions",
|
|
24
|
+
"serverless",
|
|
25
|
+
"serverless-functions",
|
|
26
|
+
"jamstack",
|
|
27
|
+
"cdn",
|
|
28
|
+
"prerender",
|
|
29
|
+
"ssr",
|
|
30
|
+
"ssg",
|
|
31
|
+
"isr",
|
|
32
|
+
"static-assets",
|
|
33
|
+
"typescript",
|
|
34
|
+
"fullstack",
|
|
35
|
+
"framework"
|
|
19
36
|
],
|
|
20
37
|
"repository": {
|
|
21
38
|
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/thirawat27/
|
|
39
|
+
"url": "git+https://github.com/thirawat27/Ruvyxa.git",
|
|
23
40
|
"directory": "packages/@ruvyxa/adapter-netlify"
|
|
24
41
|
},
|
|
25
42
|
"bugs": {
|
|
26
|
-
"url": "https://github.com/thirawat27/
|
|
43
|
+
"url": "https://github.com/thirawat27/Ruvyxa/issues"
|
|
27
44
|
},
|
|
28
|
-
"homepage": "https://github.com/thirawat27/
|
|
45
|
+
"homepage": "https://github.com/thirawat27/Ruvyxa#readme",
|
|
29
46
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
47
|
+
"node": ">=24.19.0"
|
|
31
48
|
},
|
|
32
49
|
"publishConfig": {
|
|
33
50
|
"access": "public"
|
|
@@ -39,7 +56,10 @@
|
|
|
39
56
|
}
|
|
40
57
|
},
|
|
41
58
|
"dependencies": {
|
|
42
|
-
"@ruvyxa/core": "^1.0
|
|
59
|
+
"@ruvyxa/core": "^1.1.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "24.13.3"
|
|
43
63
|
},
|
|
44
64
|
"scripts": {
|
|
45
65
|
"build": "tsc -p tsconfig.json",
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
|
|
1
3
|
import type { Adapter, AdapterArtifact, AdapterOutput, BuildContext } from '@ruvyxa/core'
|
|
2
4
|
import {
|
|
3
5
|
CLIENT_BUNDLE_PREFIX,
|
|
@@ -45,9 +47,12 @@ export interface NetlifyAdapterOptions {
|
|
|
45
47
|
* handler using the Web-standard Request/Response API. Reads the route
|
|
46
48
|
* manifest and handles SSR/API/ISR/PPR requests.
|
|
47
49
|
*/
|
|
48
|
-
function netlifyHandlerSource(
|
|
50
|
+
function netlifyHandlerSource(
|
|
51
|
+
runtimePolicy: unknown,
|
|
52
|
+
functionConfig: NetlifyFunctionConfig,
|
|
53
|
+
): string {
|
|
49
54
|
return `import { createHandler, prerenderRelativePath } from './serverless-handler.mjs';
|
|
50
|
-
import { loadRouteModule } from './route-modules.mjs';
|
|
55
|
+
import { applyPluginHttp, loadActionModule, loadRouteModule } from './route-modules.mjs';
|
|
51
56
|
// Netlify bundles the function with esbuild, so anything the deployed code
|
|
52
57
|
// needs must be reachable through the module graph. A sibling manifest.json
|
|
53
58
|
// read from import.meta.dirname is not, and never reaches /var/task.
|
|
@@ -58,10 +63,11 @@ import path from 'node:path';
|
|
|
58
63
|
|
|
59
64
|
const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
|
|
60
65
|
|
|
61
|
-
// Deploy-time prerender output is
|
|
62
|
-
//
|
|
63
|
-
// an on-demand render, and Netlify
|
|
64
|
-
// before the function is ever
|
|
66
|
+
// Deploy-time prerender output is not part of the module graph, so it reaches
|
|
67
|
+
// the bundle through the includedFiles glob in the config below. Reads stay
|
|
68
|
+
// best-effort anyway: a miss falls through to an on-demand render, and Netlify
|
|
69
|
+
// serves SSG pages from the publish directory before the function is ever
|
|
70
|
+
// invoked (config.preferStatic).
|
|
65
71
|
const prerenderDir = path.join(import.meta.dirname, 'prerender');
|
|
66
72
|
// The function bundle directory is read-only at runtime; only the platform
|
|
67
73
|
// tmp directory accepts writes. ISR revalidations land there and are read
|
|
@@ -80,6 +86,9 @@ const handler = createHandler({
|
|
|
80
86
|
i18n: manifest.i18n,
|
|
81
87
|
importPage: loadRouteModule,
|
|
82
88
|
importApi: loadRouteModule,
|
|
89
|
+
importAction: loadActionModule,
|
|
90
|
+
pluginHttp: applyPluginHttp,
|
|
91
|
+
security: runtimePolicy.security,
|
|
83
92
|
readPrerendered: (pathname, revalidate = 60) => {
|
|
84
93
|
// prerenderRelativePath rejects any request path that cannot be mapped to a
|
|
85
94
|
// location inside the cache directories, so reads can never escape them.
|
|
@@ -112,13 +121,54 @@ export default async function(request, context) {
|
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
// Netlify Functions v2 config
|
|
115
|
-
export const config = {
|
|
116
|
-
path: '/*',
|
|
117
|
-
preferStatic: true,
|
|
118
|
-
};
|
|
124
|
+
export const config = ${JSON.stringify(functionConfig, null, 2)};
|
|
119
125
|
`
|
|
120
126
|
}
|
|
121
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The Functions v2 config this adapter declares.
|
|
130
|
+
*
|
|
131
|
+
* `name` and `generator` are the Frameworks API's attribution fields: Netlify
|
|
132
|
+
* shows the name in the site UI and reads the generator to tell a
|
|
133
|
+
* framework-emitted function from a hand-written one.
|
|
134
|
+
*
|
|
135
|
+
* `includedFiles` is what carries the deploy-time prerender output into the
|
|
136
|
+
* bundle. Netlify bundles the function with esbuild, which copies only what the
|
|
137
|
+
* module graph reaches, so the HTML `readPrerendered` falls back to was being
|
|
138
|
+
* dropped. The globs resolve against the site's base directory, which is why
|
|
139
|
+
* each artifact declares its own path instead of sharing one.
|
|
140
|
+
*/
|
|
141
|
+
interface NetlifyFunctionConfig {
|
|
142
|
+
path: string
|
|
143
|
+
preferStatic: true
|
|
144
|
+
name: string
|
|
145
|
+
generator: string
|
|
146
|
+
includedFiles: string[]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Read the adapter package version so `generator` carries real semver. */
|
|
150
|
+
function packageVersion(): string {
|
|
151
|
+
const metadata = JSON.parse(
|
|
152
|
+
readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
|
|
153
|
+
) as {
|
|
154
|
+
version?: unknown
|
|
155
|
+
}
|
|
156
|
+
if (typeof metadata.version !== 'string' || !/^\d+\.\d+\.\d+/.test(metadata.version)) {
|
|
157
|
+
throw new Error('[RUV2001] netlifyAdapter: package version must be valid semver metadata')
|
|
158
|
+
}
|
|
159
|
+
return metadata.version
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function functionConfigFor(functionRoot: string): NetlifyFunctionConfig {
|
|
163
|
+
return {
|
|
164
|
+
path: '/*',
|
|
165
|
+
preferStatic: true,
|
|
166
|
+
name: 'Ruvyxa SSR',
|
|
167
|
+
generator: `ruvyxa/${packageVersion()}`,
|
|
168
|
+
includedFiles: [`${functionRoot}/prerender/**`],
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
122
172
|
/**
|
|
123
173
|
* Create a Netlify deployment adapter for Ruvyxa.
|
|
124
174
|
*
|
|
@@ -231,7 +281,10 @@ export function netlify(options: NetlifyAdapterOptions = {}): Adapter {
|
|
|
231
281
|
{
|
|
232
282
|
kind: 'function',
|
|
233
283
|
path: 'deploy/netlify/functions/ruvyxa-handler',
|
|
234
|
-
handlerSource: netlifyHandlerSource(
|
|
284
|
+
handlerSource: netlifyHandlerSource(
|
|
285
|
+
runtimePolicy,
|
|
286
|
+
functionConfigFor('functions/ruvyxa-handler'),
|
|
287
|
+
),
|
|
235
288
|
},
|
|
236
289
|
// Netlify config for the deploy directory
|
|
237
290
|
{
|
|
@@ -249,7 +302,10 @@ export function netlify(options: NetlifyAdapterOptions = {}): Adapter {
|
|
|
249
302
|
kind: 'function',
|
|
250
303
|
path: '.netlify/v1/functions/ruvyxa-handler',
|
|
251
304
|
scope: 'project',
|
|
252
|
-
handlerSource: netlifyHandlerSource(
|
|
305
|
+
handlerSource: netlifyHandlerSource(
|
|
306
|
+
runtimePolicy,
|
|
307
|
+
functionConfigFor('.netlify/v1/functions/ruvyxa-handler'),
|
|
308
|
+
),
|
|
253
309
|
} satisfies AdapterArtifact,
|
|
254
310
|
{
|
|
255
311
|
kind: 'file',
|