alchemy 0.15.3 → 0.15.5
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/bindings.d.ts +3 -1
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bindings.js +1 -0
- package/lib/cloudflare/bindings.js.map +1 -1
- package/lib/cloudflare/bound.d.ts +2 -2
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/worker.d.ts +2 -2
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +108 -83
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +12 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +17 -9
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/serde.d.ts.map +1 -1
- package/lib/serde.js +49 -13
- package/lib/serde.js.map +1 -1
- package/package.json +1 -1
- package/src/cloudflare/bindings.ts +5 -1
- package/src/cloudflare/bound.ts +4 -2
- package/src/cloudflare/worker.ts +158 -118
- package/src/cloudflare/wrangler.json.ts +27 -8
- package/src/serde.ts +57 -22
package/lib/serde.js
CHANGED
|
@@ -11,7 +11,7 @@ export async function serialize(scope, value, options) {
|
|
|
11
11
|
if (Array.isArray(value)) {
|
|
12
12
|
return Promise.all(value.map((value) => serialize(scope, value, options)));
|
|
13
13
|
}
|
|
14
|
-
if (value instanceof Secret) {
|
|
14
|
+
else if (value instanceof Secret) {
|
|
15
15
|
if (!scope.password) {
|
|
16
16
|
throw new Error("Cannot serialize secret without password");
|
|
17
17
|
}
|
|
@@ -21,26 +21,42 @@ export async function serialize(scope, value, options) {
|
|
|
21
21
|
: value.unencrypted,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
if (isType(value)) {
|
|
24
|
+
else if (isType(value)) {
|
|
25
25
|
return {
|
|
26
26
|
"@schema": value.toJSON(),
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
if (value instanceof Date) {
|
|
29
|
+
else if (value instanceof Date) {
|
|
30
30
|
return {
|
|
31
31
|
"@date": value.toISOString(),
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
if (value
|
|
35
|
-
|
|
34
|
+
else if (typeof value === "symbol") {
|
|
35
|
+
assertNotUniqueSymbol(value);
|
|
36
|
+
return {
|
|
37
|
+
"@symbol": value.toString(),
|
|
38
|
+
};
|
|
36
39
|
}
|
|
37
|
-
if (value
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
else if (value instanceof Scope) {
|
|
41
|
+
return {
|
|
42
|
+
"@scope": null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
else if (value && typeof value === "object") {
|
|
46
|
+
for (const symbol of Object.getOwnPropertySymbols(value)) {
|
|
47
|
+
assertNotUniqueSymbol(symbol);
|
|
48
|
+
}
|
|
49
|
+
for (const key of Object.keys(value)) {
|
|
50
|
+
if (parseSymbol(key)) {
|
|
51
|
+
throw new Error(`Cannot serialize property '${key}' because it looks like a stringified symbol.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return Object.fromEntries(await Promise.all([...Object.getOwnPropertySymbols(value), ...Object.keys(value)].map(async (key) => [
|
|
55
|
+
key.toString(),
|
|
56
|
+
await serialize(scope, value[key], options),
|
|
41
57
|
])));
|
|
42
58
|
}
|
|
43
|
-
if (typeof value === "function") {
|
|
59
|
+
else if (typeof value === "function") {
|
|
44
60
|
// can't serialize functions
|
|
45
61
|
return undefined;
|
|
46
62
|
}
|
|
@@ -57,17 +73,37 @@ export async function deserialize(scope, value) {
|
|
|
57
73
|
}
|
|
58
74
|
return new Secret(await decryptWithKey(value["@secret"], scope.password));
|
|
59
75
|
}
|
|
60
|
-
if ("@schema" in value) {
|
|
76
|
+
else if ("@schema" in value) {
|
|
61
77
|
return value["@schema"];
|
|
62
78
|
}
|
|
63
|
-
if ("@date" in value) {
|
|
79
|
+
else if ("@date" in value) {
|
|
64
80
|
return new Date(value["@date"]);
|
|
65
81
|
}
|
|
82
|
+
else if ("@symbol" in value) {
|
|
83
|
+
return parseSymbol(value["@symbol"]);
|
|
84
|
+
}
|
|
85
|
+
else if ("@scope" in value) {
|
|
86
|
+
return scope;
|
|
87
|
+
}
|
|
66
88
|
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, value]) => [
|
|
67
|
-
key,
|
|
89
|
+
parseSymbol(key) ?? key,
|
|
68
90
|
await deserialize(scope, value),
|
|
69
91
|
])));
|
|
70
92
|
}
|
|
71
93
|
return value;
|
|
72
94
|
}
|
|
95
|
+
const symbolPattern = /^Symbol\((.*)\)$/;
|
|
96
|
+
function parseSymbol(value) {
|
|
97
|
+
const match = value.match(symbolPattern);
|
|
98
|
+
if (!match) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return Symbol.for(match[1]);
|
|
102
|
+
}
|
|
103
|
+
function assertNotUniqueSymbol(symbol) {
|
|
104
|
+
if (symbol.description === undefined ||
|
|
105
|
+
symbol !== Symbol.for(symbol.description)) {
|
|
106
|
+
throw new Error(`Cannot serialize unique symbol: ${symbol.description}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
73
109
|
//# sourceMappingURL=serde.js.map
|
package/lib/serde.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serde.js","sourceRoot":"","sources":["../src/serde.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,yCAAyC;AACzC,SAAS,MAAM,CAAC,KAAU;IACxB,OAAO,CACL,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,CAAC,YAAY,KAAK,UAAU,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAY,EACZ,KAAU,EACV,OAEC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;
|
|
1
|
+
{"version":3,"file":"serde.js","sourceRoot":"","sources":["../src/serde.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -49,7 +49,11 @@ export type Binding =
|
|
|
49
49
|
| VectorizeIndex
|
|
50
50
|
| Worker
|
|
51
51
|
| Workflow
|
|
52
|
-
| BrowserRendering
|
|
52
|
+
| BrowserRendering
|
|
53
|
+
| Self;
|
|
54
|
+
|
|
55
|
+
export type Self = typeof Self;
|
|
56
|
+
export const Self = Symbol.for("Self");
|
|
53
57
|
|
|
54
58
|
/**
|
|
55
59
|
* Union type for all Worker binding types (API spec)
|
package/src/cloudflare/bound.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Secret } from "../secret.js";
|
|
|
3
3
|
import type { AiGateway as _AiGateway } from "./ai-gateway.js";
|
|
4
4
|
import type { Ai as _Ai } from "./ai.js";
|
|
5
5
|
import type { Assets } from "./assets.js";
|
|
6
|
-
import type { Binding } from "./bindings.js";
|
|
6
|
+
import type { Binding, Self } from "./bindings.js";
|
|
7
7
|
import type { BrowserRendering } from "./browser-rendering.js";
|
|
8
8
|
import type { R2Bucket as _R2Bucket } from "./bucket.js";
|
|
9
9
|
import type { D1Database as _D1Database } from "./d1-database.js";
|
|
@@ -48,4 +48,6 @@ export type Bound<T extends Binding> = T extends _DurableObjectNamespace
|
|
|
48
48
|
? Fetcher
|
|
49
49
|
: T extends _Ai<infer M>
|
|
50
50
|
? Ai<M>
|
|
51
|
-
:
|
|
51
|
+
: T extends Self
|
|
52
|
+
? Service
|
|
53
|
+
: Service;
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
createCloudflareApi,
|
|
14
14
|
} from "./api.js";
|
|
15
15
|
import type { Assets } from "./assets.js";
|
|
16
|
-
import type
|
|
16
|
+
import { type Bindings, Self, type WorkerBindingSpec } from "./bindings.js";
|
|
17
17
|
import type { Bound } from "./bound.js";
|
|
18
18
|
import { bundleWorkerScript } from "./bundle/bundle-worker.js";
|
|
19
19
|
import type { DurableObjectNamespace } from "./durable-object-namespace.js";
|
|
@@ -207,7 +207,7 @@ export interface WorkerProps<B extends Bindings = Bindings>
|
|
|
207
207
|
*/
|
|
208
208
|
export interface Worker<B extends Bindings = Bindings>
|
|
209
209
|
extends Resource<"cloudflare::Worker">,
|
|
210
|
-
Omit<WorkerProps<B>, "url"> {
|
|
210
|
+
Omit<WorkerProps<B>, "url" | "script"> {
|
|
211
211
|
type: "service";
|
|
212
212
|
|
|
213
213
|
/**
|
|
@@ -358,143 +358,182 @@ export const Worker = Resource(
|
|
|
358
358
|
id: string,
|
|
359
359
|
props: WorkerProps<B>,
|
|
360
360
|
): Promise<Worker<B>> {
|
|
361
|
-
// Create Cloudflare API client with automatic account discovery
|
|
362
|
-
const api = await createCloudflareApi(props);
|
|
363
|
-
|
|
364
|
-
// Use the provided name
|
|
365
|
-
const workerName = props.name ?? id;
|
|
366
|
-
|
|
367
361
|
// Validate input - we need either script, entryPoint, or bundle
|
|
368
362
|
if (!props.script && !props.entrypoint) {
|
|
369
363
|
throw new Error("One of script or entryPoint must be provided");
|
|
370
364
|
}
|
|
371
365
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (!props.adopt) {
|
|
378
|
-
await assertWorkerDoesNotExist(this, api, workerName);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
366
|
+
// Create Cloudflare API client with automatic account discovery
|
|
367
|
+
const api = await createCloudflareApi(props);
|
|
368
|
+
|
|
369
|
+
// Use the provided name
|
|
370
|
+
const workerName = props.name ?? id;
|
|
381
371
|
|
|
382
372
|
const oldBindings = await this.get<Bindings>("bindings");
|
|
383
373
|
|
|
384
374
|
const compatibilityDate = props.compatibilityDate ?? "2025-04-20";
|
|
385
375
|
const compatibilityFlags = props.compatibilityFlags ?? [];
|
|
386
376
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (binding
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
377
|
+
const uploadWorkerScript = async (props: WorkerProps<B>) => {
|
|
378
|
+
// Get the script content - either from props.script, or by bundling
|
|
379
|
+
const scriptContent =
|
|
380
|
+
props.script ??
|
|
381
|
+
(await bundleWorkerScript({
|
|
382
|
+
...props,
|
|
383
|
+
compatibilityDate,
|
|
384
|
+
compatibilityFlags,
|
|
385
|
+
}));
|
|
386
|
+
|
|
387
|
+
// Find any assets bindings
|
|
388
|
+
const assetsBindings: { name: string; assets: Assets }[] = [];
|
|
389
|
+
const workflowsBindings: Workflow[] = [];
|
|
390
|
+
|
|
391
|
+
if (props.bindings) {
|
|
392
|
+
for (const [bindingName, binding] of Object.entries(props.bindings)) {
|
|
393
|
+
if (typeof binding === "object") {
|
|
394
|
+
if (binding.type === "assets") {
|
|
395
|
+
assetsBindings.push({ name: bindingName, assets: binding });
|
|
396
|
+
} else if (binding.type === "workflow") {
|
|
397
|
+
workflowsBindings.push(binding);
|
|
398
|
+
}
|
|
407
399
|
}
|
|
408
400
|
}
|
|
409
401
|
}
|
|
410
|
-
}
|
|
411
402
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
403
|
+
// Upload any assets and get completion tokens
|
|
404
|
+
let assetUploadResult: AssetUploadResult | undefined;
|
|
405
|
+
if (assetsBindings.length > 0) {
|
|
406
|
+
// We'll use the first asset binding for now
|
|
407
|
+
// In the future, we might want to support multiple asset bindings
|
|
408
|
+
const assetBinding = assetsBindings[0];
|
|
409
|
+
|
|
410
|
+
// Upload the assets and get the completion token
|
|
411
|
+
assetUploadResult = await uploadAssets(
|
|
412
|
+
api,
|
|
413
|
+
workerName,
|
|
414
|
+
assetBinding.assets,
|
|
415
|
+
props.assets,
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Prepare metadata with bindings
|
|
420
|
+
const scriptMetadata = await prepareWorkerMetadata(
|
|
421
|
+
this,
|
|
422
|
+
oldBindings,
|
|
423
|
+
{
|
|
424
|
+
...props,
|
|
425
|
+
compatibilityDate,
|
|
426
|
+
compatibilityFlags,
|
|
427
|
+
workerName,
|
|
428
|
+
},
|
|
429
|
+
assetUploadResult,
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
await putWorker(api, workerName, scriptContent, scriptMetadata);
|
|
433
|
+
|
|
434
|
+
for (const workflow of workflowsBindings) {
|
|
435
|
+
await upsertWorkflow(api, {
|
|
436
|
+
workflowName: workflow.workflowName,
|
|
437
|
+
className: workflow.className,
|
|
438
|
+
scriptName: workerName,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
await Promise.all(
|
|
443
|
+
props.eventSources?.map((eventSource) => {
|
|
444
|
+
if (isQueue(eventSource) || isQueueEventSource(eventSource)) {
|
|
445
|
+
const queue = isQueue(eventSource)
|
|
446
|
+
? eventSource
|
|
447
|
+
: eventSource.queue;
|
|
448
|
+
return QueueConsumer(`${queue.id}-consumer`, {
|
|
449
|
+
queue,
|
|
450
|
+
scriptName: workerName,
|
|
451
|
+
accountId: api.accountId,
|
|
452
|
+
settings: isQueueEventSource(eventSource)
|
|
453
|
+
? eventSource.settings
|
|
454
|
+
: undefined,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
throw new Error(`Unsupported event source type: ${eventSource}`);
|
|
458
|
+
}) ?? [],
|
|
459
|
+
);
|
|
418
460
|
|
|
419
|
-
//
|
|
420
|
-
|
|
461
|
+
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
462
|
+
await this.set("bindings", props.bindings);
|
|
463
|
+
|
|
464
|
+
// Handle worker URL if requested
|
|
465
|
+
const workerUrl = await configureURL(
|
|
466
|
+
this,
|
|
421
467
|
api,
|
|
422
468
|
workerName,
|
|
423
|
-
|
|
424
|
-
props.assets,
|
|
469
|
+
props.url ?? false,
|
|
425
470
|
);
|
|
426
|
-
}
|
|
427
471
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
this,
|
|
431
|
-
oldBindings,
|
|
432
|
-
{
|
|
433
|
-
...props,
|
|
434
|
-
compatibilityDate,
|
|
435
|
-
compatibilityFlags,
|
|
436
|
-
},
|
|
437
|
-
assetUploadResult,
|
|
438
|
-
);
|
|
472
|
+
// Get current timestamp
|
|
473
|
+
const now = Date.now();
|
|
439
474
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
scriptName: workerName,
|
|
447
|
-
});
|
|
448
|
-
}
|
|
475
|
+
// Update cron triggers
|
|
476
|
+
if (props.crons) {
|
|
477
|
+
const res = await api.put(
|
|
478
|
+
`/accounts/${api.accountId}/workers/scripts/${workerName}/schedules`,
|
|
479
|
+
props.crons.map((cron) => ({ cron })),
|
|
480
|
+
);
|
|
449
481
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
accountId: api.accountId,
|
|
458
|
-
settings: isQueueEventSource(eventSource)
|
|
459
|
-
? eventSource.settings
|
|
460
|
-
: undefined,
|
|
461
|
-
});
|
|
482
|
+
if (!res.ok) {
|
|
483
|
+
await handleApiError(
|
|
484
|
+
res,
|
|
485
|
+
"updating cron triggers",
|
|
486
|
+
"worker",
|
|
487
|
+
workerName,
|
|
488
|
+
);
|
|
462
489
|
}
|
|
463
|
-
|
|
464
|
-
}) ?? [],
|
|
465
|
-
);
|
|
466
|
-
|
|
467
|
-
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
468
|
-
await this.set("bindings", props.bindings);
|
|
490
|
+
}
|
|
469
491
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
this,
|
|
473
|
-
api,
|
|
474
|
-
workerName,
|
|
475
|
-
props.url ?? false,
|
|
476
|
-
);
|
|
492
|
+
return { scriptMetadata, workerUrl, now };
|
|
493
|
+
};
|
|
477
494
|
|
|
478
|
-
|
|
479
|
-
|
|
495
|
+
if (this.phase === "delete") {
|
|
496
|
+
if (
|
|
497
|
+
Object.values(props.bindings ?? {}).some((binding) => binding === Self)
|
|
498
|
+
) {
|
|
499
|
+
// remove the Self bindings or else we can't remove (LOL)
|
|
500
|
+
await uploadWorkerScript({
|
|
501
|
+
...props,
|
|
502
|
+
bindings: Object.fromEntries(
|
|
503
|
+
Object.entries(props.bindings ?? {}).filter(
|
|
504
|
+
([_, binding]) => binding !== Self,
|
|
505
|
+
),
|
|
506
|
+
) as B,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
480
509
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
510
|
+
await withExponentialBackoff(
|
|
511
|
+
() =>
|
|
512
|
+
deleteWorker(this, api, {
|
|
513
|
+
...props,
|
|
514
|
+
workerName,
|
|
515
|
+
}),
|
|
516
|
+
(err) =>
|
|
517
|
+
(err.status === 400 &&
|
|
518
|
+
err.message.includes(
|
|
519
|
+
"is still referenced by service bindings in Workers",
|
|
520
|
+
)) ||
|
|
521
|
+
err.status === 500 ||
|
|
522
|
+
err.status === 503,
|
|
523
|
+
10,
|
|
524
|
+
100,
|
|
486
525
|
);
|
|
487
526
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
workerName,
|
|
494
|
-
);
|
|
527
|
+
return this.destroy();
|
|
528
|
+
}
|
|
529
|
+
if (this.phase === "create") {
|
|
530
|
+
if (!props.adopt) {
|
|
531
|
+
await assertWorkerDoesNotExist(this, api, workerName);
|
|
495
532
|
}
|
|
496
533
|
}
|
|
497
534
|
|
|
535
|
+
const { scriptMetadata, workerUrl, now } = await uploadWorkerScript(props);
|
|
536
|
+
|
|
498
537
|
// Construct the output
|
|
499
538
|
return this({
|
|
500
539
|
...props,
|
|
@@ -504,7 +543,6 @@ export const Worker = Resource(
|
|
|
504
543
|
name: workerName,
|
|
505
544
|
compatibilityDate,
|
|
506
545
|
compatibilityFlags,
|
|
507
|
-
script: scriptContent,
|
|
508
546
|
format: props.format || "esm", // Include format in the output
|
|
509
547
|
bindings: props.bindings ?? ({} as B),
|
|
510
548
|
env: props.env,
|
|
@@ -526,8 +564,9 @@ export const Worker = Resource(
|
|
|
526
564
|
async function deleteWorker<B extends Bindings>(
|
|
527
565
|
ctx: Context<Worker<B>>,
|
|
528
566
|
api: CloudflareApi,
|
|
529
|
-
workerName: string,
|
|
567
|
+
props: WorkerProps<B> & { workerName: string },
|
|
530
568
|
) {
|
|
569
|
+
const workerName = props.workerName;
|
|
531
570
|
// Delete any queue consumers attached to this worker first
|
|
532
571
|
await deleteQueueConsumers(ctx, api, workerName);
|
|
533
572
|
|
|
@@ -538,13 +577,7 @@ async function deleteWorker<B extends Bindings>(
|
|
|
538
577
|
|
|
539
578
|
// Check for success (2xx status code)
|
|
540
579
|
if (!deleteResponse.ok && deleteResponse.status !== 404) {
|
|
541
|
-
|
|
542
|
-
.json()
|
|
543
|
-
.catch(() => ({ errors: [{ message: deleteResponse.statusText }] }));
|
|
544
|
-
console.error(
|
|
545
|
-
"Error deleting worker:",
|
|
546
|
-
errorData.errors?.[0]?.message || deleteResponse.statusText,
|
|
547
|
-
);
|
|
580
|
+
await handleApiError(deleteResponse, "delete", "worker", workerName);
|
|
548
581
|
}
|
|
549
582
|
|
|
550
583
|
// Disable the URL if it was enabled
|
|
@@ -698,6 +731,7 @@ async function prepareWorkerMetadata<B extends Bindings>(
|
|
|
698
731
|
props: WorkerProps & {
|
|
699
732
|
compatibilityDate: string;
|
|
700
733
|
compatibilityFlags: string[];
|
|
734
|
+
workerName: string;
|
|
701
735
|
},
|
|
702
736
|
assetUploadResult?: AssetUploadResult,
|
|
703
737
|
): Promise<WorkerMetadata> {
|
|
@@ -752,6 +786,12 @@ async function prepareWorkerMetadata<B extends Bindings>(
|
|
|
752
786
|
name: bindingName,
|
|
753
787
|
text: binding,
|
|
754
788
|
});
|
|
789
|
+
} else if (binding === Self) {
|
|
790
|
+
meta.bindings.push({
|
|
791
|
+
type: "service",
|
|
792
|
+
name: bindingName,
|
|
793
|
+
service: props.workerName,
|
|
794
|
+
});
|
|
755
795
|
} else if (binding.type === "d1") {
|
|
756
796
|
meta.bindings.push({
|
|
757
797
|
type: "d1",
|
|
@@ -807,7 +847,7 @@ async function prepareWorkerMetadata<B extends Bindings>(
|
|
|
807
847
|
// script_name: ??,
|
|
808
848
|
});
|
|
809
849
|
// it's unclear whether this is needed, but it works both ways
|
|
810
|
-
configureClassMigration(binding, binding.id, binding.className);
|
|
850
|
+
// configureClassMigration(binding, binding.id, binding.className);
|
|
811
851
|
} else if (binding.type === "queue") {
|
|
812
852
|
meta.bindings.push({
|
|
813
853
|
type: "queue",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context } from "../context.js";
|
|
2
2
|
import { StaticJsonFile } from "../fs/static-json-file.js";
|
|
3
3
|
import { Resource } from "../resource.js";
|
|
4
|
-
import type
|
|
4
|
+
import { Self, type Bindings } from "./bindings.js";
|
|
5
5
|
import type { DurableObjectNamespace } from "./durable-object-namespace.js";
|
|
6
6
|
import type { EventSource } from "./event-source.js";
|
|
7
7
|
import { isQueueEventSource } from "./event-source.js";
|
|
@@ -95,7 +95,7 @@ export const WranglerJson = Resource(
|
|
|
95
95
|
|
|
96
96
|
// Process bindings if they exist
|
|
97
97
|
if (worker.bindings) {
|
|
98
|
-
processBindings(spec, worker.bindings, worker.eventSources);
|
|
98
|
+
processBindings(spec, worker.bindings, worker.eventSources, worker.name);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// Add environment variables as vars
|
|
@@ -170,6 +170,10 @@ export interface WranglerJsonSpec {
|
|
|
170
170
|
kv_namespaces?: {
|
|
171
171
|
binding: string;
|
|
172
172
|
id: string;
|
|
173
|
+
/**
|
|
174
|
+
* The ID of the KV namespace used during `wrangler dev`
|
|
175
|
+
*/
|
|
176
|
+
preview_id?: string;
|
|
173
177
|
}[];
|
|
174
178
|
|
|
175
179
|
/**
|
|
@@ -190,6 +194,10 @@ export interface WranglerJsonSpec {
|
|
|
190
194
|
r2_buckets?: {
|
|
191
195
|
binding: string;
|
|
192
196
|
bucket_name: string;
|
|
197
|
+
/**
|
|
198
|
+
* The preview name of this R2 bucket at the edge.
|
|
199
|
+
*/
|
|
200
|
+
preview_bucket_name?: string;
|
|
193
201
|
}[];
|
|
194
202
|
|
|
195
203
|
/**
|
|
@@ -246,6 +254,10 @@ export interface WranglerJsonSpec {
|
|
|
246
254
|
database_id: string;
|
|
247
255
|
database_name: string;
|
|
248
256
|
migrations_dir?: string;
|
|
257
|
+
/**
|
|
258
|
+
* The ID of the D1 database used during `wrangler dev`
|
|
259
|
+
*/
|
|
260
|
+
preview_database_id?: string;
|
|
249
261
|
}[];
|
|
250
262
|
|
|
251
263
|
/**
|
|
@@ -279,6 +291,7 @@ function processBindings(
|
|
|
279
291
|
spec: WranglerJsonSpec,
|
|
280
292
|
bindings: Bindings,
|
|
281
293
|
eventSources: EventSource[] | undefined,
|
|
294
|
+
workerName: string,
|
|
282
295
|
): void {
|
|
283
296
|
// Arrays to collect different binding types
|
|
284
297
|
const kvNamespaces: { binding: string; id: string }[] = [];
|
|
@@ -340,6 +353,18 @@ function processBindings(
|
|
|
340
353
|
spec.vars = {};
|
|
341
354
|
}
|
|
342
355
|
spec.vars[bindingName] = binding;
|
|
356
|
+
} else if (binding === Self) {
|
|
357
|
+
// Self(service) binding
|
|
358
|
+
services.push({
|
|
359
|
+
binding: bindingName,
|
|
360
|
+
service: workerName,
|
|
361
|
+
});
|
|
362
|
+
} else if (binding.type === "service") {
|
|
363
|
+
// Service binding
|
|
364
|
+
services.push({
|
|
365
|
+
binding: bindingName,
|
|
366
|
+
service: binding.id,
|
|
367
|
+
});
|
|
343
368
|
} else if (binding.type === "kv_namespace") {
|
|
344
369
|
// KV Namespace binding
|
|
345
370
|
kvNamespaces.push({
|
|
@@ -363,12 +388,6 @@ function processBindings(
|
|
|
363
388
|
binding: bindingName,
|
|
364
389
|
bucket_name: binding.name,
|
|
365
390
|
});
|
|
366
|
-
} else if (binding.type === "service") {
|
|
367
|
-
// Service binding
|
|
368
|
-
services.push({
|
|
369
|
-
binding: bindingName,
|
|
370
|
-
service: binding.id,
|
|
371
|
-
});
|
|
372
391
|
} else if (binding.type === "secret") {
|
|
373
392
|
// Secret binding
|
|
374
393
|
secrets.push(bindingName);
|