@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 CHANGED
@@ -1,6 +1,22 @@
1
- # @ruvyxa/adapter-netlify
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
- Netlify deployment adapter for Ruvyxa production builds.
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
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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;AAmFD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAyIpE;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;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 likewise dropped by the bundler unless the
23
- // site declares included_files. Reads are best-effort: a miss falls through to
24
- // an on-demand render, and Netlify serves SSG pages from the publish directory
25
- // before the function is ever invoked (config.preferStatic).
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":"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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.0.30",
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
- "serverless"
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/ruvyxa.git",
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/ruvyxa/issues"
43
+ "url": "https://github.com/thirawat27/Ruvyxa/issues"
27
44
  },
28
- "homepage": "https://github.com/thirawat27/ruvyxa#readme",
45
+ "homepage": "https://github.com/thirawat27/Ruvyxa#readme",
29
46
  "engines": {
30
- "node": ">=22.13.0"
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.30"
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(runtimePolicy: unknown): string {
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 likewise dropped by the bundler unless the
62
- // site declares included_files. Reads are best-effort: a miss falls through to
63
- // an on-demand render, and Netlify serves SSG pages from the publish directory
64
- // before the function is ever invoked (config.preferStatic).
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(runtimePolicy),
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(runtimePolicy),
305
+ handlerSource: netlifyHandlerSource(
306
+ runtimePolicy,
307
+ functionConfigFor('.netlify/v1/functions/ruvyxa-handler'),
308
+ ),
253
309
  } satisfies AdapterArtifact,
254
310
  {
255
311
  kind: 'file',