alchemy 0.20.1 → 0.21.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/lib/cloudflare/bound.d.ts +4 -1
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +110 -26
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +15 -7
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +19 -15
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +2 -0
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +3 -0
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +1 -1
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +4 -0
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/type.d.ts +6 -0
- package/lib/type.d.ts.map +1 -0
- package/lib/type.js +7 -0
- package/lib/type.js.map +1 -0
- package/package.json +1 -1
- package/src/cloudflare/bound.ts +45 -35
- package/src/cloudflare/worker-metadata.ts +129 -38
- package/src/cloudflare/worker.ts +135 -93
- package/src/cloudflare/workflow.ts +5 -0
- package/src/cloudflare/wrangler.json.ts +5 -1
- package/src/index.ts +1 -0
- package/src/type.ts +9 -0
package/src/cloudflare/worker.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { bootstrapPlugin } from "../runtime/plugin.js";
|
|
|
8
8
|
import { Scope } from "../scope.js";
|
|
9
9
|
import { Secret, secret } from "../secret.js";
|
|
10
10
|
import { serializeScope } from "../serde.js";
|
|
11
|
+
import type { type } from "../type.js";
|
|
11
12
|
import { withExponentialBackoff } from "../util/retry.js";
|
|
12
13
|
import { slugify } from "../util/slugify.js";
|
|
13
14
|
import { CloudflareApiError, handleApiError } from "./api-error.js";
|
|
@@ -17,7 +18,12 @@ import {
|
|
|
17
18
|
createCloudflareApi,
|
|
18
19
|
} from "./api.js";
|
|
19
20
|
import type { Assets } from "./assets.js";
|
|
20
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
type Binding,
|
|
23
|
+
type Bindings,
|
|
24
|
+
Json,
|
|
25
|
+
type WorkerBindingSpec,
|
|
26
|
+
} from "./bindings.js";
|
|
21
27
|
import type { Bound } from "./bound.js";
|
|
22
28
|
import { isBucket } from "./bucket.js";
|
|
23
29
|
import { bundleWorkerScript } from "./bundle/bundle-worker.js";
|
|
@@ -94,8 +100,10 @@ export interface AssetsConfig {
|
|
|
94
100
|
serve_directly?: boolean;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
export interface BaseWorkerProps<
|
|
98
|
-
extends
|
|
103
|
+
export interface BaseWorkerProps<
|
|
104
|
+
B extends Bindings | undefined = undefined,
|
|
105
|
+
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
106
|
+
> extends CloudflareApiOptions {
|
|
99
107
|
/**
|
|
100
108
|
* Bundle options when using entryPoint
|
|
101
109
|
*
|
|
@@ -202,17 +210,27 @@ export interface BaseWorkerProps<B extends Bindings | undefined = undefined>
|
|
|
202
210
|
* Can include queues, streams, or other event sources.
|
|
203
211
|
*/
|
|
204
212
|
eventSources?: EventSource[];
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The RPC class to use for the worker.
|
|
216
|
+
*
|
|
217
|
+
* This is only used when using the rpc property.
|
|
218
|
+
*/
|
|
219
|
+
rpc?: (new (...args: any[]) => RPC) | type<RPC>;
|
|
205
220
|
}
|
|
206
221
|
|
|
207
|
-
export interface InlineWorkerProps<
|
|
208
|
-
extends
|
|
222
|
+
export interface InlineWorkerProps<
|
|
223
|
+
B extends Bindings | undefined = Bindings,
|
|
224
|
+
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
225
|
+
> extends BaseWorkerProps<B, RPC> {
|
|
209
226
|
script: string;
|
|
210
227
|
entrypoint?: undefined;
|
|
211
228
|
}
|
|
212
229
|
|
|
213
230
|
export interface EntrypointWorkerProps<
|
|
214
231
|
B extends Bindings | undefined = Bindings,
|
|
215
|
-
|
|
232
|
+
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
233
|
+
> extends BaseWorkerProps<B, RPC> {
|
|
216
234
|
entrypoint: string;
|
|
217
235
|
script?: undefined;
|
|
218
236
|
}
|
|
@@ -220,9 +238,10 @@ export interface EntrypointWorkerProps<
|
|
|
220
238
|
/**
|
|
221
239
|
* Properties for creating or updating a Worker
|
|
222
240
|
*/
|
|
223
|
-
export type WorkerProps<
|
|
224
|
-
|
|
|
225
|
-
|
|
241
|
+
export type WorkerProps<
|
|
242
|
+
B extends Bindings | undefined = Bindings,
|
|
243
|
+
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
244
|
+
> = InlineWorkerProps<B, RPC> | EntrypointWorkerProps<B, RPC>;
|
|
226
245
|
|
|
227
246
|
export type FetchWorkerProps<
|
|
228
247
|
B extends Bindings = Bindings,
|
|
@@ -270,65 +289,70 @@ export function isWorker(resource: Resource): resource is Worker<any> {
|
|
|
270
289
|
/**
|
|
271
290
|
* Output returned after Worker creation/update
|
|
272
291
|
*/
|
|
273
|
-
export type Worker<
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
*/
|
|
282
|
-
id: string;
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* The name of the worker
|
|
286
|
-
*/
|
|
287
|
-
name: string;
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Time at which the worker was created
|
|
291
|
-
*/
|
|
292
|
-
createdAt: number;
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Time at which the worker was last updated
|
|
296
|
-
*/
|
|
297
|
-
updatedAt: number;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* The worker's URL if enabled
|
|
301
|
-
* Format: {name}.{subdomain}.workers.dev
|
|
302
|
-
*/
|
|
303
|
-
url?: string;
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* The bindings that were created
|
|
307
|
-
*/
|
|
308
|
-
bindings: B;
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Configuration for static assets
|
|
312
|
-
*/
|
|
313
|
-
assets?: AssetsConfig;
|
|
314
|
-
|
|
315
|
-
// phantom property (for typeof myWorker.Env)
|
|
316
|
-
Env: B extends Bindings
|
|
317
|
-
? {
|
|
318
|
-
[bindingName in keyof B]: Bound<B[bindingName]>;
|
|
319
|
-
}
|
|
320
|
-
: undefined;
|
|
292
|
+
export type Worker<
|
|
293
|
+
B extends Bindings | undefined = Bindings | undefined,
|
|
294
|
+
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
295
|
+
> = Resource<"cloudflare::Worker"> &
|
|
296
|
+
Omit<WorkerProps<B>, "url" | "script"> &
|
|
297
|
+
globalThis.Service & {
|
|
298
|
+
/** @internal phantom property */
|
|
299
|
+
__rpc__?: RPC;
|
|
321
300
|
|
|
322
|
-
|
|
323
|
-
* The compatibility date for the worker
|
|
324
|
-
*/
|
|
325
|
-
compatibilityDate: string;
|
|
301
|
+
type: "service";
|
|
326
302
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
303
|
+
/**
|
|
304
|
+
* The ID of the worker
|
|
305
|
+
*/
|
|
306
|
+
id: string;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* The name of the worker
|
|
310
|
+
*/
|
|
311
|
+
name: string;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Time at which the worker was created
|
|
315
|
+
*/
|
|
316
|
+
createdAt: number;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Time at which the worker was last updated
|
|
320
|
+
*/
|
|
321
|
+
updatedAt: number;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The worker's URL if enabled
|
|
325
|
+
* Format: {name}.{subdomain}.workers.dev
|
|
326
|
+
*/
|
|
327
|
+
url?: string;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* The bindings that were created
|
|
331
|
+
*/
|
|
332
|
+
bindings: B;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Configuration for static assets
|
|
336
|
+
*/
|
|
337
|
+
assets?: AssetsConfig;
|
|
338
|
+
|
|
339
|
+
// phantom property (for typeof myWorker.Env)
|
|
340
|
+
Env: B extends Bindings
|
|
341
|
+
? {
|
|
342
|
+
[bindingName in keyof B]: Bound<B[bindingName]>;
|
|
343
|
+
}
|
|
344
|
+
: undefined;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* The compatibility date for the worker
|
|
348
|
+
*/
|
|
349
|
+
compatibilityDate: string;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* The compatibility flags for the worker
|
|
353
|
+
*/
|
|
354
|
+
compatibilityFlags: string[];
|
|
355
|
+
};
|
|
332
356
|
|
|
333
357
|
/**
|
|
334
358
|
* A Cloudflare Worker is a serverless function that can be deployed to the Cloudflare network.
|
|
@@ -445,10 +469,10 @@ export type Worker<B extends Bindings | undefined = Bindings | undefined> =
|
|
|
445
469
|
* @see
|
|
446
470
|
* https://developers.cloudflare.com/workers/
|
|
447
471
|
*/
|
|
448
|
-
export function Worker<
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
): Promise<Worker<B>>;
|
|
472
|
+
export function Worker<
|
|
473
|
+
const B extends Bindings,
|
|
474
|
+
RPC extends Rpc.WorkerEntrypointBranded,
|
|
475
|
+
>(id: string, props: WorkerProps<B, RPC>): Promise<Worker<B, RPC>>;
|
|
452
476
|
export function Worker<const B extends Bindings, const E extends EventSource[]>(
|
|
453
477
|
id: string,
|
|
454
478
|
meta: ImportMeta,
|
|
@@ -461,6 +485,7 @@ export function Worker<const B extends Bindings>(
|
|
|
461
485
|
): Promise<Worker<B>> {
|
|
462
486
|
const [id, meta, props] =
|
|
463
487
|
args.length === 2 ? [args[0], undefined, args[1]] : args;
|
|
488
|
+
|
|
464
489
|
if (("fetch" in props && props.fetch) || ("queue" in props && props.queue)) {
|
|
465
490
|
const scope = Scope.current;
|
|
466
491
|
|
|
@@ -678,7 +703,11 @@ export const _Worker = Resource(
|
|
|
678
703
|
const compatibilityFlags = props.compatibilityFlags ?? [];
|
|
679
704
|
|
|
680
705
|
const uploadWorkerScript = async (props: WorkerProps<B>) => {
|
|
681
|
-
const oldBindings = await
|
|
706
|
+
const [oldBindings, oldMetadata] = await Promise.all([
|
|
707
|
+
getWorkerBindings(api, workerName),
|
|
708
|
+
getWorkerScriptMetadata(api, workerName),
|
|
709
|
+
]);
|
|
710
|
+
const oldTags = oldMetadata?.default_environment?.script?.tags;
|
|
682
711
|
|
|
683
712
|
// Get the script content - either from props.script, or by bundling
|
|
684
713
|
const scriptContent =
|
|
@@ -725,6 +754,7 @@ export const _Worker = Resource(
|
|
|
725
754
|
const scriptMetadata = await prepareWorkerMetadata(
|
|
726
755
|
this,
|
|
727
756
|
oldBindings,
|
|
757
|
+
oldTags,
|
|
728
758
|
{
|
|
729
759
|
...props,
|
|
730
760
|
compatibilityDate,
|
|
@@ -736,9 +766,6 @@ export const _Worker = Resource(
|
|
|
736
766
|
|
|
737
767
|
await putWorker(api, workerName, scriptContent, scriptMetadata);
|
|
738
768
|
|
|
739
|
-
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
740
|
-
await this.set("bindings", props.bindings);
|
|
741
|
-
|
|
742
769
|
for (const workflow of workflowsBindings) {
|
|
743
770
|
await upsertWorkflow(api, {
|
|
744
771
|
workflowName: workflow.workflowName,
|
|
@@ -1106,34 +1133,49 @@ export async function getWorkerScriptMetadata(
|
|
|
1106
1133
|
return ((await response.json()) as any).result as WorkerScriptMetadata;
|
|
1107
1134
|
}
|
|
1108
1135
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
) {
|
|
1136
|
+
async function getWorkerBindings(api: CloudflareApi, workerName: string) {
|
|
1137
|
+
// Fetch the bindings for a worker by calling the Cloudflare API endpoint:
|
|
1138
|
+
// GET /accounts/:account_id/workers/scripts/:script_name/bindings
|
|
1139
|
+
// See: https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/script_and_version_settings/methods/get/
|
|
1114
1140
|
const response = await api.get(
|
|
1115
|
-
`/accounts/${api.accountId}/workers/
|
|
1116
|
-
{
|
|
1117
|
-
headers: {
|
|
1118
|
-
Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
|
|
1119
|
-
"Content-Type": "application/json",
|
|
1120
|
-
},
|
|
1121
|
-
},
|
|
1141
|
+
`/accounts/${api.accountId}/workers/scripts/${workerName}/settings`,
|
|
1122
1142
|
);
|
|
1123
|
-
|
|
1124
1143
|
if (response.status === 404) {
|
|
1125
1144
|
return undefined;
|
|
1126
1145
|
}
|
|
1127
|
-
|
|
1128
1146
|
if (!response.ok) {
|
|
1129
1147
|
throw new Error(
|
|
1130
|
-
`
|
|
1148
|
+
`Error getting worker bindings: ${response.status} ${response.statusText}`,
|
|
1131
1149
|
);
|
|
1132
1150
|
}
|
|
1133
|
-
|
|
1134
|
-
const
|
|
1135
|
-
|
|
1136
|
-
|
|
1151
|
+
// The result is an object with a "result" property containing the bindings array
|
|
1152
|
+
const { result, success, errors } = (await response.json()) as {
|
|
1153
|
+
result: {
|
|
1154
|
+
bindings: WorkerBindingSpec[];
|
|
1155
|
+
compatibility_date: string;
|
|
1156
|
+
compatibility_flags: string[];
|
|
1157
|
+
[key: string]: any;
|
|
1158
|
+
};
|
|
1159
|
+
success: boolean;
|
|
1160
|
+
errors: Array<{
|
|
1161
|
+
code: number;
|
|
1162
|
+
message: string;
|
|
1163
|
+
documentation_url: string;
|
|
1164
|
+
[key: string]: any;
|
|
1165
|
+
}>;
|
|
1166
|
+
messages: Array<{
|
|
1167
|
+
code: number;
|
|
1168
|
+
message: string;
|
|
1169
|
+
documentation_url: string;
|
|
1170
|
+
[key: string]: any;
|
|
1171
|
+
}>;
|
|
1172
|
+
};
|
|
1173
|
+
if (!success) {
|
|
1174
|
+
throw new Error(
|
|
1175
|
+
`Error getting worker bindings: ${response.status} ${response.statusText}\nErrors:\n${errors.map((e) => `- [${e.code}] ${e.message} (${e.documentation_url})`).join("\n")}`,
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
return result.bindings;
|
|
1137
1179
|
}
|
|
1138
1180
|
|
|
1139
1181
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleApiError } from "./api-error.js";
|
|
2
2
|
import type { CloudflareApi } from "./api.js";
|
|
3
|
+
import type { Binding } from "./bindings.js";
|
|
3
4
|
|
|
4
5
|
export interface WorkflowProps {
|
|
5
6
|
/**
|
|
@@ -20,6 +21,10 @@ export interface WorkflowProps {
|
|
|
20
21
|
className?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
export function isWorkflow(binding: Binding): binding is Workflow {
|
|
25
|
+
return typeof binding === "object" && binding.type === "workflow";
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
export class Workflow<PARAMS = unknown> {
|
|
24
29
|
public readonly type = "workflow";
|
|
25
30
|
/**
|
|
@@ -17,7 +17,7 @@ export interface WranglerJsonProps {
|
|
|
17
17
|
/**
|
|
18
18
|
* The worker to generate the wrangler.json file for
|
|
19
19
|
*/
|
|
20
|
-
worker: Worker
|
|
20
|
+
worker: Worker<any>;
|
|
21
21
|
/**
|
|
22
22
|
* Path to write the wrangler.json file to
|
|
23
23
|
*
|
|
@@ -393,6 +393,10 @@ function processBindings(
|
|
|
393
393
|
}
|
|
394
394
|
// Process each binding
|
|
395
395
|
for (const [bindingName, binding] of Object.entries(bindings)) {
|
|
396
|
+
if (typeof binding === "function") {
|
|
397
|
+
// this is only reachable in the
|
|
398
|
+
throw new Error(`Invalid binding ${bindingName} is a function`);
|
|
399
|
+
}
|
|
396
400
|
if (typeof binding === "string") {
|
|
397
401
|
// Plain text binding - add to vars
|
|
398
402
|
if (!spec.vars) {
|
package/src/index.ts
CHANGED
package/src/type.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type type<T> = typeof type<T>;
|
|
2
|
+
/**
|
|
3
|
+
* Used to construct type-level alias information.
|
|
4
|
+
*/
|
|
5
|
+
export const type = ((): any => {
|
|
6
|
+
throw new Error("Should never be called, purely for type-level aliasing");
|
|
7
|
+
}) as (<T>() => T) &
|
|
8
|
+
// we also want to make this a "class type" so that syntax highlighting is always as a type
|
|
9
|
+
(new <T>() => T);
|