alchemy 0.57.2 → 0.59.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/bin/alchemy.js +1 -1
- package/lib/apply.js +3 -3
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/api-error.js +1 -1
- package/lib/cloudflare/api-error.js.map +1 -1
- package/lib/cloudflare/api-response.d.ts +19 -0
- package/lib/cloudflare/api-response.d.ts.map +1 -1
- package/lib/cloudflare/api-response.js.map +1 -1
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +10 -2
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/assets.d.ts +1 -1
- package/lib/cloudflare/assets.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts +21 -3
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +83 -53
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/container.d.ts +8 -0
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +7 -1
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/custom-domain.d.ts +8 -0
- package/lib/cloudflare/custom-domain.d.ts.map +1 -1
- package/lib/cloudflare/custom-domain.js +11 -0
- package/lib/cloudflare/custom-domain.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +15 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +24 -17
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-import.d.ts.map +1 -1
- package/lib/cloudflare/d1-import.js.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +37 -9
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +91 -5
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/index.d.ts +1 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +23 -4
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +70 -58
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.d.ts +2 -0
- package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.js +9 -7
- package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
- package/lib/cloudflare/miniflare/delete.d.ts +21 -0
- package/lib/cloudflare/miniflare/delete.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/delete.js +91 -0
- package/lib/cloudflare/miniflare/delete.js.map +1 -0
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-controller.js +26 -9
- package/lib/cloudflare/miniflare/miniflare-controller.js.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts +2 -0
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.js +3 -4
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
- package/lib/cloudflare/pipeline.d.ts +3 -0
- package/lib/cloudflare/pipeline.d.ts.map +1 -1
- package/lib/cloudflare/pipeline.js +14 -1
- package/lib/cloudflare/pipeline.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +8 -0
- package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
- package/lib/cloudflare/queue-consumer.js +15 -4
- package/lib/cloudflare/queue-consumer.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +22 -4
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +32 -9
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/route.d.ts +8 -0
- package/lib/cloudflare/route.d.ts.map +1 -1
- package/lib/cloudflare/route.js +13 -0
- package/lib/cloudflare/route.js.map +1 -1
- package/lib/cloudflare/tunnel.d.ts +448 -0
- package/lib/cloudflare/tunnel.d.ts.map +1 -0
- package/lib/cloudflare/tunnel.js +467 -0
- package/lib/cloudflare/tunnel.js.map +1 -0
- package/lib/cloudflare/worker-subdomain.d.ts +8 -0
- package/lib/cloudflare/worker-subdomain.d.ts.map +1 -1
- package/lib/cloudflare/worker-subdomain.js +9 -1
- package/lib/cloudflare/worker-subdomain.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +7 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +405 -375
- package/lib/cloudflare/worker.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 +24 -12
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +4 -8
- package/lib/destroy.js.map +1 -1
- package/lib/esbuild/bundle.d.ts +1 -1
- package/lib/secret.d.ts +18 -1
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +25 -0
- package/lib/secret.js.map +1 -1
- package/package.json +1 -1
- package/src/apply.ts +5 -6
- package/src/cloudflare/api-error.ts +2 -2
- package/src/cloudflare/api-response.ts +22 -0
- package/src/cloudflare/api.ts +13 -2
- package/src/cloudflare/bucket.ts +126 -68
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/container.ts +18 -1
- package/src/cloudflare/custom-domain.ts +22 -0
- package/src/cloudflare/d1-database.ts +44 -19
- package/src/cloudflare/d1-import.ts +1 -14
- package/src/cloudflare/hyperdrive.ts +170 -14
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/kv-namespace.ts +117 -73
- package/src/cloudflare/miniflare/build-worker-options.ts +12 -8
- package/src/cloudflare/miniflare/delete.ts +136 -0
- package/src/cloudflare/miniflare/miniflare-controller.ts +26 -9
- package/src/cloudflare/miniflare/remote-binding-proxy.ts +5 -4
- package/src/cloudflare/pipeline.ts +17 -1
- package/src/cloudflare/queue-consumer.ts +27 -5
- package/src/cloudflare/queue.ts +62 -12
- package/src/cloudflare/route.ts +24 -0
- package/src/cloudflare/tunnel.ts +911 -0
- package/src/cloudflare/worker-subdomain.ts +29 -6
- package/src/cloudflare/worker.ts +484 -465
- package/src/cloudflare/wrangler.json.ts +34 -13
- package/src/destroy.ts +4 -8
- package/src/secret.ts +30 -1
- package/templates/astro/README.md +2 -0
- package/templates/nuxt/README.md +2 -0
- package/templates/react-router/README.md +2 -0
- package/templates/rwsdk/README.md +2 -0
- package/templates/sveltekit/README.md +2 -0
- package/templates/tanstack-start/README.md +2 -0
- package/templates/typescript/README.md +2 -0
- package/templates/vite/README.md +2 -0
package/src/cloudflare/worker.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { Rpc } from "@cloudflare/workers-types";
|
|
2
|
-
import { isDeepStrictEqual } from "node:util";
|
|
3
1
|
import path from "pathe";
|
|
4
2
|
import type { Context } from "../context.ts";
|
|
5
3
|
import type { BundleProps } from "../esbuild/bundle.ts";
|
|
@@ -12,7 +10,6 @@ import { CloudflareApiError, handleApiError } from "./api-error.ts";
|
|
|
12
10
|
import {
|
|
13
11
|
type CloudflareApi,
|
|
14
12
|
type CloudflareApiOptions,
|
|
15
|
-
type InternalCloudflareApiOptions,
|
|
16
13
|
createCloudflareApi,
|
|
17
14
|
} from "./api.ts";
|
|
18
15
|
import type { Assets } from "./assets.ts";
|
|
@@ -35,6 +32,7 @@ import {
|
|
|
35
32
|
isDurableObjectNamespace,
|
|
36
33
|
} from "./durable-object-namespace.ts";
|
|
37
34
|
import { type EventSource, isQueueEventSource } from "./event-source.ts";
|
|
35
|
+
import { deleteMiniflareWorkerData } from "./miniflare/delete.ts";
|
|
38
36
|
import {
|
|
39
37
|
QueueConsumer,
|
|
40
38
|
deleteQueueConsumer,
|
|
@@ -42,8 +40,12 @@ import {
|
|
|
42
40
|
} from "./queue-consumer.ts";
|
|
43
41
|
import { isQueue } from "./queue.ts";
|
|
44
42
|
import { Route } from "./route.ts";
|
|
45
|
-
import { uploadAssets } from "./worker-assets.ts";
|
|
46
|
-
import {
|
|
43
|
+
import { type AssetUploadResult, uploadAssets } from "./worker-assets.ts";
|
|
44
|
+
import {
|
|
45
|
+
WorkerBundle,
|
|
46
|
+
type WorkerBundleSource,
|
|
47
|
+
normalizeWorkerBundle,
|
|
48
|
+
} from "./worker-bundle.ts";
|
|
47
49
|
import {
|
|
48
50
|
type WorkerScriptMetadata,
|
|
49
51
|
bumpMigrationTagVersion,
|
|
@@ -523,6 +525,14 @@ export type Worker<
|
|
|
523
525
|
placement?: {
|
|
524
526
|
mode: "smart";
|
|
525
527
|
};
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Whether the worker has a remote deployment
|
|
531
|
+
* @internal
|
|
532
|
+
*/
|
|
533
|
+
dev?: {
|
|
534
|
+
hasRemote: boolean;
|
|
535
|
+
};
|
|
526
536
|
};
|
|
527
537
|
|
|
528
538
|
/**
|
|
@@ -698,55 +708,104 @@ const _Worker = Resource(
|
|
|
698
708
|
this: Context<Worker<NoInfer<B>>>,
|
|
699
709
|
id: string,
|
|
700
710
|
props: WorkerProps<B>,
|
|
701
|
-
)
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
711
|
+
) {
|
|
712
|
+
const options = (() => {
|
|
713
|
+
if (props.projectRoot) {
|
|
714
|
+
logger.warn("projectRoot is deprecated, use cwd instead");
|
|
715
|
+
props.cwd = props.projectRoot;
|
|
716
|
+
}
|
|
717
|
+
const name = props.name ?? id;
|
|
718
|
+
const cwd = path.resolve(props.cwd ?? process.cwd());
|
|
719
|
+
const compatibilityDate =
|
|
720
|
+
props.compatibilityDate ?? DEFAULT_COMPATIBILITY_DATE;
|
|
721
|
+
const compatibilityFlags = unionCompatibilityFlags(
|
|
722
|
+
props.compatibility,
|
|
723
|
+
props.compatibilityFlags,
|
|
724
|
+
);
|
|
725
|
+
const dispatchNamespace =
|
|
726
|
+
typeof props.namespace === "string"
|
|
727
|
+
? props.namespace
|
|
728
|
+
: props.namespace?.namespaceName;
|
|
729
|
+
const bundle = normalizeWorkerBundle({
|
|
730
|
+
id,
|
|
731
|
+
entrypoint: props.entrypoint,
|
|
732
|
+
script: props.script,
|
|
733
|
+
format: props.format,
|
|
734
|
+
noBundle: props.noBundle,
|
|
735
|
+
rules: "rules" in props ? props.rules : undefined,
|
|
736
|
+
bundle: props.bundle,
|
|
737
|
+
cwd,
|
|
738
|
+
compatibilityDate,
|
|
739
|
+
compatibilityFlags,
|
|
740
|
+
outdir: props.bundle?.outdir ?? path.join(cwd, ".alchemy", "out", name),
|
|
741
|
+
sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
|
|
742
|
+
});
|
|
706
743
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
744
|
+
let assets: Assets | undefined;
|
|
745
|
+
const containers: Container[] = [];
|
|
746
|
+
const workflows: Workflow[] = [];
|
|
747
|
+
const durableObjects: DurableObjectNamespace[] = [];
|
|
748
|
+
for (const binding of Object.values(props.bindings ?? {})) {
|
|
749
|
+
if (typeof binding !== "object") continue;
|
|
710
750
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
751
|
+
if (binding.type === "assets") {
|
|
752
|
+
assets = binding;
|
|
753
|
+
} else if (binding.type === "container") {
|
|
754
|
+
containers.push(binding);
|
|
755
|
+
} else if (
|
|
756
|
+
binding.type === "workflow" &&
|
|
757
|
+
(!binding.scriptName || binding.scriptName === name)
|
|
758
|
+
) {
|
|
759
|
+
workflows.push(binding);
|
|
760
|
+
} else if (
|
|
761
|
+
binding.type === "durable_object_namespace" &&
|
|
762
|
+
(!binding.scriptName || binding.scriptName === name)
|
|
763
|
+
) {
|
|
764
|
+
durableObjects.push(binding);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
722
767
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
768
|
+
return {
|
|
769
|
+
name,
|
|
770
|
+
cwd,
|
|
771
|
+
compatibilityDate,
|
|
772
|
+
compatibilityFlags,
|
|
773
|
+
dispatchNamespace,
|
|
774
|
+
bundle,
|
|
775
|
+
assets,
|
|
776
|
+
containers,
|
|
777
|
+
workflows,
|
|
778
|
+
durableObjects,
|
|
779
|
+
};
|
|
780
|
+
})();
|
|
781
|
+
if (this.phase === "delete") {
|
|
782
|
+
if (options.bundle.isOk()) {
|
|
783
|
+
await options.bundle.value.delete?.();
|
|
784
|
+
}
|
|
785
|
+
await deleteMiniflareWorkerData(options.name, {
|
|
786
|
+
durableObjects: options.durableObjects,
|
|
787
|
+
workflows: options.workflows,
|
|
788
|
+
});
|
|
789
|
+
if (!props.version && this.output?.dev?.hasRemote !== false) {
|
|
790
|
+
const api = await createCloudflareApi(props);
|
|
791
|
+
await deleteQueueConsumers(api, options.name);
|
|
792
|
+
await deleteWorker(api, {
|
|
793
|
+
scriptName: options.name,
|
|
794
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
return this.destroy();
|
|
798
|
+
}
|
|
738
799
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
800
|
+
if (options.bundle.isErr()) {
|
|
801
|
+
throw new Error(options.bundle.error);
|
|
802
|
+
}
|
|
803
|
+
const bundle = options.bundle.value;
|
|
804
|
+
const api = await createCloudflareApi(props);
|
|
742
805
|
|
|
743
|
-
if (local) {
|
|
806
|
+
if (this.scope.local && !props.dev?.remote) {
|
|
744
807
|
let url: string | undefined;
|
|
745
|
-
if (
|
|
746
|
-
throw bundleSourceResult.error;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (props.dev && "url" in props.dev) {
|
|
808
|
+
if (props.dev?.url) {
|
|
750
809
|
url = props.dev.url;
|
|
751
810
|
} else {
|
|
752
811
|
const { MiniflareController } = await import(
|
|
@@ -754,75 +813,87 @@ const _Worker = Resource(
|
|
|
754
813
|
);
|
|
755
814
|
const controller = MiniflareController.singleton;
|
|
756
815
|
url = await controller.add({
|
|
816
|
+
api,
|
|
757
817
|
id,
|
|
758
|
-
name:
|
|
759
|
-
compatibilityDate,
|
|
760
|
-
compatibilityFlags,
|
|
818
|
+
name: options.name,
|
|
819
|
+
compatibilityDate: options.compatibilityDate,
|
|
820
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
761
821
|
bindings: props.bindings,
|
|
762
822
|
eventSources: props.eventSources,
|
|
763
823
|
assets: props.assets,
|
|
764
|
-
bundle
|
|
765
|
-
port: props.dev
|
|
824
|
+
bundle,
|
|
825
|
+
port: (props.dev as { port?: number } | undefined)?.port,
|
|
766
826
|
});
|
|
767
827
|
this.onCleanup(() => controller.dispose());
|
|
768
828
|
}
|
|
769
|
-
|
|
829
|
+
await provisionResources(props, {
|
|
830
|
+
name: options.name,
|
|
831
|
+
local: true,
|
|
832
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
833
|
+
containers: options.containers,
|
|
834
|
+
});
|
|
770
835
|
return this({
|
|
836
|
+
...props,
|
|
771
837
|
type: "service",
|
|
772
838
|
id,
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
bindings: normalizeExportBindings(workerName, props.bindings),
|
|
780
|
-
env: props.env,
|
|
781
|
-
observability: props.observability,
|
|
839
|
+
name: options.name,
|
|
840
|
+
cwd: path.relative(process.cwd(), options.cwd),
|
|
841
|
+
compatibilityDate: options.compatibilityDate,
|
|
842
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
843
|
+
format: props.format || "esm",
|
|
844
|
+
bindings: normalizeExportBindings(options.name, props.bindings),
|
|
782
845
|
createdAt: this.output?.createdAt ?? Date.now(),
|
|
783
846
|
updatedAt: Date.now(),
|
|
784
|
-
eventSources: props.eventSources,
|
|
785
847
|
url,
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
// Include placement configuration in the output
|
|
792
|
-
placement: props.placement,
|
|
793
|
-
// Include limits configuration in the output
|
|
794
|
-
limits: props.limits,
|
|
795
|
-
// phantom property
|
|
848
|
+
routes: [],
|
|
849
|
+
domains: [],
|
|
850
|
+
dev: {
|
|
851
|
+
hasRemote: this.output?.dev?.hasRemote ?? false,
|
|
852
|
+
},
|
|
796
853
|
Env: undefined!,
|
|
797
854
|
} as unknown as Worker<B>);
|
|
798
855
|
}
|
|
799
856
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
857
|
+
if (this.phase === "create" || this.output.dev?.hasRemote === false) {
|
|
858
|
+
if (props.version) {
|
|
859
|
+
// When version is specified, we adopt existing workers or create them if they don't exist
|
|
860
|
+
if (!(await workerExists(api, options))) {
|
|
861
|
+
// Create the base worker first if it doesn't exist
|
|
862
|
+
await putWorker(api, {
|
|
863
|
+
...props,
|
|
864
|
+
version: undefined,
|
|
865
|
+
workerName: options.name,
|
|
866
|
+
scriptBundle: await bundle.create(),
|
|
867
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
868
|
+
compatibilityDate: options.compatibilityDate,
|
|
869
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
870
|
+
assetUploadResult: options.assets
|
|
871
|
+
? await uploadAssets(api, {
|
|
872
|
+
workerName: options.name,
|
|
873
|
+
assets: options.assets,
|
|
874
|
+
assetConfig: props.assets,
|
|
875
|
+
namespace: options.dispatchNamespace,
|
|
876
|
+
})
|
|
877
|
+
: undefined,
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
// We always "adopt" when publishing versions
|
|
881
|
+
} else if (!props.adopt) {
|
|
882
|
+
await assertWorkerDoesNotExist(api, options.name);
|
|
883
|
+
} else if (
|
|
884
|
+
props.adopt &&
|
|
885
|
+
!options.dispatchNamespace &&
|
|
886
|
+
props.url === false
|
|
887
|
+
) {
|
|
888
|
+
// explicitly disable the workers.dev subdomain
|
|
889
|
+
await disableWorkerSubdomain(api, options.name);
|
|
812
890
|
}
|
|
813
|
-
|
|
814
|
-
} else if (bundleSourceResult.isErr()) {
|
|
815
|
-
throw new Error(bundleSourceResult.error);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
const bundleSource = bundleSourceResult.value;
|
|
819
|
-
|
|
820
|
-
if (this.phase === "update") {
|
|
891
|
+
} else if (this.phase === "update") {
|
|
821
892
|
const oldName = this.output.name ?? this.output.id;
|
|
822
|
-
const newName =
|
|
893
|
+
const newName = options.name;
|
|
823
894
|
|
|
824
895
|
if (oldName && oldName !== newName) {
|
|
825
|
-
if (dispatchNamespace) {
|
|
896
|
+
if (options.dispatchNamespace) {
|
|
826
897
|
this.replace(true);
|
|
827
898
|
} else {
|
|
828
899
|
const renameResponse = await api.patch(
|
|
@@ -837,253 +908,105 @@ const _Worker = Resource(
|
|
|
837
908
|
}
|
|
838
909
|
}
|
|
839
910
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
workflowsBindings.push(binding);
|
|
850
|
-
} else if (binding.type === "container") {
|
|
851
|
-
containersBindings.push(binding);
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
const putWorkerWithAssets = async (
|
|
857
|
-
props: WorkerProps<B>,
|
|
858
|
-
scriptBundle: WorkerBundle,
|
|
859
|
-
) => {
|
|
860
|
-
const assetUploadResult = assetsBinding
|
|
861
|
-
? await uploadAssets(api, {
|
|
862
|
-
workerName,
|
|
863
|
-
assets: assetsBinding,
|
|
864
|
-
assetConfig: props.assets,
|
|
865
|
-
namespace: dispatchNamespace,
|
|
866
|
-
})
|
|
867
|
-
: undefined;
|
|
911
|
+
const assets = options.assets
|
|
912
|
+
? await uploadAssets(api, {
|
|
913
|
+
workerName: options.name,
|
|
914
|
+
assets: options.assets,
|
|
915
|
+
assetConfig: props.assets,
|
|
916
|
+
namespace: options.dispatchNamespace,
|
|
917
|
+
})
|
|
918
|
+
: undefined;
|
|
919
|
+
let result: PutWorkerResult;
|
|
868
920
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
dispatchNamespace,
|
|
921
|
+
if (this.scope.watch) {
|
|
922
|
+
const controller = new AbortController();
|
|
923
|
+
result = await watchWorker(api, props, {
|
|
924
|
+
id,
|
|
925
|
+
name: options.name,
|
|
926
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
927
|
+
bundle,
|
|
928
|
+
compatibilityDate: options.compatibilityDate,
|
|
929
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
875
930
|
version: props.version,
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
assetUploadResult,
|
|
931
|
+
assets,
|
|
932
|
+
controller,
|
|
879
933
|
});
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
if (this.phase === "create") {
|
|
883
|
-
if (props.version) {
|
|
884
|
-
// When version is specified, we adopt existing workers or create them if they don't exist
|
|
885
|
-
if (!(await workerExists(api, workerName))) {
|
|
886
|
-
// Create the base worker first if it doesn't exist
|
|
887
|
-
const baseWorkerProps = { ...props, version: undefined };
|
|
888
|
-
await putWorkerWithAssets(
|
|
889
|
-
baseWorkerProps,
|
|
890
|
-
await bundleSource.create(),
|
|
891
|
-
);
|
|
892
|
-
}
|
|
893
|
-
// We always "adopt" when publishing versions
|
|
894
|
-
} else if (!props.adopt) {
|
|
895
|
-
await assertWorkerDoesNotExist(api, workerName);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
let putWorkerResult: PutWorkerResult;
|
|
900
|
-
if (watch) {
|
|
901
|
-
const controller = new AbortController();
|
|
902
|
-
const promise = new DeferredPromise<PutWorkerResult>();
|
|
903
|
-
const runWatch = async () => {
|
|
904
|
-
for await (const bundle of bundleSource.watch(controller.signal)) {
|
|
905
|
-
if (promise.status === "pending") {
|
|
906
|
-
await putWorkerWithAssets(props, bundle)
|
|
907
|
-
.then((result) => promise.resolve(result))
|
|
908
|
-
.catch((error) => {
|
|
909
|
-
controller.abort();
|
|
910
|
-
promise.reject(error);
|
|
911
|
-
});
|
|
912
|
-
continue;
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
logger.task("", {
|
|
916
|
-
message: "reload",
|
|
917
|
-
status: "success",
|
|
918
|
-
resource: id,
|
|
919
|
-
prefix: "build",
|
|
920
|
-
prefixColor: "cyanBright",
|
|
921
|
-
});
|
|
922
|
-
await putWorker(api, {
|
|
923
|
-
...props,
|
|
924
|
-
workerName,
|
|
925
|
-
scriptBundle: bundle,
|
|
926
|
-
dispatchNamespace,
|
|
927
|
-
version: props.version,
|
|
928
|
-
compatibilityDate,
|
|
929
|
-
compatibilityFlags,
|
|
930
|
-
assetUploadResult: assetsBinding
|
|
931
|
-
? {
|
|
932
|
-
keepAssets: true,
|
|
933
|
-
assetConfig: props.assets,
|
|
934
|
-
}
|
|
935
|
-
: undefined,
|
|
936
|
-
unstable_cacheWorkerSettings: true,
|
|
937
|
-
});
|
|
938
|
-
logger.task("", {
|
|
939
|
-
message: "updated",
|
|
940
|
-
status: "success",
|
|
941
|
-
resource: id,
|
|
942
|
-
prefix: "build",
|
|
943
|
-
prefixColor: "greenBright",
|
|
944
|
-
});
|
|
945
|
-
}
|
|
946
|
-
};
|
|
947
|
-
void runWatch(); // this is not awaited because it's an ongoing process
|
|
948
934
|
this.onCleanup(() => controller.abort());
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
logger.error(`Failed to create tail for ${workerName}`, error);
|
|
935
|
+
const tail = await createTail(api, id, options.name).catch((error) => {
|
|
936
|
+
logger.error(`Failed to create tail for ${options.name}`, error);
|
|
952
937
|
});
|
|
953
938
|
this.onCleanup(() => tail?.close());
|
|
954
939
|
} else {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
workflow.scriptName === workerName
|
|
965
|
-
) {
|
|
966
|
-
tasks.push(
|
|
967
|
-
upsertWorkflow(api, {
|
|
968
|
-
workflowName: workflow.workflowName,
|
|
969
|
-
className: workflow.className,
|
|
970
|
-
scriptName: workflow.scriptName ?? workerName,
|
|
971
|
-
}),
|
|
972
|
-
);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
if (containersBindings.length > 0) {
|
|
977
|
-
tasks.push(
|
|
978
|
-
getVersionMetadata(api, workerName, putWorkerResult.deployment_id).then(
|
|
979
|
-
(versionMetadata) =>
|
|
980
|
-
provisionContainers(api, {
|
|
981
|
-
scriptName: workerName,
|
|
982
|
-
containers: containersBindings,
|
|
983
|
-
bindings: versionMetadata.resources.bindings,
|
|
984
|
-
}),
|
|
985
|
-
),
|
|
986
|
-
);
|
|
940
|
+
result = await putWorker(api, {
|
|
941
|
+
...props,
|
|
942
|
+
workerName: options.name,
|
|
943
|
+
scriptBundle: await bundle.create(),
|
|
944
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
945
|
+
compatibilityDate: options.compatibilityDate,
|
|
946
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
947
|
+
assetUploadResult: assets,
|
|
948
|
+
});
|
|
987
949
|
}
|
|
988
950
|
|
|
989
|
-
if (
|
|
990
|
-
|
|
991
|
-
api.
|
|
992
|
-
|
|
993
|
-
props.crons?.map((cron) => ({ cron })) ?? [],
|
|
994
|
-
),
|
|
951
|
+
if (props.crons) {
|
|
952
|
+
await api.put(
|
|
953
|
+
`/accounts/${api.accountId}/workers/scripts/${options.name}/schedules`,
|
|
954
|
+
props.crons?.map((cron) => ({ cron })) ?? [],
|
|
995
955
|
);
|
|
996
956
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
957
|
+
await Promise.all(
|
|
958
|
+
options.workflows.map((workflow) =>
|
|
959
|
+
upsertWorkflow(api, {
|
|
960
|
+
workflowName: workflow.workflowName,
|
|
961
|
+
className: workflow.className,
|
|
962
|
+
scriptName: workflow.scriptName ?? options.name,
|
|
963
|
+
}),
|
|
964
|
+
),
|
|
1004
965
|
);
|
|
1005
966
|
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
scriptName: workerName,
|
|
1015
|
-
adopt: props.adopt,
|
|
1016
|
-
routes: props.routes,
|
|
1017
|
-
}),
|
|
1018
|
-
provisionSubdomain(api, {
|
|
1019
|
-
scriptName: workerName,
|
|
1020
|
-
enable: props.url ?? dispatchNamespace === undefined,
|
|
1021
|
-
previewVersionId:
|
|
1022
|
-
props.version && putWorkerResult.metadata.has_preview
|
|
1023
|
-
? putWorkerResult.id
|
|
1024
|
-
: undefined,
|
|
1025
|
-
retain: !!props.version,
|
|
1026
|
-
forceDelete:
|
|
1027
|
-
this.phase === "create" && !!props.adopt && props.url === false,
|
|
1028
|
-
}),
|
|
1029
|
-
...tasks,
|
|
1030
|
-
]);
|
|
1031
|
-
|
|
1032
|
-
const now = Date.now();
|
|
967
|
+
const { domains, routes, subdomain } = await provisionResources(props, {
|
|
968
|
+
name: options.name,
|
|
969
|
+
local: false,
|
|
970
|
+
dispatchNamespace: options.dispatchNamespace,
|
|
971
|
+
containers: options.containers,
|
|
972
|
+
result,
|
|
973
|
+
api,
|
|
974
|
+
});
|
|
1033
975
|
|
|
1034
|
-
|
|
976
|
+
const now = new Date();
|
|
1035
977
|
return this({
|
|
1036
978
|
...props,
|
|
1037
979
|
type: "service",
|
|
1038
980
|
id,
|
|
1039
981
|
entrypoint: props.entrypoint,
|
|
1040
|
-
name:
|
|
1041
|
-
cwd:
|
|
1042
|
-
compatibilityDate,
|
|
1043
|
-
compatibilityFlags,
|
|
1044
|
-
format: props.format || "esm",
|
|
1045
|
-
bindings: normalizeExportBindings(
|
|
982
|
+
name: options.name,
|
|
983
|
+
cwd: path.relative(process.cwd(), options.cwd),
|
|
984
|
+
compatibilityDate: options.compatibilityDate,
|
|
985
|
+
compatibilityFlags: options.compatibilityFlags,
|
|
986
|
+
format: props.format || "esm",
|
|
987
|
+
bindings: normalizeExportBindings(options.name, props.bindings),
|
|
1046
988
|
env: props.env,
|
|
1047
989
|
observability: props.observability,
|
|
1048
990
|
createdAt: this.output?.createdAt ?? now,
|
|
1049
991
|
updatedAt: now,
|
|
1050
992
|
eventSources: props.eventSources,
|
|
1051
993
|
url: subdomain?.url,
|
|
1052
|
-
dev: props.dev,
|
|
1053
|
-
// Include assets configuration in the output
|
|
1054
994
|
assets: props.assets,
|
|
1055
|
-
// Include cron triggers in the output
|
|
1056
995
|
crons: props.crons,
|
|
1057
|
-
// Include the created routes in the output
|
|
1058
996
|
routes,
|
|
1059
|
-
// Include the created domains in the output
|
|
1060
997
|
domains,
|
|
1061
|
-
// Include the dispatch namespace in the output
|
|
1062
998
|
namespace: props.namespace,
|
|
1063
|
-
// Include version information in the output
|
|
1064
999
|
version: props.version,
|
|
1065
|
-
// Include placement configuration in the output
|
|
1066
1000
|
placement: props.placement,
|
|
1067
|
-
// Include limits configuration in the output
|
|
1068
1001
|
limits: props.limits,
|
|
1069
|
-
// phantom property
|
|
1070
1002
|
Env: undefined!,
|
|
1003
|
+
dev: {
|
|
1004
|
+
hasRemote: true,
|
|
1005
|
+
},
|
|
1071
1006
|
} as unknown as Worker<B>);
|
|
1072
1007
|
},
|
|
1073
1008
|
);
|
|
1074
1009
|
|
|
1075
|
-
const assertUnique = <T, Key extends keyof T>(
|
|
1076
|
-
inputs: T[],
|
|
1077
|
-
key: Key,
|
|
1078
|
-
message: string,
|
|
1079
|
-
) => {
|
|
1080
|
-
const ids = inputs.map((input) => input[key]);
|
|
1081
|
-
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
1082
|
-
if (duplicates.length > 0) {
|
|
1083
|
-
throw new Error(`Duplicate ${message} found: ${duplicates.join(", ")}`);
|
|
1084
|
-
}
|
|
1085
|
-
};
|
|
1086
|
-
|
|
1087
1010
|
const normalizeExportBindings = (
|
|
1088
1011
|
scriptName: string,
|
|
1089
1012
|
bindings: Bindings = {},
|
|
@@ -1108,188 +1031,276 @@ const normalizeExportBindings = (
|
|
|
1108
1031
|
);
|
|
1109
1032
|
};
|
|
1110
1033
|
|
|
1111
|
-
const
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
api: CloudflareApi,
|
|
1121
|
-
props: {
|
|
1122
|
-
scriptName: string;
|
|
1123
|
-
containers?: Container[];
|
|
1124
|
-
bindings: WorkerBindingSpec[];
|
|
1125
|
-
},
|
|
1126
|
-
): Promise<ContainerApplication[] | undefined> {
|
|
1127
|
-
if (!props.containers?.length) {
|
|
1128
|
-
return;
|
|
1034
|
+
const assertUnique = <T, Key extends keyof T>(
|
|
1035
|
+
inputs: T[],
|
|
1036
|
+
key: Key,
|
|
1037
|
+
message: string,
|
|
1038
|
+
) => {
|
|
1039
|
+
const ids = inputs.map((input) => input[key]);
|
|
1040
|
+
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
1041
|
+
if (duplicates.length > 0) {
|
|
1042
|
+
throw new Error(`Duplicate ${message} found: ${duplicates.join(", ")}`);
|
|
1129
1043
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
async function provisionResources<B extends Bindings>(
|
|
1047
|
+
props: WorkerProps<B>,
|
|
1048
|
+
options:
|
|
1049
|
+
| {
|
|
1050
|
+
name: string;
|
|
1051
|
+
local: true;
|
|
1052
|
+
dispatchNamespace: string | undefined;
|
|
1053
|
+
containers: Container[] | undefined;
|
|
1054
|
+
result?: undefined;
|
|
1055
|
+
api?: undefined;
|
|
1139
1056
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1057
|
+
| {
|
|
1058
|
+
name: string;
|
|
1059
|
+
local: false;
|
|
1060
|
+
dispatchNamespace: string | undefined;
|
|
1061
|
+
containers: Container[] | undefined;
|
|
1062
|
+
result: PutWorkerResult;
|
|
1063
|
+
api: CloudflareApi;
|
|
1064
|
+
},
|
|
1065
|
+
) {
|
|
1066
|
+
let metadataPromise: ReturnType<typeof getVersionMetadata> | undefined;
|
|
1067
|
+
|
|
1068
|
+
const input = {
|
|
1069
|
+
containers: options.containers,
|
|
1070
|
+
domains: props.domains?.map((domain) => {
|
|
1071
|
+
if (typeof domain === "string") {
|
|
1072
|
+
return {
|
|
1073
|
+
name: domain,
|
|
1074
|
+
zoneId: undefined,
|
|
1075
|
+
adopt: props.adopt,
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
return {
|
|
1079
|
+
name: domain.domainName,
|
|
1080
|
+
zoneId: domain.zoneId,
|
|
1081
|
+
adopt: domain.adopt ?? props.adopt,
|
|
1082
|
+
};
|
|
1152
1083
|
}),
|
|
1153
|
-
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
async function provisionEventSources(
|
|
1157
|
-
api: CloudflareApi,
|
|
1158
|
-
props: {
|
|
1159
|
-
scriptName: string;
|
|
1160
|
-
eventSources?: EventSource[];
|
|
1161
|
-
adopt?: boolean;
|
|
1162
|
-
},
|
|
1163
|
-
): Promise<QueueConsumer[] | undefined> {
|
|
1164
|
-
if (!props.eventSources?.length) {
|
|
1165
|
-
return;
|
|
1166
|
-
}
|
|
1167
|
-
return await Promise.all(
|
|
1168
|
-
props.eventSources.map((eventSource) => {
|
|
1084
|
+
eventSources: props.eventSources?.map((eventSource) => {
|
|
1169
1085
|
if (isQueue(eventSource)) {
|
|
1170
|
-
return
|
|
1086
|
+
return {
|
|
1171
1087
|
queue: eventSource,
|
|
1172
|
-
scriptName: props.scriptName,
|
|
1173
1088
|
settings: eventSource.dlq
|
|
1174
1089
|
? { deadLetterQueue: eventSource.dlq }
|
|
1175
1090
|
: undefined,
|
|
1176
|
-
|
|
1177
|
-
...normalizeApiOptions(api),
|
|
1178
|
-
});
|
|
1091
|
+
};
|
|
1179
1092
|
}
|
|
1180
1093
|
if (isQueueEventSource(eventSource)) {
|
|
1181
|
-
return
|
|
1094
|
+
return {
|
|
1182
1095
|
queue: eventSource.queue,
|
|
1183
|
-
scriptName: props.scriptName,
|
|
1184
1096
|
settings: eventSource.settings,
|
|
1185
|
-
|
|
1186
|
-
...normalizeApiOptions(api),
|
|
1187
|
-
});
|
|
1097
|
+
};
|
|
1188
1098
|
}
|
|
1189
1099
|
throw new Error(`Unsupported event source: ${eventSource}`);
|
|
1190
1100
|
}),
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
adopt?: boolean;
|
|
1199
|
-
domains?: WorkerProps["domains"];
|
|
1200
|
-
},
|
|
1201
|
-
): Promise<CustomDomain[] | undefined> {
|
|
1202
|
-
if (!props.domains?.length) {
|
|
1203
|
-
return;
|
|
1204
|
-
}
|
|
1205
|
-
const domains = props.domains.map((domain) => {
|
|
1206
|
-
if (typeof domain === "string") {
|
|
1101
|
+
routes: props.routes?.map((route) => {
|
|
1102
|
+
if (typeof route === "string") {
|
|
1103
|
+
return {
|
|
1104
|
+
pattern: route,
|
|
1105
|
+
adopt: props.adopt,
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1207
1108
|
return {
|
|
1208
|
-
|
|
1209
|
-
zoneId:
|
|
1210
|
-
adopt: props.adopt,
|
|
1109
|
+
pattern: route.pattern,
|
|
1110
|
+
zoneId: route.zoneId,
|
|
1111
|
+
adopt: route.adopt ?? props.adopt,
|
|
1211
1112
|
};
|
|
1212
|
-
}
|
|
1213
|
-
return {
|
|
1214
|
-
name: domain.domainName,
|
|
1215
|
-
zoneId: domain.zoneId,
|
|
1216
|
-
adopt: domain.adopt ?? props.adopt,
|
|
1217
|
-
};
|
|
1218
|
-
});
|
|
1219
|
-
assertUnique(domains, "name", "Custom Domain");
|
|
1220
|
-
return await Promise.all(
|
|
1221
|
-
domains.map(async (domain) => {
|
|
1222
|
-
return await CustomDomain(domain.name, {
|
|
1223
|
-
workerName: props.scriptName,
|
|
1224
|
-
name: domain.name,
|
|
1225
|
-
zoneId: domain.zoneId,
|
|
1226
|
-
adopt: domain.adopt,
|
|
1227
|
-
...normalizeApiOptions(api),
|
|
1228
|
-
});
|
|
1229
1113
|
}),
|
|
1230
|
-
|
|
1231
|
-
|
|
1114
|
+
api: {
|
|
1115
|
+
accountId: props.accountId,
|
|
1116
|
+
apiKey: props.apiKey,
|
|
1117
|
+
apiToken: props.apiToken,
|
|
1118
|
+
email: props.email,
|
|
1119
|
+
baseUrl: props.baseUrl,
|
|
1120
|
+
} satisfies CloudflareApiOptions,
|
|
1121
|
+
};
|
|
1232
1122
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
props: {
|
|
1236
|
-
scriptName: string;
|
|
1237
|
-
adopt?: boolean;
|
|
1238
|
-
routes?: WorkerProps["routes"];
|
|
1239
|
-
},
|
|
1240
|
-
): Promise<Route[] | undefined> {
|
|
1241
|
-
if (!props.routes?.length) {
|
|
1242
|
-
return;
|
|
1123
|
+
if (input.routes) {
|
|
1124
|
+
assertUnique(input.routes, "pattern", "Route");
|
|
1243
1125
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1126
|
+
if (input.domains) {
|
|
1127
|
+
assertUnique(input.domains, "name", "Custom Domain");
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
const [containers, domains, eventSources, routes, subdomain] =
|
|
1131
|
+
await Promise.all([
|
|
1132
|
+
input.containers
|
|
1133
|
+
? Promise.all(
|
|
1134
|
+
input.containers.map(async (container) => {
|
|
1135
|
+
return await ContainerApplication(container.id, {
|
|
1136
|
+
image: container.image,
|
|
1137
|
+
name: container.name,
|
|
1138
|
+
instanceType: container.instanceType,
|
|
1139
|
+
observability: container.observability,
|
|
1140
|
+
durableObjects: {
|
|
1141
|
+
namespaceId: await getContainerNamespaceId(container),
|
|
1142
|
+
},
|
|
1143
|
+
schedulingPolicy: container.schedulingPolicy,
|
|
1144
|
+
adopt: container.adopt,
|
|
1145
|
+
dev: options.local,
|
|
1146
|
+
...input.api,
|
|
1147
|
+
});
|
|
1148
|
+
}),
|
|
1149
|
+
)
|
|
1150
|
+
: undefined,
|
|
1151
|
+
input.domains
|
|
1152
|
+
? Promise.all(
|
|
1153
|
+
input.domains.map(async (domain) => {
|
|
1154
|
+
return await CustomDomain(domain.name, {
|
|
1155
|
+
name: domain.name,
|
|
1156
|
+
zoneId: domain.zoneId,
|
|
1157
|
+
adopt: domain.adopt,
|
|
1158
|
+
workerName: options.name,
|
|
1159
|
+
dev: options.local,
|
|
1160
|
+
...input.api,
|
|
1161
|
+
});
|
|
1162
|
+
}),
|
|
1163
|
+
)
|
|
1164
|
+
: undefined,
|
|
1165
|
+
input.eventSources
|
|
1166
|
+
? Promise.all(
|
|
1167
|
+
input.eventSources.map(async (eventSource) => {
|
|
1168
|
+
return await QueueConsumer(`${eventSource.queue.id}-consumer`, {
|
|
1169
|
+
queue: eventSource.queue,
|
|
1170
|
+
scriptName: options.name,
|
|
1171
|
+
settings: eventSource.settings,
|
|
1172
|
+
adopt: props.adopt,
|
|
1173
|
+
dev: options.local,
|
|
1174
|
+
...input.api,
|
|
1175
|
+
});
|
|
1176
|
+
}),
|
|
1177
|
+
)
|
|
1178
|
+
: undefined,
|
|
1179
|
+
input.routes
|
|
1180
|
+
? Promise.all(
|
|
1181
|
+
input.routes.map(async (route) => {
|
|
1182
|
+
return await Route(route.pattern, {
|
|
1183
|
+
pattern: route.pattern,
|
|
1184
|
+
script: options.name,
|
|
1185
|
+
zoneId: route.zoneId,
|
|
1186
|
+
adopt: route.adopt,
|
|
1187
|
+
dev: options.local,
|
|
1188
|
+
...input.api,
|
|
1189
|
+
});
|
|
1190
|
+
}),
|
|
1191
|
+
)
|
|
1192
|
+
: undefined,
|
|
1193
|
+
(props.url ?? !options.dispatchNamespace)
|
|
1194
|
+
? WorkerSubdomain("url", {
|
|
1195
|
+
scriptName: options.name,
|
|
1196
|
+
previewVersionId: props.version ? options.result?.id : undefined,
|
|
1197
|
+
retain: !!props.version,
|
|
1198
|
+
dev: options.local,
|
|
1199
|
+
...input.api,
|
|
1200
|
+
})
|
|
1201
|
+
: undefined,
|
|
1202
|
+
]);
|
|
1203
|
+
|
|
1204
|
+
return { containers, domains, routes, eventSources, subdomain };
|
|
1205
|
+
|
|
1206
|
+
async function getContainerNamespaceId(container: Container) {
|
|
1207
|
+
if (options.local) {
|
|
1208
|
+
return container.id;
|
|
1250
1209
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1210
|
+
metadataPromise ??= getVersionMetadata(
|
|
1211
|
+
options.api,
|
|
1212
|
+
options.name,
|
|
1213
|
+
options.result.deployment_id,
|
|
1214
|
+
);
|
|
1215
|
+
const metadata = await metadataPromise;
|
|
1216
|
+
const binding = metadata.resources.bindings.find(
|
|
1217
|
+
(binding): binding is WorkerBindingDurableObjectNamespace =>
|
|
1218
|
+
binding.type === "durable_object_namespace" &&
|
|
1219
|
+
binding.class_name === container.className,
|
|
1220
|
+
);
|
|
1221
|
+
if (!binding?.namespace_id) {
|
|
1222
|
+
throw new Error(
|
|
1223
|
+
`Container ${container.name} not found in version ${options.result.deployment_id}`,
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
return binding.namespace_id;
|
|
1227
|
+
}
|
|
1269
1228
|
}
|
|
1270
1229
|
|
|
1271
|
-
async
|
|
1230
|
+
const watchWorker = async <B extends Bindings>(
|
|
1272
1231
|
api: CloudflareApi,
|
|
1273
|
-
props:
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1232
|
+
props: WorkerProps<B>,
|
|
1233
|
+
input: {
|
|
1234
|
+
id: string;
|
|
1235
|
+
name: string;
|
|
1236
|
+
dispatchNamespace: string | undefined;
|
|
1237
|
+
bundle: WorkerBundleSource;
|
|
1238
|
+
compatibilityDate: string;
|
|
1239
|
+
compatibilityFlags: string[];
|
|
1240
|
+
version: string | undefined;
|
|
1241
|
+
assets: AssetUploadResult | undefined;
|
|
1242
|
+
controller: AbortController;
|
|
1279
1243
|
},
|
|
1280
|
-
)
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1244
|
+
) => {
|
|
1245
|
+
const promise = new DeferredPromise<PutWorkerResult>();
|
|
1246
|
+
const run = async () => {
|
|
1247
|
+
for await (const bundle of input.bundle.watch(input.controller.signal)) {
|
|
1248
|
+
if (promise.status === "pending") {
|
|
1249
|
+
try {
|
|
1250
|
+
const result = await putWorker(api, {
|
|
1251
|
+
...props,
|
|
1252
|
+
workerName: input.name,
|
|
1253
|
+
scriptBundle: bundle,
|
|
1254
|
+
dispatchNamespace: input.dispatchNamespace,
|
|
1255
|
+
compatibilityDate: input.compatibilityDate,
|
|
1256
|
+
compatibilityFlags: input.compatibilityFlags,
|
|
1257
|
+
assetUploadResult: input.assets,
|
|
1258
|
+
});
|
|
1259
|
+
promise.resolve(result);
|
|
1260
|
+
} catch (error) {
|
|
1261
|
+
input.controller.abort();
|
|
1262
|
+
promise.reject(error);
|
|
1263
|
+
}
|
|
1264
|
+
continue;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
logger.task("", {
|
|
1268
|
+
message: "reload",
|
|
1269
|
+
status: "success",
|
|
1270
|
+
resource: input.id,
|
|
1271
|
+
prefix: "build",
|
|
1272
|
+
prefixColor: "cyanBright",
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
await putWorker(api, {
|
|
1276
|
+
...props,
|
|
1277
|
+
workerName: input.name,
|
|
1278
|
+
scriptBundle: bundle,
|
|
1279
|
+
dispatchNamespace: input.dispatchNamespace,
|
|
1280
|
+
version: input.version,
|
|
1281
|
+
compatibilityDate: input.compatibilityDate,
|
|
1282
|
+
compatibilityFlags: input.compatibilityFlags,
|
|
1283
|
+
assetUploadResult: input.assets
|
|
1284
|
+
? {
|
|
1285
|
+
keepAssets: true,
|
|
1286
|
+
assetConfig: props.assets,
|
|
1287
|
+
}
|
|
1288
|
+
: undefined,
|
|
1289
|
+
unstable_cacheWorkerSettings: true,
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1292
|
+
logger.task("", {
|
|
1293
|
+
message: "updated",
|
|
1294
|
+
status: "success",
|
|
1295
|
+
resource: input.id,
|
|
1296
|
+
prefix: "build",
|
|
1297
|
+
prefixColor: "greenBright",
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
void run();
|
|
1302
|
+
return await promise.value;
|
|
1303
|
+
};
|
|
1293
1304
|
|
|
1294
1305
|
type PutWorkerOptions = Omit<WorkerProps, "entrypoint"> & {
|
|
1295
1306
|
dispatchNamespace?: string;
|
|
@@ -1462,12 +1473,20 @@ export async function putWorker(
|
|
|
1462
1473
|
);
|
|
1463
1474
|
}
|
|
1464
1475
|
|
|
1465
|
-
|
|
1476
|
+
const workerExists = async (
|
|
1477
|
+
api: CloudflareApi,
|
|
1478
|
+
options: {
|
|
1479
|
+
name: string;
|
|
1480
|
+
dispatchNamespace: string | undefined;
|
|
1481
|
+
},
|
|
1482
|
+
) => {
|
|
1466
1483
|
const res = await api.get(
|
|
1467
|
-
|
|
1484
|
+
options.dispatchNamespace
|
|
1485
|
+
? `/accounts/${api.accountId}/workers/dispatch/namespaces/${options.dispatchNamespace}/scripts/${options.name}`
|
|
1486
|
+
: `/accounts/${api.accountId}/workers/scripts/${options.name}`,
|
|
1468
1487
|
);
|
|
1469
1488
|
return res.status === 200;
|
|
1470
|
-
}
|
|
1489
|
+
};
|
|
1471
1490
|
|
|
1472
1491
|
async function assertWorkerDoesNotExist(
|
|
1473
1492
|
api: CloudflareApi,
|