alchemy 0.83.0 → 0.83.2
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 +19 -11
- package/bin/commands/deploy.ts +2 -0
- package/bin/commands/destroy.ts +1 -1
- package/bin/services/execute-alchemy.ts +11 -0
- package/bin/services/package-manager.ts +5 -1
- package/lib/alchemy.d.ts +8 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +4 -0
- package/lib/alchemy.js.map +1 -1
- package/lib/aws/ec2/internet-gateway-attachment.d.ts.map +1 -1
- package/lib/aws/ec2/internet-gateway-attachment.js.map +1 -1
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +1 -1
- package/lib/aws/oidc/github-oidc-provider.js.map +1 -1
- package/lib/cloudflare/api-error.d.ts +9 -0
- package/lib/cloudflare/api-error.d.ts.map +1 -1
- package/lib/cloudflare/api-error.js +1 -24
- package/lib/cloudflare/api-error.js.map +1 -1
- package/lib/cloudflare/api-response.d.ts.map +1 -1
- package/lib/cloudflare/api-response.js.map +1 -1
- package/lib/cloudflare/api-schema.d.ts.map +1 -1
- package/lib/cloudflare/api-schema.js.map +1 -1
- package/lib/cloudflare/api-shield.d.ts.map +1 -1
- package/lib/cloudflare/api-shield.js.map +1 -1
- package/lib/cloudflare/astro/astro.d.ts.map +1 -1
- package/lib/cloudflare/astro/astro.js.map +1 -1
- package/lib/cloudflare/astro/plugin.d.ts.map +1 -1
- package/lib/cloudflare/astro/plugin.js +15 -1
- package/lib/cloudflare/astro/plugin.js.map +1 -1
- package/lib/cloudflare/bucket-custom-domain.d.ts.map +1 -1
- package/lib/cloudflare/bucket-custom-domain.js.map +1 -1
- package/lib/cloudflare/bucket.d.ts +1 -1
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +1 -1
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.js +4 -2
- package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +2 -2
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/dispatch-namespace.d.ts.map +1 -1
- package/lib/cloudflare/dispatch-namespace.js.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +25 -0
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +26 -3
- 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/logpush-job.d.ts.map +1 -1
- package/lib/cloudflare/logpush-job.js +12 -7
- package/lib/cloudflare/logpush-job.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +2 -2
- package/lib/cloudflare/ruleset.d.ts.map +1 -1
- package/lib/cloudflare/ruleset.js.map +1 -1
- package/lib/cloudflare/tunnel-route.d.ts.map +1 -1
- package/lib/cloudflare/tunnel-route.js.map +1 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-assets.d.ts +1 -1
- package/lib/cloudflare/worker-assets.d.ts.map +1 -1
- package/lib/cloudflare/worker-assets.js +1 -1
- package/lib/cloudflare/worker-assets.js.map +1 -1
- package/lib/cloudflare/worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/worker-bundle.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +3 -7
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +130 -17
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/zone-settings.d.ts.map +1 -1
- package/lib/coinbase/evm-smart-account.d.ts.map +1 -1
- package/lib/coinbase/evm-smart-account.js.map +1 -1
- package/lib/coinbase/faucet.js.map +1 -1
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js.map +1 -1
- package/lib/esbuild/bundle.d.ts.map +1 -1
- package/lib/esbuild/bundle.js.map +1 -1
- package/lib/scope.d.ts +9 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +5 -3
- package/lib/scope.js.map +1 -1
- package/lib/sentry/client-key.js +1 -1
- package/lib/sentry/client-key.js.map +1 -1
- package/lib/serde.d.ts.map +1 -1
- package/lib/serde.js +4 -0
- package/lib/serde.js.map +1 -1
- package/lib/state/d1-state-store.js.map +1 -1
- package/lib/state/instrumented-state-store.d.ts.map +1 -1
- package/lib/util/api/client/types.gen.d.ts.map +1 -1
- package/lib/util/api/core/pathSerializer.gen.d.ts.map +1 -1
- package/lib/util/api/core/pathSerializer.gen.js.map +1 -1
- package/lib/util/idempotent-spawn.d.ts.map +1 -1
- package/lib/util/idempotent-spawn.js +1 -1
- package/lib/util/idempotent-spawn.js.map +1 -1
- package/package.json +11 -11
- package/src/alchemy.ts +13 -0
- package/src/aws/ec2/internet-gateway-attachment.ts +1 -2
- package/src/aws/function.ts +2 -3
- package/src/aws/oidc/github-oidc-provider.ts +4 -2
- package/src/cloudflare/api-error.ts +1 -35
- package/src/cloudflare/api-response.ts +3 -2
- package/src/cloudflare/api-schema.ts +3 -2
- package/src/cloudflare/api-shield.ts +3 -2
- package/src/cloudflare/astro/astro.ts +4 -2
- package/src/cloudflare/astro/plugin.ts +15 -1
- package/src/cloudflare/bucket-custom-domain.ts +1 -2
- package/src/cloudflare/bucket.ts +9 -2
- package/src/cloudflare/bundle/plugin-wasm.ts +4 -5
- package/src/cloudflare/container.ts +4 -3
- package/src/cloudflare/dispatch-namespace.ts +4 -2
- package/src/cloudflare/hyperdrive.ts +38 -3
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/logpush-job.ts +16 -13
- package/src/cloudflare/queue-consumer.ts +2 -2
- package/src/cloudflare/ruleset.ts +3 -2
- package/src/cloudflare/tunnel-route.ts +4 -2
- package/src/cloudflare/website.ts +4 -2
- package/src/cloudflare/worker-assets.ts +6 -1
- package/src/cloudflare/worker-bundle.ts +2 -1
- package/src/cloudflare/worker-metadata.ts +3 -6
- package/src/cloudflare/worker.ts +139 -17
- package/src/cloudflare/zone-settings.ts +1 -2
- package/src/coinbase/evm-smart-account.ts +1 -2
- package/src/coinbase/faucet.ts +3 -1
- package/src/context.ts +3 -2
- package/src/esbuild/bundle.ts +3 -2
- package/src/scope.ts +13 -2
- package/src/sentry/client-key.ts +5 -1
- package/src/serde.ts +4 -0
- package/src/state/d1-state-store.ts +2 -3
- package/src/state/instrumented-state-store.ts +3 -3
- package/src/util/api/client/types.gen.ts +4 -3
- package/src/util/api/core/pathSerializer.gen.ts +1 -2
- package/src/util/idempotent-spawn.ts +5 -1
- package/templates/astro/wrangler.jsonc +1 -1
- package/workers/cloudflare-state-store.js +57 -57
- package/workers/remote-binding-proxy.js +42 -15
- package/workers/tunnel-proxy.js +1 -1
|
@@ -7,13 +7,27 @@ const isAstroCheck =
|
|
|
7
7
|
process.argv.includes("check");
|
|
8
8
|
|
|
9
9
|
const alchemy = (options?: Options): AstroIntegration => {
|
|
10
|
-
|
|
10
|
+
const integration = cloudflare({
|
|
11
11
|
platformProxy: getPlatformProxyOptions(
|
|
12
12
|
options?.platformProxy,
|
|
13
13
|
!isAstroCheck,
|
|
14
14
|
),
|
|
15
15
|
...options,
|
|
16
16
|
});
|
|
17
|
+
const setup = integration.hooks["astro:config:setup"];
|
|
18
|
+
integration.hooks["astro:config:setup"] = async (options) => {
|
|
19
|
+
options.updateConfig({
|
|
20
|
+
vite: {
|
|
21
|
+
server: {
|
|
22
|
+
watch: {
|
|
23
|
+
ignored: ["**/.alchemy/**"],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
await setup?.(options);
|
|
29
|
+
};
|
|
30
|
+
return integration;
|
|
17
31
|
};
|
|
18
32
|
|
|
19
33
|
export default alchemy;
|
|
@@ -13,8 +13,7 @@ import { inferZoneIdFromPattern } from "./route.ts";
|
|
|
13
13
|
import type { Zone } from "./zone.ts";
|
|
14
14
|
|
|
15
15
|
export interface R2BucketCustomDomainProps
|
|
16
|
-
extends CloudflareApiOptions,
|
|
17
|
-
R2BucketCustomDomainOptions {
|
|
16
|
+
extends CloudflareApiOptions, R2BucketCustomDomainOptions {
|
|
18
17
|
/**
|
|
19
18
|
* The bucket to attach the domain to.
|
|
20
19
|
*/
|
package/src/cloudflare/bucket.ts
CHANGED
|
@@ -546,7 +546,9 @@ export async function R2Bucket(
|
|
|
546
546
|
options?: Pick<R2PutOptions, "httpMetadata">,
|
|
547
547
|
): Promise<PutR2ObjectResponse> => {
|
|
548
548
|
if (isLocal) {
|
|
549
|
-
return await (
|
|
549
|
+
return await (
|
|
550
|
+
await localBucket()
|
|
551
|
+
).put(
|
|
550
552
|
key,
|
|
551
553
|
typeof value === "string"
|
|
552
554
|
? value
|
|
@@ -1331,7 +1333,12 @@ function mapHeadersToHttpMetadata(headers: Headers): R2HTTPMetadata {
|
|
|
1331
1333
|
|
|
1332
1334
|
export async function putObject(
|
|
1333
1335
|
api: CloudflareApi,
|
|
1334
|
-
{
|
|
1336
|
+
{
|
|
1337
|
+
bucketName,
|
|
1338
|
+
key,
|
|
1339
|
+
object,
|
|
1340
|
+
options,
|
|
1341
|
+
}: {
|
|
1335
1342
|
bucketName: string;
|
|
1336
1343
|
key: string;
|
|
1337
1344
|
object: PutObjectObject;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type esbuild from "esbuild";
|
|
2
2
|
import assert from "node:assert";
|
|
3
|
+
import crypto from "node:crypto";
|
|
3
4
|
import fs from "node:fs/promises";
|
|
4
5
|
import path from "pathe";
|
|
5
6
|
import type { WorkerBundle } from "../worker-bundle.ts";
|
|
@@ -35,11 +36,9 @@ export function createWasmPlugin() {
|
|
|
35
36
|
build.initialOptions.outdir,
|
|
36
37
|
);
|
|
37
38
|
|
|
38
|
-
// Use
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
copyFrom,
|
|
42
|
-
);
|
|
39
|
+
// Use path hash as module specifier for portability (note: the `?module` suffix is not needed in workerd)
|
|
40
|
+
const hash = crypto.createHash("sha256").update(copyFrom).digest("hex");
|
|
41
|
+
const specifier = `${hash}.wasm`;
|
|
43
42
|
|
|
44
43
|
// Copy to outdir so it's included in the upload
|
|
45
44
|
const copyTo = path.join(outdir, specifier);
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
* for Cloudflare API authentication.
|
|
17
17
|
*/
|
|
18
18
|
export interface ContainerProps
|
|
19
|
-
extends
|
|
19
|
+
extends
|
|
20
|
+
Omit<ImageProps, "registry" | "skipPush">,
|
|
20
21
|
Partial<CloudflareApiOptions> {
|
|
21
22
|
/**
|
|
22
23
|
* The class name for the container binding.
|
|
@@ -890,7 +891,7 @@ export async function createContainerApplication(
|
|
|
890
891
|
return result.result;
|
|
891
892
|
}
|
|
892
893
|
|
|
893
|
-
const error = result.errors.find((e) => e.code ===
|
|
894
|
+
const error = result.errors.find((e) => e.code === 1608);
|
|
894
895
|
if (error) {
|
|
895
896
|
// WEIRD: json-encoded error message - might change when they release an official API
|
|
896
897
|
const errorMessage = JSON.parse(error.message) as {
|
|
@@ -938,7 +939,7 @@ export async function createContainerApplication(
|
|
|
938
939
|
}
|
|
939
940
|
|
|
940
941
|
throw Error(
|
|
941
|
-
`Failed to create container application: ${result.errors?.map((e
|
|
942
|
+
`Failed to create container application: ${result.errors?.map((e) => `[${e.code}] ${e.message}`).join(", ") ?? "Unknown error"}`,
|
|
942
943
|
);
|
|
943
944
|
}
|
|
944
945
|
type Region =
|
|
@@ -45,8 +45,10 @@ export function isDispatchNamespace(
|
|
|
45
45
|
/**
|
|
46
46
|
* Output returned after Dispatch Namespace creation/update
|
|
47
47
|
*/
|
|
48
|
-
export interface DispatchNamespace
|
|
49
|
-
|
|
48
|
+
export interface DispatchNamespace extends Omit<
|
|
49
|
+
DispatchNamespaceProps,
|
|
50
|
+
"delete"
|
|
51
|
+
> {
|
|
50
52
|
type: "dispatch_namespace";
|
|
51
53
|
/**
|
|
52
54
|
* The name of the namespace
|
|
@@ -210,6 +210,12 @@ export interface HyperdriveProps extends CloudflareApiOptions {
|
|
|
210
210
|
* @default origin
|
|
211
211
|
*/
|
|
212
212
|
origin?: HyperdriveOriginInput;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Whether to run the hyperdrive remotely instead of locally
|
|
216
|
+
* @default false
|
|
217
|
+
*/
|
|
218
|
+
remote?: boolean;
|
|
213
219
|
};
|
|
214
220
|
}
|
|
215
221
|
|
|
@@ -247,6 +253,11 @@ export type Hyperdrive = Omit<HyperdriveProps, "origin" | "dev"> & {
|
|
|
247
253
|
* The connection string to use for local development
|
|
248
254
|
*/
|
|
249
255
|
origin: Secret;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Whether the hyperdrive is running remotely
|
|
259
|
+
*/
|
|
260
|
+
remote: boolean;
|
|
250
261
|
};
|
|
251
262
|
|
|
252
263
|
/**
|
|
@@ -333,6 +344,22 @@ export type Hyperdrive = Omit<HyperdriveProps, "origin" | "dev"> & {
|
|
|
333
344
|
* user: "postgres"
|
|
334
345
|
* }
|
|
335
346
|
* });
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* // Create a Hyperdrive that runs remotely even in local dev mode
|
|
350
|
+
* const remoteDevHyperdrive = await Hyperdrive("remote-dev-db", {
|
|
351
|
+
* name: "remote-dev-db",
|
|
352
|
+
* origin: {
|
|
353
|
+
* database: "postgres",
|
|
354
|
+
* host: "database.example.com",
|
|
355
|
+
* password: alchemy.secret(process.env.DB_PASSWORD),
|
|
356
|
+
* port: 5432,
|
|
357
|
+
* user: "postgres"
|
|
358
|
+
* },
|
|
359
|
+
* dev: {
|
|
360
|
+
* remote: true
|
|
361
|
+
* }
|
|
362
|
+
* });
|
|
336
363
|
*/
|
|
337
364
|
export async function Hyperdrive(
|
|
338
365
|
id: string,
|
|
@@ -343,6 +370,7 @@ export async function Hyperdrive(
|
|
|
343
370
|
origin: toConnectionString(
|
|
344
371
|
normalizeHyperdriveOrigin(props.dev?.origin ?? origin),
|
|
345
372
|
),
|
|
373
|
+
remote: props.dev?.remote ?? false,
|
|
346
374
|
force: Scope.current.local,
|
|
347
375
|
};
|
|
348
376
|
return await _Hyperdrive(id, {
|
|
@@ -364,6 +392,7 @@ interface InternalHyperdriveProps extends CloudflareApiOptions {
|
|
|
364
392
|
mtls?: HyperdriveMtls;
|
|
365
393
|
dev: {
|
|
366
394
|
origin: Secret;
|
|
395
|
+
remote?: boolean;
|
|
367
396
|
force?: boolean;
|
|
368
397
|
};
|
|
369
398
|
adopt?: boolean;
|
|
@@ -382,7 +411,7 @@ const _Hyperdrive = Resource(
|
|
|
382
411
|
const name =
|
|
383
412
|
props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
384
413
|
|
|
385
|
-
if (this.scope.local) {
|
|
414
|
+
if (this.scope.local && !props.dev?.remote) {
|
|
386
415
|
return {
|
|
387
416
|
id,
|
|
388
417
|
hyperdriveId: hyperdriveId || "",
|
|
@@ -390,7 +419,10 @@ const _Hyperdrive = Resource(
|
|
|
390
419
|
origin: props.origin,
|
|
391
420
|
caching: props.caching,
|
|
392
421
|
mtls: props.mtls,
|
|
393
|
-
dev:
|
|
422
|
+
dev: {
|
|
423
|
+
origin: props.dev.origin,
|
|
424
|
+
remote: false,
|
|
425
|
+
},
|
|
394
426
|
type: "hyperdrive",
|
|
395
427
|
};
|
|
396
428
|
}
|
|
@@ -485,7 +517,10 @@ const _Hyperdrive = Resource(
|
|
|
485
517
|
origin: props.origin,
|
|
486
518
|
caching: result.caching,
|
|
487
519
|
mtls: result.mtls,
|
|
488
|
-
dev:
|
|
520
|
+
dev: {
|
|
521
|
+
origin: props.dev.origin,
|
|
522
|
+
remote: props.dev.remote ?? false,
|
|
523
|
+
},
|
|
489
524
|
type: "hyperdrive",
|
|
490
525
|
};
|
|
491
526
|
},
|
package/src/cloudflare/index.ts
CHANGED
|
@@ -41,6 +41,7 @@ export * from "./hyperdrive.ts";
|
|
|
41
41
|
export * from "./images.ts";
|
|
42
42
|
export * from "./kv-namespace.ts";
|
|
43
43
|
export * from "./logpush-job.ts";
|
|
44
|
+
export * from "./miniflare/miniflare-controller.ts";
|
|
44
45
|
export * from "./next.ts";
|
|
45
46
|
export * from "./nuxt/nuxt.ts";
|
|
46
47
|
export * from "./orange.ts";
|
|
@@ -349,7 +349,7 @@ const _LogPushJob = Resource(
|
|
|
349
349
|
"cloudflare::LogPushJob",
|
|
350
350
|
async function (
|
|
351
351
|
this: Context<LogPushJob>,
|
|
352
|
-
|
|
352
|
+
id: string,
|
|
353
353
|
props: Omit<LogPushJobProps, "destination"> & {
|
|
354
354
|
destination: Secret<string> | R2Bucket;
|
|
355
355
|
},
|
|
@@ -424,15 +424,22 @@ const _LogPushJob = Resource(
|
|
|
424
424
|
accessKeyId = apiToken.accessKeyId.unencrypted;
|
|
425
425
|
secretAccessKey = apiToken.secretAccessKey.unencrypted;
|
|
426
426
|
} catch (err) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
427
|
+
const message = [
|
|
428
|
+
`Cannot create LogPushJob "${id}" because credentials for destination R2 bucket "${bucket.name}" could not be created. This may be because of an authentication error.`,
|
|
429
|
+
];
|
|
430
|
+
if (api.credentials.type === "api-token") {
|
|
431
|
+
message.push(
|
|
432
|
+
"Please ensure that your API token has the correct permissions, or use a global API key and email instead.",
|
|
433
|
+
);
|
|
434
|
+
} else if (api.credentials.type === "oauth") {
|
|
435
|
+
message.push(
|
|
436
|
+
"Please use a global API key and email, or create an API token with the necessary permissions.",
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
message.push(
|
|
440
|
+
"See https://alchemy.run/guides/cloudflare/ for more details.",
|
|
435
441
|
);
|
|
442
|
+
throw new Error(message.join("\n"), { cause: err });
|
|
436
443
|
}
|
|
437
444
|
}
|
|
438
445
|
|
|
@@ -523,10 +530,6 @@ const _LogPushJob = Resource(
|
|
|
523
530
|
},
|
|
524
531
|
// if we just recently created an api token for R2, we can retry on 1002 which are caused by token propagation
|
|
525
532
|
(error: CloudflareApiError) => {
|
|
526
|
-
console.warn(
|
|
527
|
-
"Received error when creating LogPush job, there may be a propagation delay",
|
|
528
|
-
error.message,
|
|
529
|
-
);
|
|
530
533
|
return error.errorData?.[0]?.code === 1002;
|
|
531
534
|
},
|
|
532
535
|
30,
|
|
@@ -20,7 +20,7 @@ export interface QueueConsumerSettings {
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Maximum number of concurrent consumer worker invocations
|
|
23
|
-
* @default
|
|
23
|
+
* @default undefined
|
|
24
24
|
*/
|
|
25
25
|
maxConcurrency?: number;
|
|
26
26
|
|
|
@@ -32,7 +32,7 @@ export interface QueueConsumerSettings {
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Maximum time in milliseconds to wait for batch to fill
|
|
35
|
-
* @default
|
|
35
|
+
* @default 5_000
|
|
36
36
|
*/
|
|
37
37
|
maxWaitTimeMs?: number;
|
|
38
38
|
|
|
@@ -12,8 +12,9 @@ import { findZoneForHostname, type Zone } from "./zone.ts";
|
|
|
12
12
|
/**
|
|
13
13
|
* Properties for creating or updating a Ruleset
|
|
14
14
|
*/
|
|
15
|
-
export interface RulesetProps<
|
|
16
|
-
extends
|
|
15
|
+
export interface RulesetProps<
|
|
16
|
+
Phase extends RulePhase,
|
|
17
|
+
> extends Partial<CloudflareApiOptions> {
|
|
17
18
|
/**
|
|
18
19
|
* The zone to apply the ruleset to
|
|
19
20
|
*/
|
|
@@ -88,8 +88,10 @@ export function isTunnelRoute(resource: any): resource is TunnelRoute {
|
|
|
88
88
|
/**
|
|
89
89
|
* Output returned after TunnelRoute creation/update
|
|
90
90
|
*/
|
|
91
|
-
export interface TunnelRoute
|
|
92
|
-
|
|
91
|
+
export interface TunnelRoute extends Omit<
|
|
92
|
+
TunnelRouteProps,
|
|
93
|
+
"delete" | "tunnel" | "routeId"
|
|
94
|
+
> {
|
|
93
95
|
/**
|
|
94
96
|
* The ID of the route
|
|
95
97
|
*/
|
|
@@ -18,8 +18,10 @@ import { computeWorkerDevDomain } from "./worker-subdomain.ts";
|
|
|
18
18
|
import { type AssetsConfig, Worker, type WorkerProps } from "./worker.ts";
|
|
19
19
|
import { WranglerJson, type WranglerJsonSpec } from "./wrangler.json.ts";
|
|
20
20
|
|
|
21
|
-
export interface WebsiteProps<B extends Bindings>
|
|
22
|
-
|
|
21
|
+
export interface WebsiteProps<B extends Bindings> extends Omit<
|
|
22
|
+
WorkerProps<B>,
|
|
23
|
+
"assets" | "dev"
|
|
24
|
+
> {
|
|
23
25
|
/**
|
|
24
26
|
* Configuration for the build command
|
|
25
27
|
*
|
|
@@ -31,7 +31,12 @@ interface FileMetadata {
|
|
|
31
31
|
*/
|
|
32
32
|
export async function uploadAssets(
|
|
33
33
|
api: CloudflareApi,
|
|
34
|
-
{
|
|
34
|
+
{
|
|
35
|
+
workerName,
|
|
36
|
+
assets,
|
|
37
|
+
assetConfig,
|
|
38
|
+
namespace,
|
|
39
|
+
}: {
|
|
35
40
|
workerName: string;
|
|
36
41
|
assets: Assets;
|
|
37
42
|
assetConfig?: WorkerProps["assets"];
|
|
@@ -242,7 +242,8 @@ export namespace WorkerBundleSource {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
export interface ESBuildProps
|
|
245
|
-
extends
|
|
245
|
+
extends
|
|
246
|
+
WorkerBundleSource.BaseProps,
|
|
246
247
|
Omit<
|
|
247
248
|
esbuild.BuildOptions,
|
|
248
249
|
"entryPoints" | "format" | "absWorkingDir" | "outdir"
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
isWorker,
|
|
25
25
|
Worker,
|
|
26
26
|
type AssetsConfig,
|
|
27
|
+
type WorkerPlacement,
|
|
27
28
|
type WorkerProps,
|
|
28
29
|
} from "./worker.ts";
|
|
29
30
|
|
|
@@ -217,9 +218,7 @@ export interface WorkerMetadata {
|
|
|
217
218
|
suspended: boolean;
|
|
218
219
|
}[];
|
|
219
220
|
containers?: { class_name: string }[];
|
|
220
|
-
placement?:
|
|
221
|
-
mode: "smart";
|
|
222
|
-
};
|
|
221
|
+
placement?: WorkerPlacement;
|
|
223
222
|
limits?: {
|
|
224
223
|
cpu_ms?: number;
|
|
225
224
|
};
|
|
@@ -240,9 +239,7 @@ export async function prepareWorkerMetadata(
|
|
|
240
239
|
};
|
|
241
240
|
tags?: string[];
|
|
242
241
|
unstable_cacheWorkerSettings?: boolean;
|
|
243
|
-
placement?:
|
|
244
|
-
mode: "smart";
|
|
245
|
-
};
|
|
242
|
+
placement?: WorkerPlacement;
|
|
246
243
|
},
|
|
247
244
|
): Promise<WorkerMetadata> {
|
|
248
245
|
const oldSettings = await (
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -365,22 +365,16 @@ export interface BaseWorkerProps<
|
|
|
365
365
|
};
|
|
366
366
|
|
|
367
367
|
/**
|
|
368
|
-
*
|
|
368
|
+
* Placement configuration for the worker.
|
|
369
369
|
*
|
|
370
|
-
* Controls
|
|
370
|
+
* Controls where your Worker runs to reduce latency to back-end infrastructure.
|
|
371
|
+
* Only one placement option can be specified (mutually exclusive).
|
|
371
372
|
*
|
|
372
|
-
* When omitted,
|
|
373
|
+
* When omitted, the Worker runs in the data center closest to the incoming request.
|
|
374
|
+
*
|
|
375
|
+
* @see https://developers.cloudflare.com/workers/configuration/smart-placement/
|
|
373
376
|
*/
|
|
374
|
-
placement?:
|
|
375
|
-
/**
|
|
376
|
-
* The placement mode for the worker.
|
|
377
|
-
*
|
|
378
|
-
* - "smart": Automatically optimize placement based on performance metrics
|
|
379
|
-
*
|
|
380
|
-
* @default undefined (smart placement disabled)
|
|
381
|
-
*/
|
|
382
|
-
mode: "smart";
|
|
383
|
-
};
|
|
377
|
+
placement?: WorkerPlacement;
|
|
384
378
|
|
|
385
379
|
limits?: {
|
|
386
380
|
/**
|
|
@@ -477,6 +471,136 @@ export interface WorkerObservability {
|
|
|
477
471
|
};
|
|
478
472
|
}
|
|
479
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Worker placement configuration for controlling where your Worker runs.
|
|
476
|
+
*
|
|
477
|
+
* Only one placement option can be specified at a time (mutually exclusive).
|
|
478
|
+
*
|
|
479
|
+
* @see https://developers.cloudflare.com/workers/configuration/smart-placement/
|
|
480
|
+
*/
|
|
481
|
+
export type WorkerPlacement =
|
|
482
|
+
| WorkerPlacementSmart
|
|
483
|
+
| WorkerPlacementRegion
|
|
484
|
+
| WorkerPlacementHost
|
|
485
|
+
| WorkerPlacementHostname;
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Smart placement mode - Cloudflare automatically places your Worker
|
|
489
|
+
* closest to the upstream with the most requests.
|
|
490
|
+
*
|
|
491
|
+
* Use when your Worker connects to multiple back-end services or you
|
|
492
|
+
* don't know the exact location of your infrastructure.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```ts
|
|
496
|
+
* const worker = await Worker("api", {
|
|
497
|
+
* entrypoint: "./src/worker.ts",
|
|
498
|
+
* placement: { mode: "smart" }
|
|
499
|
+
* });
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
export interface WorkerPlacementSmart {
|
|
503
|
+
/**
|
|
504
|
+
* Enable smart placement mode.
|
|
505
|
+
*
|
|
506
|
+
* Cloudflare automatically analyzes your Worker's traffic patterns and
|
|
507
|
+
* places it in an optimal location based on performance metrics.
|
|
508
|
+
*/
|
|
509
|
+
mode: "smart";
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Region-based placement - place your Worker closest to a specific
|
|
514
|
+
* cloud provider region.
|
|
515
|
+
*
|
|
516
|
+
* Use when your back-end infrastructure runs in a known AWS, GCP, or Azure region.
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* const worker = await Worker("api", {
|
|
521
|
+
* entrypoint: "./src/worker.ts",
|
|
522
|
+
* placement: { region: "aws:us-east-1" }
|
|
523
|
+
* });
|
|
524
|
+
* ```
|
|
525
|
+
*/
|
|
526
|
+
export interface WorkerPlacementRegion {
|
|
527
|
+
/**
|
|
528
|
+
* Cloud provider region to place your Worker closest to.
|
|
529
|
+
*
|
|
530
|
+
* Format: `{provider}:{region}`
|
|
531
|
+
*
|
|
532
|
+
* Supported providers:
|
|
533
|
+
* - AWS: `aws:us-east-1`, `aws:us-west-2`, `aws:eu-central-1`, etc.
|
|
534
|
+
* - GCP: `gcp:us-east4`, `gcp:europe-west1`, `gcp:asia-east1`, etc.
|
|
535
|
+
* - Azure: `azure:westeurope`, `azure:eastus`, `azure:southeastasia`, etc.
|
|
536
|
+
*
|
|
537
|
+
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html
|
|
538
|
+
* @see https://cloud.google.com/compute/docs/regions-zones
|
|
539
|
+
* @see https://learn.microsoft.com/en-us/azure/reliability/regions-list
|
|
540
|
+
*
|
|
541
|
+
* @example "aws:us-east-1"
|
|
542
|
+
* @example "gcp:us-east4"
|
|
543
|
+
* @example "azure:westeurope"
|
|
544
|
+
*/
|
|
545
|
+
region: string;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Host-based placement (layer 4) - place your Worker closest to a specific
|
|
550
|
+
* TCP endpoint.
|
|
551
|
+
*
|
|
552
|
+
* Use when your infrastructure is not in a major cloud provider and you need
|
|
553
|
+
* to probe a TCP service (like a database) to determine optimal placement.
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```ts
|
|
557
|
+
* const worker = await Worker("api", {
|
|
558
|
+
* entrypoint: "./src/worker.ts",
|
|
559
|
+
* placement: { host: "my-database.example.com:5432" }
|
|
560
|
+
* });
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
export interface WorkerPlacementHost {
|
|
564
|
+
/**
|
|
565
|
+
* Host endpoint to probe (TCP/layer 4) for placement.
|
|
566
|
+
*
|
|
567
|
+
* Cloudflare uses TCP CONNECT checks to measure latency and selects
|
|
568
|
+
* the best data center. Use this for database hosts or other TCP services.
|
|
569
|
+
*
|
|
570
|
+
* Format: `hostname:port`
|
|
571
|
+
*
|
|
572
|
+
* @example "my_database_host.com:5432"
|
|
573
|
+
*/
|
|
574
|
+
host: string;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Hostname-based placement (layer 7) - place your Worker closest to a specific
|
|
579
|
+
* HTTP endpoint.
|
|
580
|
+
*
|
|
581
|
+
* Use when your infrastructure is not in a major cloud provider and you need
|
|
582
|
+
* to probe an HTTP service (like an API) to determine optimal placement.
|
|
583
|
+
*
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* const worker = await Worker("api", {
|
|
587
|
+
* entrypoint: "./src/worker.ts",
|
|
588
|
+
* placement: { hostname: "my-api.example.com" }
|
|
589
|
+
* });
|
|
590
|
+
* ```
|
|
591
|
+
*/
|
|
592
|
+
export interface WorkerPlacementHostname {
|
|
593
|
+
/**
|
|
594
|
+
* Hostname to probe (HTTP/layer 7) for placement.
|
|
595
|
+
*
|
|
596
|
+
* Cloudflare uses HTTP HEAD checks to measure latency and selects
|
|
597
|
+
* the best data center. Use this for API endpoints or other HTTP services.
|
|
598
|
+
*
|
|
599
|
+
* @example "my_api_server.com"
|
|
600
|
+
*/
|
|
601
|
+
hostname: string;
|
|
602
|
+
}
|
|
603
|
+
|
|
480
604
|
export interface InlineWorkerProps<
|
|
481
605
|
B extends Bindings | undefined = Bindings,
|
|
482
606
|
RPC extends Rpc.WorkerEntrypointBranded = Rpc.WorkerEntrypointBranded,
|
|
@@ -630,11 +754,9 @@ export type Worker<
|
|
|
630
754
|
version?: string;
|
|
631
755
|
|
|
632
756
|
/**
|
|
633
|
-
*
|
|
757
|
+
* Placement configuration for the worker
|
|
634
758
|
*/
|
|
635
|
-
placement?:
|
|
636
|
-
mode: "smart";
|
|
637
|
-
};
|
|
759
|
+
placement?: WorkerPlacement;
|
|
638
760
|
|
|
639
761
|
/**
|
|
640
762
|
* Whether the worker has a remote deployment
|
|
@@ -89,8 +89,7 @@ export interface AutomaticHTTPSRewritesSetting extends CloudflareSettingBase {
|
|
|
89
89
|
/**
|
|
90
90
|
* Automatic Platform Optimization setting
|
|
91
91
|
*/
|
|
92
|
-
export interface AutomaticPlatformOptimizationSetting
|
|
93
|
-
extends CloudflareSettingBase {
|
|
92
|
+
export interface AutomaticPlatformOptimizationSetting extends CloudflareSettingBase {
|
|
94
93
|
id: "automatic_platform_optimization";
|
|
95
94
|
value: {
|
|
96
95
|
enabled: boolean;
|
|
@@ -48,8 +48,7 @@ export interface EvmSmartAccountProps extends CoinbaseClientOptions {
|
|
|
48
48
|
faucet?: FaucetConfig;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export interface EvmSmartAccount
|
|
52
|
-
extends Resource<"coinbase::evm-smart-account"> {
|
|
51
|
+
export interface EvmSmartAccount extends Resource<"coinbase::evm-smart-account"> {
|
|
53
52
|
/**
|
|
54
53
|
* The smart account name in CDP
|
|
55
54
|
*/
|
package/src/coinbase/faucet.ts
CHANGED
|
@@ -141,7 +141,9 @@ for (const account of accounts) {
|
|
|
141
141
|
|
|
142
142
|
// Skip if already processed in this run
|
|
143
143
|
if (funded.has(key)) {
|
|
144
|
-
console.log(
|
|
144
|
+
console.log(
|
|
145
|
+
` ⏭️ Skipping ${token} on ${network} (already requested)`,
|
|
146
|
+
);
|
|
145
147
|
continue;
|
|
146
148
|
}
|
|
147
149
|
|
package/src/context.ts
CHANGED
|
@@ -17,8 +17,9 @@ export type Context<
|
|
|
17
17
|
Props extends ResourceProps = ResourceProps,
|
|
18
18
|
> = CreateContext<Out> | UpdateContext<Out, Props> | DeleteContext<Out, Props>;
|
|
19
19
|
|
|
20
|
-
export interface CreateContext<
|
|
21
|
-
extends
|
|
20
|
+
export interface CreateContext<
|
|
21
|
+
Out extends ResourceAttributes,
|
|
22
|
+
> extends BaseContext<Out> {
|
|
22
23
|
phase: "create";
|
|
23
24
|
output?: undefined;
|
|
24
25
|
props?: undefined;
|
package/src/esbuild/bundle.ts
CHANGED
|
@@ -73,8 +73,9 @@ export interface BundleProps extends Partial<esbuild.BuildOptions> {
|
|
|
73
73
|
/**
|
|
74
74
|
* Output returned after bundle creation/update
|
|
75
75
|
*/
|
|
76
|
-
export interface Bundle<
|
|
77
|
-
extends BundleProps
|
|
76
|
+
export interface Bundle<
|
|
77
|
+
P extends BundleProps = BundleProps,
|
|
78
|
+
> extends BundleProps {
|
|
78
79
|
/**
|
|
79
80
|
* Path to the bundled file
|
|
80
81
|
* Absolute or relative path to the generated bundle
|