@moku-labs/worker 0.5.1 → 0.7.0
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 +10 -9
- package/dist/cli-Bb37rYq_.mjs +3640 -0
- package/dist/cli-C8DdTtzn.cjs +3740 -0
- package/dist/cli.cjs +3 -1920
- package/dist/cli.d.cts +1 -270
- package/dist/cli.d.mts +1 -270
- package/dist/cli.mjs +1 -1895
- package/dist/index-BKOUpKtC.d.cts +404 -0
- package/dist/index-BKOUpKtC.d.mts +404 -0
- package/dist/index.cjs +61 -63
- package/dist/index.d.cts +338 -166
- package/dist/index.d.mts +338 -166
- package/dist/index.mjs +49 -53
- package/package.json +1 -1
- package/dist/config-BYPJvEbl.d.cts +0 -88
- package/dist/config-BYPJvEbl.d.mts +0 -88
- package/dist/storage-COo-F38H.mjs +0 -884
- package/dist/storage-CgXl-dUA.cjs +0 -949
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { PluginCtx, PluginInstance } from "@moku-labs/core";
|
|
2
|
+
|
|
3
|
+
//#region src/config.d.ts
|
|
4
|
+
/** Per-request Cloudflare bindings object (env). Framework-level shared type. */
|
|
5
|
+
type WorkerEnv = Record<string, unknown>;
|
|
6
|
+
/** Global framework config — flat, with complete defaults. */
|
|
7
|
+
type WorkerConfig = {
|
|
8
|
+
stage: "production" | "development" | "test";
|
|
9
|
+
name: string;
|
|
10
|
+
compatibilityDate: string;
|
|
11
|
+
};
|
|
12
|
+
/** Global framework events — declared once, visible to every plugin. */
|
|
13
|
+
type WorkerEvents = {
|
|
14
|
+
"request:start": {
|
|
15
|
+
method: string;
|
|
16
|
+
path: string;
|
|
17
|
+
requestId: string;
|
|
18
|
+
};
|
|
19
|
+
"request:end": {
|
|
20
|
+
method: string;
|
|
21
|
+
path: string;
|
|
22
|
+
status: number;
|
|
23
|
+
ms: number;
|
|
24
|
+
};
|
|
25
|
+
"deploy:phase": {
|
|
26
|
+
phase: string;
|
|
27
|
+
detail?: string;
|
|
28
|
+
};
|
|
29
|
+
"deploy:complete": {
|
|
30
|
+
url: string;
|
|
31
|
+
};
|
|
32
|
+
"provision:resource": {
|
|
33
|
+
kind: "kv" | "r2" | "d1" | "queue" | "do";
|
|
34
|
+
name: string;
|
|
35
|
+
};
|
|
36
|
+
"provision:plan": {
|
|
37
|
+
exists: number;
|
|
38
|
+
missing: number;
|
|
39
|
+
account: string;
|
|
40
|
+
};
|
|
41
|
+
"provision:skip": {
|
|
42
|
+
kind: "kv" | "r2" | "d1" | "queue" | "do";
|
|
43
|
+
name: string;
|
|
44
|
+
};
|
|
45
|
+
"auth:verified": {
|
|
46
|
+
account: string;
|
|
47
|
+
accountId: string;
|
|
48
|
+
scopes: string[];
|
|
49
|
+
};
|
|
50
|
+
"dev:phase": {
|
|
51
|
+
phase: string;
|
|
52
|
+
detail?: string;
|
|
53
|
+
};
|
|
54
|
+
"dev:rebuilt": {
|
|
55
|
+
files: number;
|
|
56
|
+
ms: number;
|
|
57
|
+
};
|
|
58
|
+
"dev:error": {
|
|
59
|
+
message: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Worker-bound plugin context for Layer-3 consumer plugins. Aliases the core
|
|
64
|
+
* {@link PluginCtx} with the global {@link WorkerEvents} pre-merged into the event
|
|
65
|
+
* map, so a consumer plugin types its own `config`/`state`/`emit` by passing only
|
|
66
|
+
* its OWN event map — never hand-merging `WorkerEvents`, and never importing from
|
|
67
|
+
* `@moku-labs/core` (a Layer-1 boundary the spec validator flags for consumers).
|
|
68
|
+
*
|
|
69
|
+
* A plugin that resolves sibling plugins also needs a `require` field; intersect the
|
|
70
|
+
* public `Server.RequireFn` for it, exactly as this framework's own plugins do. When
|
|
71
|
+
* you need the unaliased shape (e.g. a different global event map), use the raw
|
|
72
|
+
* re-exported {@link PluginCtx} instead.
|
|
73
|
+
*
|
|
74
|
+
* @template Config - This plugin's own flat configuration object.
|
|
75
|
+
* @template State - This plugin's mutable state (use `Record<string, never>` when stateless).
|
|
76
|
+
* @template Events - This plugin's own event map, merged on top of {@link WorkerEvents}; defaults to none.
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import type { Server, WorkerPluginCtx } from "@moku-labs/worker";
|
|
80
|
+
* type MyEvents = { "my:done": { id: string } };
|
|
81
|
+
* export type MyCtx = WorkerPluginCtx<MyConfig, Record<string, never>, MyEvents> & {
|
|
82
|
+
* require: Server.RequireFn;
|
|
83
|
+
* };
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
type WorkerPluginCtx<Config, State, Events extends Record<string, unknown> = Record<never, never>> = PluginCtx<Config, State, WorkerEvents & Events>;
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/plugins/deploy/types.d.ts
|
|
89
|
+
/**
|
|
90
|
+
* A web-site build hook wired in from the consumer's deploy/dev script — e.g.
|
|
91
|
+
* `() => webApp.cli.build()`. This is the seam that lets one small app-side script compose a
|
|
92
|
+
* Moku Web app with this Worker framework: `dev` / `deploy` invoke it to (re)build the site before
|
|
93
|
+
* serving or deploying. The hook may resolve ANYTHING — `void`, the web app's own build summary, or
|
|
94
|
+
* a `{ files }` count; when the resolved value carries a numeric `files` field it is surfaced in
|
|
95
|
+
* `dev:rebuilt`, otherwise the count is reported as 0. Returning `Promise<unknown>` keeps the hook
|
|
96
|
+
* assignable from any real build function (whose return type the worker framework cannot know).
|
|
97
|
+
*
|
|
98
|
+
* @returns Resolves when the web build completes (the value is read opportunistically for `files`).
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* await server.cli.dev({ webBuild: () => web.cli.build() });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
type WebBuild = () => Promise<unknown>;
|
|
105
|
+
/** deploy plugin configuration. Flat; complete defaults so omission never yields undefined. */
|
|
106
|
+
type Config$1 = {
|
|
107
|
+
/**
|
|
108
|
+
* Wrangler config file generated/updated and read by `wrangler deploy`. Default "wrangler.jsonc".
|
|
109
|
+
* Also the file parsed in the universal/non-moku path.
|
|
110
|
+
*/
|
|
111
|
+
configFile: string;
|
|
112
|
+
/**
|
|
113
|
+
* The Worker entry module → wrangler `main` (e.g. "src/cloudflare/worker.ts"). Required for any
|
|
114
|
+
* real Worker deploy (its absence is wrangler's "Missing entry-point" error).
|
|
115
|
+
*/
|
|
116
|
+
entry?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Enable Node.js compat → `compatibility_flags: ["nodejs_compat"]`. Needed when the Worker bundle
|
|
119
|
+
* pulls in Node-flavored code (e.g. composing the deploy/cli tooling into the runtime app).
|
|
120
|
+
*/
|
|
121
|
+
nodeCompat?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Static assets served via `env.<binding>` → the wrangler `assets` block. `spa: true` sets
|
|
124
|
+
* `not_found_handling: "single-page-application"` so client-routed deep links resolve to index.html.
|
|
125
|
+
*/
|
|
126
|
+
assets?: {
|
|
127
|
+
binding: string;
|
|
128
|
+
directory: string;
|
|
129
|
+
spa?: boolean;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Escape hatch — extra top-level wrangler keys merged into the generated config for anything the
|
|
133
|
+
* typed fields above don't cover (`vars`, `routes`, `observability`, `triggers`, …). The
|
|
134
|
+
* deploy-managed resource keys (name, compatibility_date, kv_namespaces, r2_buckets, d1_databases,
|
|
135
|
+
* queues, durable_objects, and the auto-derived Durable Object `migrations`) always win over these.
|
|
136
|
+
*/
|
|
137
|
+
wrangler?: Record<string, unknown>;
|
|
138
|
+
/**
|
|
139
|
+
* Standing CI/automated default for `run()`. When true (or when stdout is non-TTY) the deploy
|
|
140
|
+
* never prompts and auto-confirms every gate; `run({ ci })` overrides it per call. CF credentials
|
|
141
|
+
* are read from the env (CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID) via `ctx.env`. Default false.
|
|
142
|
+
*/
|
|
143
|
+
ci: boolean; /** Globs watched by `dev()` to trigger a Moku-site rebuild. */
|
|
144
|
+
watch: string[];
|
|
145
|
+
/**
|
|
146
|
+
* Standing default web-site build hook (e.g. `() => webApp.cli.build()`). Usually passed
|
|
147
|
+
* call-time to `dev` / `deploy` via `opts.webBuild` (the script-driven path); set here only for
|
|
148
|
+
* a persistent default. When absent, dev() falls back to `buildCommand`, then auto-detects
|
|
149
|
+
* `scripts/build.ts`.
|
|
150
|
+
*/
|
|
151
|
+
webBuild?: WebBuild; /** Shell rebuild fallback (e.g. "bun run scripts/build.ts"); empty → auto-detect scripts/build.ts. */
|
|
152
|
+
buildCommand: string; /** Apply local D1 migrations before serving when a d1 manifest is present. */
|
|
153
|
+
migrateLocal: boolean; /** Debounce window (ms) coalescing rapid file changes into one rebuild. */
|
|
154
|
+
debounceMs: number;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Discriminated union of per-INSTANCE resource descriptors. Each resource plugin's `deployManifest()`
|
|
158
|
+
* returns an ARRAY of these (one per configured instance). `name` is the base Cloudflare resource
|
|
159
|
+
* name (stage-suffixed downstream via {@link stageName}); `binding` is the stable env var. Durable
|
|
160
|
+
* Objects carry no provisioned `name` — they ship with the Worker script — and declare the exported
|
|
161
|
+
* `className` instead.
|
|
162
|
+
*/
|
|
163
|
+
type ResourceManifest = {
|
|
164
|
+
kind: "r2";
|
|
165
|
+
name: string;
|
|
166
|
+
binding: string;
|
|
167
|
+
upload?: string;
|
|
168
|
+
} | {
|
|
169
|
+
kind: "kv";
|
|
170
|
+
name: string;
|
|
171
|
+
binding: string;
|
|
172
|
+
} | {
|
|
173
|
+
kind: "d1";
|
|
174
|
+
name: string;
|
|
175
|
+
binding: string;
|
|
176
|
+
migrations?: string;
|
|
177
|
+
} | {
|
|
178
|
+
kind: "queue";
|
|
179
|
+
name: string;
|
|
180
|
+
binding: string;
|
|
181
|
+
} | {
|
|
182
|
+
kind: "do";
|
|
183
|
+
binding: string;
|
|
184
|
+
className: string;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* The whole deploy manifest the pipeline consumes (assembled, or caller-supplied for the
|
|
188
|
+
* universal path).
|
|
189
|
+
*/
|
|
190
|
+
type ExternalManifest = {
|
|
191
|
+
/** Worker name. */name: string; /** Cloudflare compatibility date. */
|
|
192
|
+
compatibilityDate: string; /** Resource descriptors to provision. */
|
|
193
|
+
resources: ResourceManifest[];
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* A resource that already exists in the account (the infra preflight discovered it), with its
|
|
197
|
+
* captured Cloudflare id when the kind has one (kv namespace id, d1 database id).
|
|
198
|
+
*/
|
|
199
|
+
type ProvisionedRef = {
|
|
200
|
+
/** The resource descriptor from the manifest. */resource: ResourceManifest; /** The existing resource's Cloudflare id (kv/d1 only). */
|
|
201
|
+
id?: string;
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Read-only infra preflight result: which declared resources already exist in the Cloudflare
|
|
205
|
+
* account versus which are still missing and must be created. Produced by `checkInfra()`.
|
|
206
|
+
*/
|
|
207
|
+
type InfraPlan = {
|
|
208
|
+
/** Resolved account display name (or id when the name is unknown). */account: string; /** Resolved Cloudflare account id used for the existence checks. */
|
|
209
|
+
accountId: string; /** Declared resources that already exist (with their captured ids where applicable). */
|
|
210
|
+
exists: ProvisionedRef[]; /** Declared resources that do not yet exist and must be created. */
|
|
211
|
+
missing: ResourceManifest[];
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* A resource that failed to provision, with the (branded) error message captured so the guided flow
|
|
215
|
+
* can show WHICH resource failed and why — instead of aborting the whole run on the first failure.
|
|
216
|
+
*/
|
|
217
|
+
type ProvisionFailure = {
|
|
218
|
+
/** The resource descriptor that failed to create. */resource: ResourceManifest; /** The captured error message (e.g. the branded wrangler failure). */
|
|
219
|
+
error: string;
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Outcome of acting on an {@link InfraPlan}: the resources just created, those skipped because they
|
|
223
|
+
* already existed, those that FAILED to create, and the merged id map (binding → Cloudflare id) for
|
|
224
|
+
* the config writer. Provisioning is resilient — a single resource failure is captured here, not
|
|
225
|
+
* thrown, so the guided flow can report a clear per-resource result.
|
|
226
|
+
*/
|
|
227
|
+
type ProvisionResult = {
|
|
228
|
+
/** Resources created during this run. */created: ProvisionedRef[]; /** Resources skipped because they already existed. */
|
|
229
|
+
skipped: ProvisionedRef[]; /** Resources that failed to create (captured, not thrown). */
|
|
230
|
+
failed: ProvisionFailure[]; /** Merged binding → Cloudflare id map (existing + created) for writeWranglerConfig. */
|
|
231
|
+
ids: Record<string, string>;
|
|
232
|
+
};
|
|
233
|
+
/** Result of verifying the `.env` Cloudflare API token and resolving its account. */
|
|
234
|
+
type AuthStatus = {
|
|
235
|
+
/** Whether the token is present and active. */ok: boolean; /** Resolved account display name (or id when the name is unknown). */
|
|
236
|
+
account: string; /** Resolved Cloudflare account id. */
|
|
237
|
+
accountId: string; /** Token scopes, when discoverable (empty otherwise). */
|
|
238
|
+
scopes: string[];
|
|
239
|
+
};
|
|
240
|
+
/** One Cloudflare API-token permission group the app's manifest requires. */
|
|
241
|
+
type PermissionGroup = {
|
|
242
|
+
/** Human-readable group label, e.g. "Account · D1". */group: string; /** Permission scope. */
|
|
243
|
+
scope: "Edit" | "Read"; /** Why it is required, e.g. "d1", "queue", "deploy", "account". */
|
|
244
|
+
reason: string; /** Whether Cloudflare's stock "Edit Cloudflare Workers" template already includes it. */
|
|
245
|
+
inBaseTemplate: boolean;
|
|
246
|
+
};
|
|
247
|
+
/** The Cloudflare API token this app requires, derived from its manifest. */
|
|
248
|
+
type TokenRequirement = {
|
|
249
|
+
/** The recommended starting template. */base: "Edit Cloudflare Workers"; /** The full set of permission groups required. */
|
|
250
|
+
required: PermissionGroup[]; /** Groups NOT in the base template that the user must add (e.g. D1, Queues). */
|
|
251
|
+
toAdd: PermissionGroup[];
|
|
252
|
+
};
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/plugins/cli/types.d.ts
|
|
255
|
+
/** Resolved configuration for the cli plugin. Flat; complete defaults so omission never yields undefined. */
|
|
256
|
+
type Config = {
|
|
257
|
+
/**
|
|
258
|
+
* Default local dev port forwarded to deploy.dev when dev() gets no port.
|
|
259
|
+
* Passed through to `wrangler dev --port <n>`.
|
|
260
|
+
*
|
|
261
|
+
* @default 8787
|
|
262
|
+
*/
|
|
263
|
+
readonly port: number;
|
|
264
|
+
};
|
|
265
|
+
/** Public api surface of the cli plugin, mounted at app.cli.*. */
|
|
266
|
+
type Api = {
|
|
267
|
+
/**
|
|
268
|
+
* Run the Worker locally via Wrangler (delegates to deploy.dev). Resolves the port from
|
|
269
|
+
* `opts.port`, else a `--port <n>` CLI flag, else the configured default (8787). A failure renders
|
|
270
|
+
* a branded `✗` line and sets a non-zero exit code rather than throwing a raw stack trace.
|
|
271
|
+
*
|
|
272
|
+
* @param opts - Optional port override and web build hook.
|
|
273
|
+
* @param opts.port - Local dev port to bind (overrides the `--port` flag and the default).
|
|
274
|
+
* @param opts.webBuild - Rebuild the web site on change (e.g. `() => webApp.cli.build()`).
|
|
275
|
+
* @returns Resolves when the dev session ends.
|
|
276
|
+
* @example
|
|
277
|
+
* ```ts
|
|
278
|
+
* await app.cli.dev({ webBuild: () => web.cli.build() }); // port from --port or 8787
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
dev(opts?: {
|
|
282
|
+
port?: number;
|
|
283
|
+
webBuild?: WebBuild;
|
|
284
|
+
}): Promise<void>;
|
|
285
|
+
/**
|
|
286
|
+
* One-command Cloudflare deploy (delegates to deploy.run). Guided/interactive by default; pass
|
|
287
|
+
* `{ ci: true }` for the automated/non-interactive path (CI). A failure renders a branded `✗`
|
|
288
|
+
* line and sets a non-zero exit code rather than throwing a raw stack trace.
|
|
289
|
+
*
|
|
290
|
+
* @param opts - Optional ci flag and a web build hook.
|
|
291
|
+
* @param opts.ci - Automated mode: never prompts, auto-confirms. Omit/false → guided on a TTY.
|
|
292
|
+
* @param opts.webBuild - Build the web site first (e.g. `() => webApp.cli.build()`), before deploy.
|
|
293
|
+
* @returns Resolves once the deploy completes (or after a failure is rendered).
|
|
294
|
+
* @example
|
|
295
|
+
* ```ts
|
|
296
|
+
* await app.cli.deploy({ webBuild: () => web.cli.build() }); // guided
|
|
297
|
+
* await app.cli.deploy({ ci: true, webBuild: () => web.cli.build() }); // CI
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
deploy(opts?: {
|
|
301
|
+
ci?: boolean;
|
|
302
|
+
webBuild?: WebBuild;
|
|
303
|
+
}): Promise<void>;
|
|
304
|
+
/**
|
|
305
|
+
* Verify the `.env` Cloudflare token (no sub), or print the config-derived token-creation
|
|
306
|
+
* guidance (`"setup"`). Delegates to deploy.verifyAuth() / deploy.tokenInstructions().
|
|
307
|
+
*
|
|
308
|
+
* @param sub - Pass "setup" to print token guidance; omit to verify the current token.
|
|
309
|
+
* @returns Resolves once the auth check or guidance render completes.
|
|
310
|
+
* @example
|
|
311
|
+
* ```ts
|
|
312
|
+
* await app.cli.auth(); // verify the current token
|
|
313
|
+
* await app.cli.auth("setup"); // print what token to create
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
auth(sub?: "setup"): Promise<void>;
|
|
317
|
+
/**
|
|
318
|
+
* One-shot preflight report: token + account (verifyAuth) and infra drift (checkInfra),
|
|
319
|
+
* each rendered as a branded check line.
|
|
320
|
+
*
|
|
321
|
+
* @returns Resolves once the report is printed.
|
|
322
|
+
* @example
|
|
323
|
+
* ```ts
|
|
324
|
+
* await app.cli.doctor();
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
doctor(): Promise<void>;
|
|
328
|
+
/**
|
|
329
|
+
* Print the resolved Cloudflare account for the current `.env` token (delegates to verifyAuth).
|
|
330
|
+
*
|
|
331
|
+
* @returns Resolves once the account summary is printed.
|
|
332
|
+
* @example
|
|
333
|
+
* ```ts
|
|
334
|
+
* await app.cli.whoami();
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
whoami(): Promise<void>;
|
|
338
|
+
/**
|
|
339
|
+
* Run an arbitrary `wrangler` command through the branded CLI — the escape hatch for subcommands
|
|
340
|
+
* Moku does not wrap (kv / d1 / r2 / queues / secret / tail / …). Streams wrangler's output.
|
|
341
|
+
*
|
|
342
|
+
* @param args - The wrangler arguments (e.g. ["kv", "namespace", "list"]).
|
|
343
|
+
* @returns Resolves once wrangler exits.
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* await app.cli.wrangler(["kv", "namespace", "list"]);
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
wrangler(args: string[]): Promise<void>;
|
|
350
|
+
};
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/plugins/cli/index.d.ts
|
|
353
|
+
/**
|
|
354
|
+
* Standard tier (node-only) — developer-facing CLI surface.
|
|
355
|
+
*
|
|
356
|
+
* Mounts `app.cli.dev()` and `app.cli.deploy()` as thin passthroughs to deployPlugin.
|
|
357
|
+
* Hooks subscribe to the global deploy:phase / provision:resource / deploy:complete events
|
|
358
|
+
* and print a live progress TUI via the injected ctx.log core API.
|
|
359
|
+
*
|
|
360
|
+
* Inline lambdas on `api`/`hooks` preserve event-name inference so the hook map keys
|
|
361
|
+
* are constrained to `WorkerEvents` keys (spec/15 §5).
|
|
362
|
+
*
|
|
363
|
+
* @see README.md
|
|
364
|
+
*/
|
|
365
|
+
declare const cliPlugin: import("@moku-labs/core").PluginInstance<"cli", Config, Record<string, never>, Api, {}> & Record<never, never>;
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region src/plugins/deploy/index.d.ts
|
|
368
|
+
/**
|
|
369
|
+
* Complex tier (node-only) — build-time deploy orchestrator over the five resource plugins.
|
|
370
|
+
*
|
|
371
|
+
* Assembles each resource plugin's deployManifest() via ctx.require, provisions resources,
|
|
372
|
+
* generates/updates wrangler config, uploads the R2 upload dir, and runs wrangler deploy.
|
|
373
|
+
* Also supports a universal path: run({ manifest }) uses a caller-supplied manifest verbatim.
|
|
374
|
+
*
|
|
375
|
+
* Emits only the global events `deploy:phase`, `deploy:complete`, and `provision:resource`
|
|
376
|
+
* (declared in WorkerEvents — no per-plugin events block).
|
|
377
|
+
*
|
|
378
|
+
* @see README.md
|
|
379
|
+
*/
|
|
380
|
+
declare const deployPlugin: import("@moku-labs/core").PluginInstance<"deploy", Config$1, Record<string, never>, {
|
|
381
|
+
run(opts?: {
|
|
382
|
+
ci?: boolean;
|
|
383
|
+
stage?: string;
|
|
384
|
+
webBuild?: WebBuild;
|
|
385
|
+
manifest?: ExternalManifest;
|
|
386
|
+
}): Promise<void>;
|
|
387
|
+
dev(opts?: {
|
|
388
|
+
port?: number;
|
|
389
|
+
stage?: string;
|
|
390
|
+
webBuild?: WebBuild;
|
|
391
|
+
}): Promise<void>;
|
|
392
|
+
init: (opts?: {
|
|
393
|
+
ci?: boolean;
|
|
394
|
+
}) => Promise<void>;
|
|
395
|
+
checkInfra: () => Promise<InfraPlan>;
|
|
396
|
+
provisionInfra: (plan: InfraPlan) => Promise<ProvisionResult>;
|
|
397
|
+
verifyAuth: () => Promise<AuthStatus>;
|
|
398
|
+
requiredToken: () => TokenRequirement;
|
|
399
|
+
ciToken: () => PermissionGroup[];
|
|
400
|
+
tokenInstructions: () => string;
|
|
401
|
+
wrangler: (args: string[]) => Promise<void>;
|
|
402
|
+
}, {}> & Record<never, never>;
|
|
403
|
+
//#endregion
|
|
404
|
+
export { WorkerConfig as a, WorkerPluginCtx as c, ResourceManifest as i, cliPlugin as n, WorkerEnv as o, ExternalManifest as r, WorkerEvents as s, deployPlugin as t };
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_cli = require("./cli-C8DdTtzn.cjs");
|
|
3
3
|
let _moku_labs_common = require("@moku-labs/common");
|
|
4
|
+
//#region src/env-provider.ts
|
|
5
|
+
/**
|
|
6
|
+
* Build the default env provider: a shallow copy of `process.env` when a `process` global exists,
|
|
7
|
+
* else an empty record. Safe to evaluate at Worker cold start — it never throws on a missing
|
|
8
|
+
* `process` (typeof of an undeclared identifier is the string "undefined", not a ReferenceError).
|
|
9
|
+
*
|
|
10
|
+
* @returns An {@link EnvProvider} named `worker-process-env`.
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // wired by createApp so `ctx.env.get("CLOUDFLARE_API_TOKEN")` resolves under Bun/Node
|
|
14
|
+
* const provider = workerSafeProcessEnv();
|
|
15
|
+
* provider.load().CLOUDFLARE_API_TOKEN;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
const workerSafeProcessEnv = () => ({
|
|
19
|
+
name: "worker-process-env",
|
|
20
|
+
/**
|
|
21
|
+
* Read a shallow copy of `process.env`, or `{}` when there is no `process` global (workerd
|
|
22
|
+
* without nodejs_compat). Never throws at cold start.
|
|
23
|
+
*
|
|
24
|
+
* @returns The current environment as a flat record (empty when `process` is absent).
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* workerSafeProcessEnv().load();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
load() {
|
|
31
|
+
return typeof process === "undefined" ? {} : { ...process.env };
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
//#endregion
|
|
4
35
|
//#region src/plugins/server/api.ts
|
|
5
36
|
/**
|
|
6
37
|
* Builds the `app.server.*` surface the consumer's Worker default export reads.
|
|
@@ -471,9 +502,9 @@ const createServerState = (endpoints) => {
|
|
|
471
502
|
*
|
|
472
503
|
* @see README.md
|
|
473
504
|
*/
|
|
474
|
-
const serverPlugin =
|
|
505
|
+
const serverPlugin = require_cli.createPlugin("server", {
|
|
475
506
|
events: (register) => register.map({ "server:matched": "An endpoint matched a request" }),
|
|
476
|
-
depends: [
|
|
507
|
+
depends: [require_cli.bindingsPlugin],
|
|
477
508
|
config: { endpoints: [] },
|
|
478
509
|
createState: ({ config }) => createServerState(config.endpoints),
|
|
479
510
|
api: (ctx) => createServerApi(ctx),
|
|
@@ -484,51 +515,7 @@ const serverPlugin = require_storage.createPlugin("server", {
|
|
|
484
515
|
});
|
|
485
516
|
//#endregion
|
|
486
517
|
//#region src/index.ts
|
|
487
|
-
|
|
488
|
-
* @file `@moku-labs/worker` — server-side Cloudflare Workers app + deploy framework on `@moku-labs/core`.
|
|
489
|
-
*
|
|
490
|
-
* The package root exports the bound {@link createApp} factory (the Layer-3 entry
|
|
491
|
-
* point), {@link createPlugin} for consumer plugins, every runtime plugin instance,
|
|
492
|
-
* the `server`/`durable-objects` helpers, and the framework types. Node-only tooling
|
|
493
|
-
* (`deploy`, `cli`) ships from the separate `@moku-labs/worker/cli` entry, never here.
|
|
494
|
-
*
|
|
495
|
-
* `createApp(options?)` boots a fully-typed, synchronous, per-isolate app. The
|
|
496
|
-
* framework defaults `[logPlugin, envPlugin, stagePlugin, bindingsPlugin, serverPlugin]`
|
|
497
|
-
* are applied first, then the `options` below are shallow-merged on top:
|
|
498
|
-
*
|
|
499
|
-
* - `config` — `Partial<WorkerConfig>`; defaults `{ stage: "production", name: "moku-worker", compatibilityDate: "" }`.
|
|
500
|
-
* `config.stage` is the single stage source: the framework mirrors it into the `stage` core
|
|
501
|
-
* plugin so `ctx.stage.*` / `app.stage.*` stay in lockstep with `ctx.global.stage` (see {@link createApp}).
|
|
502
|
-
* - `pluginConfigs` — per-plugin config overrides keyed by plugin name (e.g. `server.endpoints`, `bindings.required`); default `{}`.
|
|
503
|
-
* - `plugins` — extra `PluginInstance[]` appended to the defaults; default `[]`. Do NOT re-list a default plugin.
|
|
504
|
-
* - `onReady` — optional `(app) => void`, runs after every plugin's `onInit`.
|
|
505
|
-
* - `onError` — optional `(error) => void` boot/lifecycle error handler.
|
|
506
|
-
* - `onStart` / `onStop` — optional `() => void | Promise<void>` runtime lifecycle hooks (`app.start()` / `app.stop()`).
|
|
507
|
-
*
|
|
508
|
-
* Re-listing a default plugin name in `plugins` throws
|
|
509
|
-
* `TypeError: [moku-worker] Duplicate plugin name: "<name>"` — `bindings` and `server`
|
|
510
|
-
* are already wired, so consumers list only the resource plugins they add (`kv`, `d1`, …).
|
|
511
|
-
*
|
|
512
|
-
* Minimal HTTP Worker (shape taken from the server integration test):
|
|
513
|
-
*
|
|
514
|
-
* ```typescript
|
|
515
|
-
* import { createApp, endpoint } from "@moku-labs/worker";
|
|
516
|
-
*
|
|
517
|
-
* export const app = createApp({
|
|
518
|
-
* config: { name: "my-worker", compatibilityDate: "2024-09-23" },
|
|
519
|
-
* pluginConfigs: {
|
|
520
|
-
* server: { endpoints: [endpoint("/health").get(() => new Response("ok"))] }
|
|
521
|
-
* }
|
|
522
|
-
* });
|
|
523
|
-
*
|
|
524
|
-
* // worker.ts — the default export is hand-assembled; no plugin produces it.
|
|
525
|
-
* export default {
|
|
526
|
-
* fetch: (request: Request, env: Record<string, unknown>, ctx: ExecutionContext) =>
|
|
527
|
-
* app.server.handle(request, env, ctx)
|
|
528
|
-
* } satisfies ExportedHandler;
|
|
529
|
-
* ```
|
|
530
|
-
*/
|
|
531
|
-
const framework = require_storage.createCore(require_storage.coreConfig, { plugins: [require_storage.bindingsPlugin, serverPlugin] });
|
|
518
|
+
const framework = require_cli.createCore(require_cli.coreConfig, { plugins: [require_cli.bindingsPlugin, serverPlugin] });
|
|
532
519
|
const { createPlugin } = framework;
|
|
533
520
|
/** The core-bound app factory; wrapped by {@link createApp} to bridge `config.stage`. */
|
|
534
521
|
const boundCreateApp = framework.createApp;
|
|
@@ -544,8 +531,11 @@ const boundCreateApp = framework.createApp;
|
|
|
544
531
|
* that sees the consumer's chosen stage, so it mirrors `config.stage` into the stage
|
|
545
532
|
* plugin's level-4 `pluginConfigs` override (`WorkerConfig.stage → pluginConfigs.stage.stage`).
|
|
546
533
|
* When `config.stage` is omitted, the global config and the stage plugin both fall back
|
|
547
|
-
* to their identical `"production"` default.
|
|
548
|
-
*
|
|
534
|
+
* to their identical `"production"` default. It ALSO wires a default workerd-safe
|
|
535
|
+
* {@link workerSafeProcessEnv} provider into the `env` core plugin (same bridge mechanism) so
|
|
536
|
+
* deploy/auth can read `CLOUDFLARE_API_TOKEN` and friends via `ctx.env` — without it the env plugin
|
|
537
|
+
* has zero providers and every `ctx.env` read is undefined. See the module JSDoc above for the
|
|
538
|
+
* full options/defaults table.
|
|
549
539
|
*
|
|
550
540
|
* @param options - The createApp options (`config`, `pluginConfigs`, `plugins`, and lifecycle callbacks).
|
|
551
541
|
* @returns The initialized app — every plugin's `onInit` has already run.
|
|
@@ -553,26 +543,34 @@ const boundCreateApp = framework.createApp;
|
|
|
553
543
|
* ```typescript
|
|
554
544
|
* const app = createApp({ config: { stage: "development", name: "my-worker" } });
|
|
555
545
|
* app.stage.isDev(); // true — bridged from config.stage
|
|
546
|
+
* app.env.get("CLOUDFLARE_API_TOKEN"); // read from process.env via the default env provider
|
|
556
547
|
* ```
|
|
557
548
|
*/
|
|
558
549
|
const createApp = (options) => {
|
|
559
550
|
const explicitStage = options?.config?.stage;
|
|
560
|
-
|
|
551
|
+
const provided = options?.pluginConfigs;
|
|
552
|
+
const pluginConfigs = {
|
|
553
|
+
...options?.pluginConfigs,
|
|
554
|
+
env: {
|
|
555
|
+
...provided?.env,
|
|
556
|
+
providers: provided?.env?.providers ?? [workerSafeProcessEnv()]
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
if (explicitStage !== void 0) pluginConfigs.stage = { stage: explicitStage };
|
|
561
560
|
return boundCreateApp({
|
|
562
561
|
...options,
|
|
563
|
-
pluginConfigs
|
|
564
|
-
...options?.pluginConfigs,
|
|
565
|
-
stage: { stage: explicitStage }
|
|
566
|
-
}
|
|
562
|
+
pluginConfigs
|
|
567
563
|
});
|
|
568
564
|
};
|
|
569
565
|
//#endregion
|
|
570
|
-
exports.bindingsPlugin =
|
|
566
|
+
exports.bindingsPlugin = require_cli.bindingsPlugin;
|
|
567
|
+
exports.cliPlugin = require_cli.cliPlugin;
|
|
571
568
|
exports.createApp = createApp;
|
|
572
569
|
exports.createPlugin = createPlugin;
|
|
573
|
-
exports.d1Plugin =
|
|
574
|
-
exports.defineDurableObject =
|
|
575
|
-
exports.
|
|
570
|
+
exports.d1Plugin = require_cli.d1Plugin;
|
|
571
|
+
exports.defineDurableObject = require_cli.defineDurableObject;
|
|
572
|
+
exports.deployPlugin = require_cli.deployPlugin;
|
|
573
|
+
exports.durableObjectsPlugin = require_cli.durableObjectsPlugin;
|
|
576
574
|
exports.endpoint = endpoint;
|
|
577
575
|
Object.defineProperty(exports, "envPlugin", {
|
|
578
576
|
enumerable: true,
|
|
@@ -580,14 +578,14 @@ Object.defineProperty(exports, "envPlugin", {
|
|
|
580
578
|
return _moku_labs_common.envPlugin;
|
|
581
579
|
}
|
|
582
580
|
});
|
|
583
|
-
exports.kvPlugin =
|
|
581
|
+
exports.kvPlugin = require_cli.kvPlugin;
|
|
584
582
|
Object.defineProperty(exports, "logPlugin", {
|
|
585
583
|
enumerable: true,
|
|
586
584
|
get: function() {
|
|
587
585
|
return _moku_labs_common.logPlugin;
|
|
588
586
|
}
|
|
589
587
|
});
|
|
590
|
-
exports.queuesPlugin =
|
|
588
|
+
exports.queuesPlugin = require_cli.queuesPlugin;
|
|
591
589
|
exports.serverPlugin = serverPlugin;
|
|
592
|
-
exports.stagePlugin =
|
|
593
|
-
exports.storagePlugin =
|
|
590
|
+
exports.stagePlugin = require_cli.stagePlugin;
|
|
591
|
+
exports.storagePlugin = require_cli.storagePlugin;
|