alchemy 0.5.2 → 0.7.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/lib/cloudflare/account-api-token.d.ts +6 -1
- package/lib/cloudflare/account-api-token.js +5 -1
- package/lib/cloudflare/account-id.d.ts +5 -1
- package/lib/cloudflare/account-id.js +5 -0
- package/lib/cloudflare/api-error.d.ts +32 -0
- package/lib/cloudflare/api-error.js +47 -0
- package/lib/cloudflare/api.d.ts +16 -49
- package/lib/cloudflare/api.js +37 -149
- package/lib/cloudflare/auth.d.ts +55 -38
- package/lib/cloudflare/auth.js +148 -77
- package/lib/cloudflare/bindings.d.ts +19 -7
- package/lib/cloudflare/bindings.js +0 -9
- package/lib/cloudflare/bound.d.ts +2 -1
- package/lib/cloudflare/bucket.d.ts +30 -5
- package/lib/cloudflare/bucket.js +12 -11
- package/lib/cloudflare/custom-domain.d.ts +2 -1
- package/lib/cloudflare/custom-domain.js +3 -2
- package/lib/cloudflare/dns-records.d.ts +2 -1
- package/lib/cloudflare/dns-records.js +2 -2
- package/lib/cloudflare/index.d.ts +1 -0
- package/lib/cloudflare/index.js +1 -0
- package/lib/cloudflare/kv-namespace.d.ts +7 -1
- package/lib/cloudflare/kv-namespace.js +72 -71
- package/lib/cloudflare/permission-groups.d.ts +4 -0
- package/lib/cloudflare/permission-groups.js +5 -1
- package/lib/cloudflare/r2-rest-state-store.d.ts +3 -17
- package/lib/cloudflare/r2-rest-state-store.js +4 -12
- package/lib/cloudflare/worker.d.ts +2 -6
- package/lib/cloudflare/worker.js +58 -90
- package/lib/cloudflare/workflow.d.ts +46 -0
- package/lib/cloudflare/workflow.js +29 -0
- package/lib/cloudflare/zone.d.ts +2 -6
- package/lib/cloudflare/zone.js +1 -3
- package/lib/internal/docs/providers.js +1 -8
- package/package.json +5 -1
- package/src/cloudflare/account-api-token.ts +7 -3
- package/src/cloudflare/account-id.ts +12 -0
- package/src/cloudflare/api-error.ts +58 -0
- package/src/cloudflare/api.ts +50 -216
- package/src/cloudflare/auth.ts +262 -119
- package/src/cloudflare/bindings.ts +21 -16
- package/src/cloudflare/bound.ts +4 -1
- package/src/cloudflare/bucket.ts +52 -29
- package/src/cloudflare/custom-domain.ts +8 -3
- package/src/cloudflare/dns-records.ts +7 -3
- package/src/cloudflare/durable-object-namespace.ts +1 -1
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/kv-namespace.ts +117 -105
- package/src/cloudflare/permission-groups.ts +5 -1
- package/src/cloudflare/r2-rest-state-store.ts +8 -31
- package/src/cloudflare/worker.ts +71 -141
- package/src/cloudflare/workflow.ts +79 -0
- package/src/cloudflare/zone.ts +17 -25
- package/src/internal/docs/providers.ts +1 -8
package/src/cloudflare/worker.ts
CHANGED
|
@@ -3,28 +3,28 @@ import * as fs from "fs/promises";
|
|
|
3
3
|
import type { Context } from "../context";
|
|
4
4
|
import { Bundle, type BundleProps } from "../esbuild/bundle";
|
|
5
5
|
import { Resource } from "../resource";
|
|
6
|
-
import { isSecret } from "../secret";
|
|
7
6
|
import { getContentType } from "../util/content-type";
|
|
8
7
|
import { withExponentialBackoff } from "../util/retry";
|
|
9
8
|
import { slugify } from "../util/slugify";
|
|
10
|
-
import { type CloudflareApi, createCloudflareApi } from "./api";
|
|
11
|
-
import type { Assets } from "./assets";
|
|
12
9
|
import {
|
|
13
|
-
|
|
14
|
-
type
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from "./
|
|
10
|
+
createCloudflareApi,
|
|
11
|
+
type CloudflareApi,
|
|
12
|
+
type CloudflareApiOptions,
|
|
13
|
+
} from "./api";
|
|
14
|
+
import { type Assets } from "./assets";
|
|
15
|
+
import { type Bindings, type WorkerBindingSpec } from "./bindings";
|
|
18
16
|
import type { Bound } from "./bound";
|
|
19
|
-
import type
|
|
17
|
+
import { type DurableObjectNamespace } from "./durable-object-namespace";
|
|
20
18
|
import { isKVNamespace } from "./kv-namespace";
|
|
21
19
|
import type { WorkerScriptMetadata } from "./worker-metadata";
|
|
22
20
|
import type { SingleStepMigration } from "./worker-migration";
|
|
21
|
+
import { upsertWorkflow, type Workflow } from "./workflow";
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* Properties for creating or updating a Worker
|
|
26
25
|
*/
|
|
27
|
-
export interface WorkerProps<B extends Bindings = Bindings>
|
|
26
|
+
export interface WorkerProps<B extends Bindings = Bindings>
|
|
27
|
+
extends CloudflareApiOptions {
|
|
28
28
|
/**
|
|
29
29
|
* The worker script content (JavaScript or WASM)
|
|
30
30
|
* One of script, entryPoint, or bundle must be provided
|
|
@@ -58,12 +58,6 @@ export interface WorkerProps<B extends Bindings = Bindings> {
|
|
|
58
58
|
*/
|
|
59
59
|
name: string;
|
|
60
60
|
|
|
61
|
-
/**
|
|
62
|
-
* Routes to associate with this worker
|
|
63
|
-
* Format: example.com/* or *.example.com/*
|
|
64
|
-
*/
|
|
65
|
-
routes?: string[];
|
|
66
|
-
|
|
67
61
|
/**
|
|
68
62
|
* Bindings to attach to the worker
|
|
69
63
|
*/
|
|
@@ -236,7 +230,7 @@ export const Worker = Resource(
|
|
|
236
230
|
props: WorkerProps<B>
|
|
237
231
|
): Promise<Worker<B>> {
|
|
238
232
|
// Create Cloudflare API client with automatic account discovery
|
|
239
|
-
const api = await createCloudflareApi();
|
|
233
|
+
const api = await createCloudflareApi(props);
|
|
240
234
|
|
|
241
235
|
// Use the provided name
|
|
242
236
|
const workerName = props.name;
|
|
@@ -262,10 +256,16 @@ export const Worker = Resource(
|
|
|
262
256
|
|
|
263
257
|
// Find any assets bindings
|
|
264
258
|
const assetsBindings: { name: string; assets: Assets }[] = [];
|
|
259
|
+
const workflowsBindings: Workflow[] = [];
|
|
260
|
+
|
|
265
261
|
if (props.bindings) {
|
|
266
262
|
for (const [bindingName, binding] of Object.entries(props.bindings)) {
|
|
267
|
-
if (
|
|
268
|
-
|
|
263
|
+
if (typeof binding === "object") {
|
|
264
|
+
if (binding.type === "assets") {
|
|
265
|
+
assetsBindings.push({ name: bindingName, assets: binding });
|
|
266
|
+
} else if (binding.type === "workflow") {
|
|
267
|
+
workflowsBindings.push(binding);
|
|
268
|
+
}
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
}
|
|
@@ -293,15 +293,19 @@ export const Worker = Resource(
|
|
|
293
293
|
assetUploadResult
|
|
294
294
|
);
|
|
295
295
|
|
|
296
|
-
// Upload the worker script
|
|
297
296
|
await putWorker(api, workerName, scriptContent, scriptMetadata);
|
|
298
297
|
|
|
298
|
+
for (const workflow of workflowsBindings) {
|
|
299
|
+
await upsertWorkflow(api, {
|
|
300
|
+
workflowName: workflow.workflowName,
|
|
301
|
+
className: workflow.className,
|
|
302
|
+
scriptName: workerName,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
299
306
|
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
300
307
|
await this.set("bindings", props.bindings);
|
|
301
308
|
|
|
302
|
-
// Handle routes if requested
|
|
303
|
-
await setupRoutes(api, workerName, props.routes || []);
|
|
304
|
-
|
|
305
309
|
// Handle worker URL if requested
|
|
306
310
|
const workerUrl = await configureURL(
|
|
307
311
|
this,
|
|
@@ -320,7 +324,6 @@ export const Worker = Resource(
|
|
|
320
324
|
name: workerName,
|
|
321
325
|
script: scriptContent,
|
|
322
326
|
format: props.format || "esm", // Include format in the output
|
|
323
|
-
routes: props.routes || [],
|
|
324
327
|
bindings: props.bindings ?? ({} as B),
|
|
325
328
|
env: props.env,
|
|
326
329
|
observability: scriptMetadata.observability,
|
|
@@ -354,35 +357,6 @@ async function deleteWorker<B extends Bindings>(
|
|
|
354
357
|
);
|
|
355
358
|
}
|
|
356
359
|
|
|
357
|
-
// Also remove any associated routes if they exist
|
|
358
|
-
if (ctx.output?.routes && ctx.output.routes.length > 0 && api.zoneId) {
|
|
359
|
-
// First get existing routes to find their IDs
|
|
360
|
-
const routesResponse = await api.get(`/zones/${api.zoneId}/workers/routes`);
|
|
361
|
-
|
|
362
|
-
if (!routesResponse.ok) {
|
|
363
|
-
throw new Error(
|
|
364
|
-
`Could not fetch routes for cleanup: ${routesResponse.status} ${routesResponse.statusText}`
|
|
365
|
-
);
|
|
366
|
-
}
|
|
367
|
-
const routesData: any = await routesResponse.json();
|
|
368
|
-
const existingRoutes = routesData.result || [];
|
|
369
|
-
|
|
370
|
-
for (const route of existingRoutes) {
|
|
371
|
-
if (ctx.output.routes.includes(route.pattern)) {
|
|
372
|
-
// Delete the route
|
|
373
|
-
const routeDeleteResponse = await api.delete(
|
|
374
|
-
`/zones/${api.zoneId}/workers/routes/${route.id}`
|
|
375
|
-
);
|
|
376
|
-
|
|
377
|
-
if (!routeDeleteResponse.ok) {
|
|
378
|
-
console.warn(
|
|
379
|
-
`Failed to delete route ${route.pattern}: ${routeDeleteResponse.status} ${routeDeleteResponse.statusText}`
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
360
|
// Disable the URL if it was enabled
|
|
387
361
|
if (ctx.output?.url) {
|
|
388
362
|
try {
|
|
@@ -566,60 +540,79 @@ async function prepareWorkerMetadata<B extends Bindings>(
|
|
|
566
540
|
service: binding.id,
|
|
567
541
|
});
|
|
568
542
|
} else if (binding.type === "durable_object_namespace") {
|
|
569
|
-
const stableId = binding.id;
|
|
570
|
-
const className = binding.className;
|
|
571
|
-
|
|
572
543
|
meta.bindings.push({
|
|
573
544
|
type: "durable_object_namespace",
|
|
574
545
|
name: bindingName,
|
|
575
|
-
class_name: className,
|
|
546
|
+
class_name: binding.className,
|
|
576
547
|
script_name: binding.scriptName,
|
|
577
548
|
environment: binding.environment,
|
|
578
549
|
namespace_id: binding.namespaceId,
|
|
579
550
|
});
|
|
580
|
-
|
|
581
|
-
const oldBinding: DurableObjectNamespace | undefined = Object.values(
|
|
582
|
-
oldBindings ?? {}
|
|
583
|
-
)
|
|
584
|
-
?.filter(isDurableObjectNamespace)
|
|
585
|
-
?.find((b) => b.id === stableId);
|
|
586
|
-
|
|
587
|
-
if (!oldBinding) {
|
|
588
|
-
if (binding.sqlite) {
|
|
589
|
-
meta.migrations!.new_sqlite_classes!.push(className);
|
|
590
|
-
} else {
|
|
591
|
-
meta.migrations!.new_classes!.push(className);
|
|
592
|
-
}
|
|
593
|
-
} else if (oldBinding.className !== className) {
|
|
594
|
-
meta.migrations!.renamed_classes!.push({
|
|
595
|
-
from: oldBinding.className,
|
|
596
|
-
to: className,
|
|
597
|
-
});
|
|
598
|
-
}
|
|
551
|
+
configureClassMigration(binding, binding.id, binding.className);
|
|
599
552
|
} else if (binding.type === "r2_bucket") {
|
|
600
553
|
meta.bindings.push({
|
|
601
554
|
type: "r2_bucket",
|
|
602
555
|
name: bindingName,
|
|
603
556
|
bucket_name: binding.name,
|
|
604
557
|
});
|
|
605
|
-
} else if (
|
|
558
|
+
} else if (binding.type === "assets") {
|
|
606
559
|
meta.bindings.push({
|
|
607
560
|
type: "assets",
|
|
608
561
|
name: bindingName,
|
|
609
562
|
});
|
|
610
|
-
} else if (
|
|
563
|
+
} else if (binding.type === "secret") {
|
|
611
564
|
meta.bindings.push({
|
|
612
565
|
type: "secret_text",
|
|
613
566
|
name: bindingName,
|
|
614
567
|
text: binding.unencrypted,
|
|
615
568
|
});
|
|
569
|
+
} else if (binding.type === "workflow") {
|
|
570
|
+
meta.bindings.push({
|
|
571
|
+
type: "workflow",
|
|
572
|
+
name: bindingName,
|
|
573
|
+
workflow_name: binding.workflowName,
|
|
574
|
+
class_name: binding.className,
|
|
575
|
+
// this should be set if the Workflow is in another script ...
|
|
576
|
+
// script_name: ??,
|
|
577
|
+
});
|
|
578
|
+
// it's unclear whether this is needed, but it works both ways
|
|
579
|
+
configureClassMigration(binding, binding.id, binding.className);
|
|
616
580
|
} else {
|
|
617
581
|
// @ts-expect-error - we should never reach here
|
|
618
582
|
throw new Error(`Unsupported binding type: ${binding.type}`);
|
|
619
583
|
}
|
|
620
584
|
}
|
|
621
585
|
|
|
586
|
+
function configureClassMigration(
|
|
587
|
+
binding: DurableObjectNamespace | Workflow,
|
|
588
|
+
stableId: string,
|
|
589
|
+
className: string
|
|
590
|
+
) {
|
|
591
|
+
const oldBinding: DurableObjectNamespace | Workflow | undefined =
|
|
592
|
+
Object.values(oldBindings ?? {})
|
|
593
|
+
?.filter(
|
|
594
|
+
(b) =>
|
|
595
|
+
typeof b === "object" &&
|
|
596
|
+
(b.type === "durable_object_namespace" || b.type === "workflow")
|
|
597
|
+
)
|
|
598
|
+
?.find((b) => b.id === stableId);
|
|
599
|
+
|
|
600
|
+
if (!oldBinding) {
|
|
601
|
+
if (binding.type === "durable_object_namespace" && binding.sqlite) {
|
|
602
|
+
meta.migrations!.new_sqlite_classes!.push(className);
|
|
603
|
+
} else {
|
|
604
|
+
meta.migrations!.new_classes!.push(className);
|
|
605
|
+
}
|
|
606
|
+
} else if (oldBinding.className !== className) {
|
|
607
|
+
meta.migrations!.renamed_classes!.push({
|
|
608
|
+
from: oldBinding.className,
|
|
609
|
+
to: className,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
622
614
|
// Convert env variables to plain_text bindings
|
|
615
|
+
// TODO(sam): remove Worker.env in favor of always bindings
|
|
623
616
|
if (props.env) {
|
|
624
617
|
for (const [key, value] of Object.entries(props.env)) {
|
|
625
618
|
meta.bindings.push({
|
|
@@ -717,67 +710,6 @@ async function bundleWorkerScript<B extends Bindings>(props: WorkerProps) {
|
|
|
717
710
|
}
|
|
718
711
|
}
|
|
719
712
|
|
|
720
|
-
async function setupRoutes(
|
|
721
|
-
api: CloudflareApi,
|
|
722
|
-
workerName: string,
|
|
723
|
-
routes: string[]
|
|
724
|
-
) {
|
|
725
|
-
// Set up routes if provided
|
|
726
|
-
if (routes && routes.length > 0 && api.zoneId) {
|
|
727
|
-
// First get existing routes
|
|
728
|
-
const routesResponse = await api.get(`/zones/${api.zoneId}/workers/routes`);
|
|
729
|
-
|
|
730
|
-
if (!routesResponse.ok) {
|
|
731
|
-
throw new Error(
|
|
732
|
-
`Could not fetch routes: ${routesResponse.status} ${routesResponse.statusText}`
|
|
733
|
-
);
|
|
734
|
-
}
|
|
735
|
-
const routesData: any = await routesResponse.json();
|
|
736
|
-
const existingRoutes = routesData.result || [];
|
|
737
|
-
|
|
738
|
-
// For each desired route
|
|
739
|
-
for (const pattern of routes) {
|
|
740
|
-
const existingRoute = existingRoutes.find(
|
|
741
|
-
(r: any) => r.pattern === pattern
|
|
742
|
-
);
|
|
743
|
-
|
|
744
|
-
if (existingRoute) {
|
|
745
|
-
// Update if script name doesn't match
|
|
746
|
-
if (existingRoute.script !== workerName) {
|
|
747
|
-
const updateRouteResponse = await api.put(
|
|
748
|
-
`/zones/${api.zoneId}/workers/routes/${existingRoute.id}`,
|
|
749
|
-
{
|
|
750
|
-
pattern,
|
|
751
|
-
script: workerName,
|
|
752
|
-
}
|
|
753
|
-
);
|
|
754
|
-
|
|
755
|
-
if (!updateRouteResponse.ok) {
|
|
756
|
-
console.warn(
|
|
757
|
-
`Failed to update route ${pattern}: ${updateRouteResponse.status} ${updateRouteResponse.statusText}`
|
|
758
|
-
);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
} else {
|
|
762
|
-
// Create new route
|
|
763
|
-
const createRouteResponse = await api.post(
|
|
764
|
-
`/zones/${api.zoneId}/workers/routes`,
|
|
765
|
-
{
|
|
766
|
-
pattern,
|
|
767
|
-
script: workerName,
|
|
768
|
-
}
|
|
769
|
-
);
|
|
770
|
-
|
|
771
|
-
if (!createRouteResponse.ok) {
|
|
772
|
-
throw new Error(
|
|
773
|
-
`Failed to create route ${pattern}: ${createRouteResponse.status} ${createRouteResponse.statusText}`
|
|
774
|
-
);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
713
|
async function configureURL<B extends Bindings>(
|
|
782
714
|
ctx: Context<Worker<B>>,
|
|
783
715
|
api: CloudflareApi,
|
|
@@ -1006,8 +938,6 @@ async function uploadAssets(
|
|
|
1006
938
|
formData.append(fileHash, blob, fileHash);
|
|
1007
939
|
}
|
|
1008
940
|
|
|
1009
|
-
console.log(`Uploading ${totalBytes} bytes of assets`);
|
|
1010
|
-
|
|
1011
941
|
// Upload this batch of files
|
|
1012
942
|
const uploadResponse = await api.post(
|
|
1013
943
|
`/accounts/${api.accountId}/workers/assets/upload?base64=true`,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CloudflareApi } from "./api";
|
|
2
|
+
import { handleApiError } from "./api-error";
|
|
3
|
+
|
|
4
|
+
export interface WorkflowProps {
|
|
5
|
+
/**
|
|
6
|
+
* Name of the workflow
|
|
7
|
+
*
|
|
8
|
+
* @maxLength 64
|
|
9
|
+
* @minLength 1
|
|
10
|
+
* @default - className if provided, otherwise id
|
|
11
|
+
*/
|
|
12
|
+
workflowName?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Name of the class that implements the workflow
|
|
15
|
+
*
|
|
16
|
+
* @maxLength 255
|
|
17
|
+
* @minLength 1
|
|
18
|
+
* @default - workflowName if provided, otherwise id
|
|
19
|
+
*/
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class Workflow<PARAMS = unknown> {
|
|
24
|
+
public readonly type: "workflow" = "workflow";
|
|
25
|
+
/**
|
|
26
|
+
* Phantom property to preserve workflow params at the type level.
|
|
27
|
+
*
|
|
28
|
+
* No value exists.
|
|
29
|
+
*/
|
|
30
|
+
public readonly _PARAMS: PARAMS = undefined!;
|
|
31
|
+
|
|
32
|
+
public readonly workflowName: string;
|
|
33
|
+
public readonly className: string;
|
|
34
|
+
|
|
35
|
+
constructor(
|
|
36
|
+
public readonly id: string,
|
|
37
|
+
props: WorkflowProps = {}
|
|
38
|
+
) {
|
|
39
|
+
this.workflowName = props.workflowName ?? props.className ?? id;
|
|
40
|
+
this.className = props.className ?? this.workflowName;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface WorkflowMetadata {
|
|
45
|
+
id: string; // uuid
|
|
46
|
+
class_name: string;
|
|
47
|
+
created_on: string; // date-time
|
|
48
|
+
modified_on: string; // date-time
|
|
49
|
+
name: string; // maxLength: 64, minLength: 1
|
|
50
|
+
script_name: string;
|
|
51
|
+
triggered_on: string; // date-time
|
|
52
|
+
version_id: string; // uuid
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function upsertWorkflow(
|
|
56
|
+
api: CloudflareApi,
|
|
57
|
+
props: WorkflowProps & {
|
|
58
|
+
workflowName: string;
|
|
59
|
+
scriptName: string;
|
|
60
|
+
}
|
|
61
|
+
) {
|
|
62
|
+
const response = await api.put(
|
|
63
|
+
`/accounts/${api.accountId}/workflows/${props.workflowName}`,
|
|
64
|
+
{
|
|
65
|
+
class_name: props.className,
|
|
66
|
+
script_name: props.scriptName,
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
await handleApiError(response, "create", "workflow", props.workflowName);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const body = (await response.json()) as {
|
|
75
|
+
result: WorkflowMetadata;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return body.result;
|
|
79
|
+
}
|
package/src/cloudflare/zone.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Context } from "../context";
|
|
2
2
|
import { Resource } from "../resource";
|
|
3
|
-
import { createCloudflareApi } from "./api";
|
|
3
|
+
import { createCloudflareApi, type CloudflareApiOptions } from "./api";
|
|
4
4
|
import type {
|
|
5
5
|
AlwaysUseHTTPSValue,
|
|
6
6
|
AutomaticHTTPSRewritesValue,
|
|
@@ -24,18 +24,12 @@ import type {
|
|
|
24
24
|
/**
|
|
25
25
|
* Properties for creating or updating a Zone
|
|
26
26
|
*/
|
|
27
|
-
export interface ZoneProps {
|
|
27
|
+
export interface ZoneProps extends CloudflareApiOptions {
|
|
28
28
|
/**
|
|
29
29
|
* The domain name for the zone
|
|
30
30
|
*/
|
|
31
31
|
name: string;
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Account ID to use for the zone
|
|
35
|
-
* If not provided, will use the default account
|
|
36
|
-
*/
|
|
37
|
-
accountId?: string;
|
|
38
|
-
|
|
39
33
|
/**
|
|
40
34
|
* The type of zone to create
|
|
41
35
|
* "full" - Full zone implies that DNS is hosted with Cloudflare
|
|
@@ -305,12 +299,10 @@ export const Zone = Resource(
|
|
|
305
299
|
async function (
|
|
306
300
|
this: Context<Zone>,
|
|
307
301
|
id: string,
|
|
308
|
-
props: ZoneProps
|
|
302
|
+
props: ZoneProps
|
|
309
303
|
): Promise<Zone> {
|
|
310
304
|
// Create Cloudflare API client with automatic account discovery
|
|
311
|
-
const api = await createCloudflareApi(
|
|
312
|
-
accountId: props.accountId,
|
|
313
|
-
});
|
|
305
|
+
const api = await createCloudflareApi(props);
|
|
314
306
|
|
|
315
307
|
if (this.phase === "delete") {
|
|
316
308
|
if (this.output?.id) {
|
|
@@ -322,7 +314,7 @@ export const Zone = Resource(
|
|
|
322
314
|
errors: [{ message: deleteResponse.statusText }],
|
|
323
315
|
}));
|
|
324
316
|
throw new Error(
|
|
325
|
-
`Error deleting zone '${props.name}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}
|
|
317
|
+
`Error deleting zone '${props.name}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`
|
|
326
318
|
);
|
|
327
319
|
}
|
|
328
320
|
} else {
|
|
@@ -337,7 +329,7 @@ export const Zone = Resource(
|
|
|
337
329
|
|
|
338
330
|
if (!response.ok) {
|
|
339
331
|
throw new Error(
|
|
340
|
-
`Error getting zone '${props.name}': ${response.statusText}
|
|
332
|
+
`Error getting zone '${props.name}': ${response.statusText}`
|
|
341
333
|
);
|
|
342
334
|
}
|
|
343
335
|
|
|
@@ -385,13 +377,13 @@ export const Zone = Resource(
|
|
|
385
377
|
if (response.status === 400 && body.includes("already exists")) {
|
|
386
378
|
// Zone already exists, fetch it instead
|
|
387
379
|
console.warn(
|
|
388
|
-
`Zone '${props.name}' already exists during Zone create, adopting it
|
|
380
|
+
`Zone '${props.name}' already exists during Zone create, adopting it...`
|
|
389
381
|
);
|
|
390
382
|
const getResponse = await api.get(`/zones?name=${props.name}`);
|
|
391
383
|
|
|
392
384
|
if (!getResponse.ok) {
|
|
393
385
|
throw new Error(
|
|
394
|
-
`Error fetching existing zone '${props.name}': ${getResponse.statusText}
|
|
386
|
+
`Error fetching existing zone '${props.name}': ${getResponse.statusText}`
|
|
395
387
|
);
|
|
396
388
|
}
|
|
397
389
|
|
|
@@ -400,13 +392,13 @@ export const Zone = Resource(
|
|
|
400
392
|
).result;
|
|
401
393
|
if (zones.length === 0) {
|
|
402
394
|
throw new Error(
|
|
403
|
-
`Zone '${props.name}' does not exist, but the name is reserved for another user
|
|
395
|
+
`Zone '${props.name}' does not exist, but the name is reserved for another user.`
|
|
404
396
|
);
|
|
405
397
|
}
|
|
406
398
|
zoneData = zones[0];
|
|
407
399
|
} else {
|
|
408
400
|
throw new Error(
|
|
409
|
-
`Error creating zone '${props.name}': ${response.statusText}\n${body}
|
|
401
|
+
`Error creating zone '${props.name}': ${response.statusText}\n${body}`
|
|
410
402
|
);
|
|
411
403
|
}
|
|
412
404
|
} else {
|
|
@@ -437,7 +429,7 @@ export const Zone = Resource(
|
|
|
437
429
|
settings: await getZoneSettings(api, zoneData.id),
|
|
438
430
|
});
|
|
439
431
|
}
|
|
440
|
-
}
|
|
432
|
+
}
|
|
441
433
|
);
|
|
442
434
|
|
|
443
435
|
/**
|
|
@@ -446,7 +438,7 @@ export const Zone = Resource(
|
|
|
446
438
|
async function updateZoneSettings(
|
|
447
439
|
api: any,
|
|
448
440
|
zoneId: string,
|
|
449
|
-
settings: ZoneProps["settings"]
|
|
441
|
+
settings: ZoneProps["settings"]
|
|
450
442
|
): Promise<void> {
|
|
451
443
|
if (!settings) return;
|
|
452
444
|
|
|
@@ -480,7 +472,7 @@ async function updateZoneSettings(
|
|
|
480
472
|
`/zones/${zoneId}/settings/${settingId}`,
|
|
481
473
|
{
|
|
482
474
|
value,
|
|
483
|
-
} as UpdateZoneSettingParams
|
|
475
|
+
} as UpdateZoneSettingParams
|
|
484
476
|
);
|
|
485
477
|
|
|
486
478
|
if (!response.ok) {
|
|
@@ -490,10 +482,10 @@ async function updateZoneSettings(
|
|
|
490
482
|
return;
|
|
491
483
|
}
|
|
492
484
|
throw new Error(
|
|
493
|
-
`Failed to update zone setting ${key}: ${response.statusText}
|
|
485
|
+
`Failed to update zone setting ${key}: ${response.statusText}`
|
|
494
486
|
);
|
|
495
487
|
}
|
|
496
|
-
})
|
|
488
|
+
})
|
|
497
489
|
);
|
|
498
490
|
}
|
|
499
491
|
|
|
@@ -502,13 +494,13 @@ async function updateZoneSettings(
|
|
|
502
494
|
*/
|
|
503
495
|
async function getZoneSettings(
|
|
504
496
|
api: any,
|
|
505
|
-
zoneId: string
|
|
497
|
+
zoneId: string
|
|
506
498
|
): Promise<Zone["settings"]> {
|
|
507
499
|
const settingsResponse = await api.get(`/zones/${zoneId}/settings`);
|
|
508
500
|
|
|
509
501
|
if (!settingsResponse.ok) {
|
|
510
502
|
throw new Error(
|
|
511
|
-
`Failed to fetch zone settings: ${settingsResponse.status} ${settingsResponse.statusText}
|
|
503
|
+
`Failed to fetch zone settings: ${settingsResponse.status} ${settingsResponse.statusText}`
|
|
512
504
|
);
|
|
513
505
|
}
|
|
514
506
|
|
|
@@ -67,13 +67,6 @@ export async function Providers({
|
|
|
67
67
|
.filter((dirent) => dirent.isDirectory() && !exclude.includes(dirent.name))
|
|
68
68
|
.map((dirent) => path.join(dirent.parentPath, dirent.name));
|
|
69
69
|
|
|
70
|
-
// For each provider, list all files
|
|
71
|
-
if (filter === false) {
|
|
72
|
-
return [];
|
|
73
|
-
} else if (typeof filter === "number") {
|
|
74
|
-
providers = providers.slice(0, filter);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
70
|
if (parallel) {
|
|
78
71
|
return await Promise.all(
|
|
79
72
|
providers.map((provider) =>
|
|
@@ -152,7 +145,7 @@ async function generateProviderDocs({
|
|
|
152
145
|
The ${provider} Service has the following resources:
|
|
153
146
|
${alchemy.files(files)}
|
|
154
147
|
|
|
155
|
-
A file is considered a "Resource" if it contains a const <ResourceName> = Resource(...) call or if it is a function that calls a Resource function, e.g. const TypeScriptFile = () => File(...).
|
|
148
|
+
A file is considered a "Resource" if it contains a const <ResourceName> = Resource(...) call or if it is a function that calls a Resource function, e.g. const TypeScriptFile = () => File(...), or it is the Workflow or DurableObject classes.
|
|
156
149
|
A file is considered a "Client" if it exposes a wrapper around creating a SDK client or fetch.
|
|
157
150
|
A file is considered a "Utility" if it contains utility functions that are not resources or clients.
|
|
158
151
|
A file is considered a "Types" if it contains just type definitions and maybe helpers around working with those types.
|