@astrale-os/adapter-cloudflare 0.5.0-beta.155 → 0.5.0-beta.157
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 +19 -0
- package/dist/build/frontend/files.js +61 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -40,6 +40,25 @@ exact installed Release evidence, and opens
|
|
|
40
40
|
the default View when the Application has a frontend. These are Project-tooling behaviors rather
|
|
41
41
|
than Cloudflare adapter responsibilities.
|
|
42
42
|
|
|
43
|
+
## Frontend files
|
|
44
|
+
|
|
45
|
+
The Worker runs before Workers Static Assets on every request and owns frontend response headers
|
|
46
|
+
and routing, for `cloudflare()` and `astrale()` deployments alike. Frontend preparation therefore
|
|
47
|
+
refuses a built frontend whose root contains `_headers`, `_redirects`, or `.assetsignore`, in any
|
|
48
|
+
letter case, as a file or a directory. Wrangler would apply them as asset configuration in a direct
|
|
49
|
+
deployment, while a managed deployment would serve them as public files. The refusal happens while
|
|
50
|
+
the artifact is prepared, before any provider change. Vite copies its public directory (`public/`
|
|
51
|
+
by default) to that root: remove them there, or stop the plugin that emits them. The same names
|
|
52
|
+
below the root, such as `docs/_headers`, remain ordinary files.
|
|
53
|
+
|
|
54
|
+
The Worker is also the only server-side code, so preparation likewise refuses a root name starting
|
|
55
|
+
with `_worker.js`, the name of a Cloudflare Pages worker script: a `_worker.js` file or directory,
|
|
56
|
+
or a sibling such as `_worker.js.map`. Wrangler refuses to upload these as assets, since they may
|
|
57
|
+
hold server-side code, so a direct deployment would fail at upload, while a managed deployment would
|
|
58
|
+
publish them. Unlike the names above, the match is case-sensitive, as Wrangler's is: `_Worker.js`
|
|
59
|
+
and a nested `docs/_worker.js` remain ordinary files. Remove such a file from the public directory,
|
|
60
|
+
or rename it if it is a browser script.
|
|
61
|
+
|
|
43
62
|
## Provider-local staging
|
|
44
63
|
|
|
45
64
|
Managed Cloudflare providers may stage immutable implementation candidates without exposing their
|
|
@@ -2,6 +2,28 @@ import { frontend as frontendBuild } from '@astrale-os/sdk/deployment/build';
|
|
|
2
2
|
import { readFile, readdir, rm } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { buildViteFrontend } from './vite.js';
|
|
5
|
+
/**
|
|
6
|
+
* Root names that Cloudflare Workers Static Assets reads as configuration rather than serving.
|
|
7
|
+
*
|
|
8
|
+
* Wrangler withholds them from a direct upload and applies them, while the managed upload through
|
|
9
|
+
* Services serves them as ordinary public files, so the same output would behave differently per
|
|
10
|
+
* adapter. The Worker runs first on every request and owns frontend response headers and routing for
|
|
11
|
+
* both, which leaves these files nothing to configure.
|
|
12
|
+
*/
|
|
13
|
+
const RESERVED_ROOT_NAMES = new Set([
|
|
14
|
+
'_headers',
|
|
15
|
+
'_redirects',
|
|
16
|
+
'.assetsignore',
|
|
17
|
+
]);
|
|
18
|
+
/**
|
|
19
|
+
* Name of a Cloudflare Pages worker script, the server-side code of a Pages project.
|
|
20
|
+
*
|
|
21
|
+
* Wrangler refuses to upload a root asset under this name, since that would publish the code, unless
|
|
22
|
+
* an `.assetsignore` exists, and the reserved names above already exclude one. A direct deployment
|
|
23
|
+
* would therefore fail at upload, while the managed upload through Services would publish the code.
|
|
24
|
+
* Neither adapter runs a Pages worker: the Worker is the only server-side code for both.
|
|
25
|
+
*/
|
|
26
|
+
const PAGES_WORKER_NAME = '_worker.js';
|
|
5
27
|
export async function frontendFiles(input) {
|
|
6
28
|
const frontend = input.frontend;
|
|
7
29
|
if (frontend === undefined)
|
|
@@ -18,11 +40,50 @@ export async function frontendFiles(input) {
|
|
|
18
40
|
signal: input.signal,
|
|
19
41
|
});
|
|
20
42
|
const files = frontendBuild.files(frontend, await readFiles(input.output));
|
|
43
|
+
refuseReservedNames(files);
|
|
44
|
+
refusePagesWorker(files);
|
|
21
45
|
// A name the bundler reported but that never reached disk is not a served path; keeping only the
|
|
22
46
|
// intersection means the evidence describes exactly what this deployment will answer with.
|
|
23
47
|
const served = new Set(files.map((file) => file.path));
|
|
24
48
|
return { files, addressed: built.addressed.filter((path) => served.has(path)) };
|
|
25
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Refuse output that Cloudflare would read as asset configuration instead of serving it.
|
|
52
|
+
*
|
|
53
|
+
* Only the root is reserved: a nested `docs/_headers` stays an ordinary file. The match ignores case
|
|
54
|
+
* and covers directories, because Wrangler's upload filter withholds any root entry under these names
|
|
55
|
+
* regardless of case, and a case-insensitive filesystem hands it `_Headers` when it reads `_headers`.
|
|
56
|
+
*/
|
|
57
|
+
function refuseReservedNames(files) {
|
|
58
|
+
const reserved = new Set(files
|
|
59
|
+
.map((file) => file.path.split('/')[0])
|
|
60
|
+
.filter((name) => RESERVED_ROOT_NAMES.has(name.toLowerCase())));
|
|
61
|
+
if (reserved.size === 0)
|
|
62
|
+
return;
|
|
63
|
+
const names = [...reserved].join(', ');
|
|
64
|
+
throw new TypeError(`Frontend output contains reserved Cloudflare asset configuration name(s) at its root: ${names}. ` +
|
|
65
|
+
'A direct cloudflare() deployment would apply them as Workers Static Assets configuration, while a managed astrale() deployment would serve them as public files. ' +
|
|
66
|
+
'The Worker owns frontend response headers and routing for both adapters: remove them from the Vite public directory, or stop the build from emitting them.');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Refuse output that Wrangler would decline to upload as a Cloudflare Pages worker script.
|
|
70
|
+
*
|
|
71
|
+
* Wrangler tests the relative path with a plain `startsWith`, not through its case-insensitive upload
|
|
72
|
+
* filter, so the match here is a case-sensitive prefix of the root name too. It covers a `_worker.js`
|
|
73
|
+
* file or directory and siblings such as `_worker.js.map`, which Wrangler refuses alike, while both
|
|
74
|
+
* adapters serve `_Worker.js` or a nested `docs/_worker.js` as an ordinary file.
|
|
75
|
+
*/
|
|
76
|
+
function refusePagesWorker(files) {
|
|
77
|
+
const workers = new Set(files
|
|
78
|
+
.map((file) => file.path.split('/')[0])
|
|
79
|
+
.filter((name) => name.startsWith(PAGES_WORKER_NAME)));
|
|
80
|
+
if (workers.size === 0)
|
|
81
|
+
return;
|
|
82
|
+
const names = [...workers].join(', ');
|
|
83
|
+
throw new TypeError(`Frontend output contains Cloudflare Pages worker name(s) at its root: ${names}. ` +
|
|
84
|
+
`A direct cloudflare() deployment would fail because Wrangler refuses to upload a root name starting with ${PAGES_WORKER_NAME} as possible server-side code, while a managed astrale() deployment would serve them as public files. ` +
|
|
85
|
+
'The Worker is the only server-side code for both adapters: remove or rename them in the Vite public directory, or stop the build from emitting them.');
|
|
86
|
+
}
|
|
26
87
|
async function readFiles(root, current = '') {
|
|
27
88
|
const entries = await readdir(join(root, current), { withFileTypes: true });
|
|
28
89
|
const files = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/adapter-cloudflare",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.157",
|
|
4
4
|
"description": "Deploy an Astrale application through Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adapter",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"registry": "https://registry.npmjs.org/"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@astrale-os/sdk": "0.6.0-beta.
|
|
56
|
+
"@astrale-os/sdk": "0.6.0-beta.2",
|
|
57
57
|
"@noble/hashes": "2.3.0",
|
|
58
58
|
"hono": "^4.6.20",
|
|
59
59
|
"jose": "^6.1.3",
|