@astrale-os/adapter-cloudflare 0.5.0-beta.146 → 0.5.0-beta.147
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/dist/adapter.js +1 -1
- package/dist/build/artifact.js +3 -1
- package/dist/build/configuration/addressing.js +6 -0
- package/dist/build/frontend/readiness.js +1 -1
- package/dist/build/worker/codegen/service.d.ts +1 -0
- package/dist/build/worker/codegen/service.js +1 -0
- package/dist/build/worker/execution.prepare.js +3 -0
- package/dist/deploy/deploy.js +11 -3
- package/dist/deploy/readiness.d.ts +1 -1
- package/dist/deploy/readiness.js +5 -2
- package/dist/params.d.ts +3 -0
- package/dist/worker/entry.d.ts +1 -0
- package/dist/worker/entry.js +13 -11
- package/package.json +2 -2
package/dist/adapter.js
CHANGED
|
@@ -20,7 +20,7 @@ export function cloudflare(parameters = {}) {
|
|
|
20
20
|
waitForReadiness: (release, signal, version, worker, workerName) => waitForReadiness(async (release, options) => {
|
|
21
21
|
const checks = {
|
|
22
22
|
...options,
|
|
23
|
-
fetch: versionReadinessFetch(release.addressing.
|
|
23
|
+
fetch: versionReadinessFetch(release.addressing.publicUrl, version, globalThis.fetch, workerName, release.addressing.issuer),
|
|
24
24
|
};
|
|
25
25
|
await verifyReadiness(release, checks);
|
|
26
26
|
await verifyWorkerFrontend(release, worker, checks);
|
package/dist/build/artifact.js
CHANGED
|
@@ -155,7 +155,9 @@ async function prepare(params, context, direct) {
|
|
|
155
155
|
? Object.freeze({ kind: 'provider-assigned', claim: name })
|
|
156
156
|
: Object.freeze({
|
|
157
157
|
kind: 'configured',
|
|
158
|
-
addressing: addressing(configuredIssuer
|
|
158
|
+
addressing: addressing(params.identityIssuer ?? configuredIssuer, {
|
|
159
|
+
publicUrl: configuredIssuer,
|
|
160
|
+
}),
|
|
159
161
|
}),
|
|
160
162
|
});
|
|
161
163
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { addressing } from '@astrale-os/sdk/deployment/release';
|
|
2
2
|
export function deploymentAddressing(parameters) {
|
|
3
|
+
if (parameters.identityIssuer !== undefined) {
|
|
4
|
+
addressing(parameters.identityIssuer);
|
|
5
|
+
if (parameters.route === undefined && parameters.addressing === undefined) {
|
|
6
|
+
throw new TypeError('A stable Cloudflare identityIssuer requires explicit public addressing.');
|
|
7
|
+
}
|
|
8
|
+
}
|
|
3
9
|
const routed = parameters.route === undefined ? undefined : addressing(`https://${parameters.route}`).issuer;
|
|
4
10
|
if (parameters.addressing === undefined)
|
|
5
11
|
return routed;
|
|
@@ -9,7 +9,7 @@ export async function verifyWorkerFrontend(release, worker, options = {}) {
|
|
|
9
9
|
const expected = frontendRevision(worker.assets.files);
|
|
10
10
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
11
11
|
for (const route of frontend.routes) {
|
|
12
|
-
const response = await fetcher(new URL(route.path, release.addressing.
|
|
12
|
+
const response = await fetcher(new URL(route.path, release.addressing.publicUrl).href, {
|
|
13
13
|
redirect: 'error',
|
|
14
14
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
15
15
|
});
|
|
@@ -8,6 +8,7 @@ export interface ExecutionCodegenOptions {
|
|
|
8
8
|
readonly frontendRevision?: string;
|
|
9
9
|
readonly maximumRequestBytes?: number;
|
|
10
10
|
readonly invocationTimeoutMs?: number;
|
|
11
|
+
readonly identityIssuer?: string;
|
|
11
12
|
readonly providerAssignedWorker?: string;
|
|
12
13
|
readonly tokenExchange?: ExchangeOptions | false;
|
|
13
14
|
readonly router?: {
|
|
@@ -45,6 +45,7 @@ ${frontend}${options.frontendRevision === undefined ? '' : ` frontendRevision:
|
|
|
45
45
|
resolveUrl: (env, requestOrigin) => env.WORKER_URL ?? env.IDENTITY_ISS ?? requestOrigin,
|
|
46
46
|
${options.maximumRequestBytes === undefined ? '' : `maximumRequestBytes: ${options.maximumRequestBytes},`}
|
|
47
47
|
${options.invocationTimeoutMs === undefined ? '' : `invocationTimeoutMs: ${options.invocationTimeoutMs},`}
|
|
48
|
+
${options.identityIssuer === undefined ? '' : `identityIssuer: ${JSON.stringify(options.identityIssuer)},`}
|
|
48
49
|
${options.providerAssignedWorker === undefined ? '' : `providerAssignedWorker: ${JSON.stringify(options.providerAssignedWorker)},`}
|
|
49
50
|
${options.tokenExchange === undefined ? '' : `tokenExchange: ${JSON.stringify(options.tokenExchange)} as const,`}
|
|
50
51
|
selfBinding: (env) => env.SELF,${routeSubrequest}
|
|
@@ -18,6 +18,9 @@ export async function prepareExecution(input) {
|
|
|
18
18
|
const invocationTimeoutMs = workerInvocationTimeout(input.params.invocationTimeoutMs);
|
|
19
19
|
const serviceSource = generateExecutionService({
|
|
20
20
|
origin: input.context.build.schema.compiled.root.origin,
|
|
21
|
+
...(input.params.identityIssuer === undefined
|
|
22
|
+
? {}
|
|
23
|
+
: { identityIssuer: input.params.identityIssuer }),
|
|
21
24
|
runtimeSpecifier,
|
|
22
25
|
workerSpecifier,
|
|
23
26
|
build: input.context.build,
|
package/dist/deploy/deploy.js
CHANGED
|
@@ -150,7 +150,15 @@ function partialProvider(cause, artifact) {
|
|
|
150
150
|
let issuer;
|
|
151
151
|
if (cause.applied.url !== undefined) {
|
|
152
152
|
try {
|
|
153
|
-
|
|
153
|
+
const observed = addressing(cause.applied.url);
|
|
154
|
+
if (artifact.addressing.kind === 'configured') {
|
|
155
|
+
if (observed.publicUrl === artifact.addressing.addressing.publicUrl) {
|
|
156
|
+
issuer = artifact.addressing.addressing.issuer;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
issuer = observed.issuer;
|
|
161
|
+
}
|
|
154
162
|
}
|
|
155
163
|
catch {
|
|
156
164
|
// The provider effect remains known when its printed URL is not Addressing.
|
|
@@ -178,10 +186,10 @@ function observeAddressing(artifact, deployedUrl, expectedWorker) {
|
|
|
178
186
|
if (deployedUrl === undefined)
|
|
179
187
|
return artifact.addressing.addressing;
|
|
180
188
|
const observed = addressing(deployedUrl);
|
|
181
|
-
if (observed.
|
|
189
|
+
if (observed.publicUrl !== artifact.addressing.addressing.publicUrl) {
|
|
182
190
|
throw new TypeError('Cloudflare deployed URL differs from configured Addressing.');
|
|
183
191
|
}
|
|
184
|
-
return
|
|
192
|
+
return artifact.addressing.addressing;
|
|
185
193
|
}
|
|
186
194
|
if (deployedUrl === undefined) {
|
|
187
195
|
throw new TypeError('Cloudflare did not report provider-assigned Addressing.');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { verifyReadiness } from '@astrale-os/sdk/deployment/verify';
|
|
2
2
|
type ReadinessFetch = NonNullable<NonNullable<Parameters<typeof verifyReadiness>[1]>['fetch']>;
|
|
3
3
|
/** Readiness is evidence for the provider version, not just a compatible Publication. */
|
|
4
|
-
export declare function versionReadinessFetch(issuer: string, version: string, fetcher?: typeof fetch, workerName?: string): ReadinessFetch;
|
|
4
|
+
export declare function versionReadinessFetch(issuer: string, version: string, fetcher?: typeof fetch, workerName?: string, identityIssuer?: string): ReadinessFetch;
|
|
5
5
|
export {};
|
package/dist/deploy/readiness.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** Readiness is evidence for the provider version, not just a compatible Publication. */
|
|
2
|
-
export function versionReadinessFetch(issuer, version, fetcher = globalThis.fetch, workerName) {
|
|
2
|
+
export function versionReadinessFetch(issuer, version, fetcher = globalThis.fetch, workerName, identityIssuer = issuer) {
|
|
3
3
|
return async (input, init) => {
|
|
4
|
-
|
|
4
|
+
const origin = new URL(input).origin;
|
|
5
|
+
if (origin !== issuer && origin === identityIssuer)
|
|
6
|
+
return fetcher(input, init);
|
|
7
|
+
if (origin !== issuer) {
|
|
5
8
|
throw new TypeError('Cloudflare readiness cannot leave the expected Worker origin.');
|
|
6
9
|
}
|
|
7
10
|
const headers = new Headers();
|
package/dist/params.d.ts
CHANGED
|
@@ -18,6 +18,9 @@ export interface CloudflareParams {
|
|
|
18
18
|
* present they must identify the same HTTPS origin.
|
|
19
19
|
*/
|
|
20
20
|
readonly addressing?: string;
|
|
21
|
+
/** Stable Domain issuer when this deployment serves at a different public origin.
|
|
22
|
+
* Requires explicit route or addressing and the existing issuer signing key. */
|
|
23
|
+
readonly identityIssuer?: string;
|
|
21
24
|
/** Gitignored secrets file (whole contents = secrets), e.g. `'.env.dev'`. */
|
|
22
25
|
readonly secrets?: string;
|
|
23
26
|
/**
|
package/dist/worker/entry.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export interface CloudflareWorkerConfig<RuntimeValue extends Runtime, Bindings e
|
|
|
25
25
|
readonly privateKey: JsonWebKey | ((bindings: Bindings) => JsonWebKey);
|
|
26
26
|
readonly resolveEnvironment?: (bindings: Bindings) => Environment;
|
|
27
27
|
readonly resolveUrl?: (bindings: Bindings, requestOrigin: string) => string;
|
|
28
|
+
readonly identityIssuer?: string;
|
|
28
29
|
readonly providerAssignedWorker?: string;
|
|
29
30
|
readonly selfBinding?: (bindings: Bindings) => Fetcher | null | undefined;
|
|
30
31
|
readonly routeSubrequest?: (url: URL, bindings: Bindings) => Fetcher | null | undefined;
|
package/dist/worker/entry.js
CHANGED
|
@@ -14,7 +14,7 @@ export function generatedCloudflareWorkerEntry() {
|
|
|
14
14
|
}
|
|
15
15
|
function createCloudflareWorkerEntry(restore) {
|
|
16
16
|
return function (config) {
|
|
17
|
-
let
|
|
17
|
+
let currentPublicUrl;
|
|
18
18
|
let realized;
|
|
19
19
|
const realize = () => {
|
|
20
20
|
if (realized !== undefined)
|
|
@@ -26,23 +26,25 @@ function createCloudflareWorkerEntry(restore) {
|
|
|
26
26
|
const application = serve({
|
|
27
27
|
runtime: source.runtime,
|
|
28
28
|
load(environment) {
|
|
29
|
-
if (
|
|
29
|
+
if (currentPublicUrl !== environment.publicUrl) {
|
|
30
30
|
throw new TypeError('Cloudflare Worker request origin differs from its current Release.');
|
|
31
31
|
}
|
|
32
|
-
return assemble(build, addressing(environment.
|
|
32
|
+
return assemble(build, addressing(config.identityIssuer ?? environment.publicUrl, {
|
|
33
|
+
publicUrl: environment.publicUrl,
|
|
34
|
+
}));
|
|
33
35
|
},
|
|
34
36
|
initialize: (environment) => config.resolveEnvironment === undefined
|
|
35
37
|
? environment.bindings
|
|
36
38
|
: config.resolveEnvironment(environment.bindings),
|
|
37
39
|
identity(environment) {
|
|
38
40
|
return createIdentity({
|
|
39
|
-
issuer: issuer.accept(environment.
|
|
41
|
+
issuer: issuer.accept(config.identityIssuer ?? environment.publicUrl),
|
|
40
42
|
subject: build.schema.compiled.root.origin,
|
|
41
43
|
privateKey: typeof config.privateKey === 'function'
|
|
42
44
|
? config.privateKey(environment.bindings)
|
|
43
45
|
: config.privateKey,
|
|
44
46
|
fetch: routedFetch(application, environment, config),
|
|
45
|
-
...(new URL(environment.
|
|
47
|
+
...(new URL(environment.publicUrl).protocol === 'http:'
|
|
46
48
|
? { allowInsecureHttp: true }
|
|
47
49
|
: {}),
|
|
48
50
|
...(config.tokenExchange === undefined
|
|
@@ -68,22 +70,22 @@ function createCloudflareWorkerEntry(restore) {
|
|
|
68
70
|
return Object.freeze({
|
|
69
71
|
async fetch(request, bindings, context) {
|
|
70
72
|
const url = new URL(request.url);
|
|
71
|
-
const
|
|
73
|
+
const publicUrl = canonicalServingUrl(bindings.WORKER_URL ??
|
|
72
74
|
bindings.IDENTITY_ISS ??
|
|
73
75
|
config.resolveUrl?.(bindings, requestOrigin(url, request)) ??
|
|
74
76
|
requestOrigin(url, request));
|
|
75
77
|
if (config.providerAssignedWorker !== undefined &&
|
|
76
78
|
bindings.WORKER_URL === undefined &&
|
|
77
79
|
bindings.IDENTITY_ISS === undefined &&
|
|
78
|
-
!matchesWorkersDevClaim(
|
|
80
|
+
!matchesWorkersDevClaim(publicUrl, config.providerAssignedWorker)) {
|
|
79
81
|
return new Response('Request origin differs from provider-assigned Addressing.', {
|
|
80
82
|
status: 421,
|
|
81
83
|
});
|
|
82
84
|
}
|
|
83
|
-
if (
|
|
85
|
+
if (currentPublicUrl !== undefined && currentPublicUrl !== publicUrl) {
|
|
84
86
|
return new Response('Request origin differs from the current Release.', { status: 421 });
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
currentPublicUrl = publicUrl;
|
|
87
89
|
if (config.frontend !== undefined) {
|
|
88
90
|
const frontend = await frontendAsset(config.frontend, bindings.ASSETS, url, request, config.frontendRevision);
|
|
89
91
|
if (frontend !== undefined)
|
|
@@ -95,7 +97,7 @@ function createCloudflareWorkerEntry(restore) {
|
|
|
95
97
|
if (frontend !== undefined)
|
|
96
98
|
return withProviderVersion(frontend, bindings);
|
|
97
99
|
}
|
|
98
|
-
const response = await application.fetch(request, Object.freeze({ bindings,
|
|
100
|
+
const response = await application.fetch(request, Object.freeze({ bindings, publicUrl }), context);
|
|
99
101
|
return withProviderVersion(response, bindings);
|
|
100
102
|
},
|
|
101
103
|
});
|
|
@@ -112,7 +114,7 @@ function routedFetch(application, environment, config) {
|
|
|
112
114
|
return async (input, init) => {
|
|
113
115
|
const { request, rejectRedirect } = prepareCloudflareRequest(input, init);
|
|
114
116
|
const destination = new URL(request.url);
|
|
115
|
-
if (destination.origin === environment.
|
|
117
|
+
if (destination.origin === environment.publicUrl) {
|
|
116
118
|
const self = config.selfBinding?.(environment.bindings);
|
|
117
119
|
return dispatchCloudflareRequest(request, rejectRedirect, (selected) => self === null || self === undefined
|
|
118
120
|
? application.fetch(selected, environment)
|
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.147",
|
|
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.5.0-beta.
|
|
56
|
+
"@astrale-os/sdk": "0.5.0-beta.144",
|
|
57
57
|
"@noble/hashes": "2.3.0",
|
|
58
58
|
"hono": "^4.6.20",
|
|
59
59
|
"jose": "^6.1.3",
|