alchemy 0.6.0 → 0.7.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.
- package/lib/cloudflare/bindings.d.ts +21 -7
- package/lib/cloudflare/bindings.js +0 -9
- package/lib/cloudflare/bound.d.ts +4 -1
- package/lib/cloudflare/d1-database.d.ts +134 -0
- package/lib/cloudflare/d1-database.js +161 -0
- package/lib/cloudflare/index.d.ts +4 -0
- package/lib/cloudflare/index.js +4 -0
- package/lib/cloudflare/kv-namespace.d.ts +0 -1
- package/lib/cloudflare/kv-namespace.js +0 -3
- package/lib/cloudflare/queue.d.ts +147 -0
- package/lib/cloudflare/queue.js +192 -0
- package/lib/cloudflare/worker.js +78 -34
- package/lib/cloudflare/workflow.d.ts +46 -0
- package/lib/cloudflare/workflow.js +29 -0
- package/lib/cloudflare/wrangler.json.d.ts +82 -185
- package/lib/cloudflare/wrangler.json.js +124 -17
- package/lib/internal/docs/providers.js +1 -1
- package/package.json +1 -1
- package/src/cloudflare/bindings.ts +27 -18
- package/src/cloudflare/bound.ts +10 -1
- package/src/cloudflare/d1-database.ts +354 -0
- package/src/cloudflare/durable-object-namespace.ts +1 -1
- package/src/cloudflare/index.ts +4 -0
- package/src/cloudflare/kv-namespace.ts +0 -6
- package/src/cloudflare/queue.ts +371 -0
- package/src/cloudflare/worker.ts +85 -45
- package/src/cloudflare/workflow.ts +79 -0
- package/src/cloudflare/wrangler.json.ts +239 -218
- package/src/internal/docs/providers.ts +1 -1
|
@@ -1,309 +1,330 @@
|
|
|
1
|
-
import * as fs from "fs/promises";
|
|
2
1
|
import type { Context } from "../context";
|
|
2
|
+
import { StaticJsonFile } from "../fs";
|
|
3
3
|
import { Resource } from "../resource";
|
|
4
|
+
import type { Bindings } from "./bindings";
|
|
5
|
+
import type { DurableObjectNamespace } from "./durable-object-namespace";
|
|
6
|
+
import type { Worker } from "./worker";
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Properties for wrangler.json configuration file
|
|
7
10
|
*/
|
|
8
11
|
export interface WranglerJsonProps {
|
|
12
|
+
name?: string;
|
|
9
13
|
/**
|
|
10
|
-
* The
|
|
14
|
+
* The worker to generate the wrangler.json file for
|
|
11
15
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
worker: Worker;
|
|
14
17
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
18
|
+
* Path to write the wrangler.json file to
|
|
19
|
+
*
|
|
20
|
+
* @default cwd/wrangler.json
|
|
17
21
|
*/
|
|
18
|
-
|
|
22
|
+
path?: string;
|
|
23
|
+
}
|
|
19
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Output returned after WranglerJson creation/update
|
|
27
|
+
*/
|
|
28
|
+
export interface WranglerJson
|
|
29
|
+
extends Resource<"cloudflare::WranglerJson">,
|
|
30
|
+
WranglerJsonProps {
|
|
20
31
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @default "index.ts" or "index.js"
|
|
32
|
+
* Time at which the file was created
|
|
23
33
|
*/
|
|
24
|
-
|
|
34
|
+
createdAt: number;
|
|
25
35
|
|
|
26
36
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @default "dist"
|
|
37
|
+
* Time at which the file was last updated
|
|
29
38
|
*/
|
|
30
|
-
|
|
39
|
+
updatedAt: number;
|
|
31
40
|
|
|
32
41
|
/**
|
|
33
|
-
*
|
|
42
|
+
* Path to the wrangler.json file
|
|
34
43
|
*/
|
|
35
|
-
|
|
44
|
+
path: string;
|
|
45
|
+
}
|
|
36
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Resource for managing wrangler.json configuration files
|
|
49
|
+
*/
|
|
50
|
+
export const WranglerJson = Resource(
|
|
51
|
+
"cloudflare::WranglerJson",
|
|
52
|
+
async function (
|
|
53
|
+
this: Context<WranglerJson>,
|
|
54
|
+
id: string,
|
|
55
|
+
props: WranglerJsonProps
|
|
56
|
+
): Promise<WranglerJson> {
|
|
57
|
+
// Default path is wrangler.json in current directory
|
|
58
|
+
const filePath = props.path || "wrangler.json";
|
|
59
|
+
|
|
60
|
+
if (this.phase === "delete") {
|
|
61
|
+
return this.destroy();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (props.worker.entrypoint === undefined) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
"Worker must have an entrypoint to generate a wrangler.json"
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const worker = props.worker;
|
|
71
|
+
|
|
72
|
+
const spec: WranglerJsonSpec = {
|
|
73
|
+
name: worker.name,
|
|
74
|
+
// Use entrypoint as main if it exists
|
|
75
|
+
main: worker.entrypoint,
|
|
76
|
+
// see: https://developers.cloudflare.com/workers/configuration/compatibility-dates/
|
|
77
|
+
compatibility_date: "2022-04-05",
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Process bindings if they exist
|
|
81
|
+
if (worker.bindings) {
|
|
82
|
+
processBindings(spec, worker.bindings);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Add environment variables as vars
|
|
86
|
+
if (worker.env) {
|
|
87
|
+
spec.vars = { ...worker.env };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await StaticJsonFile("wrangler.json", spec);
|
|
91
|
+
|
|
92
|
+
// Return the resource
|
|
93
|
+
return this({
|
|
94
|
+
...props,
|
|
95
|
+
path: filePath,
|
|
96
|
+
createdAt: Date.now(),
|
|
97
|
+
updatedAt: Date.now(),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Wrangler.json configuration specification based on Cloudflare's schema
|
|
104
|
+
*/
|
|
105
|
+
export interface WranglerJsonSpec {
|
|
37
106
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @default true
|
|
107
|
+
* The name of the worker
|
|
40
108
|
*/
|
|
41
|
-
|
|
109
|
+
name: string;
|
|
42
110
|
|
|
43
111
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @default false
|
|
112
|
+
* Main entry point for the worker
|
|
46
113
|
*/
|
|
47
|
-
|
|
114
|
+
main?: string;
|
|
48
115
|
|
|
49
116
|
/**
|
|
50
|
-
*
|
|
117
|
+
* A date in the form yyyy-mm-dd used to determine Workers runtime version
|
|
51
118
|
*/
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Binding name
|
|
55
|
-
*/
|
|
56
|
-
name: string;
|
|
57
|
-
/**
|
|
58
|
-
* Service environment
|
|
59
|
-
*/
|
|
60
|
-
environment?: string;
|
|
61
|
-
}>;
|
|
119
|
+
compatibility_date?: string;
|
|
62
120
|
|
|
63
121
|
/**
|
|
64
|
-
*
|
|
122
|
+
* A list of flags that enable features from upcoming Workers runtime
|
|
65
123
|
*/
|
|
66
|
-
|
|
124
|
+
compatibility_flags?: string[];
|
|
67
125
|
|
|
68
126
|
/**
|
|
69
|
-
*
|
|
127
|
+
* Whether to enable a workers.dev URL for this worker
|
|
70
128
|
*/
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Binding name
|
|
74
|
-
*/
|
|
75
|
-
binding: string;
|
|
76
|
-
/**
|
|
77
|
-
* KV namespace ID
|
|
78
|
-
*/
|
|
79
|
-
id: string;
|
|
80
|
-
/**
|
|
81
|
-
* Preview KV namespace ID
|
|
82
|
-
*/
|
|
83
|
-
preview_id?: string;
|
|
84
|
-
}>;
|
|
129
|
+
workers_dev?: boolean;
|
|
85
130
|
|
|
86
131
|
/**
|
|
87
|
-
*
|
|
132
|
+
* Routes to attach to the worker
|
|
88
133
|
*/
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Binding name
|
|
92
|
-
*/
|
|
93
|
-
binding: string;
|
|
94
|
-
/**
|
|
95
|
-
* Bucket name
|
|
96
|
-
*/
|
|
97
|
-
bucket_name: string;
|
|
98
|
-
/**
|
|
99
|
-
* Preview bucket name
|
|
100
|
-
*/
|
|
101
|
-
preview_bucket_name?: string;
|
|
102
|
-
}>;
|
|
134
|
+
routes?: string[];
|
|
103
135
|
|
|
104
136
|
/**
|
|
105
|
-
*
|
|
137
|
+
* KV Namespace bindings
|
|
106
138
|
*/
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Binding name
|
|
110
|
-
*/
|
|
139
|
+
kv_namespaces?: {
|
|
111
140
|
binding: string;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*/
|
|
115
|
-
database_name: string;
|
|
116
|
-
/**
|
|
117
|
-
* Database ID
|
|
118
|
-
*/
|
|
119
|
-
database_id: string;
|
|
120
|
-
/**
|
|
121
|
-
* Preview database ID
|
|
122
|
-
*/
|
|
123
|
-
preview_database_id?: string;
|
|
124
|
-
}>;
|
|
141
|
+
id: string;
|
|
142
|
+
}[];
|
|
125
143
|
|
|
126
144
|
/**
|
|
127
145
|
* Durable Object bindings
|
|
128
146
|
*/
|
|
129
147
|
durable_objects?: {
|
|
130
|
-
|
|
131
|
-
* Durable Object bindings
|
|
132
|
-
*/
|
|
133
|
-
bindings: Array<{
|
|
134
|
-
/**
|
|
135
|
-
* Binding name
|
|
136
|
-
*/
|
|
148
|
+
bindings: {
|
|
137
149
|
name: string;
|
|
138
|
-
/**
|
|
139
|
-
* Class name
|
|
140
|
-
*/
|
|
141
150
|
class_name: string;
|
|
142
|
-
/**
|
|
143
|
-
* Script name
|
|
144
|
-
*/
|
|
145
151
|
script_name?: string;
|
|
146
|
-
/**
|
|
147
|
-
* Environment name
|
|
148
|
-
*/
|
|
149
152
|
environment?: string;
|
|
150
|
-
}
|
|
153
|
+
}[];
|
|
151
154
|
};
|
|
152
155
|
|
|
153
156
|
/**
|
|
154
|
-
*
|
|
155
|
-
*/
|
|
156
|
-
queues?: {
|
|
157
|
-
/**
|
|
158
|
-
* Producer bindings
|
|
159
|
-
*/
|
|
160
|
-
producers?: Array<{
|
|
161
|
-
/**
|
|
162
|
-
* Binding name
|
|
163
|
-
*/
|
|
164
|
-
binding: string;
|
|
165
|
-
/**
|
|
166
|
-
* Queue name
|
|
167
|
-
*/
|
|
168
|
-
queue: string;
|
|
169
|
-
}>;
|
|
170
|
-
/**
|
|
171
|
-
* Consumer configuration
|
|
172
|
-
*/
|
|
173
|
-
consumers?: Array<{
|
|
174
|
-
/**
|
|
175
|
-
* Queue name
|
|
176
|
-
*/
|
|
177
|
-
queue: string;
|
|
178
|
-
/**
|
|
179
|
-
* Maximum batch size
|
|
180
|
-
*/
|
|
181
|
-
max_batch_size?: number;
|
|
182
|
-
/**
|
|
183
|
-
* Maximum batch timeout
|
|
184
|
-
*/
|
|
185
|
-
max_batch_timeout?: number;
|
|
186
|
-
/**
|
|
187
|
-
* Maximum retries
|
|
188
|
-
*/
|
|
189
|
-
max_retries?: number;
|
|
190
|
-
/**
|
|
191
|
-
* Dead letter queue
|
|
192
|
-
*/
|
|
193
|
-
dead_letter_queue?: string;
|
|
194
|
-
}>;
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Analytics Engine bindings
|
|
157
|
+
* R2 bucket bindings
|
|
199
158
|
*/
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Binding name
|
|
203
|
-
*/
|
|
159
|
+
r2_buckets?: {
|
|
204
160
|
binding: string;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
*/
|
|
208
|
-
dataset?: string;
|
|
209
|
-
}>;
|
|
161
|
+
bucket_name: string;
|
|
162
|
+
}[];
|
|
210
163
|
|
|
211
164
|
/**
|
|
212
|
-
*
|
|
165
|
+
* Queue bindings
|
|
213
166
|
*/
|
|
214
|
-
|
|
167
|
+
queues?: {
|
|
168
|
+
binding: string;
|
|
169
|
+
queue: string;
|
|
170
|
+
}[];
|
|
215
171
|
|
|
216
172
|
/**
|
|
217
|
-
*
|
|
173
|
+
* Service bindings
|
|
218
174
|
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
};
|
|
175
|
+
services?: {
|
|
176
|
+
binding: string;
|
|
177
|
+
service: string;
|
|
178
|
+
environment?: string;
|
|
179
|
+
}[];
|
|
225
180
|
|
|
226
181
|
/**
|
|
227
|
-
*
|
|
182
|
+
* Workflow bindings
|
|
228
183
|
*/
|
|
229
|
-
|
|
184
|
+
workflows?: {
|
|
185
|
+
name: string;
|
|
186
|
+
binding: string;
|
|
187
|
+
class_name: string;
|
|
188
|
+
}[];
|
|
230
189
|
|
|
231
190
|
/**
|
|
232
|
-
*
|
|
191
|
+
* Plain text bindings (vars)
|
|
233
192
|
*/
|
|
234
|
-
|
|
193
|
+
vars?: Record<string, string>;
|
|
235
194
|
|
|
236
195
|
/**
|
|
237
|
-
*
|
|
238
|
-
* "bundled" - Includes resources like CPU and memory. Better for consistent workloads.
|
|
239
|
-
* "unbound" - Pay only for what you use. Better for sporadic workloads.
|
|
196
|
+
* Assets bindings
|
|
240
197
|
*/
|
|
241
|
-
|
|
198
|
+
assets?: {
|
|
199
|
+
directory: string;
|
|
200
|
+
binding: string;
|
|
201
|
+
};
|
|
242
202
|
|
|
243
203
|
/**
|
|
244
|
-
*
|
|
245
|
-
* @internal
|
|
204
|
+
* Workflow bindings
|
|
246
205
|
*/
|
|
247
|
-
|
|
248
|
-
}
|
|
206
|
+
wasm_modules?: Record<string, string>;
|
|
249
207
|
|
|
250
|
-
/**
|
|
251
|
-
* Output returned after WranglerJson creation/update
|
|
252
|
-
*/
|
|
253
|
-
export interface WranglerJson
|
|
254
|
-
extends Resource<"cloudflare::WranglerJson">,
|
|
255
|
-
WranglerJsonProps {
|
|
256
208
|
/**
|
|
257
|
-
*
|
|
209
|
+
* Safe mode configuration
|
|
258
210
|
*/
|
|
259
|
-
|
|
211
|
+
node_compat?: boolean;
|
|
260
212
|
|
|
261
213
|
/**
|
|
262
|
-
*
|
|
214
|
+
* Whether to minify the worker script
|
|
263
215
|
*/
|
|
264
|
-
|
|
216
|
+
minify?: boolean;
|
|
265
217
|
}
|
|
266
218
|
|
|
267
219
|
/**
|
|
268
|
-
*
|
|
220
|
+
* Process worker bindings into wrangler.json format
|
|
269
221
|
*/
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
222
|
+
function processBindings(spec: WranglerJsonSpec, bindings: Bindings): void {
|
|
223
|
+
// Arrays to collect different binding types
|
|
224
|
+
const kvNamespaces: { binding: string; id: string }[] = [];
|
|
225
|
+
const durableObjects: {
|
|
226
|
+
name: string;
|
|
227
|
+
class_name: string;
|
|
228
|
+
script_name?: string;
|
|
229
|
+
environment?: string;
|
|
230
|
+
}[] = [];
|
|
231
|
+
const r2Buckets: { binding: string; bucket_name: string }[] = [];
|
|
232
|
+
const services: { binding: string; service: string; environment?: string }[] =
|
|
233
|
+
[];
|
|
234
|
+
const secrets: string[] = [];
|
|
235
|
+
const workflows: { name: string; binding: string; class_name: string }[] = [];
|
|
236
|
+
const d1Databases: {
|
|
237
|
+
binding: string;
|
|
238
|
+
database_id: string;
|
|
239
|
+
database_name: string;
|
|
240
|
+
}[] = [];
|
|
241
|
+
const queues: { binding: string; queue: string }[] = [];
|
|
279
242
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
243
|
+
// Process each binding
|
|
244
|
+
for (const [bindingName, binding] of Object.entries(bindings)) {
|
|
245
|
+
if (typeof binding === "string") {
|
|
246
|
+
// Plain text binding - add to vars
|
|
247
|
+
if (!spec.vars) {
|
|
248
|
+
spec.vars = {};
|
|
288
249
|
}
|
|
289
|
-
|
|
250
|
+
spec.vars[bindingName] = binding;
|
|
251
|
+
} else if (binding.type === "kv_namespace") {
|
|
252
|
+
// KV Namespace binding
|
|
253
|
+
kvNamespaces.push({
|
|
254
|
+
binding: bindingName,
|
|
255
|
+
id: binding.namespaceId,
|
|
256
|
+
});
|
|
257
|
+
} else if (
|
|
258
|
+
typeof binding === "object" &&
|
|
259
|
+
binding.type === "durable_object_namespace"
|
|
260
|
+
) {
|
|
261
|
+
// Durable Object binding
|
|
262
|
+
const doBinding = binding as DurableObjectNamespace;
|
|
263
|
+
durableObjects.push({
|
|
264
|
+
name: bindingName,
|
|
265
|
+
class_name: doBinding.className,
|
|
266
|
+
script_name: doBinding.scriptName,
|
|
267
|
+
environment: doBinding.environment,
|
|
268
|
+
});
|
|
269
|
+
} else if (binding.type === "r2_bucket") {
|
|
270
|
+
r2Buckets.push({
|
|
271
|
+
binding: bindingName,
|
|
272
|
+
bucket_name: binding.name,
|
|
273
|
+
});
|
|
274
|
+
} else if (binding.type === "service") {
|
|
275
|
+
// Service binding
|
|
276
|
+
services.push({
|
|
277
|
+
binding: bindingName,
|
|
278
|
+
service: binding.id,
|
|
279
|
+
});
|
|
280
|
+
} else if (binding.type === "secret") {
|
|
281
|
+
// Secret binding
|
|
282
|
+
secrets.push(bindingName);
|
|
283
|
+
} else if (binding.type === "assets") {
|
|
284
|
+
spec.assets = {
|
|
285
|
+
directory: binding.path,
|
|
286
|
+
binding: bindingName,
|
|
287
|
+
};
|
|
288
|
+
} else if (binding.type === "workflow") {
|
|
289
|
+
workflows.push({
|
|
290
|
+
name: bindingName,
|
|
291
|
+
binding: binding.id,
|
|
292
|
+
class_name: binding.className,
|
|
293
|
+
});
|
|
294
|
+
} else if (binding.type === "d1") {
|
|
295
|
+
d1Databases.push({
|
|
296
|
+
binding: bindingName,
|
|
297
|
+
database_id: binding.id,
|
|
298
|
+
database_name: binding.name,
|
|
299
|
+
});
|
|
300
|
+
} else if (binding.type === "queue") {
|
|
301
|
+
queues.push({
|
|
302
|
+
binding: bindingName,
|
|
303
|
+
queue: binding.name,
|
|
304
|
+
});
|
|
290
305
|
}
|
|
306
|
+
}
|
|
291
307
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
308
|
+
// Add collected bindings to the spec
|
|
309
|
+
if (kvNamespaces.length > 0) {
|
|
310
|
+
spec.kv_namespaces = kvNamespaces;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (durableObjects.length > 0) {
|
|
314
|
+
spec.durable_objects = {
|
|
315
|
+
bindings: durableObjects,
|
|
297
316
|
};
|
|
317
|
+
}
|
|
298
318
|
|
|
299
|
-
|
|
300
|
-
|
|
319
|
+
if (r2Buckets.length > 0) {
|
|
320
|
+
spec.r2_buckets = r2Buckets;
|
|
321
|
+
}
|
|
301
322
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
323
|
+
if (services.length > 0) {
|
|
324
|
+
spec.services = services;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (queues.length > 0) {
|
|
328
|
+
spec.queues = queues;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
@@ -145,7 +145,7 @@ async function generateProviderDocs({
|
|
|
145
145
|
The ${provider} Service has the following resources:
|
|
146
146
|
${alchemy.files(files)}
|
|
147
147
|
|
|
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(...).
|
|
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.
|
|
149
149
|
A file is considered a "Client" if it exposes a wrapper around creating a SDK client or fetch.
|
|
150
150
|
A file is considered a "Utility" if it contains utility functions that are not resources or clients.
|
|
151
151
|
A file is considered a "Types" if it contains just type definitions and maybe helpers around working with those types.
|