alchemy 0.77.0 → 0.77.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,KAAM,SAAQ,UAAU;IACvC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK,yFAGR,OAAO,CAAC,KAAK,CAAC,MAChB,MAAM,SACH,UAAU,KAChB,OAAO,CAAC,KAAK,CAAC,CA8IlB,CAAC"}
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,CACA;IACE;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,GACD;IACE;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,EAAE,kBAAkB,CAAC;IAE1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CACJ,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK,yFAGR,OAAO,CAAC,KAAK,CAAC,MAChB,MAAM,SACH,UAAU,KAChB,OAAO,CAAC,KAAK,CAAC,CA8KlB,CAAC"}
@@ -28,11 +28,26 @@ export const Image = Resource("docker::Image", async function (id, props) {
28
28
  // This is intentional as other resources might depend on the same image
29
29
  return this.destroy();
30
30
  }
31
+ const tag = props.tag || "latest";
32
+ const name = props.name ||
33
+ (typeof props.image === "string"
34
+ ? props.image
35
+ : props.image?.name)?.split(":")[0] ||
36
+ id;
37
+ const imageRef = `${name}:${tag}`;
38
+ let imageId;
39
+ if (props.image) {
40
+ const image = typeof props.image === "string" ? props.image : props.image.imageRef;
41
+ const kind = typeof props.image === "object" && props.image.kind === "Image"
42
+ ? "local"
43
+ : "remote";
44
+ if (kind === "remote") {
45
+ await api.pullImage(image);
46
+ }
47
+ await api.tagImage(image, imageRef);
48
+ // TODO: Extract image ID from pull output if available
49
+ }
31
50
  else {
32
- // Normalize properties
33
- const tag = props.tag || "latest";
34
- const name = props.name || id;
35
- const imageRef = `${name}:${tag}`;
36
51
  let context;
37
52
  let dockerfile;
38
53
  if (props.build?.dockerfile && props.build?.context) {
@@ -56,7 +71,7 @@ export const Image = Resource("docker::Image", async function (id, props) {
56
71
  // Prepare build options
57
72
  const buildOptions = props.build?.args || {};
58
73
  // Add platform if specified
59
- let buildArgs = ["build", "-t", imageRef];
74
+ const buildArgs = ["build", "-t", imageRef];
60
75
  if (props.build?.platform) {
61
76
  buildArgs.push("--platform", props.build.platform);
62
77
  }
@@ -70,10 +85,20 @@ export const Image = Resource("docker::Image", async function (id, props) {
70
85
  buildArgs.push("--cache-from", cacheSource);
71
86
  }
72
87
  }
88
+ // Add cache destinations if specified
89
+ if (props.build?.cacheTo && props.build.cacheTo.length > 0) {
90
+ for (const cacheTarget of props.build.cacheTo) {
91
+ buildArgs.push("--cache-to", cacheTarget);
92
+ }
93
+ }
73
94
  // Add build arguments
74
95
  for (const [key, value] of Object.entries(buildOptions)) {
75
96
  buildArgs.push("--build-arg", `${key}=${value}`);
76
97
  }
98
+ // Add build options if specified
99
+ if (props.build?.options && props.build.options.length > 0) {
100
+ buildArgs.push(...props.build.options);
101
+ }
77
102
  buildArgs.push("-f", dockerfile);
78
103
  // Add context path
79
104
  buildArgs.push(context);
@@ -81,62 +106,65 @@ export const Image = Resource("docker::Image", async function (id, props) {
81
106
  const { stdout } = await api.exec(buildArgs);
82
107
  // Extract image ID from build output if available
83
108
  const imageIdMatch = /Successfully built ([a-f0-9]+)/.exec(stdout);
84
- const imageId = imageIdMatch ? imageIdMatch[1] : undefined;
85
- // Handle push if required
86
- let repoDigest;
87
- let finalImageRef = imageRef;
88
- if (props.registry && !props.skipPush) {
89
- const { server, username, password } = props.registry;
90
- // Ensure the registry server does not have trailing slash
91
- const registryHost = server.replace(/\/$/, "");
92
- // Determine if the built image already includes a registry host (e.g. ghcr.io/user/repo)
93
- const firstSegment = imageRef.split("/")[0];
94
- const hasRegistryPrefix = firstSegment.includes(".");
95
- // Compose the target image reference that will be pushed
96
- const targetImage = hasRegistryPrefix
97
- ? imageRef // already fully-qualified
98
- : `${registryHost}/${imageRef}`;
99
- try {
100
- // Create a temporary directory that will act as an isolated Docker config
101
- // (credentials) directory. This prevents race-conditions when multiple
102
- // concurrent tests perform `docker login` / `logout` by ensuring each
103
- // Image operation has its own credential store.
104
- const tempConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), "docker-config-"));
105
- const api = new DockerApi({ configDir: tempConfigDir });
106
- // Authenticate to registry using the isolated config directory
107
- await api.login(registryHost, username, password.unencrypted);
108
- // Tag local image with fully qualified name if necessary
109
- if (targetImage !== imageRef) {
110
- await api.exec(["tag", imageRef, targetImage]);
111
- }
112
- // Push the image
113
- const { stdout: pushOut } = await api.exec(["push", targetImage]);
114
- // Attempt to extract the repo digest from push output
115
- const digestMatch = /digest:\s+([a-z0-9]+:[a-f0-9]{64})/.exec(pushOut);
116
- if (digestMatch) {
117
- const digestHash = digestMatch[1];
118
- // Strip tag (anything after last :) to build image@digest reference
119
- const [repoWithoutTag] = targetImage.split(":").length > 2
120
- ? [targetImage] // unlikely but safety
121
- : [targetImage.substring(0, targetImage.lastIndexOf(":"))];
122
- repoDigest = `${repoWithoutTag}@${digestHash}`;
123
- }
124
- // Update the final image reference to point at the pushed image
125
- finalImageRef = targetImage;
109
+ imageId = imageIdMatch ? imageIdMatch[1] : undefined;
110
+ }
111
+ // Handle push if required
112
+ let repoDigest;
113
+ let finalImageRef = imageRef;
114
+ if (props.registry && !props.skipPush) {
115
+ const { server, username, password } = props.registry;
116
+ // Ensure the registry server does not have trailing slash
117
+ const registryHost = server.replace(/\/$/, "");
118
+ // Determine if the built image already includes a registry host (e.g. ghcr.io/user/repo)
119
+ const firstSegment = imageRef.split("/")[0];
120
+ const hasRegistryPrefix = firstSegment.includes(".");
121
+ // Compose the target image reference that will be pushed
122
+ const targetImage = hasRegistryPrefix
123
+ ? imageRef // already fully-qualified
124
+ : `${registryHost}/${imageRef}`;
125
+ try {
126
+ // Create a temporary directory that will act as an isolated Docker config
127
+ // (credentials) directory. This prevents race-conditions when multiple
128
+ // concurrent tests perform `docker login` / `logout` by ensuring each
129
+ // Image operation has its own credential store.
130
+ const tempConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), "docker-config-"));
131
+ const api = new DockerApi({ configDir: tempConfigDir });
132
+ // Authenticate to registry using the isolated config directory
133
+ await api.login(registryHost, username, password.unencrypted);
134
+ // Tag local image with fully qualified name if necessary
135
+ if (targetImage !== imageRef) {
136
+ await api.exec(["tag", imageRef, targetImage]);
126
137
  }
127
- finally {
128
- // Clean up credentials from the isolated config
129
- await api.logout(registryHost);
138
+ // Push the image
139
+ const { stdout: pushOut } = await api.exec(["push", targetImage]);
140
+ // Attempt to extract the repo digest from push output
141
+ const digestMatch = /digest:\s+([a-z0-9]+:[a-f0-9]{64})/.exec(pushOut);
142
+ if (digestMatch) {
143
+ const digestHash = digestMatch[1];
144
+ // Strip tag (anything after last :) to build image@digest reference
145
+ const [repoWithoutTag] = targetImage.split(":").length > 2
146
+ ? [targetImage] // unlikely but safety
147
+ : [targetImage.substring(0, targetImage.lastIndexOf(":"))];
148
+ repoDigest = `${repoWithoutTag}@${digestHash}`;
130
149
  }
150
+ // Update the final image reference to point at the pushed image
151
+ finalImageRef = targetImage;
152
+ }
153
+ finally {
154
+ // Clean up credentials from the isolated config
155
+ await api.logout(registryHost);
131
156
  }
132
- return {
133
- ...props,
134
- name,
135
- imageRef: finalImageRef,
136
- imageId,
137
- repoDigest,
138
- builtAt: Date.now(),
139
- };
140
157
  }
158
+ return {
159
+ kind: "Image",
160
+ ...props,
161
+ tag,
162
+ name,
163
+ imageRef: finalImageRef,
164
+ imageId,
165
+ repoDigest,
166
+ builtAt: Date.now(),
167
+ build: props.build,
168
+ };
141
169
  });
142
170
  //# sourceMappingURL=image.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ export interface RemoteImageProps {
20
20
  * Docker Remote Image resource
21
21
  */
22
22
  export interface RemoteImage extends RemoteImageProps {
23
+ kind: "RemoteImage";
23
24
  /**
24
25
  * Full image reference (name:tag)
25
26
  */
@@ -1 +1 @@
1
- {"version":3,"file":"remote-image.d.ts","sourceRoot":"","sources":["../../src/docker/remote-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,yFAGd,OAAO,CAAC,WAAW,CAAC,OACrB,MAAM,SACJ,gBAAgB,KACtB,OAAO,CAAC,WAAW,CAAC,CAuBxB,CAAC"}
1
+ {"version":3,"file":"remote-image.d.ts","sourceRoot":"","sources":["../../src/docker/remote-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,IAAI,EAAE,aAAa,CAAC;IACpB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,yFAGd,OAAO,CAAC,WAAW,CAAC,OACrB,MAAM,SACJ,gBAAgB,KACtB,OAAO,CAAC,WAAW,CAAC,CAyBxB,CAAC"}
@@ -26,8 +26,10 @@ export const RemoteImage = Resource("docker::RemoteImage", async function (_id,
26
26
  // Pull image
27
27
  await api.pullImage(imageRef);
28
28
  return {
29
+ kind: "RemoteImage",
29
30
  ...props,
30
31
  imageRef,
32
+ tag,
31
33
  createdAt: Date.now(),
32
34
  };
33
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote-image.js","sourceRoot":"","sources":["../../src/docker/remote-image.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAqCrC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CACjC,qBAAqB,EACrB,KAAK,WAEH,GAAW,EACX,KAAuB;IAEvB,+BAA+B;IAC/B,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;IAE5B,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,4EAA4E;QAC5E,wEAAwE;QACxE,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,uBAAuB;QACvB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,QAAQ,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;QAExC,aAAa;QACb,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAE9B,OAAO;YACL,GAAG,KAAK;YACR,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC"}
1
+ {"version":3,"file":"remote-image.js","sourceRoot":"","sources":["../../src/docker/remote-image.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAsCrC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CACjC,qBAAqB,EACrB,KAAK,WAEH,GAAW,EACX,KAAuB;IAEvB,+BAA+B;IAC/B,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC;IAE5B,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,4EAA4E;QAC5E,wEAAwE;QACxE,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,uBAAuB;QACvB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,QAAQ,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;QAExC,aAAa;QACb,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAE9B,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,GAAG,KAAK;YACR,QAAQ;YACR,GAAG;YACH,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;AACH,CAAC,CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.77.0",
3
+ "version": "0.77.1",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Sam Goodwin <sam@alchemy.run>",
6
6
  "homepage": "https://alchemy.run",
@@ -4,4 +4,4 @@
4
4
  /**
5
5
  * The default Cloudflare Workers compatibility date, set based on the latest workerd release at the time of build.
6
6
  */
7
- export const DEFAULT_COMPATIBILITY_DATE = "2025-10-31";
7
+ export const DEFAULT_COMPATIBILITY_DATE = "2025-11-09";
@@ -218,10 +218,10 @@ export async function Container<T>(
218
218
  const isDev = scope.local && !props.dev?.remote;
219
219
  if (isDev) {
220
220
  const image = await Image(id, {
221
+ ...props,
221
222
  name: `cloudflare-dev/${name}`, // prefix used by Miniflare
222
223
  tag,
223
- build: props.build,
224
- });
224
+ } as ImageProps);
225
225
 
226
226
  return {
227
227
  ...output,
@@ -235,16 +235,19 @@ export async function Container<T>(
235
235
  const image = await Image(id, {
236
236
  name: `${api.accountId}/${name}`,
237
237
  tag,
238
- build: {
239
- platform: props.build?.platform ?? "linux/amd64",
240
- ...props.build,
241
- },
238
+ build: props.build
239
+ ? {
240
+ platform: props.build?.platform ?? "linux/amd64",
241
+ ...props.build,
242
+ }
243
+ : undefined,
244
+ image: props.image,
242
245
  registry: {
243
246
  server: "registry.cloudflare.com",
244
247
  username: credentials.username || credentials.user!,
245
248
  password: secret(credentials.password),
246
249
  },
247
- });
250
+ } as ImageProps);
248
251
 
249
252
  return {
250
253
  ...output,
@@ -8,6 +8,7 @@ import {
8
8
  type CloudflareApi,
9
9
  type CloudflareApiOptions,
10
10
  } from "./api.ts";
11
+ import { withJurisdiction } from "./bucket.ts";
11
12
  import { cloneD1Database } from "./d1-clone.ts";
12
13
  import { applyLocalD1Migrations } from "./d1-local-migrations.ts";
13
14
  import { applyMigrations, listMigrationsFiles } from "./d1-migrations.ts";
@@ -15,6 +16,8 @@ import { deleteMiniflareBinding } from "./miniflare/delete.ts";
15
16
 
16
17
  const DEFAULT_MIGRATIONS_TABLE = "d1_migrations";
17
18
 
19
+ export type D1DatabaseJurisdiction = "default" | "eu" | "fedramp";
20
+
18
21
  type PrimaryLocationHint =
19
22
  | "wnam"
20
23
  | "enam"
@@ -115,6 +118,12 @@ export interface D1DatabaseProps extends CloudflareApiOptions {
115
118
  */
116
119
  force?: boolean;
117
120
  };
121
+
122
+ /**
123
+ * Optional jurisdiction for the bucket
124
+ * Determines the regulatory jurisdiction the bucket data falls under
125
+ */
126
+ jurisdiction?: D1DatabaseJurisdiction;
118
127
  }
119
128
 
120
129
  export function isD1Database(resource: any): resource is D1Database {
@@ -157,6 +166,11 @@ export type D1Database = Pick<
157
166
  */
158
167
  remote: boolean;
159
168
  };
169
+
170
+ /**
171
+ * The jurisdiction of the database
172
+ */
173
+ jurisdiction: D1DatabaseJurisdiction;
160
174
  };
161
175
 
162
176
  /**
@@ -260,10 +274,11 @@ const _D1Database = Resource(
260
274
  async function (
261
275
  this: Context<D1Database>,
262
276
  id: string,
263
- props: D1DatabaseProps = {},
277
+ props: D1DatabaseProps,
264
278
  ): Promise<D1Database> {
265
279
  const databaseName =
266
280
  props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
281
+ const jurisdiction = props.jurisdiction ?? "default";
267
282
 
268
283
  if (this.phase === "update" && this.output?.name !== databaseName) {
269
284
  this.replace();
@@ -294,6 +309,7 @@ const _D1Database = Resource(
294
309
  migrationsDir: props.migrationsDir,
295
310
  migrationsTable: props.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE,
296
311
  dev,
312
+ jurisdiction,
297
313
  };
298
314
  }
299
315
 
@@ -304,7 +320,7 @@ const _D1Database = Resource(
304
320
  await deleteMiniflareBinding(this.scope, "d1", this.output.dev.id);
305
321
  }
306
322
  if (props.delete !== false && this.output?.id) {
307
- await deleteDatabase(api, this.output.id);
323
+ await deleteDatabase(api, this.output.id, props);
308
324
  }
309
325
  // Return void (a deleted database has no content)
310
326
  return this.destroy();
@@ -328,7 +344,7 @@ const _D1Database = Resource(
328
344
 
329
345
  // If clone property is provided, perform cloning after database creation
330
346
  if (props.clone && dbData.result.uuid) {
331
- await cloneDb(api, props.clone, dbData.result.uuid);
347
+ await cloneDb(api, props.clone, dbData.result.uuid, jurisdiction);
332
348
  }
333
349
  } catch (error) {
334
350
  // Check if this is a "database already exists" error and adopt is enabled
@@ -339,7 +355,7 @@ const _D1Database = Resource(
339
355
  ) {
340
356
  logger.log(`Database ${databaseName} already exists, adopting it`);
341
357
  // Find the existing database by name
342
- const databases = await listDatabases(api, databaseName);
358
+ const databases = await listDatabases(api, databaseName, props);
343
359
  const existingDb = databases.find((db) => db.name === databaseName);
344
360
 
345
361
  if (!existingDb) {
@@ -349,7 +365,7 @@ const _D1Database = Resource(
349
365
  }
350
366
 
351
367
  // Get the database details using its ID
352
- dbData = await getDatabase(api, existingDb.id);
368
+ dbData = await getDatabase(api, existingDb.id, props);
353
369
 
354
370
  // Update the database with the provided properties
355
371
  if (props.readReplication) {
@@ -413,6 +429,7 @@ const _D1Database = Resource(
413
429
  dev,
414
430
  migrationsDir: props.migrationsDir,
415
431
  migrationsTable: props.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE,
432
+ jurisdiction,
416
433
  };
417
434
  },
418
435
  );
@@ -454,6 +471,9 @@ export async function createDatabase(
454
471
  const createResponse = await api.post(
455
472
  `/accounts/${api.accountId}/d1/database`,
456
473
  createPayload,
474
+ {
475
+ headers: withJurisdiction(props),
476
+ },
457
477
  );
458
478
 
459
479
  if (!createResponse.ok) {
@@ -474,6 +494,7 @@ export async function createDatabase(
474
494
  export async function getDatabase(
475
495
  api: CloudflareApi,
476
496
  databaseId?: string,
497
+ props: D1DatabaseProps = {},
477
498
  ): Promise<CloudflareD1Response> {
478
499
  if (!databaseId) {
479
500
  throw new Error("Database ID is required");
@@ -481,6 +502,9 @@ export async function getDatabase(
481
502
 
482
503
  const response = await api.get(
483
504
  `/accounts/${api.accountId}/d1/database/${databaseId}`,
505
+ {
506
+ headers: withJurisdiction(props),
507
+ },
484
508
  );
485
509
 
486
510
  if (!response.ok) {
@@ -496,6 +520,7 @@ export async function getDatabase(
496
520
  export async function deleteDatabase(
497
521
  api: CloudflareApi,
498
522
  databaseId?: string,
523
+ props: D1DatabaseProps = {},
499
524
  ): Promise<void> {
500
525
  if (!databaseId) {
501
526
  logger.log("No database ID provided, skipping delete");
@@ -505,6 +530,9 @@ export async function deleteDatabase(
505
530
  // Delete D1 database
506
531
  const deleteResponse = await api.delete(
507
532
  `/accounts/${api.accountId}/d1/database/${databaseId}`,
533
+ {
534
+ headers: withJurisdiction(props),
535
+ },
508
536
  );
509
537
 
510
538
  if (!deleteResponse.ok && deleteResponse.status !== 404) {
@@ -524,12 +552,16 @@ export async function deleteDatabase(
524
552
  export async function listDatabases(
525
553
  api: CloudflareApi,
526
554
  name?: string,
555
+ props: D1DatabaseProps = {},
527
556
  ): Promise<{ name: string; id: string }[]> {
528
557
  // Construct query string if name is provided
529
558
  const queryParams = name ? `?name=${encodeURIComponent(name)}` : "";
530
559
 
531
560
  const response = await api.get(
532
561
  `/accounts/${api.accountId}/d1/database${queryParams}`,
562
+ {
563
+ headers: withJurisdiction(props),
564
+ },
533
565
  );
534
566
 
535
567
  if (!response.ok) {
@@ -582,6 +614,9 @@ export async function updateDatabase(
582
614
  const updateResponse = await api.patch(
583
615
  `/accounts/${api.accountId}/d1/database/${databaseId}`,
584
616
  updatePayload,
617
+ {
618
+ headers: withJurisdiction(props),
619
+ },
585
620
  );
586
621
 
587
622
  if (!updateResponse.ok) {
@@ -608,6 +643,7 @@ async function cloneDb(
608
643
  api: CloudflareApi,
609
644
  sourceDb: D1Database | { id: string } | { name: string },
610
645
  targetDbId: string,
646
+ jurisdiction: D1DatabaseJurisdiction,
611
647
  ): Promise<void> {
612
648
  let sourceId: string;
613
649
 
@@ -617,7 +653,9 @@ async function cloneDb(
617
653
  sourceId = sourceDb.id;
618
654
  } else if ("name" in sourceDb && sourceDb.name) {
619
655
  // Look up ID by name
620
- const databases = await listDatabases(api, sourceDb.name);
656
+ const databases = await listDatabases(api, sourceDb.name, {
657
+ jurisdiction,
658
+ });
621
659
  const foundDb = databases.find((db) => db.name === sourceDb.name);
622
660
 
623
661
  if (!foundDb) {
package/src/docker/api.ts CHANGED
@@ -177,6 +177,13 @@ export class DockerApi {
177
177
  return this.exec(["pull", image]);
178
178
  }
179
179
 
180
+ async tagImage(
181
+ source: string,
182
+ target: string,
183
+ ): Promise<{ stdout: string; stderr: string }> {
184
+ return this.exec(["tag", source, target]);
185
+ }
186
+
180
187
  /**
181
188
  * Build Docker image
182
189
  *