devflare 1.0.0-next.59 → 1.0.0-next.60
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/_chunks/{build-IR-IaQN1.js → build-Dp8k2SWa.js} +1 -1
- package/dist/_chunks/{build-artifacts-C7JfIRnw.js → build-artifacts-DLEYfdVL.js} +2 -2
- package/dist/_chunks/{cli-yOO5yCaf.js → cli-BlVetiEh.js} +5 -5
- package/dist/_chunks/{compiler-okj8qvCh.js → compiler-CgIFPfRA.js} +23 -1
- package/dist/_chunks/{config-C8Qux0NR.js → config-BwRb2_vD.js} +1 -1
- package/dist/_chunks/{deploy-BG2PHaWu.js → deploy-Blrdr3Gv.js} +2 -2
- package/dist/_chunks/{dev-BgQl56Bd.js → dev-DRP6LR2H.js} +42 -7
- package/dist/_chunks/{previews-fTFp1WkQ.js → previews-D-GPVCeq.js} +1 -1
- package/dist/_chunks/r2-presign-runtime-zTOLS0Ea.js +291 -0
- package/dist/_chunks/{runtime-DL-Nz3k8.js → runtime-RekfD_2X.js} +325 -1
- package/dist/_chunks/{vite-De7bGxC6.js → vite-CtvgOi1c.js} +2 -2
- package/dist/bridge/miniflare-gateway.d.ts +45 -0
- package/dist/bridge/miniflare-gateway.d.ts.map +1 -0
- package/dist/bridge/miniflare.d.ts +8 -1
- package/dist/bridge/miniflare.d.ts.map +1 -1
- package/dist/bridge/r2-presign-runtime.d.ts +9 -0
- package/dist/bridge/r2-presign-runtime.d.ts.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/config/compiler.d.ts.map +1 -1
- package/dist/dev-server/gateway-script.d.ts +2 -1
- package/dist/dev-server/gateway-script.d.ts.map +1 -1
- package/dist/dev-server/miniflare-dev-config.d.ts +13 -0
- package/dist/dev-server/miniflare-dev-config.d.ts.map +1 -1
- package/dist/dev-server/miniflare-worker-config.d.ts +7 -0
- package/dist/dev-server/miniflare-worker-config.d.ts.map +1 -1
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-process.d.ts +9 -0
- package/dist/dev-server/vite-process.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/r2-presign.d.ts +164 -0
- package/dist/runtime/r2-presign.d.ts.map +1 -0
- package/dist/test/index.js +41 -4
- package/dist/test/simple-context-gateway-script.d.ts.map +1 -1
- package/dist/test/simple-context-mfconfig.d.ts +8 -0
- package/dist/test/simple-context-mfconfig.d.ts.map +1 -1
- package/dist/test/simple-context-multi-worker.d.ts.map +1 -1
- package/dist/test/simple-context-runtime.d.ts.map +1 -1
- package/dist/test/simple-context-startup.d.ts.map +1 -1
- package/dist/test/simple-context.d.ts.map +1 -1
- package/dist/vite/index.js +1 -1
- package/package.json +3 -2
- package/dist/_chunks/local-workflow-entrypoints-ZIL7apIa.js +0 -90
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as getDurableObjectOptions, t as durableObject } from "../_chunks/decorators-QmV57ixr.js";
|
|
2
2
|
import { A as createTailEvent, C as createDurableObjectWebSocketCloseEvent, D as createFetchEvent, E as createEmailEvent, O as createQueueEvent, S as createDurableObjectFetchEvent, T as createDurableObjectWebSocketMessageEvent, _ as runWithContext, a as getDurableObjectFetchEvent, b as createContextProxy, c as getDurableObjectWebSocketMessageEvent, d as getEventContextOrNull, f as getFetchEvent, g as hasContext, h as getTailEvent, i as getDurableObjectEvent, k as createScheduledEvent, l as getEmailEvent, m as getScheduledEvent, n as getContextOrNull, o as getDurableObjectWebSocketCloseEvent, p as getQueueEvent, r as getDurableObjectAlarmEvent, s as getDurableObjectWebSocketErrorEvent, t as getContext, u as getEventContext, v as runWithEventContext, w as createDurableObjectWebSocketErrorEvent, x as createDurableObjectAlarmEvent, y as ContextAccessError } from "../_chunks/context-CX50Y2Kb.js";
|
|
3
3
|
import { clearLocalSendEmailBindings, setLocalSendEmailBindings } from "../utils/send-email.js";
|
|
4
|
-
import { _ as
|
|
5
|
-
export { ContextAccessError, assertExplicit2ArgStyle, assertExplicitQueueHandlerStyle, assertExplicitScheduledHandlerStyle, clearLocalSendEmailBindings, createContextProxy, createDurableObjectAlarmEvent, createDurableObjectFetchEvent, createDurableObjectWebSocketCloseEvent, createDurableObjectWebSocketErrorEvent, createDurableObjectWebSocketMessageEvent, createEmailEvent, createFetchEvent, createQueueEvent, createResolveFetch, createRouteResolve, createScheduledEvent, createTailEvent, ctx, defineFetchHandler, defineQueueHandler, defineScheduledHandler, durableObject, env, event, getContext, getContextOrNull, getDurableObjectAlarmEvent, getDurableObjectEvent, getDurableObjectFetchEvent, getDurableObjectOptions, getDurableObjectWebSocketCloseEvent, getDurableObjectWebSocketErrorEvent, getDurableObjectWebSocketMessageEvent, getEmailEvent, getEventContext, getEventContextOrNull, getFetchEvent, getQueueEvent, getScheduledEvent, getTailEvent, hasContext, invokeFetchHandler, invokeFetchModule, invokeRouteModules, locals, markResolveStyle, markWorkerStyle, matchFetchRoute, resolveFetchHandler, runWithContext, runWithEventContext, sequence, setLocalSendEmailBindings, vars };
|
|
4
|
+
import { C as vars, S as locals, _ as resolveFetchHandler, a as matchFetchRoute, b as env, c as assertExplicitScheduledHandlerStyle, d as defineQueueHandler, f as defineScheduledHandler, g as markWorkerStyle, h as markResolveStyle, i as invokeRouteModules, l as createResolveFetch, m as invokeFetchModule, n as presignR2Put, o as assertExplicit2ArgStyle, p as invokeFetchHandler, r as createRouteResolve, s as assertExplicitQueueHandlerStyle, t as presignR2Get, u as defineFetchHandler, v as sequence, x as event, y as ctx } from "../_chunks/runtime-RekfD_2X.js";
|
|
5
|
+
export { ContextAccessError, assertExplicit2ArgStyle, assertExplicitQueueHandlerStyle, assertExplicitScheduledHandlerStyle, clearLocalSendEmailBindings, createContextProxy, createDurableObjectAlarmEvent, createDurableObjectFetchEvent, createDurableObjectWebSocketCloseEvent, createDurableObjectWebSocketErrorEvent, createDurableObjectWebSocketMessageEvent, createEmailEvent, createFetchEvent, createQueueEvent, createResolveFetch, createRouteResolve, createScheduledEvent, createTailEvent, ctx, defineFetchHandler, defineQueueHandler, defineScheduledHandler, durableObject, env, event, getContext, getContextOrNull, getDurableObjectAlarmEvent, getDurableObjectEvent, getDurableObjectFetchEvent, getDurableObjectOptions, getDurableObjectWebSocketCloseEvent, getDurableObjectWebSocketErrorEvent, getDurableObjectWebSocketMessageEvent, getEmailEvent, getEventContext, getEventContextOrNull, getFetchEvent, getQueueEvent, getScheduledEvent, getTailEvent, hasContext, invokeFetchHandler, invokeFetchModule, invokeRouteModules, locals, markResolveStyle, markWorkerStyle, matchFetchRoute, presignR2Get, presignR2Put, resolveFetchHandler, runWithContext, runWithEventContext, sequence, setLocalSendEmailBindings, vars };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** URL path prefix of the local presign endpoint served by devflare gateways. */
|
|
2
|
+
export declare const R2_PRESIGN_LOCAL_PATH_PREFIX = "/_devflare/r2/presigned/";
|
|
3
|
+
/** Env/var names devflare injects in local dev + tests to enable local presigning. */
|
|
4
|
+
export declare const R2_PRESIGN_SECRET_VAR = "DEVFLARE_R2_PRESIGN_SECRET";
|
|
5
|
+
export declare const R2_PRESIGN_ORIGIN_VAR = "DEVFLARE_R2_PRESIGN_ORIGIN";
|
|
6
|
+
/** Var (injected at deploy compile time) mapping R2 binding names to bucket metadata. */
|
|
7
|
+
export declare const R2_BUCKETS_VAR = "DEVFLARE_R2_BUCKETS";
|
|
8
|
+
/** Default env/secret names for R2 S3 API credentials in production. */
|
|
9
|
+
export declare const R2_ACCOUNT_ID_VAR = "R2_ACCOUNT_ID";
|
|
10
|
+
export declare const R2_ACCESS_KEY_ID_VAR = "R2_ACCESS_KEY_ID";
|
|
11
|
+
export declare const R2_SECRET_ACCESS_KEY_VAR = "R2_SECRET_ACCESS_KEY";
|
|
12
|
+
/**
|
|
13
|
+
* R2 S3 API credentials used for production presigning.
|
|
14
|
+
* Create them under Cloudflare Dashboard → R2 → Manage R2 API Tokens.
|
|
15
|
+
*/
|
|
16
|
+
export interface R2PresignCredentials {
|
|
17
|
+
/** Cloudflare account id that owns the bucket (not secret). */
|
|
18
|
+
accountId: string;
|
|
19
|
+
/** R2 S3 API access key id. */
|
|
20
|
+
accessKeyId: string;
|
|
21
|
+
/** R2 S3 API secret access key. Store as a Worker secret, never in config. */
|
|
22
|
+
secretAccessKey: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Options shared by `presignR2Put` and `presignR2Get`.
|
|
26
|
+
*/
|
|
27
|
+
export interface R2PresignBaseOptions {
|
|
28
|
+
/**
|
|
29
|
+
* URL lifetime in seconds. Enforced by R2 in production and by the
|
|
30
|
+
* devflare gateway locally.
|
|
31
|
+
*
|
|
32
|
+
* @default 900 (15 minutes). Maximum 604800 (7 days).
|
|
33
|
+
*/
|
|
34
|
+
expiresIn?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Production credentials override. When omitted they are read from `env`
|
|
37
|
+
* under `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID` and `R2_SECRET_ACCESS_KEY`.
|
|
38
|
+
* Ignored in local dev (the gateway signs with its own per-boot secret).
|
|
39
|
+
*/
|
|
40
|
+
credentials?: R2PresignCredentials;
|
|
41
|
+
/**
|
|
42
|
+
* Production bucket name override. When omitted it is resolved from the
|
|
43
|
+
* `DEVFLARE_R2_BUCKETS` var that `devflare` injects at deploy compile
|
|
44
|
+
* time from `bindings.r2`. Ignored in local dev (the binding name routes
|
|
45
|
+
* directly to the local bucket).
|
|
46
|
+
*/
|
|
47
|
+
bucketName?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Jurisdiction of the production bucket (e.g. `'eu'`), which changes the
|
|
50
|
+
* S3 endpoint host. When omitted it is resolved from `DEVFLARE_R2_BUCKETS`
|
|
51
|
+
* (i.e. from the `jurisdiction` field on the R2 binding config).
|
|
52
|
+
*/
|
|
53
|
+
jurisdiction?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Options for `presignR2Put`.
|
|
57
|
+
*/
|
|
58
|
+
export interface R2PresignPutOptions extends R2PresignBaseOptions {
|
|
59
|
+
/**
|
|
60
|
+
* Content type the uploader must send. Enforced cryptographically in both
|
|
61
|
+
* environments: it is a signed header in production and part of the
|
|
62
|
+
* signed canonical string locally, so a mismatching `Content-Type` on the
|
|
63
|
+
* actual PUT is rejected.
|
|
64
|
+
*/
|
|
65
|
+
contentType?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Exact body size in bytes the uploader must send. Enforced in both
|
|
68
|
+
* environments (signed `Content-Length` header in production; header +
|
|
69
|
+
* actual byte count locally). Prefer this over `maxSizeBytes` when the
|
|
70
|
+
* file size is known up front — it is the only size guarantee real R2
|
|
71
|
+
* presigned PUTs can enforce. GOTCHA: the client must then send a
|
|
72
|
+
* fixed-size body (`File`/`Blob`/`ArrayBuffer`); a streamed body carries
|
|
73
|
+
* no `Content-Length` header and fails the signed-header check.
|
|
74
|
+
*/
|
|
75
|
+
contentLength?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Upper size bound in bytes. Enforced by the devflare gateway locally.
|
|
78
|
+
* GOTCHA: real R2 presigned PUT URLs CANNOT enforce an upper bound —
|
|
79
|
+
* only an exact signed `Content-Length` — so in production this value is
|
|
80
|
+
* advisory. Always confirm the object with a server-side `head()` before
|
|
81
|
+
* committing quota.
|
|
82
|
+
*/
|
|
83
|
+
maxSizeBytes?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Options for `presignR2Get`.
|
|
87
|
+
*/
|
|
88
|
+
export type R2PresignGetOptions = R2PresignBaseOptions;
|
|
89
|
+
/**
|
|
90
|
+
* A presigned request the browser can execute directly against storage.
|
|
91
|
+
*/
|
|
92
|
+
export interface PresignedR2Request {
|
|
93
|
+
/** Fully-signed URL to fetch. Treat as opaque; it embeds the signature. */
|
|
94
|
+
url: string;
|
|
95
|
+
/** HTTP method the URL was signed for (`HEAD` is also accepted for `GET` URLs). */
|
|
96
|
+
method: 'PUT' | 'GET';
|
|
97
|
+
/**
|
|
98
|
+
* Headers the client MUST send for the signature to validate (e.g. the
|
|
99
|
+
* pinned `content-type`). `content-length` is intentionally omitted —
|
|
100
|
+
* browsers set it automatically from the request body and reject manual
|
|
101
|
+
* assignment.
|
|
102
|
+
*/
|
|
103
|
+
headers: Record<string, string>;
|
|
104
|
+
/** Moment the URL stops being accepted. */
|
|
105
|
+
expiresAt: Date;
|
|
106
|
+
/** Object key the URL operates on. */
|
|
107
|
+
key: string;
|
|
108
|
+
/** `'local'` when served by the devflare gateway, `'remote'` for real R2. */
|
|
109
|
+
mode: 'local' | 'remote';
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Presign a direct-to-R2 `PUT` URL for a browser (or any HTTP client) upload.
|
|
113
|
+
*
|
|
114
|
+
* Resolves to a real R2 S3 presigned URL in production and to a signed
|
|
115
|
+
* devflare-gateway URL in local dev and the test harness — same call, same
|
|
116
|
+
* guarantees (signature, expiry, method, content type, size), so upload and
|
|
117
|
+
* quota logic can be exercised identically in every environment.
|
|
118
|
+
*
|
|
119
|
+
* @param env - The platform env (`platform.env` in SvelteKit, `env` in a
|
|
120
|
+
* Worker handler). Used to detect the local dev context and to read
|
|
121
|
+
* production credentials/bucket mapping.
|
|
122
|
+
* @param binding - The R2 binding name from `bindings.r2` (e.g. `'BUCKET'`).
|
|
123
|
+
* @param key - Object key to upload to. Percent-encoding is handled internally.
|
|
124
|
+
* @param options - Expiry, enforcement (content type / length / max size) and
|
|
125
|
+
* production credential overrides.
|
|
126
|
+
* @returns The presigned request: `url` to PUT to, `headers` the client must
|
|
127
|
+
* send, and `expiresAt`.
|
|
128
|
+
* @throws {Error} in production when credentials or the bucket mapping are missing.
|
|
129
|
+
* @throws {TypeError | RangeError} on invalid inputs.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* // Server (SvelteKit endpoint) — reserve quota first, then presign:
|
|
134
|
+
* const { url, headers } = await presignR2Put(platform.env, 'BUCKET', `media/${id}.png`, {
|
|
135
|
+
* expiresIn: 600,
|
|
136
|
+
* contentType: file.type,
|
|
137
|
+
* contentLength: file.size
|
|
138
|
+
* })
|
|
139
|
+
*
|
|
140
|
+
* // Browser — upload directly to storage:
|
|
141
|
+
* await fetch(url, { method: 'PUT', body: file, headers })
|
|
142
|
+
*
|
|
143
|
+
* // Server — finalize: confirm the object before committing quota:
|
|
144
|
+
* const head = await platform.env.BUCKET.head(`media/${id}.png`)
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function presignR2Put(env: Record<string, unknown>, binding: string, key: string, options?: R2PresignPutOptions): Promise<PresignedR2Request>;
|
|
148
|
+
/**
|
|
149
|
+
* Presign a direct-from-R2 `GET` URL (also valid for `HEAD`) so a browser can
|
|
150
|
+
* download an object without routing the bytes through the Worker.
|
|
151
|
+
*
|
|
152
|
+
* Same dev/prod symmetry as {@link presignR2Put}. Note that browser reads
|
|
153
|
+
* from real R2 additionally require CORS rules on the bucket itself.
|
|
154
|
+
*
|
|
155
|
+
* @param env - The platform env (see {@link presignR2Put}).
|
|
156
|
+
* @param binding - The R2 binding name from `bindings.r2`.
|
|
157
|
+
* @param key - Object key to read.
|
|
158
|
+
* @param options - Expiry and production credential overrides.
|
|
159
|
+
* @returns The presigned request; `headers` is always empty for GET.
|
|
160
|
+
* @throws {Error} in production when credentials or the bucket mapping are missing.
|
|
161
|
+
* @throws {TypeError | RangeError} on invalid inputs.
|
|
162
|
+
*/
|
|
163
|
+
export declare function presignR2Get(env: Record<string, unknown>, binding: string, key: string, options?: R2PresignGetOptions): Promise<PresignedR2Request>;
|
|
164
|
+
//# sourceMappingURL=r2-presign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2-presign.d.ts","sourceRoot":"","sources":["../../src/runtime/r2-presign.ts"],"names":[],"mappings":"AAuBA,iFAAiF;AACjF,eAAO,MAAM,4BAA4B,6BAA6B,CAAA;AAKtE,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,+BAA+B,CAAA;AACjE,eAAO,MAAM,qBAAqB,+BAA+B,CAAA;AAEjE,yFAAyF;AACzF,eAAO,MAAM,cAAc,wBAAwB,CAAA;AAEnD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,kBAAkB,CAAA;AAChD,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AACtD,eAAO,MAAM,wBAAwB,yBAAyB,CAAA;AAY9D;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;OAIG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAA;IAElC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,oBAAoB;IAChE;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAA;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAA;IACX,mFAAmF;IACnF,MAAM,EAAE,KAAK,GAAG,KAAK,CAAA;IACrB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,2CAA2C;IAC3C,SAAS,EAAE,IAAI,CAAA;IACf,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,6EAA6E;IAC7E,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;CACxB;AAqYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAe7B"}
|
package/dist/test/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import { d as getPrimaryAccount, n as getEffectiveAccountId } from "../_chunks/p
|
|
|
7
7
|
import { A as createTailEvent, D as createFetchEvent, E as createEmailEvent, F as BridgeClient, M as createEnvProxy, O as createQueueEvent, P as setBindingHints, _ as runWithContext, k as createScheduledEvent, v as runWithEventContext, x as createDurableObjectAlarmEvent } from "../_chunks/context-CX50Y2Kb.js";
|
|
8
8
|
import { createLocalSendEmailBinding, wrapEnvSendEmailBindings } from "../utils/send-email.js";
|
|
9
9
|
import { n as __setTestContext, r as env, t as __clearTestContext } from "../_chunks/env-S0_nMVz1.js";
|
|
10
|
-
import {
|
|
10
|
+
import { _ as resolveFetchHandler, a as matchFetchRoute, m as invokeFetchModule, r as createRouteResolve } from "../_chunks/runtime-RekfD_2X.js";
|
|
11
11
|
import { i as extractBindingHints, n as createLocalWorkerLoaderBinding, r as disposeLocalWorkerLoaderBindings, t as createLocalHyperdrive } from "../_chunks/local-hyperdrive-CJ90j46O.js";
|
|
12
12
|
import { E as buildTailConsumersConfig, T as buildStreamingTailConsumersConfig, a as hasServiceBindings, i as hasCrossWorkerDOs, m as buildHyperdrivesConfig, o as resolveDOBindings, r as clearBundleCache, s as resolveServiceBindings, t as discoverRoutes, u as buildAnalyticsEngineConfig } from "../_chunks/routes-BMU7ga_l.js";
|
|
13
13
|
import { i as findFiles, t as DEFAULT_DO_PATTERN } from "../_chunks/glob-CmQOvunB.js";
|
|
14
14
|
import { a as isRemoteModeActive, i as getRemoteModeStatus } from "../_chunks/remote-config-D39BY9ji.js";
|
|
15
|
-
import {
|
|
15
|
+
import { n as bundleWorkflowEntrypointScript, t as R2_PRESIGN_RUNTIME_JS } from "../_chunks/r2-presign-runtime-zTOLS0Ea.js";
|
|
16
16
|
import { a as resolveLocalSecretValuesForBindings, n as buildLocalSecretWrappedBindingConfig } from "../_chunks/local-secrets-6sMstHXw.js";
|
|
17
17
|
import { t as buildLocalBindingShimServiceConfig } from "../_chunks/local-media-bindings-DsAW4AMF.js";
|
|
18
18
|
import { t as canProceedWithTest } from "../_chunks/usage-BBTGzjon.js";
|
|
@@ -1574,6 +1574,8 @@ function buildRemoteAndStaticBindings(config) {
|
|
|
1574
1574
|
//#region src/test/simple-context-gateway-script.ts
|
|
1575
1575
|
function buildGatewayScript(bundledCode, wrappers, nativeRpcBindingNames = []) {
|
|
1576
1576
|
return `
|
|
1577
|
+
${R2_PRESIGN_RUNTIME_JS}
|
|
1578
|
+
|
|
1577
1579
|
// Bundled transport + DO classes
|
|
1578
1580
|
${bundledCode}
|
|
1579
1581
|
|
|
@@ -1630,6 +1632,10 @@ export default {
|
|
|
1630
1632
|
})
|
|
1631
1633
|
return new Response(null, { status: 101, webSocket: client })
|
|
1632
1634
|
}
|
|
1635
|
+
const presignResponse = await __devflareR2PresignHandle(request, env, new URL(request.url))
|
|
1636
|
+
if (presignResponse) {
|
|
1637
|
+
return presignResponse
|
|
1638
|
+
}
|
|
1633
1639
|
return new Response('Gateway')
|
|
1634
1640
|
}
|
|
1635
1641
|
}
|
|
@@ -3332,6 +3338,20 @@ function createDisposeContext(state) {
|
|
|
3332
3338
|
//#endregion
|
|
3333
3339
|
//#region src/test/simple-context-mfconfig.ts
|
|
3334
3340
|
/**
|
|
3341
|
+
* Return `bindings` with the local R2 presign gateway origin added, when (and
|
|
3342
|
+
* only when) the presign secret was wired in. The origin can only be built at
|
|
3343
|
+
* boot time — the test context picks a fresh port per startup attempt — so
|
|
3344
|
+
* this runs next to each `new Miniflare(...)` call rather than in the config
|
|
3345
|
+
* builder.
|
|
3346
|
+
*/
|
|
3347
|
+
function addR2PresignOriginVar(bindings, port) {
|
|
3348
|
+
if (!bindings || typeof bindings.DEVFLARE_R2_PRESIGN_SECRET !== "string") return bindings;
|
|
3349
|
+
return {
|
|
3350
|
+
...bindings,
|
|
3351
|
+
DEVFLARE_R2_PRESIGN_ORIGIN: `http://127.0.0.1:${port}`
|
|
3352
|
+
};
|
|
3353
|
+
}
|
|
3354
|
+
/**
|
|
3335
3355
|
* Build the seed Miniflare config for an inline (single-worker) bridge.
|
|
3336
3356
|
* Pure: no I/O, no closures.
|
|
3337
3357
|
*/
|
|
@@ -3484,6 +3504,7 @@ function applyMultiWorkerConfig(mfConfig, config, serviceBindingResolution, doBi
|
|
|
3484
3504
|
...mfConfig.artifacts && { artifacts: mfConfig.artifacts },
|
|
3485
3505
|
...mfConfig.secretsStoreSecrets && { secretsStoreSecrets: mfConfig.secretsStoreSecrets },
|
|
3486
3506
|
...mfConfig.wrappedBindings && { wrappedBindings: mfConfig.wrappedBindings },
|
|
3507
|
+
...mfConfig.bindings && { bindings: mfConfig.bindings },
|
|
3487
3508
|
...mfConfig.email && { email: mfConfig.email },
|
|
3488
3509
|
...Object.keys(primaryDurableObjects).length > 0 && { durableObjects: primaryDurableObjects },
|
|
3489
3510
|
...mfConfig.serviceBindings || serviceBindingResolution?.primaryServiceBindings ? { serviceBindings: {
|
|
@@ -3529,6 +3550,7 @@ function applyMultiWorkerConfig(mfConfig, config, serviceBindingResolution, doBi
|
|
|
3529
3550
|
delete mfConfig.artifacts;
|
|
3530
3551
|
delete mfConfig.secretsStoreSecrets;
|
|
3531
3552
|
delete mfConfig.wrappedBindings;
|
|
3553
|
+
delete mfConfig.bindings;
|
|
3532
3554
|
delete mfConfig.serviceBindings;
|
|
3533
3555
|
delete mfConfig.__devflareLocalSecretWorkers;
|
|
3534
3556
|
delete mfConfig.__devflareLocalBindingWorkers;
|
|
@@ -3597,10 +3619,13 @@ async function startBridgeBackedTestContext(mfConfig) {
|
|
|
3597
3619
|
let miniflare = null;
|
|
3598
3620
|
let client = null;
|
|
3599
3621
|
try {
|
|
3600
|
-
|
|
3622
|
+
const attemptConfig = {
|
|
3601
3623
|
...mfConfig,
|
|
3602
3624
|
port
|
|
3603
|
-
}
|
|
3625
|
+
};
|
|
3626
|
+
const bindingsWithOrigin = addR2PresignOriginVar(attemptConfig.bindings, port);
|
|
3627
|
+
if (bindingsWithOrigin) attemptConfig.bindings = bindingsWithOrigin;
|
|
3628
|
+
miniflare = new Miniflare(expandLocalBindingWorkers(attemptConfig));
|
|
3604
3629
|
await miniflare.ready;
|
|
3605
3630
|
const miniflareBindings = wrapEnvSendEmailBindings(await miniflare.getBindings());
|
|
3606
3631
|
client = await connectBridgeClientWithRetry(`ws://localhost:${port}`);
|
|
@@ -3636,6 +3661,9 @@ async function bootTestRuntime(mfConfig, usesMultiWorker) {
|
|
|
3636
3661
|
if (usesMultiWorker) {
|
|
3637
3662
|
const { Miniflare } = await import("miniflare");
|
|
3638
3663
|
const activePort = await getAvailablePort();
|
|
3664
|
+
const primaryWorker = Array.isArray(mfConfig.workers) ? mfConfig.workers[0] : void 0;
|
|
3665
|
+
const primaryBindings = addR2PresignOriginVar(primaryWorker?.bindings, activePort);
|
|
3666
|
+
if (primaryWorker && primaryBindings) primaryWorker.bindings = primaryBindings;
|
|
3639
3667
|
const miniflare = new Miniflare({
|
|
3640
3668
|
...mfConfig,
|
|
3641
3669
|
port: activePort
|
|
@@ -3728,6 +3756,11 @@ async function createTestContext(configPath) {
|
|
|
3728
3756
|
if (needsMultiWorkerForServices) serviceBindingResolution = await resolveServiceBindings(config, configDir);
|
|
3729
3757
|
if (needsMultiWorkerForDOs) doBindingResolution = await resolveDOBindings(config, configDir);
|
|
3730
3758
|
const mfConfig = buildInlineBridgeMfConfig(config, { cwd: configDir });
|
|
3759
|
+
const r2PresignSecret = config.bindings?.r2 ? `${crypto.randomUUID()}${crypto.randomUUID()}` : null;
|
|
3760
|
+
if (r2PresignSecret) mfConfig.bindings = {
|
|
3761
|
+
...mfConfig.bindings,
|
|
3762
|
+
DEVFLARE_R2_PRESIGN_SECRET: r2PresignSecret
|
|
3763
|
+
};
|
|
3731
3764
|
const transportFile = resolveTransportFile(configDir, config.files?.transport);
|
|
3732
3765
|
if (transportFile) state.transportDecode = await loadTransportDecoders(configDir, transportFile);
|
|
3733
3766
|
const gateway = await buildDurableObjectGateway(config, configDir, transportFile);
|
|
@@ -3742,6 +3775,10 @@ async function createTestContext(configPath) {
|
|
|
3742
3775
|
state.miniflare = runtime.miniflare;
|
|
3743
3776
|
state.miniflareBindings = runtime.miniflareBindings;
|
|
3744
3777
|
state.client = runtime.client;
|
|
3778
|
+
if (r2PresignSecret && state.miniflareBindings) {
|
|
3779
|
+
state.miniflareBindings.DEVFLARE_R2_PRESIGN_SECRET = r2PresignSecret;
|
|
3780
|
+
state.miniflareBindings.DEVFLARE_R2_PRESIGN_ORIGIN = `http://127.0.0.1:${activePort}`;
|
|
3781
|
+
}
|
|
3745
3782
|
const disposeContext = createDisposeContext(state);
|
|
3746
3783
|
const getTestEnv = () => {
|
|
3747
3784
|
return new Proxy({}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context-gateway-script.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-gateway-script.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"simple-context-gateway-script.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-gateway-script.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,qBAAqB,GAAE,MAAM,EAAO,GAClC,MAAM,CA0NR"}
|
|
@@ -2,6 +2,14 @@ import type { DevflareConfig } from '../config/index.js';
|
|
|
2
2
|
export interface BuildInlineBridgeMfConfigOptions {
|
|
3
3
|
cwd?: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Return `bindings` with the local R2 presign gateway origin added, when (and
|
|
7
|
+
* only when) the presign secret was wired in. The origin can only be built at
|
|
8
|
+
* boot time — the test context picks a fresh port per startup attempt — so
|
|
9
|
+
* this runs next to each `new Miniflare(...)` call rather than in the config
|
|
10
|
+
* builder.
|
|
11
|
+
*/
|
|
12
|
+
export declare function addR2PresignOriginVar(bindings: Record<string, unknown> | undefined, port: number): Record<string, unknown> | undefined;
|
|
5
13
|
/**
|
|
6
14
|
* Build the seed Miniflare config for an inline (single-worker) bridge.
|
|
7
15
|
* Pure: no I/O, no closures.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context-mfconfig.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-mfconfig.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAU/C,MAAM,WAAW,gCAAgC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,gCAAqC,GAC5C,GAAG,CA6QL"}
|
|
1
|
+
{"version":3,"file":"simple-context-mfconfig.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-mfconfig.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAU/C,MAAM,WAAW,gCAAgC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC7C,IAAI,EAAE,MAAM,GACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKrC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,gCAAqC,GAC5C,GAAG,CA6QL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context-multi-worker.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-multi-worker.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAE3F,KAAK,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAA;AAClF,KAAK,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAA;AAExE;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,cAAc,EACtB,wBAAwB,EAAE,wBAAwB,GAAG,IAAI,EACzD,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,GAC7C,IAAI,
|
|
1
|
+
{"version":3,"file":"simple-context-multi-worker.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-multi-worker.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAE3F,KAAK,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAA;AAClF,KAAK,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAA;AAExE;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,cAAc,EACtB,wBAAwB,EAAE,wBAAwB,GAAG,IAAI,EACzD,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,GAC7C,IAAI,CA+FN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context-runtime.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-runtime.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"simple-context-runtime.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-runtime.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAMpD,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,GAAG,CAAA;IACd,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC1C,8CAA8C;IAC9C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACpC,QAAQ,EAAE,GAAG,EACb,eAAe,EAAE,OAAO,GACtB,OAAO,CAAC,iBAAiB,CAAC,CA6B5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context-startup.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-startup.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"simple-context-startup.d.ts","sourceRoot":"","sources":["../../src/test/simple-context-startup.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAU/C,MAAM,WAAW,8BAA8B;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,GAAG,CAAA;IACd,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAa1E;AAUD,wBAAsB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA2BrF;AAiDD,wBAAsB,4BAA4B,CACjD,QAAQ,EAAE,GAAG,GACX,OAAO,CAAC,8BAA8B,CAAC,CAkDzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-context.d.ts","sourceRoot":"","sources":["../../src/test/simple-context.ts"],"names":[],"mappings":"AA2EA;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"simple-context.d.ts","sourceRoot":"","sources":["../../src/test/simple-context.ts"],"names":[],"mappings":"AA2EA;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmI1E;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACxB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAA;AAEhD,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA"}
|
package/dist/vite/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as devflarePlugin, c as getDevflareConfigs, i as writeGeneratedViteConfig, n as resolveEffectiveViteProject, o as getPluginContext, r as resolveViteUserConfig, s as getCloudflareConfig, t as hasInlineViteConfig } from "../_chunks/vite-
|
|
1
|
+
import { a as devflarePlugin, c as getDevflareConfigs, i as writeGeneratedViteConfig, n as resolveEffectiveViteProject, o as getPluginContext, r as resolveViteUserConfig, s as getCloudflareConfig, t as hasInlineViteConfig } from "../_chunks/vite-CtvgOi1c.js";
|
|
2
2
|
export { devflarePlugin as default, devflarePlugin, getCloudflareConfig, getDevflareConfigs, getPluginContext, hasInlineViteConfig, resolveEffectiveViteProject, resolveViteUserConfig, writeGeneratedViteConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflare",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.60",
|
|
4
4
|
"description": "Devflare is a developer-first toolkit for Cloudflare Workers that sits on top of Miniflare and Wrangler-compatible config",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"test:unit": "bun test tests/unit",
|
|
85
85
|
"test:coverage": "bun test tests/unit --coverage",
|
|
86
86
|
"test:integration:control": "bun test tests/integration/cli tests/integration/examples tests/integration/package-entry tests/integration/vite",
|
|
87
|
-
"test:integration:bridge": "bun test tests/integration/bridge/bridge-proxy.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/case18-do.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/durable-object.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/miniflare.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-transfer.test.ts --parallel=1 --max-concurrency=1",
|
|
87
|
+
"test:integration:bridge": "bun test tests/integration/bridge/bridge-proxy.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/case18-do.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/durable-object.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/miniflare.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-transfer.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-presign.test.ts --parallel=1 --max-concurrency=1",
|
|
88
88
|
"test:integration:test-context": "bun test tests/integration/test-context --parallel=1 --max-concurrency=1",
|
|
89
89
|
"test:integration:dev-server": "bun test tests/integration/dev-server --parallel=1 --max-concurrency=1",
|
|
90
90
|
"test:integration:shims": "bun test tests/integration/shims --parallel=1 --max-concurrency=1",
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
97
|
"@puppeteer/browsers": "^2.10.3",
|
|
98
|
+
"aws4fetch": "^1.0.20",
|
|
98
99
|
"c12": "^2.0.1",
|
|
99
100
|
"chokidar": "^4.0.3",
|
|
100
101
|
"citty": "^0.1.6",
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { x as normalizeWorkflowBinding } from "./schema-normalization-Zgm4W6O6.js";
|
|
2
|
-
import { i as findFiles, r as DEFAULT_WORKFLOW_PATTERN } from "./glob-CmQOvunB.js";
|
|
3
|
-
import { t as bundleWorkerEntry } from "./worker-bundler-dTTnYU3n.js";
|
|
4
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
|
-
import { join, relative, resolve } from "pathe";
|
|
6
|
-
//#region src/workflows/local-workflow-entrypoints.ts
|
|
7
|
-
function findExportedClasses(code) {
|
|
8
|
-
const classes = [];
|
|
9
|
-
const classPattern = /export\s+class\s+(\w+)/g;
|
|
10
|
-
let match = classPattern.exec(code);
|
|
11
|
-
while (match !== null) {
|
|
12
|
-
classes.push(match[1]);
|
|
13
|
-
match = classPattern.exec(code);
|
|
14
|
-
}
|
|
15
|
-
return classes;
|
|
16
|
-
}
|
|
17
|
-
function toImportSpecifier(fromDir, filePath) {
|
|
18
|
-
const relativePath = relative(fromDir, filePath).replace(/\\/g, "/");
|
|
19
|
-
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
20
|
-
}
|
|
21
|
-
async function discoverWorkflowClasses(config, configDir) {
|
|
22
|
-
const classToFilePath = /* @__PURE__ */ new Map();
|
|
23
|
-
const workflowPatternConfig = config.files?.workflows;
|
|
24
|
-
const workflowPattern = typeof workflowPatternConfig === "string" ? workflowPatternConfig : DEFAULT_WORKFLOW_PATTERN;
|
|
25
|
-
if (workflowPatternConfig === false) return classToFilePath;
|
|
26
|
-
const files = await findFiles(workflowPattern, { cwd: configDir });
|
|
27
|
-
for (const filePath of files) try {
|
|
28
|
-
const code = await readFile(filePath, "utf-8");
|
|
29
|
-
for (const className of findExportedClasses(code)) classToFilePath.set(className, filePath);
|
|
30
|
-
} catch {}
|
|
31
|
-
return classToFilePath;
|
|
32
|
-
}
|
|
33
|
-
async function resolveLocalWorkflowEntrypoints(config, configDir) {
|
|
34
|
-
const workflows = config.bindings?.workflows;
|
|
35
|
-
if (!workflows || Object.keys(workflows).length === 0) return [];
|
|
36
|
-
const classToFilePath = await discoverWorkflowClasses(config, configDir);
|
|
37
|
-
const entrypoints = [];
|
|
38
|
-
for (const [bindingName, binding] of Object.entries(workflows)) {
|
|
39
|
-
const normalized = normalizeWorkflowBinding(binding);
|
|
40
|
-
if (normalized.scriptName) continue;
|
|
41
|
-
const scriptPath = classToFilePath.get(normalized.className);
|
|
42
|
-
if (!scriptPath) throw new Error(`Workflow binding ${bindingName} (className: '${normalized.className}') not found.\nEither set files.workflows to match the workflow source file, or set scriptName when the workflow lives in another worker.`);
|
|
43
|
-
entrypoints.push({
|
|
44
|
-
bindingName,
|
|
45
|
-
className: normalized.className,
|
|
46
|
-
scriptPath
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return entrypoints;
|
|
50
|
-
}
|
|
51
|
-
function buildWorkflowVirtualEntry(entrypoints, entryDir) {
|
|
52
|
-
const imports = entrypoints.map((entrypoint, index) => {
|
|
53
|
-
const importName = `__DevflareWorkflow${index}`;
|
|
54
|
-
const importPath = toImportSpecifier(entryDir, entrypoint.scriptPath);
|
|
55
|
-
return {
|
|
56
|
-
importName,
|
|
57
|
-
className: entrypoint.className,
|
|
58
|
-
line: `import { ${entrypoint.className} as ${importName} } from '${importPath}'`
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
const exports = imports.map((entrypoint) => {
|
|
62
|
-
return `export { ${entrypoint.importName} as ${entrypoint.className} }`;
|
|
63
|
-
});
|
|
64
|
-
return [
|
|
65
|
-
...imports.map((entrypoint) => entrypoint.line),
|
|
66
|
-
"",
|
|
67
|
-
...exports
|
|
68
|
-
].join("\n");
|
|
69
|
-
}
|
|
70
|
-
async function bundleWorkflowEntrypointScript(config, configDir, options = {}) {
|
|
71
|
-
const entrypoints = await resolveLocalWorkflowEntrypoints(config, configDir);
|
|
72
|
-
if (entrypoints.length === 0) return "";
|
|
73
|
-
const entryDir = resolve(configDir, ".devflare", "workflow-entrypoints");
|
|
74
|
-
const entryPath = join(entryDir, "__entry.ts");
|
|
75
|
-
const outFile = join(entryDir, "index.js");
|
|
76
|
-
await mkdir(entryDir, { recursive: true });
|
|
77
|
-
await writeFile(entryPath, buildWorkflowVirtualEntry(entrypoints, entryDir));
|
|
78
|
-
await bundleWorkerEntry({
|
|
79
|
-
cwd: configDir,
|
|
80
|
-
inputFile: entryPath,
|
|
81
|
-
outFile,
|
|
82
|
-
rolldownOptions: config.rolldown?.options,
|
|
83
|
-
sourcemap: config.rolldown?.sourcemap,
|
|
84
|
-
minify: config.rolldown?.minify,
|
|
85
|
-
logger: options.logger
|
|
86
|
-
});
|
|
87
|
-
return await readFile(outFile, "utf-8");
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
export { bundleWorkflowEntrypointScript as t };
|