alchemy 0.77.5 → 0.79.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 +2414 -323
- package/bin/commands/util.ts +234 -315
- package/bin/services/execute-alchemy.ts +8 -33
- package/lib/cloudflare/assets.js +1 -1
- package/lib/cloudflare/assets.js.map +1 -1
- package/lib/cloudflare/astro/plugin.d.ts.map +1 -1
- package/lib/cloudflare/astro/plugin.js +3 -1
- package/lib/cloudflare/astro/plugin.js.map +1 -1
- package/lib/cloudflare/auth.d.ts +73 -68
- package/lib/cloudflare/auth.d.ts.map +1 -1
- package/lib/cloudflare/auth.js +73 -72
- package/lib/cloudflare/auth.js.map +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.d.ts +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.d.ts.map +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.js +2 -2
- package/lib/cloudflare/cloudflare-env-proxy.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 +0 -3
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +10 -4
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +3 -2
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/index.d.ts +2 -2
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +2 -2
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/permission-groups.d.ts +35 -0
- package/lib/cloudflare/permission-groups.d.ts.map +1 -1
- package/lib/cloudflare/permission-groups.js +42 -0
- package/lib/cloudflare/permission-groups.js.map +1 -1
- package/lib/cloudflare/worker-assets.d.ts.map +1 -1
- package/lib/cloudflare/worker-assets.js +22 -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 +1 -0
- package/lib/cloudflare/worker-bundle.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +2 -0
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +15 -3
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +1 -0
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +6 -0
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/docker/api.d.ts.map +1 -1
- package/lib/docker/api.js +2 -1
- package/lib/docker/api.js.map +1 -1
- package/lib/util/camel-to-snake.d.ts +1 -1
- package/lib/util/camel-to-snake.d.ts.map +1 -1
- package/lib/util/camel-to-snake.js +26 -13
- package/lib/util/camel-to-snake.js.map +1 -1
- package/lib/util/detect-node-runtime.d.ts.map +1 -1
- package/lib/util/detect-node-runtime.js +0 -2
- package/lib/util/detect-node-runtime.js.map +1 -1
- package/lib/util/detect-package-manager.d.ts +1 -1
- package/lib/util/detect-package-manager.d.ts.map +1 -1
- package/lib/util/detect-package-manager.js +11 -8
- package/lib/util/detect-package-manager.js.map +1 -1
- package/package.json +5 -1
- package/src/cloudflare/assets.ts +1 -1
- package/src/cloudflare/astro/plugin.ts +8 -1
- package/src/cloudflare/auth.ts +94 -75
- package/src/cloudflare/cloudflare-env-proxy.ts +5 -1
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/container.ts +10 -7
- package/src/cloudflare/d1-database.ts +6 -2
- package/src/cloudflare/index.ts +2 -2
- package/src/cloudflare/permission-groups.ts +42 -0
- package/src/cloudflare/worker-assets.ts +34 -1
- package/src/cloudflare/worker-bundle.ts +1 -0
- package/src/cloudflare/worker.ts +27 -2
- package/src/cloudflare/workflow.ts +9 -0
- package/src/docker/api.ts +2 -1
- package/src/util/camel-to-snake.ts +34 -19
- package/src/util/detect-node-runtime.ts +0 -2
- package/src/util/detect-package-manager.ts +12 -8
- package/templates/tanstack-start/alchemy.run.ts +8 -2
- package/templates/tanstack-start/src/routes/demo.start.server-funcs.tsx +11 -16
- package/workers/tunnel-proxy.js +1 -1
package/src/cloudflare/assets.ts
CHANGED
|
@@ -65,7 +65,7 @@ export namespace Assets {
|
|
|
65
65
|
* @returns Metadata for all assets in the directory
|
|
66
66
|
*/
|
|
67
67
|
export const read = async (root: string): Promise<FileMetadata[]> => {
|
|
68
|
-
const matcher = ignore().add(".assetsignore");
|
|
68
|
+
const matcher = ignore().add([".assetsignore", "_headers", "_redirects"]);
|
|
69
69
|
const ignorePath = path.join(root, ".assetsignore");
|
|
70
70
|
try {
|
|
71
71
|
const content = await fs.readFile(ignorePath, "utf-8");
|
|
@@ -2,9 +2,16 @@ import cloudflare, { type Options } from "@astrojs/cloudflare";
|
|
|
2
2
|
import type { AstroIntegration } from "astro";
|
|
3
3
|
import { getPlatformProxyOptions } from "../cloudflare-env-proxy.ts";
|
|
4
4
|
|
|
5
|
+
const isAstroCheck =
|
|
6
|
+
!!process.argv.find((arg) => arg.includes("astro")) &&
|
|
7
|
+
process.argv.includes("check");
|
|
8
|
+
|
|
5
9
|
const alchemy = (options?: Options): AstroIntegration => {
|
|
6
10
|
return cloudflare({
|
|
7
|
-
platformProxy: getPlatformProxyOptions(
|
|
11
|
+
platformProxy: getPlatformProxyOptions(
|
|
12
|
+
options?.platformProxy,
|
|
13
|
+
!isAstroCheck,
|
|
14
|
+
),
|
|
8
15
|
...options,
|
|
9
16
|
});
|
|
10
17
|
};
|
package/src/cloudflare/auth.ts
CHANGED
|
@@ -18,88 +18,106 @@ export namespace CloudflareAuth {
|
|
|
18
18
|
name: string;
|
|
19
19
|
};
|
|
20
20
|
export const ALL_SCOPES = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"access:write":
|
|
21
|
+
"access:read":
|
|
22
|
+
"See Cloudflare Access data such as zones, applications, certificates, device postures, groups, identity providers, login counts, organizations, policies, service tokens, and users",
|
|
23
|
+
"access:write":
|
|
24
|
+
"See and change Cloudflare Access data such as zones, applications, certificates, device postures, groups, identity providers, login counts, organizations, policies, service tokens, and users",
|
|
24
25
|
"account:read":
|
|
25
|
-
"See your account info such as account details, analytics, and memberships
|
|
26
|
-
"agw:read": "
|
|
27
|
-
"agw:run": "
|
|
28
|
-
"
|
|
29
|
-
"ai:
|
|
30
|
-
"
|
|
31
|
-
"aiaudit:
|
|
32
|
-
"
|
|
33
|
-
"aig:
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"browser:
|
|
37
|
-
"
|
|
38
|
-
"cfone:
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
26
|
+
"See your account info such as account details, analytics, and memberships",
|
|
27
|
+
"agw:read": "Grants read level access to Agents Gateway",
|
|
28
|
+
"agw:run": "Grants run level access to Agents Gateway",
|
|
29
|
+
"agw:write": "Grants read and write level access to Agents Gateway",
|
|
30
|
+
"ai:read": "Grants read level access to Workers AI",
|
|
31
|
+
"ai:write": "Grants write level access to Workers AI",
|
|
32
|
+
"aiaudit:read": "Grants read level access to AI Audit",
|
|
33
|
+
"aiaudit:write": "Grants write level access to AI Audit",
|
|
34
|
+
"aig:read": "Grants read level access to AI Gateway",
|
|
35
|
+
"aig:write": "Grants write level access to AI Gateway",
|
|
36
|
+
"auditlogs:read": "View Cloudflare Account Audit Logs",
|
|
37
|
+
"browser:read": "Grants read level access to Browser Rendering",
|
|
38
|
+
"browser:write": "Grants write level access to Browser Rendering",
|
|
39
|
+
"cfone:read": "Grants read level access to Cloudforce One data",
|
|
40
|
+
"cfone:write": "Grants write level access to Cloudforce One data",
|
|
41
|
+
"cloudchamber:write": "See and make changes to Cloudchamber",
|
|
42
|
+
"connectivity:admin":
|
|
43
|
+
"See, change, and bind to Connectivity Directory services, including creating services targeting Cloudflare Tunnel",
|
|
44
|
+
"connectivity:bind":
|
|
45
|
+
"read, list, and bind to Connectivity Directory services, as well as read and list Cloudflare Tunnels",
|
|
46
|
+
"connectivity:read":
|
|
47
|
+
"See Connectivity Directory services and Cloudflare Tunnels",
|
|
48
|
+
"constellation:write":
|
|
49
|
+
"Grants write access to Constellation configuration and models",
|
|
50
|
+
"containers:write": "See and make changes to Workers Containers",
|
|
51
|
+
"d1:write": "See and make changes to D1",
|
|
52
|
+
"dex:read": "Grants read level access to Cloudflare DEX",
|
|
53
|
+
"dex:write": "Grants write level access to Cloudflare DEX",
|
|
54
|
+
"dns_analytics:read":
|
|
55
|
+
"Grants read level access to Cloudflare DNS Analytics",
|
|
56
|
+
"dns_records:edit": "Grants edit level access to dns records",
|
|
57
|
+
"dns_records:read": "Grants read level access to dns records",
|
|
58
|
+
"dns_settings:read": "Grants read level access to Cloudflare DNS Settings",
|
|
59
|
+
"firstpartytags:write":
|
|
60
|
+
"Can see, edit and publish Google tag gateway configuration.",
|
|
61
|
+
"lb:edit": "Grants edit level access to lb and lb pools",
|
|
62
|
+
"lb:read": "Grants read level access to lb and lb pools",
|
|
63
|
+
"logpush:read": "See Cloudflare Logpush data",
|
|
64
|
+
"logpush:write": "See and change Cloudflare Logpush data",
|
|
65
|
+
"notification:read": "View Cloudflare Notifications",
|
|
66
|
+
"notification:write": "View and Modify Cloudflare Notifications",
|
|
67
|
+
"pages:read": "See Cloudflare Pages projects, settings and deployments",
|
|
68
|
+
"pages:write":
|
|
69
|
+
"See and change Cloudflare Pages projects, settings and deployments",
|
|
70
|
+
"pipelines:read": "Grants read level access to Cloudflare Pipelines",
|
|
71
|
+
"pipelines:setup":
|
|
72
|
+
"Grants permission to generate R2 tokens for Workers Pipelines",
|
|
73
|
+
"pipelines:write": "Grants write level access to Cloudflare Pipelines",
|
|
74
|
+
"query_cache:write": "See and make changes to Hyperdrive",
|
|
75
|
+
"queues:write": "See and change Cloudflare Queues settings and data",
|
|
76
|
+
"r2_catalog:write": "Grants write level access to R2 Data Catalog",
|
|
77
|
+
"radar:read": "Grants access to read Cloudflare Radar data",
|
|
78
|
+
"rag:read": "Grants read level access to Auto Rag",
|
|
79
|
+
"rag:write": "Grants write level access to Auto Rag",
|
|
80
|
+
"secrets_store:read": "Grants read level access to Secrets Store",
|
|
81
|
+
"secrets_store:write": "Grants write level access to Secrets Store",
|
|
82
|
+
"ssl_certs:write":
|
|
83
|
+
"Grants read and write access to SSL MTLS certificates or Certificate Store",
|
|
84
|
+
"sso-connector:read": "See Cloudflare SSO connectors",
|
|
85
|
+
"sso-connector:write":
|
|
86
|
+
"See Cloudflare SSO connectors to toggle activation and deactivation of SSO",
|
|
87
|
+
"teams:pii": "See personally identifiable Cloudflare Teams data",
|
|
88
|
+
"teams:read":
|
|
89
|
+
"See Cloudflare Teams data such as zones, gateway, and argo tunnel details",
|
|
90
|
+
"teams:secure_location":
|
|
91
|
+
"See all DNS Location data but can only change secure DNS Locations",
|
|
92
|
+
"teams:write":
|
|
93
|
+
"See and change Cloudflare Teams data such as zones, gateway, and argo tunnel details",
|
|
94
|
+
"url_scanner:read": "Grants read level access to URL Scanner",
|
|
95
|
+
"url_scanner:write": "Grants write level access to URL Scanner",
|
|
80
96
|
"user:read":
|
|
81
|
-
"See your user info such as name, email address, and account memberships
|
|
82
|
-
"vectorize:write": "
|
|
97
|
+
"See your user info such as name, email address, and account memberships",
|
|
98
|
+
"vectorize:write": "See and make changes to Vectorize",
|
|
99
|
+
"workers:read":
|
|
100
|
+
"See Cloudflare Workers data such as zones, KV storage, R2 storage, scripts, and routes",
|
|
83
101
|
"workers:write":
|
|
84
|
-
"See and change Cloudflare Workers data such as zones, KV storage,
|
|
85
|
-
"workers_builds:read":
|
|
86
|
-
|
|
102
|
+
"See and change Cloudflare Workers data such as zones, KV storage, R2 storage, scripts, and routes",
|
|
103
|
+
"workers_builds:read":
|
|
104
|
+
"See Cloudflare Workers Builds data such as builds, build configuration, and build logs",
|
|
105
|
+
"workers_builds:write":
|
|
106
|
+
"See and change Cloudflare Workers Builds data such as builds, build configuration, and build logs",
|
|
87
107
|
"workers_kv:write":
|
|
88
|
-
"See and change Cloudflare Workers KV Storage data such as keys and namespaces
|
|
89
|
-
"workers_observability:read":
|
|
90
|
-
|
|
108
|
+
"See and change Cloudflare Workers KV Storage data such as keys and namespaces",
|
|
109
|
+
"workers_observability:read":
|
|
110
|
+
"Grants read access to Cloudflare Workers Observability",
|
|
91
111
|
"workers_observability_telemetry:write":
|
|
92
|
-
"
|
|
112
|
+
"Grants write access to Cloudflare Workers Observability Telemetry API",
|
|
93
113
|
"workers_routes:write":
|
|
94
|
-
"See and change Cloudflare Workers data such as filters and routes
|
|
114
|
+
"See and change Cloudflare Workers data such as filters and routes",
|
|
95
115
|
"workers_scripts:write":
|
|
96
|
-
"See and change Cloudflare Workers scripts, durable objects, subdomains, triggers, and tail data
|
|
97
|
-
"workers_tail:read": "See Cloudflare Workers tail and script data
|
|
98
|
-
"zone:read": "Grants read level access to account zone
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// "See, change, and bind to Connectivity Directory services, including creating services targeting Cloudflare Tunnel.",
|
|
102
|
-
};
|
|
116
|
+
"See and change Cloudflare Workers scripts, durable objects, subdomains, triggers, and tail data",
|
|
117
|
+
"workers_tail:read": "See Cloudflare Workers tail and script data",
|
|
118
|
+
"zone:read": "Grants read level access to account zone",
|
|
119
|
+
} as const;
|
|
120
|
+
export type Scope = keyof typeof ALL_SCOPES;
|
|
103
121
|
export const DEFAULT_SCOPES = [
|
|
104
122
|
"account:read",
|
|
105
123
|
"user:read",
|
|
@@ -119,6 +137,7 @@ export namespace CloudflareAuth {
|
|
|
119
137
|
"containers:write",
|
|
120
138
|
"cloudchamber:write",
|
|
121
139
|
"vectorize:write",
|
|
140
|
+
"connectivity:admin",
|
|
122
141
|
];
|
|
123
142
|
|
|
124
143
|
/**
|
|
@@ -16,6 +16,7 @@ export const getCloudflareEnvProxy = async <E>(
|
|
|
16
16
|
|
|
17
17
|
export const getPlatformProxyOptions = (
|
|
18
18
|
input: GetPlatformProxyOptions = {},
|
|
19
|
+
throws: boolean = true,
|
|
19
20
|
): GetPlatformProxyOptions => {
|
|
20
21
|
const persist =
|
|
21
22
|
input.persist === false
|
|
@@ -37,7 +38,10 @@ export const getPlatformProxyOptions = (
|
|
|
37
38
|
}
|
|
38
39
|
return {
|
|
39
40
|
...input,
|
|
40
|
-
configPath: validateConfigPath(
|
|
41
|
+
configPath: validateConfigPath(
|
|
42
|
+
input.configPath ?? getDefaultConfigPath(),
|
|
43
|
+
throws,
|
|
44
|
+
),
|
|
41
45
|
persist,
|
|
42
46
|
};
|
|
43
47
|
};
|
|
@@ -221,6 +221,11 @@ export async function Container<T>(
|
|
|
221
221
|
...props,
|
|
222
222
|
name: `cloudflare-dev/${name}`, // prefix used by Miniflare
|
|
223
223
|
tag,
|
|
224
|
+
build: props.build ?? {
|
|
225
|
+
dockerfile: "Dockerfile",
|
|
226
|
+
platform: "linux/amd64",
|
|
227
|
+
context: process.cwd(),
|
|
228
|
+
},
|
|
224
229
|
} as ImageProps);
|
|
225
230
|
|
|
226
231
|
return {
|
|
@@ -240,7 +245,11 @@ export async function Container<T>(
|
|
|
240
245
|
platform: props.build?.platform ?? "linux/amd64",
|
|
241
246
|
...props.build,
|
|
242
247
|
}
|
|
243
|
-
:
|
|
248
|
+
: {
|
|
249
|
+
dockerfile: "Dockerfile",
|
|
250
|
+
platform: "linux/amd64",
|
|
251
|
+
context: process.cwd(),
|
|
252
|
+
},
|
|
244
253
|
image: props.image,
|
|
245
254
|
registry: {
|
|
246
255
|
server: "registry.cloudflare.com",
|
|
@@ -562,9 +571,6 @@ export const ContainerApplication = Resource(
|
|
|
562
571
|
logs: {
|
|
563
572
|
enabled: true,
|
|
564
573
|
},
|
|
565
|
-
logging: {
|
|
566
|
-
enabled: true,
|
|
567
|
-
},
|
|
568
574
|
},
|
|
569
575
|
};
|
|
570
576
|
if (this.phase === "update" && this.output?.id) {
|
|
@@ -1039,9 +1045,6 @@ interface CreateRolloutApplicationResponse {
|
|
|
1039
1045
|
logs?: {
|
|
1040
1046
|
enabled: boolean;
|
|
1041
1047
|
};
|
|
1042
|
-
logging?: {
|
|
1043
|
-
enabled: boolean;
|
|
1044
|
-
};
|
|
1045
1048
|
};
|
|
1046
1049
|
};
|
|
1047
1050
|
target_configuration: DeploymentConfiguration;
|
|
@@ -386,7 +386,10 @@ const _D1Database = Resource(
|
|
|
386
386
|
`Cannot update primaryLocationHint from '${this.output.primaryLocationHint}' to '${props.primaryLocationHint}' after database creation.`,
|
|
387
387
|
);
|
|
388
388
|
}
|
|
389
|
-
if (
|
|
389
|
+
if (
|
|
390
|
+
(props.jurisdiction ?? "default") !==
|
|
391
|
+
(this.output?.jurisdiction ?? "default")
|
|
392
|
+
) {
|
|
390
393
|
throw new Error(
|
|
391
394
|
`Cannot update jurisdiction from '${this.output.jurisdiction}' to '${props.jurisdiction}' after database creation.`,
|
|
392
395
|
);
|
|
@@ -468,7 +471,8 @@ export async function createDatabase(
|
|
|
468
471
|
// Create new D1 database
|
|
469
472
|
const createPayload: any = {
|
|
470
473
|
name: databaseName,
|
|
471
|
-
jurisdiction:
|
|
474
|
+
jurisdiction:
|
|
475
|
+
props.jurisdiction !== "default" ? props.jurisdiction : undefined,
|
|
472
476
|
};
|
|
473
477
|
|
|
474
478
|
if (props.primaryLocationHint) {
|
package/src/cloudflare/index.ts
CHANGED
|
@@ -69,11 +69,11 @@ export * from "./vectorize-metadata-index.ts";
|
|
|
69
69
|
export * from "./version-metadata.ts";
|
|
70
70
|
export * from "./vite/vite.ts";
|
|
71
71
|
export * from "./website.ts";
|
|
72
|
-
export
|
|
72
|
+
export * from "./worker-loader.ts";
|
|
73
73
|
export * from "./worker-ref.ts";
|
|
74
74
|
export * from "./worker-stub.ts";
|
|
75
75
|
export * from "./worker-subdomain.ts";
|
|
76
76
|
export * from "./worker.ts";
|
|
77
|
-
export
|
|
77
|
+
export * from "./workflow.ts";
|
|
78
78
|
export * from "./wrangler.json.ts";
|
|
79
79
|
export * from "./zone.ts";
|
|
@@ -359,6 +359,18 @@ export const PERMISSION_GROUPS = [
|
|
|
359
359
|
description: "Grants write access to Account Rulesets",
|
|
360
360
|
scopes: ["com.cloudflare.api.account"],
|
|
361
361
|
},
|
|
362
|
+
{
|
|
363
|
+
id: "ece81d7757ff406cad61f221a4920d55",
|
|
364
|
+
name: "Account Security Center Insights Read",
|
|
365
|
+
description: "Grants read access to Security Center Insights",
|
|
366
|
+
scopes: ["com.cloudflare.api.account"],
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: "cfa2e2893226455c9b945914969dff7c",
|
|
370
|
+
name: "Account Security Center Insights Write",
|
|
371
|
+
description: "Grants write access to Security Center Insights",
|
|
372
|
+
scopes: ["com.cloudflare.api.account"],
|
|
373
|
+
},
|
|
362
374
|
{
|
|
363
375
|
id: "c1fde68c7bcc44588cbb6ddbc16d6480",
|
|
364
376
|
name: "Account Settings Read",
|
|
@@ -527,6 +539,18 @@ export const PERMISSION_GROUPS = [
|
|
|
527
539
|
description: "Grants write access to Browser Rendering API",
|
|
528
540
|
scopes: ["com.cloudflare.api.account"],
|
|
529
541
|
},
|
|
542
|
+
{
|
|
543
|
+
id: "da5fe84b9c5446a0a5955b673fafa288",
|
|
544
|
+
name: "CASB Read",
|
|
545
|
+
description: "Grants read access to Cloudflare CASB",
|
|
546
|
+
scopes: ["com.cloudflare.api.account"],
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
id: "b9ed086b20864ad89c5aac24cdd02365",
|
|
550
|
+
name: "CASB Write",
|
|
551
|
+
description: "Grants write access to Cloudflare CASB",
|
|
552
|
+
scopes: ["com.cloudflare.api.account"],
|
|
553
|
+
},
|
|
530
554
|
{
|
|
531
555
|
id: "47b936e2027140c0a474cac8887b8c29",
|
|
532
556
|
name: "CF Agents Read",
|
|
@@ -970,6 +994,18 @@ export const PERMISSION_GROUPS = [
|
|
|
970
994
|
description: "Grants full access to Email Security dmarc reports\n",
|
|
971
995
|
scopes: ["com.cloudflare.api.account.zone"],
|
|
972
996
|
},
|
|
997
|
+
{
|
|
998
|
+
id: "2d5b4b1f6c89487bb7184c2c1dcd3bf1",
|
|
999
|
+
name: "Email Sending Read",
|
|
1000
|
+
description: "Grants access to reading data from Email Sending",
|
|
1001
|
+
scopes: ["com.cloudflare.api.account"],
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
id: "5df633d6b41c42bcaf5b4a62b9d14b64",
|
|
1005
|
+
name: "Email Sending Write",
|
|
1006
|
+
description: "Grants access to reading and writing data from Email Sending",
|
|
1007
|
+
scopes: ["com.cloudflare.api.account"],
|
|
1008
|
+
},
|
|
973
1009
|
{
|
|
974
1010
|
id: "4ec32dfcb35641c5bb32d5ef1ab963b4",
|
|
975
1011
|
name: "Firewall Services Read",
|
|
@@ -1426,6 +1462,12 @@ export const PERMISSION_GROUPS = [
|
|
|
1426
1462
|
description: "Grants admin access to Realtime configuration",
|
|
1427
1463
|
scopes: ["com.cloudflare.api.account"],
|
|
1428
1464
|
},
|
|
1465
|
+
{
|
|
1466
|
+
id: "9bb90620717647a39679e1d951f140d6",
|
|
1467
|
+
name: "Registrar Domains Read",
|
|
1468
|
+
description: "Grants read access to Cloudflare Registrar domains",
|
|
1469
|
+
scopes: ["com.cloudflare.api.account"],
|
|
1470
|
+
},
|
|
1429
1471
|
{
|
|
1430
1472
|
id: "93ae59e7a40c4287a57ff6e501186a63",
|
|
1431
1473
|
name: "Response Compression Read",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "pathe";
|
|
2
3
|
import { AsyncQueue } from "../util/async-queue.ts";
|
|
3
4
|
import { withExponentialBackoff } from "../util/retry.ts";
|
|
4
5
|
import { extractCloudflareResult } from "./api-response.ts";
|
|
@@ -38,7 +39,10 @@ export async function uploadAssets(
|
|
|
38
39
|
},
|
|
39
40
|
): Promise<AssetUploadResult> {
|
|
40
41
|
// Process the assets configuration once at the beginning
|
|
41
|
-
const processedConfig =
|
|
42
|
+
const processedConfig = await createAssetConfigWithFiles(
|
|
43
|
+
assets.path,
|
|
44
|
+
assetConfig,
|
|
45
|
+
);
|
|
42
46
|
|
|
43
47
|
const manifest: Record<string, FileMetadata> = {};
|
|
44
48
|
const filesByHash = new Map<string, Assets.FileMetadata>();
|
|
@@ -95,6 +99,35 @@ export async function uploadAssets(
|
|
|
95
99
|
};
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
async function createAssetConfigWithFiles(
|
|
103
|
+
assetsPath: string,
|
|
104
|
+
config: AssetsConfig = {},
|
|
105
|
+
): Promise<AssetsConfig> {
|
|
106
|
+
const [_headers, _redirects] = await Promise.all([
|
|
107
|
+
readFileOrProperty("_headers"),
|
|
108
|
+
readFileOrProperty("_redirects"),
|
|
109
|
+
]);
|
|
110
|
+
return createAssetConfig({
|
|
111
|
+
...config,
|
|
112
|
+
_headers,
|
|
113
|
+
_redirects,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
async function readFileOrProperty(
|
|
117
|
+
property: "_headers" | "_redirects",
|
|
118
|
+
): Promise<string | undefined> {
|
|
119
|
+
const content = await fs
|
|
120
|
+
.readFile(path.join(assetsPath, property), "utf-8")
|
|
121
|
+
.catch(() => undefined);
|
|
122
|
+
if (content && config[property]) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Cannot use both ${property} file and ${property} property`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return content ?? config[property];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
/**
|
|
99
132
|
* Creates asset configuration object from provided config or defaults
|
|
100
133
|
*/
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -51,11 +51,17 @@ import {
|
|
|
51
51
|
import {
|
|
52
52
|
type WorkerScriptMetadata,
|
|
53
53
|
bumpMigrationTagVersion,
|
|
54
|
+
getWorkerSettings,
|
|
54
55
|
prepareWorkerMetadata,
|
|
55
56
|
} from "./worker-metadata.ts";
|
|
56
57
|
import { WorkerSubdomain, disableWorkerSubdomain } from "./worker-subdomain.ts";
|
|
57
58
|
import { createTail } from "./worker-tail.ts";
|
|
58
|
-
import {
|
|
59
|
+
import {
|
|
60
|
+
Workflow,
|
|
61
|
+
deleteWorkflow,
|
|
62
|
+
isWorkflow,
|
|
63
|
+
upsertWorkflow,
|
|
64
|
+
} from "./workflow.ts";
|
|
59
65
|
|
|
60
66
|
// Previous versions of `Worker` used the `Bundle` resource.
|
|
61
67
|
// This import is here to avoid errors when destroying the `Bundle` resource.
|
|
@@ -71,11 +77,13 @@ import { createEmptyWorker, exists } from "./worker-stub.ts";
|
|
|
71
77
|
export interface AssetsConfig {
|
|
72
78
|
/**
|
|
73
79
|
* The contents of a _headers file (used to attach custom headers on asset responses)
|
|
80
|
+
* @default the `_headers` file in the assets directory, if present
|
|
74
81
|
*/
|
|
75
82
|
_headers?: string;
|
|
76
83
|
|
|
77
84
|
/**
|
|
78
85
|
* The contents of a _redirects file (used to apply redirects or proxy paths ahead of asset serving)
|
|
86
|
+
* @default the `_redirects` file in the assets directory, if present
|
|
79
87
|
*/
|
|
80
88
|
_redirects?: string;
|
|
81
89
|
|
|
@@ -949,7 +957,10 @@ const _Worker = Resource(
|
|
|
949
957
|
await createEmptyWorker(api, options.name, props.version);
|
|
950
958
|
}
|
|
951
959
|
} else {
|
|
952
|
-
await
|
|
960
|
+
await Promise.all([
|
|
961
|
+
deleteQueueConsumers(api, options.name),
|
|
962
|
+
deleteWorkflows(api, options.name),
|
|
963
|
+
]);
|
|
953
964
|
await deleteWorker(api, {
|
|
954
965
|
scriptName: options.name,
|
|
955
966
|
dispatchNamespace: options.dispatchNamespace,
|
|
@@ -1706,6 +1717,20 @@ async function deleteQueueConsumers(api: CloudflareApi, scriptName: string) {
|
|
|
1706
1717
|
);
|
|
1707
1718
|
}
|
|
1708
1719
|
|
|
1720
|
+
async function deleteWorkflows(api: CloudflareApi, scriptName: string) {
|
|
1721
|
+
const settings = await getWorkerSettings(api, scriptName);
|
|
1722
|
+
await Promise.all(
|
|
1723
|
+
(settings?.bindings ?? []).map(async (binding) => {
|
|
1724
|
+
if (
|
|
1725
|
+
binding.type === "workflow" &&
|
|
1726
|
+
(binding.script_name === scriptName || !binding.script_name)
|
|
1727
|
+
) {
|
|
1728
|
+
await deleteWorkflow(api, binding.workflow_name);
|
|
1729
|
+
}
|
|
1730
|
+
}),
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1709
1734
|
export async function deleteWorker(
|
|
1710
1735
|
api: CloudflareApi,
|
|
1711
1736
|
props: {
|
|
@@ -116,3 +116,12 @@ export async function upsertWorkflow(
|
|
|
116
116
|
|
|
117
117
|
return body.result;
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
export async function deleteWorkflow(api: CloudflareApi, name: string) {
|
|
121
|
+
const response = await api.delete(
|
|
122
|
+
`/accounts/${api.accountId}/workflows/${name}`,
|
|
123
|
+
);
|
|
124
|
+
if (!response.ok && response.status !== 404) {
|
|
125
|
+
await handleApiError(response, "delete", "workflow", name);
|
|
126
|
+
}
|
|
127
|
+
}
|
package/src/docker/api.ts
CHANGED
|
@@ -134,7 +134,8 @@ export class DockerApi {
|
|
|
134
134
|
} catch (error: any) {
|
|
135
135
|
const message = stderr || error.message || "Command failed";
|
|
136
136
|
if (
|
|
137
|
-
message.includes("unexpected status from HEAD request")
|
|
137
|
+
(message.includes("unexpected status from HEAD request") ||
|
|
138
|
+
message.includes("502 Bad Gateway")) &&
|
|
138
139
|
remainingAttempts > 0
|
|
139
140
|
) {
|
|
140
141
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
@@ -2,26 +2,41 @@ export interface LogPushProps {
|
|
|
2
2
|
maxFooBar: string;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
export function camelToSnakeObjectDeep<T
|
|
5
|
+
export function camelToSnakeObjectDeep<T>(
|
|
6
6
|
obj: T,
|
|
7
|
-
): T extends undefined ? undefined : CamelToSnake<T> {
|
|
8
|
-
|
|
9
|
-
obj
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
7
|
+
): T extends undefined ? undefined : T extends object ? CamelToSnake<T> : T {
|
|
8
|
+
if (obj === undefined || obj === null) {
|
|
9
|
+
return obj as any;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// If it's not an object (primitive types), return as-is
|
|
13
|
+
if (typeof obj !== "object") {
|
|
14
|
+
return obj as any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (obj instanceof RegExp) {
|
|
18
|
+
return obj as any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Handle arrays
|
|
22
|
+
if (Array.isArray(obj)) {
|
|
23
|
+
return obj.map(camelToSnakeObjectDeep) as any;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Handle objects
|
|
27
|
+
return Object.fromEntries(
|
|
28
|
+
Object.entries(obj).map(([key, value]) => [
|
|
29
|
+
key
|
|
30
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2") // Handle consecutive capitals: "FOOBar" -> "FOO_Bar"
|
|
31
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2") // Handle normal camelCase: "fooBar" -> "foo_Bar"
|
|
32
|
+
.toLowerCase(),
|
|
33
|
+
Array.isArray(value)
|
|
34
|
+
? value.map(camelToSnakeObjectDeep)
|
|
35
|
+
: typeof value === "object" && value !== null
|
|
36
|
+
? camelToSnakeObjectDeep(value)
|
|
37
|
+
: value,
|
|
38
|
+
]),
|
|
39
|
+
) as any;
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
// Helper to check if a character is uppercase
|
|
@@ -6,7 +6,5 @@ export type Runtime = "bun" | "deno" | "node";
|
|
|
6
6
|
export function detectRuntime(): Runtime {
|
|
7
7
|
if (typeof Bun !== "undefined" && Bun !== null) return "bun";
|
|
8
8
|
if (typeof Deno !== "undefined" && Deno !== null) return "deno";
|
|
9
|
-
if (typeof process !== "undefined" && process.release?.name === "node")
|
|
10
|
-
return "node";
|
|
11
9
|
return "node";
|
|
12
10
|
}
|