@ruvyxa/adapter-cloudflare 1.0.25 → 1.0.26

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
@@ -41,3 +41,9 @@ This adapter supports SSR, API, SSG, and CSR routes via the Edge runtime (`--tar
41
41
  PPR are rejected because the assets binding is read-only and the adapter does not configure a
42
42
  persistent KV or Durable Object cache. Static assets are served through the assets binding; dynamic
43
43
  routes use compiled edge modules loaded from a static registry in the Worker bundle.
44
+
45
+ Validated built-in middleware is embedded into the Worker and runs with Fetch/Web APIs—CORS, rate
46
+ limiting, timing, logging, and custom response headers therefore match the native server without
47
+ Node.js polyfills. When `image.onDemand` is enabled, the Worker delegates same-origin image
48
+ transforms to Cloudflare's `fetch(..., { cf: { image } })`; the Cloudflare account must have image
49
+ transformations enabled.
@@ -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;AAQzF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAgDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CA+FjF;eAEc,iBAAiB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgD,MAAM,cAAc,CAAA;AASzF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAsED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAgGjF;eAEc,iBAAiB"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { clientBuildOutput, headersFileContents, projectRelativeOutDir, validateBuildContext, } from '@ruvyxa/core';
1
+ import { clientBuildOutput, headersFileContents, projectRelativeOutDir, runtimeBuildPolicy, validateBuildContext, } from '@ruvyxa/core';
2
2
  /**
3
3
  * Compatibility date this adapter's generated Worker is verified against.
4
4
  *
@@ -15,15 +15,37 @@ const DEFAULT_COMPATIBILITY_DATE = '2025-09-01';
15
15
  * Static assets (client bundles, pre-rendered pages for SSG/CSR) are served
16
16
  * by Cloudflare's `assets` binding; the Worker only handles dynamic routes.
17
17
  */
18
- function workerHandlerSource() {
18
+ function workerHandlerSource(runtimePolicy) {
19
19
  return `import { createHandler } from './serverless-handler.mjs';
20
20
  import { loadRouteModule } from './route-modules.mjs';
21
21
  // A JS module, not a JSON import: import attributes for JSON are not uniformly
22
22
  // available across bundlers and Worker compatibility dates.
23
23
  import manifest from './manifest.mjs';
24
24
 
25
+ const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
26
+
27
+ async function optimizeImage(request, { src, width, quality }) {
28
+ if (width > (runtimePolicy.image?.maxWidth ?? 3840)) {
29
+ return new Response('Image width exceeds configured maximum', { status: 400 });
30
+ }
31
+ const source = new URL(src, request.url);
32
+ const transformed = await fetch(source, {
33
+ cf: { image: { width, quality, fit: 'scale-down', format: 'auto' } },
34
+ });
35
+ const headers = new Headers(transformed.headers);
36
+ headers.set('cache-control', 'public, max-age=86400, stale-while-revalidate=604800');
37
+ return new Response(transformed.body, {
38
+ status: transformed.status,
39
+ statusText: transformed.statusText,
40
+ headers,
41
+ });
42
+ }
43
+
25
44
  const handler = createHandler({
26
45
  routes: manifest.routes,
46
+ middleware: runtimePolicy.middleware,
47
+ i18n: manifest.i18n,
48
+ optimizeImage: runtimePolicy.image?.onDemand === true ? optimizeImage : undefined,
27
49
  importPage: loadRouteModule,
28
50
  importApi: loadRouteModule,
29
51
  readPrerendered: (pathname) => {
@@ -78,6 +100,7 @@ export function cloudflareAdapter(options = {}) {
78
100
  // Config files are committed or read on other machines; never embed the
79
101
  // absolute build-machine outDir in them.
80
102
  const relativeOutDir = projectRelativeOutDir(ctx);
103
+ const runtimePolicy = runtimeBuildPolicy(ctx);
81
104
  const wranglerConfig = JSON.stringify({
82
105
  name: 'ruvyxa-app',
83
106
  main: './worker/index.mjs',
@@ -108,7 +131,7 @@ export function cloudflareAdapter(options = {}) {
108
131
  {
109
132
  kind: 'function',
110
133
  path: 'deploy/cloudflare/worker',
111
- handlerSource: workerHandlerSource(),
134
+ handlerSource: workerHandlerSource(runtimePolicy),
112
135
  },
113
136
  // Wrangler config pointing at the Worker + assets
114
137
  {
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-cloudflare",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Shape Ruvyxa builds for Cloudflare edge targets with typed worker and asset output metadata.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -39,7 +39,7 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@ruvyxa/core": "^1.0.25"
42
+ "@ruvyxa/core": "^1.0.26"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "tsc -p tsconfig.json",
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  clientBuildOutput,
4
4
  headersFileContents,
5
5
  projectRelativeOutDir,
6
+ runtimeBuildPolicy,
6
7
  validateBuildContext,
7
8
  } from '@ruvyxa/core'
8
9
 
@@ -52,15 +53,37 @@ const DEFAULT_COMPATIBILITY_DATE = '2025-09-01'
52
53
  * Static assets (client bundles, pre-rendered pages for SSG/CSR) are served
53
54
  * by Cloudflare's `assets` binding; the Worker only handles dynamic routes.
54
55
  */
55
- function workerHandlerSource(): string {
56
+ function workerHandlerSource(runtimePolicy: unknown): string {
56
57
  return `import { createHandler } from './serverless-handler.mjs';
57
58
  import { loadRouteModule } from './route-modules.mjs';
58
59
  // A JS module, not a JSON import: import attributes for JSON are not uniformly
59
60
  // available across bundlers and Worker compatibility dates.
60
61
  import manifest from './manifest.mjs';
61
62
 
63
+ const runtimePolicy = ${JSON.stringify(runtimePolicy ?? {})};
64
+
65
+ async function optimizeImage(request, { src, width, quality }) {
66
+ if (width > (runtimePolicy.image?.maxWidth ?? 3840)) {
67
+ return new Response('Image width exceeds configured maximum', { status: 400 });
68
+ }
69
+ const source = new URL(src, request.url);
70
+ const transformed = await fetch(source, {
71
+ cf: { image: { width, quality, fit: 'scale-down', format: 'auto' } },
72
+ });
73
+ const headers = new Headers(transformed.headers);
74
+ headers.set('cache-control', 'public, max-age=86400, stale-while-revalidate=604800');
75
+ return new Response(transformed.body, {
76
+ status: transformed.status,
77
+ statusText: transformed.statusText,
78
+ headers,
79
+ });
80
+ }
81
+
62
82
  const handler = createHandler({
63
83
  routes: manifest.routes,
84
+ middleware: runtimePolicy.middleware,
85
+ i18n: manifest.i18n,
86
+ optimizeImage: runtimePolicy.image?.onDemand === true ? optimizeImage : undefined,
64
87
  importPage: loadRouteModule,
65
88
  importApi: loadRouteModule,
66
89
  readPrerendered: (pathname) => {
@@ -121,6 +144,7 @@ export function cloudflareAdapter(options: CloudflareAdapterOptions = {}): Adapt
121
144
  // Config files are committed or read on other machines; never embed the
122
145
  // absolute build-machine outDir in them.
123
146
  const relativeOutDir = projectRelativeOutDir(ctx)
147
+ const runtimePolicy = runtimeBuildPolicy(ctx)
124
148
 
125
149
  const wranglerConfig = JSON.stringify(
126
150
  {
@@ -162,7 +186,7 @@ export function cloudflareAdapter(options: CloudflareAdapterOptions = {}): Adapt
162
186
  {
163
187
  kind: 'function',
164
188
  path: 'deploy/cloudflare/worker',
165
- handlerSource: workerHandlerSource(),
189
+ handlerSource: workerHandlerSource(runtimePolicy),
166
190
  },
167
191
  // Wrangler config pointing at the Worker + assets
168
192
  {