@bascik/adapter-cloudflare 1.0.0-rc.1 → 1.0.0-rc.11
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/LICENSE +18 -92
- package/README.md +75 -4
- package/dist/build.d.ts +8 -0
- package/dist/build.js +416 -102
- package/dist/build.js.map +1 -1
- package/dist/compat.d.ts +32 -1
- package/dist/compat.js +63 -6
- package/dist/compat.js.map +1 -1
- package/dist/component-host.d.ts +16 -0
- package/dist/component-host.js +113 -0
- package/dist/component-host.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.js +301 -16
- package/dist/config.js.map +1 -1
- package/dist/headers-file.d.ts +83 -0
- package/dist/headers-file.js +298 -0
- package/dist/headers-file.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +32 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +84 -10
- package/dist/runtime.js +288 -53
- package/dist/runtime.js.map +1 -1
- package/package.json +17 -11
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generated public/_headers on Cloudflare.
|
|
3
|
+
*
|
|
4
|
+
* Static files are served by the asset layer without the Worker, so the
|
|
5
|
+
* headers the Worker sends on what it answers have to be written here for
|
|
6
|
+
* them: the security headers (`security.headers`, `security.hsts`) as one
|
|
7
|
+
* site-wide `/*` rule, and the opt-in `contentSecurityPolicy` as one
|
|
8
|
+
* exact-path rule per static page (from the same pkg function the Node
|
|
9
|
+
* servers and the Worker use, with the build's hashes). Responses the Worker
|
|
10
|
+
* makes itself never get `_headers` rules, and an asset it forwards gets them
|
|
11
|
+
* once, from the asset layer, so no header is sent twice.
|
|
12
|
+
*
|
|
13
|
+
* How Cloudflare reads the file (workers-shared, which miniflare runs): rules
|
|
14
|
+
* are a record keyed by path, so a second rule with a path the author used
|
|
15
|
+
* replaces the author's, at the place of the first; the rules that match a
|
|
16
|
+
* URL apply in file order; a header two of them set is joined with a comma;
|
|
17
|
+
* `! Name` in a rule removes what earlier rules set, before that rule's own
|
|
18
|
+
* values; a line over 2000 characters is skipped; and it stops reading at the
|
|
19
|
+
* 101st path line.
|
|
20
|
+
*
|
|
21
|
+
* So, whenever Bascik writes anything into the file:
|
|
22
|
+
* 1. the site-wide rule comes first (Bascik's, or the author's own `/*`
|
|
23
|
+
* moved to the top with Bascik's headers it does not set added);
|
|
24
|
+
* 2. the static pages' CSP rules come next, never as a second rule for a
|
|
25
|
+
* path the author has (the line goes into the author's rule), and not at
|
|
26
|
+
* all for a page an author rule already sets or removes the CSP header
|
|
27
|
+
* on: the author's value wins there;
|
|
28
|
+
* 3. the author's other rules follow, and each one that sets a security
|
|
29
|
+
* header (any Bascik can write, whatever the toggles say) or a header
|
|
30
|
+
* the author's `/*` sets gets a `! Name` line first: a later, more
|
|
31
|
+
* specific rule replaces the value instead of being joined to it, the
|
|
32
|
+
* same way under every security setting.
|
|
33
|
+
* When Bascik writes nothing (headers, HSTS and CSP all off), the author's
|
|
34
|
+
* file ships as written.
|
|
35
|
+
*/
|
|
36
|
+
import { contentSecurityPolicyHeader, DEFAULT_RESPONSE_SECURITY, SECURITY_HEADERS, } from "@bascik/bascik/runtime";
|
|
37
|
+
/** Cloudflare reads at most this many rules (path lines) from _headers. */
|
|
38
|
+
export const CLOUDFLARE_HEADERS_RULE_LIMIT = 100;
|
|
39
|
+
/** Cloudflare skips any _headers line longer than this, with no error. */
|
|
40
|
+
export const CLOUDFLARE_HEADERS_LINE_LIMIT = 2000;
|
|
41
|
+
const SITE_WIDE_PATH = "/*";
|
|
42
|
+
/** How Cloudflare tells a path line from a header line (its own pattern). */
|
|
43
|
+
const PATH_LINE = /^([^\s]+:\/\/|\/)/;
|
|
44
|
+
const UNSET_PREFIX = "! ";
|
|
45
|
+
const CSP_NAMES = [
|
|
46
|
+
"content-security-policy",
|
|
47
|
+
"content-security-policy-report-only",
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Every header Bascik can write here, whatever `security` turns on or off:
|
|
51
|
+
* an author's rule that sets one replaces the earlier value under every
|
|
52
|
+
* setting, so a toggle never changes how the author's own rules combine.
|
|
53
|
+
*/
|
|
54
|
+
const MANAGED_HEADERS = new Set([
|
|
55
|
+
...Object.keys(SECURITY_HEADERS),
|
|
56
|
+
"strict-transport-security",
|
|
57
|
+
...CSP_NAMES,
|
|
58
|
+
]);
|
|
59
|
+
/** `x-frame-options` -> `X-Frame-Options`. Cloudflare matches names in any case. */
|
|
60
|
+
const headerName = (lower) => lower.replace(/(^|-)([a-z])/g, (_, dash, c) => `${dash}${c.toUpperCase()}`);
|
|
61
|
+
/** The rules of a _headers text, as Cloudflare reads them (indentation is not significant). */
|
|
62
|
+
const parseRules = (lines) => {
|
|
63
|
+
const rules = [];
|
|
64
|
+
let rule;
|
|
65
|
+
lines.forEach((raw, index) => {
|
|
66
|
+
const line = raw.trim();
|
|
67
|
+
if (line === "" || line.startsWith("#"))
|
|
68
|
+
return;
|
|
69
|
+
if (PATH_LINE.test(line)) {
|
|
70
|
+
if (rule)
|
|
71
|
+
rule.end = index;
|
|
72
|
+
rule = {
|
|
73
|
+
path: line,
|
|
74
|
+
line: index,
|
|
75
|
+
end: lines.length,
|
|
76
|
+
sets: new Set(),
|
|
77
|
+
unsets: new Set(),
|
|
78
|
+
};
|
|
79
|
+
rules.push(rule);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!rule)
|
|
83
|
+
return;
|
|
84
|
+
if (line.startsWith(UNSET_PREFIX))
|
|
85
|
+
rule.unsets.add(line.slice(UNSET_PREFIX.length).trim().toLowerCase());
|
|
86
|
+
else if (line.includes(":"))
|
|
87
|
+
rule.sets.add(line.slice(0, line.indexOf(":")).trim().toLowerCase());
|
|
88
|
+
});
|
|
89
|
+
return rules;
|
|
90
|
+
};
|
|
91
|
+
const linesOf = (text) => text === "" ? [] : text.replace(/\s*$/, "").split(/\r?\n/);
|
|
92
|
+
/**
|
|
93
|
+
* How many rules Cloudflare reads from a _headers text: one per path line
|
|
94
|
+
* that has a header or a `! Name` under it. A path written twice counts
|
|
95
|
+
* twice, because Cloudflare stops at a count of path lines, not of paths.
|
|
96
|
+
*/
|
|
97
|
+
export const countHeadersRules = (text) => parseRules(linesOf(text)).filter((rule) => rule.sets.size + rule.unsets.size)
|
|
98
|
+
.length;
|
|
99
|
+
/** Cloudflare's own pattern match (workers-shared generateRuleRegExp), for path rules. */
|
|
100
|
+
const ruleMatches = (rulePath, path) => {
|
|
101
|
+
if (!rulePath.startsWith("/"))
|
|
102
|
+
return false;
|
|
103
|
+
const source = rulePath
|
|
104
|
+
.split("*")
|
|
105
|
+
.map((part) => part.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"))
|
|
106
|
+
.join(".*")
|
|
107
|
+
.replace(/:[A-Za-z]\w*/g, "[^/]+");
|
|
108
|
+
try {
|
|
109
|
+
return new RegExp(`^${source}$`).test(path);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/** What to do when the static headers do not fit in _headers, for this variant. */
|
|
116
|
+
const remedy = (variant) => variant === "workers"
|
|
117
|
+
? `Let the Worker send the headers on every response instead: in your wrangler.jsonc (or wrangler.json or wrangler.toml) set ` +
|
|
118
|
+
`"assets": { "run_worker_first": true }, and Bascik writes no _headers rules for them.`
|
|
119
|
+
: `Cloudflare Pages cannot run the Worker before static files, so build with --target cloudflare-workers and set ` +
|
|
120
|
+
`"assets": { "run_worker_first": true } in your wrangler.jsonc; the Worker then sends the headers on every response.`;
|
|
121
|
+
/**
|
|
122
|
+
* The whole public/_headers text: the site-wide security rule, the static
|
|
123
|
+
* pages' CSP rules, and the author's rules. The author's text unchanged when
|
|
124
|
+
* Bascik has nothing to write; "" when there is no file at all.
|
|
125
|
+
*/
|
|
126
|
+
export const buildHeadersFile = ({ authored, security = DEFAULT_RESPONSE_SECURITY, base, csp, variant = "workers", }) => {
|
|
127
|
+
const lines = linesOf(authored);
|
|
128
|
+
const rules = parseRules(lines);
|
|
129
|
+
// Cloudflare keeps the last rule written for a path, at the place of the first.
|
|
130
|
+
const effective = new Map();
|
|
131
|
+
for (const rule of rules)
|
|
132
|
+
effective.set(rule.path, rule);
|
|
133
|
+
const authorSiteWide = effective.get(SITE_WIDE_PATH);
|
|
134
|
+
// name (lowercase) -> value, in the order Node sends them.
|
|
135
|
+
const siteWide = new Map(Object.entries(security.headers));
|
|
136
|
+
if (security.hsts !== null)
|
|
137
|
+
siteWide.set("strict-transport-security", security.hsts);
|
|
138
|
+
/** Lines to add right after a rule's path line, by that line's index. */
|
|
139
|
+
const additions = new Map();
|
|
140
|
+
const add = (rule, line) => {
|
|
141
|
+
const list = additions.get(rule.line) ?? [];
|
|
142
|
+
list.push(line);
|
|
143
|
+
additions.set(rule.line, list);
|
|
144
|
+
};
|
|
145
|
+
// The static pages' CSP.
|
|
146
|
+
const prefix = base === "/" ? "" : base.replace(/\/$/, "");
|
|
147
|
+
const cspRules = [];
|
|
148
|
+
const cspInAuthorRules = [];
|
|
149
|
+
const cspRoutes = new Map();
|
|
150
|
+
if (csp) {
|
|
151
|
+
for (const route of csp.staticRoutes) {
|
|
152
|
+
const { name, value } = contentSecurityPolicyHeader(csp.policy, csp.hashes[route]);
|
|
153
|
+
const path = `${prefix}${route}`;
|
|
154
|
+
const line = ` ${headerName(name)}: ${value}`;
|
|
155
|
+
// An author's rule that sets or removes this header on the page wins.
|
|
156
|
+
const authorDecides = [...effective.values()].some((rule) => (rule.sets.has(name) || rule.unsets.has(name)) &&
|
|
157
|
+
ruleMatches(rule.path, path));
|
|
158
|
+
if (authorDecides)
|
|
159
|
+
continue;
|
|
160
|
+
if (line.trim().length > CLOUDFLARE_HEADERS_LINE_LIMIT)
|
|
161
|
+
throw new Error(`[bascik] --target cloudflare: the ${headerName(name)} line for the static page ${path} is ` +
|
|
162
|
+
`${line.trim().length} characters (one hash for each of its inline scripts and styles), but Cloudflare ` +
|
|
163
|
+
`skips any _headers line over ${CLOUDFLARE_HEADERS_LINE_LIMIT} characters, so the page would ship with no ` +
|
|
164
|
+
`policy and no error. ${remedy(variant)} Or move some of the page's inline scripts and styles into files.`);
|
|
165
|
+
cspRoutes.set(path, route);
|
|
166
|
+
const own = effective.get(path);
|
|
167
|
+
// Never a second rule for the author's path: it would replace theirs.
|
|
168
|
+
if (own)
|
|
169
|
+
cspInAuthorRules.push([own, line]);
|
|
170
|
+
else
|
|
171
|
+
cspRules.push(path, line);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (siteWide.size === 0 && cspRoutes.size === 0)
|
|
175
|
+
return authored;
|
|
176
|
+
// A later rule replaces a security header (or one the author's `/*` sets)
|
|
177
|
+
// instead of joining it.
|
|
178
|
+
const replaced = new Set([
|
|
179
|
+
...MANAGED_HEADERS,
|
|
180
|
+
...siteWide.keys(),
|
|
181
|
+
...(authorSiteWide?.sets ?? []),
|
|
182
|
+
]);
|
|
183
|
+
for (const rule of effective.values()) {
|
|
184
|
+
if (rule === authorSiteWide) {
|
|
185
|
+
// The author's own `/*`: their values and removals stand.
|
|
186
|
+
for (const [name, value] of siteWide)
|
|
187
|
+
if (!rule.sets.has(name) && !rule.unsets.has(name))
|
|
188
|
+
add(rule, ` ${headerName(name)}: ${value}`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
for (const name of rule.sets)
|
|
192
|
+
if (replaced.has(name) && !rule.unsets.has(name))
|
|
193
|
+
add(rule, ` ${UNSET_PREFIX}${headerName(name)}`);
|
|
194
|
+
}
|
|
195
|
+
for (const [rule, line] of cspInAuthorRules)
|
|
196
|
+
add(rule, line);
|
|
197
|
+
const skip = new Set();
|
|
198
|
+
const rendered = (from, to) => {
|
|
199
|
+
const out = [];
|
|
200
|
+
for (let i = from; i < to; i++) {
|
|
201
|
+
if (skip.has(i))
|
|
202
|
+
continue;
|
|
203
|
+
out.push(lines[i]);
|
|
204
|
+
const extra = additions.get(i);
|
|
205
|
+
if (extra)
|
|
206
|
+
out.push(...extra);
|
|
207
|
+
}
|
|
208
|
+
while (out.length && out[out.length - 1].trim() === "")
|
|
209
|
+
out.pop();
|
|
210
|
+
return out;
|
|
211
|
+
};
|
|
212
|
+
const blocks = [];
|
|
213
|
+
if (authorSiteWide) {
|
|
214
|
+
// First: the author's `/*` (with the comments above it when it is their
|
|
215
|
+
// first rule). An earlier `/*` rule Cloudflare already ignores (the last
|
|
216
|
+
// one written wins) is left out, or it would take the moved rule's place.
|
|
217
|
+
const from = authorSiteWide === rules[0] ? 0 : authorSiteWide.line;
|
|
218
|
+
blocks.push(rendered(from, authorSiteWide.end));
|
|
219
|
+
for (let i = from; i < authorSiteWide.end; i++)
|
|
220
|
+
skip.add(i);
|
|
221
|
+
for (const rule of rules)
|
|
222
|
+
if (rule.path === SITE_WIDE_PATH)
|
|
223
|
+
for (let i = rule.line; i < rule.end; i++)
|
|
224
|
+
skip.add(i);
|
|
225
|
+
}
|
|
226
|
+
else if (siteWide.size > 0) {
|
|
227
|
+
blocks.push([
|
|
228
|
+
SITE_WIDE_PATH,
|
|
229
|
+
...[...siteWide].map(([name, value]) => ` ${headerName(name)}: ${value}`),
|
|
230
|
+
]);
|
|
231
|
+
}
|
|
232
|
+
if (cspRules.length)
|
|
233
|
+
blocks.push(cspRules);
|
|
234
|
+
const rest = rendered(0, lines.length);
|
|
235
|
+
if (rest.length)
|
|
236
|
+
blocks.push(rest);
|
|
237
|
+
const text = `${blocks.map((b) => b.join("\n")).join("\n\n")}\n`;
|
|
238
|
+
const tooLong = text
|
|
239
|
+
.split("\n")
|
|
240
|
+
.findIndex((line) => line.trim().length > CLOUDFLARE_HEADERS_LINE_LIMIT);
|
|
241
|
+
if (tooLong !== -1) {
|
|
242
|
+
const line = text.split("\n")[tooLong].trim();
|
|
243
|
+
throw new Error(`[bascik] --target cloudflare: a line in your _headers is ${line.length} characters ` +
|
|
244
|
+
`(${line.slice(0, 60)}...), but Cloudflare skips any _headers line over ${CLOUDFLARE_HEADERS_LINE_LIMIT} ` +
|
|
245
|
+
`characters with no error. Shorten it.`);
|
|
246
|
+
}
|
|
247
|
+
const total = countHeadersRules(text);
|
|
248
|
+
if (total > CLOUDFLARE_HEADERS_RULE_LIMIT) {
|
|
249
|
+
const newSiteWide = !authorSiteWide && siteWide.size > 0 ? 1 : 0;
|
|
250
|
+
const cspPages = cspRules.length / 2;
|
|
251
|
+
const authoredRules = total - newSiteWide - cspPages;
|
|
252
|
+
const parts = [
|
|
253
|
+
...(cspPages
|
|
254
|
+
? [`${cspPages} for contentSecurityPolicy, one for each static page`]
|
|
255
|
+
: []),
|
|
256
|
+
...(newSiteWide
|
|
257
|
+
? ["1 site-wide rule for security.headers and security.hsts"]
|
|
258
|
+
: []),
|
|
259
|
+
...(authoredRules ? [`${authoredRules} already in your _headers`] : []),
|
|
260
|
+
];
|
|
261
|
+
throw new Error(`[bascik] --target cloudflare: public/_headers needs ${total} rules (${parts.join(", ")}), but Cloudflare ` +
|
|
262
|
+
`reads at most ${CLOUDFLARE_HEADERS_RULE_LIMIT} and drops the rest with no error. ${remedy(variant)} ` +
|
|
263
|
+
`Or remove rules from your _headers (a path written twice counts twice).`);
|
|
264
|
+
}
|
|
265
|
+
return text;
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* The author's _headers rules that set or remove a security header on a page
|
|
269
|
+
* the Worker renders. `_headers` reaches static files only, so on those pages
|
|
270
|
+
* the Worker keeps `security.headers`' value: one warning per rule, naming a
|
|
271
|
+
* page, so the author can move the value into the config.
|
|
272
|
+
*/
|
|
273
|
+
export const workerPageHeaderOverrides = ({ authored, security = DEFAULT_RESPONSE_SECURITY, base, workerPages, }) => {
|
|
274
|
+
const prefix = base === "/" ? "" : base.replace(/\/$/, "");
|
|
275
|
+
const watched = new Set([
|
|
276
|
+
...MANAGED_HEADERS,
|
|
277
|
+
...Object.keys(security.headers),
|
|
278
|
+
]);
|
|
279
|
+
const warnings = [];
|
|
280
|
+
const effective = new Map();
|
|
281
|
+
for (const rule of parseRules(linesOf(authored)))
|
|
282
|
+
effective.set(rule.path, rule);
|
|
283
|
+
for (const rule of effective.values()) {
|
|
284
|
+
const names = [...rule.sets, ...rule.unsets].filter((n) => watched.has(n));
|
|
285
|
+
if (!names.length)
|
|
286
|
+
continue;
|
|
287
|
+
const page = workerPages
|
|
288
|
+
.map((p) => `${prefix}${p}`)
|
|
289
|
+
.find((p) => ruleMatches(rule.path, p));
|
|
290
|
+
if (!page)
|
|
291
|
+
continue;
|
|
292
|
+
warnings.push(`[bascik] --target cloudflare: your _headers rule ${rule.path} sets ${[...new Set(names)].map(headerName).join(", ")}, ` +
|
|
293
|
+
`but ${page} is rendered by the Worker and _headers rules reach static files only, so that page keeps ` +
|
|
294
|
+
`Bascik's value. To change the header on every page, set it in security.headers.`);
|
|
295
|
+
}
|
|
296
|
+
return warnings;
|
|
297
|
+
};
|
|
298
|
+
//# sourceMappingURL=headers-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers-file.js","sourceRoot":"","sources":["../src/headers-file.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Default export of @bascik/adapter-cloudflare.
|
|
5
5
|
*/
|
|
6
|
-
export { CLOUDFLARE_COMPATIBILITY_DATE, CLOUDFLARE_COMPATIBILITY_FLAGS } from "./compat.js";
|
|
6
|
+
export { CLOUDFLARE_COMPATIBILITY_DATE, CLOUDFLARE_COMPATIBILITY_FLAGS, } from "./compat.js";
|
|
7
7
|
export { buildInvocationRoutes } from "./build.js";
|
|
8
8
|
declare const _default: import("@bascik/bascik/adapter").HostingAdapter;
|
|
9
9
|
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,42 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Default export of @bascik/adapter-cloudflare.
|
|
5
5
|
*/
|
|
6
|
-
import { defineAdapter } from "@bascik/bascik/adapter";
|
|
6
|
+
import { defineAdapter, resolvePlatformCli, availableDevPort, } from "@bascik/bascik/adapter";
|
|
7
7
|
import { build } from "./build.js";
|
|
8
|
-
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
export { CLOUDFLARE_COMPATIBILITY_DATE, CLOUDFLARE_COMPATIBILITY_FLAGS, } from "./compat.js";
|
|
9
10
|
export { buildInvocationRoutes } from "./build.js";
|
|
10
11
|
export default defineAdapter({
|
|
11
12
|
name: "cloudflare",
|
|
12
13
|
build,
|
|
14
|
+
async dev({ projectRoot, outDir, variant, port }) {
|
|
15
|
+
const cli = await resolvePlatformCli(projectRoot, "wrangler", "wrangler");
|
|
16
|
+
const inspectorPort = await availableDevPort();
|
|
17
|
+
return {
|
|
18
|
+
command: process.execPath,
|
|
19
|
+
args: [
|
|
20
|
+
cli,
|
|
21
|
+
...(variant === "pages"
|
|
22
|
+
? [
|
|
23
|
+
"pages",
|
|
24
|
+
"dev",
|
|
25
|
+
join(outDir, "public"),
|
|
26
|
+
"--compatibility-flag",
|
|
27
|
+
"nodejs_compat",
|
|
28
|
+
]
|
|
29
|
+
: ["dev", "--config", join(outDir, "wrangler.jsonc")]),
|
|
30
|
+
"--ip",
|
|
31
|
+
"127.0.0.1",
|
|
32
|
+
"--port",
|
|
33
|
+
String(port),
|
|
34
|
+
"--inspector-port",
|
|
35
|
+
String(inspectorPort),
|
|
36
|
+
"--persist-to",
|
|
37
|
+
join(projectRoot, ".wrangler", "state"),
|
|
38
|
+
],
|
|
39
|
+
cwd: projectRoot,
|
|
40
|
+
env: { WRANGLER_SEND_METRICS: "false" },
|
|
41
|
+
};
|
|
42
|
+
},
|
|
13
43
|
});
|
|
14
44
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,eAAe,aAAa,CAAC;IAC3B,IAAI,EAAE,YAAY;IAClB,KAAK;IACL,KAAK,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9C,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QAC1E,MAAM,aAAa,GAAG,MAAM,gBAAgB,EAAE,CAAC;QAC/C,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,QAAQ;YACzB,IAAI,EAAE;gBACJ,GAAG;gBACH,GAAG,CAAC,OAAO,KAAK,OAAO;oBACrB,CAAC,CAAC;wBACE,OAAO;wBACP,KAAK;wBACL,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;wBACtB,sBAAsB;wBACtB,eAAe;qBAChB;oBACH,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBACxD,MAAM;gBACN,WAAW;gBACX,QAAQ;gBACR,MAAM,CAAC,IAAI,CAAC;gBACZ,kBAAkB;gBAClB,MAAM,CAAC,aAAa,CAAC;gBACrB,cAAc;gBACd,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC;aACxC;YACD,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,EAAE,qBAAqB,EAAE,OAAO,EAAE;SACxC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* The request handler that runs inside a Cloudflare Worker (prompt 134).
|
|
5
5
|
* ─────────────────────────────────────────────────────────────────────────────
|
|
6
6
|
*
|
|
7
|
-
* Portable: no Node imports
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Portable: no Node imports (the request-time component host,
|
|
8
|
+
* component-host.ts, uses `node:crypto` under `nodejs_compat` and is bundled
|
|
9
|
+
* only for sites with components, prompt 157). It is bundled into the
|
|
10
|
+
* generated `_worker.js` together with the site graph emitted by
|
|
11
|
+
* `serverless-artifacts.ts`, and it drives the same execution core the Node
|
|
12
|
+
* server uses (`lib/request-execution.ts`).
|
|
11
13
|
*
|
|
12
14
|
* Request flow inside the Worker:
|
|
13
15
|
*
|
|
@@ -28,16 +30,41 @@
|
|
|
28
30
|
* (`{ name: "cloudflare", env, waitUntil }`). Nothing is copied onto globals
|
|
29
31
|
* and `process.env` is never touched.
|
|
30
32
|
*/
|
|
31
|
-
import { type ApiHandlerModule, type PlatformContext, type ScriptJobRunner, type ApiRouteDefinition } from "@bascik/bascik/runtime";
|
|
33
|
+
import { type ApiHandlerModule, type ExecutionPlan, type PlatformContext, type RenderHost, type ScriptJobRunner, type ApiRouteDefinition, type ContentSecurityPolicyConfig, type CspRouteHashes, type RequestRenderLimits, type ResponseSecurity } from "@bascik/bascik/runtime";
|
|
32
34
|
/** A request-time script job inside a dynamic page template. */
|
|
33
35
|
export interface GraphScriptJob {
|
|
34
36
|
id: string;
|
|
35
37
|
mode: "server" | "stream";
|
|
38
|
+
/**
|
|
39
|
+
* The component's element classes for this job's output (prompt 157):
|
|
40
|
+
* set on component scripts, and on a page job a component placed
|
|
41
|
+
* statically, so their returned markup is styled like the component's own.
|
|
42
|
+
*/
|
|
43
|
+
outputScope?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Where a component script is authored (`server script in
|
|
46
|
+
* src/components/x.html:12`), set on component jobs (prompt 157): the
|
|
47
|
+
* bundled stack names only the Worker file, so a failure is located from
|
|
48
|
+
* this instead.
|
|
49
|
+
*/
|
|
50
|
+
owner?: string;
|
|
36
51
|
/** Loader for the compiled module; `default` is the handler. */
|
|
37
52
|
load: () => Promise<{
|
|
38
53
|
default: unknown;
|
|
39
54
|
}>;
|
|
40
55
|
}
|
|
56
|
+
/** The build's component manifest, as the portable renderer reads it. */
|
|
57
|
+
export type ComponentManifest = NonNullable<RenderHost["manifest"]>;
|
|
58
|
+
/**
|
|
59
|
+
* Request-time components (prompt 157): the manifest, emitted by build.ts
|
|
60
|
+
* only when it lists a component, and the component scripts it names, keyed
|
|
61
|
+
* by job id. They belong to no page: any page's script may return any
|
|
62
|
+
* component.
|
|
63
|
+
*/
|
|
64
|
+
export interface GraphComponents {
|
|
65
|
+
manifest: ComponentManifest;
|
|
66
|
+
jobs: Record<string, GraphScriptJob>;
|
|
67
|
+
}
|
|
41
68
|
export interface GraphPageSegment {
|
|
42
69
|
kind: "static" | "script";
|
|
43
70
|
/** UTF-8 text for static segments. */
|
|
@@ -67,12 +94,46 @@ export interface SiteGraph {
|
|
|
67
94
|
onServerScriptError: "error" | "warn" | "ignore";
|
|
68
95
|
/** Dynamic pages by canonical path. */
|
|
69
96
|
pages: Record<string, GraphPage>;
|
|
70
|
-
/** Sorted API routes (static
|
|
97
|
+
/** Sorted API routes (static, then `[param]`, then catch-all). */
|
|
71
98
|
apiRoutes: GraphApiRoute[];
|
|
72
99
|
/** Optional authored 500 page body. */
|
|
73
100
|
custom500?: string;
|
|
101
|
+
/** A static `404.html` is deployed; its own URLs answer 404, as on Node. */
|
|
102
|
+
staticNotFoundPage?: boolean;
|
|
74
103
|
/** Release identity for diagnostics headers. */
|
|
75
104
|
release: string;
|
|
105
|
+
/** Present when the site renders component tags in script output. */
|
|
106
|
+
components?: GraphComponents;
|
|
107
|
+
/**
|
|
108
|
+
* Opt-in `contentSecurityPolicy`: the policy and the build hashes of each
|
|
109
|
+
* page the Worker renders (static pages carry theirs in _headers).
|
|
110
|
+
*/
|
|
111
|
+
contentSecurityPolicy?: {
|
|
112
|
+
policy: ContentSecurityPolicyConfig;
|
|
113
|
+
hashes: Record<string, CspRouteHashes>;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* The build's `security.headers`, `security.hsts` and
|
|
117
|
+
* `security.privateDynamicPages`, resolved. Absent: the defaults.
|
|
118
|
+
*/
|
|
119
|
+
responseSecurity?: ResponseSecurity;
|
|
120
|
+
/**
|
|
121
|
+
* Set when the Worker runs before every static file (`run_worker_first:
|
|
122
|
+
* true` in the authored wrangler config): the build writes no `_headers`
|
|
123
|
+
* rules, and the Worker adds the security headers, and each listed static
|
|
124
|
+
* page's CSP, to what the asset layer returns. A header the response
|
|
125
|
+
* already has (from the author's own `_headers`) is kept.
|
|
126
|
+
*/
|
|
127
|
+
assetHeaders?: {
|
|
128
|
+
/** Static pages (paths without the base) whose CSP the Worker sends. */
|
|
129
|
+
cspRoutes: string[];
|
|
130
|
+
};
|
|
131
|
+
/** The build's `security.hideDotfiles`. Absent: true. */
|
|
132
|
+
hideDotfiles?: boolean;
|
|
133
|
+
/** The build's `scripts.stripAnsi`. Absent: true. */
|
|
134
|
+
stripAnsi?: boolean;
|
|
135
|
+
/** The build's `scripts.renderLimits`. Absent: the defaults. */
|
|
136
|
+
renderLimits?: Partial<RequestRenderLimits>;
|
|
76
137
|
}
|
|
77
138
|
export interface CloudflareAssetsBinding {
|
|
78
139
|
fetch(request: Request): Promise<Response>;
|
|
@@ -93,15 +154,28 @@ export declare const stripBase: (pathname: string, base: string) => string | nul
|
|
|
93
154
|
/** Derive the client IP from Cloudflare's trusted header; never from X-Forwarded-For. */
|
|
94
155
|
export declare const cloudflareRemoteIp: (request: Request) => string;
|
|
95
156
|
/**
|
|
96
|
-
* Build a `ScriptJobRunner` for one request
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* empty after), `warn` logs and yields empty, `ignore` yields empty.
|
|
157
|
+
* Build a `ScriptJobRunner` for one request: the page's own jobs, then the
|
|
158
|
+
* component scripts of `graph.components` (prompt 157), under the graph's
|
|
159
|
+
* script deadline and error policy (see `runGraphJob`).
|
|
100
160
|
*/
|
|
101
161
|
export declare const createGraphJobRunner: (page: GraphPage, graph: SiteGraph, request: Request, context: {
|
|
102
162
|
remoteIp: string;
|
|
103
163
|
platform: PlatformContext;
|
|
104
164
|
}, log: (message: string) => void) => ScriptJobRunner;
|
|
165
|
+
/**
|
|
166
|
+
* The page's plan and runner for one request. With a component manifest
|
|
167
|
+
* that has something to render (prompt 157), the runner is wrapped so
|
|
168
|
+
* component tags in job output are rendered (component-host.ts), and the
|
|
169
|
+
* component scripts run like page jobs with the parent's remaining budget.
|
|
170
|
+
* Without one, plan and runner are exactly what they always were.
|
|
171
|
+
*/
|
|
172
|
+
export declare const createPageExecution: (page: GraphPage, graph: SiteGraph, request: Request, context: {
|
|
173
|
+
remoteIp: string;
|
|
174
|
+
platform: PlatformContext;
|
|
175
|
+
}, log: (message: string) => void) => {
|
|
176
|
+
plan: ExecutionPlan;
|
|
177
|
+
run: ScriptJobRunner;
|
|
178
|
+
};
|
|
105
179
|
export interface CreateWorkerOptions {
|
|
106
180
|
/** Diagnostics sink; defaults to `console.error`. Never reaches the client. */
|
|
107
181
|
log?: (message: string) => void;
|