alchemy 0.11.0 → 0.11.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.
@@ -59,6 +59,10 @@ export interface FunctionProps {
59
59
  * Function URL configuration for direct HTTP(S) invocation
60
60
  */
61
61
  url?: {
62
+ /**
63
+ * Configure type of response for the function URL
64
+ */
65
+ invokeMode?: "BUFFERED" | "RESPONSE_STREAM";
62
66
  /**
63
67
  * Authentication type for the function URL
64
68
  */
@@ -220,7 +224,7 @@ export interface Function extends Resource<"lambda::Function">, FunctionProps {
220
224
  * });
221
225
  *
222
226
  * @example
223
- * // Create a function with a public URL endpoint and CORS
227
+ * // Create a function with a public URL endpoint, CORS and optional response streaming
224
228
  * const apiFunction = await Function("public-api", {
225
229
  * functionName: "public-api",
226
230
  * zipPath: "./dist/api.zip",
@@ -228,6 +232,7 @@ export interface Function extends Resource<"lambda::Function">, FunctionProps {
228
232
  * handler: "api.handler",
229
233
  * url: {
230
234
  * authType: "NONE",
235
+ * invokeMode: "RESPONSE_STREAM",
231
236
  * cors: {
232
237
  * allowOrigins: ["*"],
233
238
  * allowMethods: ["GET", "POST"],
@@ -38,7 +38,7 @@ import { ignore } from "../util/ignore";
38
38
  * });
39
39
  *
40
40
  * @example
41
- * // Create a function with a public URL endpoint and CORS
41
+ * // Create a function with a public URL endpoint, CORS and optional response streaming
42
42
  * const apiFunction = await Function("public-api", {
43
43
  * functionName: "public-api",
44
44
  * zipPath: "./dist/api.zip",
@@ -46,6 +46,7 @@ import { ignore } from "../util/ignore";
46
46
  * handler: "api.handler",
47
47
  * url: {
48
48
  * authType: "NONE",
49
+ * invokeMode: "RESPONSE_STREAM",
49
50
  * cors: {
50
51
  * allowOrigins: ["*"],
51
52
  * allowMethods: ["GET", "POST"],
@@ -122,6 +123,7 @@ export const Function = Resource("lambda::Function", async function (id, props)
122
123
  const updateResult = await client.send(new UpdateFunctionUrlConfigCommand({
123
124
  FunctionName: props.functionName,
124
125
  AuthType: props.url.authType || "NONE",
126
+ InvokeMode: props.url.invokeMode || "BUFFERED",
125
127
  Cors: props.url.cors
126
128
  ? {
127
129
  AllowCredentials: props.url.cors.allowCredentials,
@@ -157,6 +159,7 @@ export const Function = Resource("lambda::Function", async function (id, props)
157
159
  const createResult = await client.send(new CreateFunctionUrlConfigCommand({
158
160
  FunctionName: props.functionName,
159
161
  AuthType: props.url.authType || "NONE",
162
+ InvokeMode: props.url.invokeMode || "BUFFERED",
160
163
  Cors: props.url.cors
161
164
  ? {
162
165
  AllowCredentials: props.url.cors.allowCredentials,
@@ -194,6 +197,7 @@ export const Function = Resource("lambda::Function", async function (id, props)
194
197
  const createResult = await client.send(new CreateFunctionUrlConfigCommand({
195
198
  FunctionName: props.functionName,
196
199
  AuthType: props.url.authType || "NONE",
200
+ InvokeMode: props.url.invokeMode || "BUFFERED",
197
201
  Cors: props.url.cors
198
202
  ? {
199
203
  AllowCredentials: props.url.cors.allowCredentials,
@@ -300,6 +304,7 @@ export const Function = Resource("lambda::Function", async function (id, props)
300
304
  const createResult = await client.send(new CreateFunctionUrlConfigCommand({
301
305
  FunctionName: props.functionName,
302
306
  AuthType: props.url.authType || "NONE",
307
+ InvokeMode: props.url.invokeMode || "BUFFERED",
303
308
  Cors: props.url.cors
304
309
  ? {
305
310
  AllowCredentials: props.url.cors.allowCredentials,
@@ -126,6 +126,8 @@ async function getRefreshedAuthConfig() {
126
126
  return authConfig;
127
127
  }
128
128
  async function writeWranglerConfig(config) {
129
+ if (config.exists === false)
130
+ return;
129
131
  const TOML = await import("@iarna/toml");
130
132
  const configPath = await findWranglerConfig();
131
133
  config = {
@@ -140,9 +142,21 @@ async function writeWranglerConfig(config) {
140
142
  const authConfigCache = {};
141
143
  async function readWranglerConfig() {
142
144
  const configPath = await findWranglerConfig();
143
- const config = (authConfigCache[configPath] ??= await parseTOML(await fs.readFile(configPath, "utf-8")));
144
- config.path = configPath;
145
- return config;
145
+ try {
146
+ const config = (authConfigCache[configPath] ??= await parseTOML(await fs.readFile(configPath, "utf-8")));
147
+ config.path = configPath;
148
+ return config;
149
+ }
150
+ catch (e) {
151
+ if (e.code === "ENOENT") {
152
+ // The config doesn't exist
153
+ return {
154
+ path: configPath,
155
+ exists: false
156
+ };
157
+ }
158
+ throw e;
159
+ }
146
160
  }
147
161
  let wranglerConfigPath;
148
162
  async function findWranglerConfig() {
@@ -139,6 +139,7 @@ export const D1DatabaseResource = Resource("cloudflare::D1Database", async funct
139
139
  readReplication: dbData.result.read_replication,
140
140
  primaryLocationHint: props.primaryLocationHint,
141
141
  accountId: api.accountId,
142
+ migrationsDir: props.migrationsDir
142
143
  });
143
144
  }
144
145
  });
@@ -132,6 +132,7 @@ export interface WranglerJsonSpec {
132
132
  binding: string;
133
133
  database_id: string;
134
134
  database_name: string;
135
+ migrations_dir?: string;
135
136
  }[];
136
137
  /**
137
138
  * Assets bindings
@@ -113,6 +113,7 @@ function processBindings(spec, bindings) {
113
113
  binding: bindingName,
114
114
  database_id: binding.id,
115
115
  database_name: binding.name,
116
+ migrations_dir: binding.migrationsDir,
116
117
  });
117
118
  }
118
119
  else if (binding.type === "queue") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "type": "module",
5
5
  "module": "./lib/index.js",
6
6
  "scripts": {
@@ -88,6 +88,11 @@ export interface FunctionProps {
88
88
  * Function URL configuration for direct HTTP(S) invocation
89
89
  */
90
90
  url?: {
91
+ /**
92
+ * Configure type of response for the function URL
93
+ */
94
+ invokeMode?: "BUFFERED" | "RESPONSE_STREAM";
95
+
91
96
  /**
92
97
  * Authentication type for the function URL
93
98
  */
@@ -277,7 +282,7 @@ export interface Function extends Resource<"lambda::Function">, FunctionProps {
277
282
  * });
278
283
  *
279
284
  * @example
280
- * // Create a function with a public URL endpoint and CORS
285
+ * // Create a function with a public URL endpoint, CORS and optional response streaming
281
286
  * const apiFunction = await Function("public-api", {
282
287
  * functionName: "public-api",
283
288
  * zipPath: "./dist/api.zip",
@@ -285,6 +290,7 @@ export interface Function extends Resource<"lambda::Function">, FunctionProps {
285
290
  * handler: "api.handler",
286
291
  * url: {
287
292
  * authType: "NONE",
293
+ * invokeMode: "RESPONSE_STREAM",
288
294
  * cors: {
289
295
  * allowOrigins: ["*"],
290
296
  * allowMethods: ["GET", "POST"],
@@ -387,6 +393,7 @@ export const Function = Resource(
387
393
  new UpdateFunctionUrlConfigCommand({
388
394
  FunctionName: props.functionName,
389
395
  AuthType: props.url.authType || "NONE",
396
+ InvokeMode: props.url.invokeMode || "BUFFERED",
390
397
  Cors: props.url.cors
391
398
  ? {
392
399
  AllowCredentials: props.url.cors.allowCredentials,
@@ -425,6 +432,7 @@ export const Function = Resource(
425
432
  new CreateFunctionUrlConfigCommand({
426
433
  FunctionName: props.functionName,
427
434
  AuthType: props.url.authType || "NONE",
435
+ InvokeMode: props.url.invokeMode || "BUFFERED",
428
436
  Cors: props.url.cors
429
437
  ? {
430
438
  AllowCredentials: props.url.cors.allowCredentials,
@@ -465,6 +473,7 @@ export const Function = Resource(
465
473
  new CreateFunctionUrlConfigCommand({
466
474
  FunctionName: props.functionName,
467
475
  AuthType: props.url.authType || "NONE",
476
+ InvokeMode: props.url.invokeMode || "BUFFERED",
468
477
  Cors: props.url.cors
469
478
  ? {
470
479
  AllowCredentials: props.url.cors.allowCredentials,
@@ -585,6 +594,7 @@ export const Function = Resource(
585
594
  new CreateFunctionUrlConfigCommand({
586
595
  FunctionName: props.functionName,
587
596
  AuthType: props.url.authType || "NONE",
597
+ InvokeMode: props.url.invokeMode || "BUFFERED",
588
598
  Cors: props.url.cors
589
599
  ? {
590
600
  AllowCredentials: props.url.cors.allowCredentials,
@@ -239,6 +239,8 @@ interface WranglerConfig {
239
239
  refresh_token?: string;
240
240
  expiration_time?: string;
241
241
  scopes?: string[];
242
+ /** exists is `false` if the config file doesn't exist, like in CI */
243
+ exists?: boolean;
242
244
  /** @deprecated - this field was only provided by the deprecated v1 `wrangler config` command. */
243
245
  api_token?: string;
244
246
  }
@@ -258,6 +260,8 @@ async function getRefreshedAuthConfig(): Promise<WranglerConfig> {
258
260
  }
259
261
 
260
262
  async function writeWranglerConfig(config: WranglerConfig) {
263
+ if (config.exists === false) return
264
+
261
265
  const TOML = await import("@iarna/toml");
262
266
  const configPath = await findWranglerConfig();
263
267
  config = {
@@ -274,11 +278,24 @@ const authConfigCache: Record<string, WranglerConfig> = {};
274
278
 
275
279
  async function readWranglerConfig(): Promise<WranglerConfig> {
276
280
  const configPath = await findWranglerConfig();
277
- const config = (authConfigCache[configPath] ??= await parseTOML(
278
- await fs.readFile(configPath, "utf-8")
279
- ));
280
- config.path = configPath;
281
- return config;
281
+ try {
282
+ const config = (authConfigCache[configPath] ??= await parseTOML(
283
+ await fs.readFile(configPath, "utf-8")
284
+ ));
285
+ config.path = configPath;
286
+
287
+ return config
288
+ } catch (e: any) {
289
+ if (e.code === "ENOENT") {
290
+ // The config doesn't exist
291
+ return {
292
+ path: configPath,
293
+ exists: false
294
+ }
295
+ }
296
+
297
+ throw e
298
+ }
282
299
  }
283
300
 
284
301
  let wranglerConfigPath: string | undefined;
@@ -278,6 +278,7 @@ export const D1DatabaseResource = Resource(
278
278
  readReplication: dbData.result.read_replication,
279
279
  primaryLocationHint: props.primaryLocationHint,
280
280
  accountId: api.accountId,
281
+ migrationsDir: props.migrationsDir
281
282
  });
282
283
  }
283
284
  }
@@ -207,6 +207,7 @@ export interface WranglerJsonSpec {
207
207
  binding: string;
208
208
  database_id: string;
209
209
  database_name: string;
210
+ migrations_dir?: string
210
211
  }[];
211
212
 
212
213
  /**
@@ -254,6 +255,7 @@ function processBindings(spec: WranglerJsonSpec, bindings: Bindings): void {
254
255
  binding: string;
255
256
  database_id: string;
256
257
  database_name: string;
258
+ migrations_dir?: string;
257
259
  }[] = [];
258
260
  const queues: { binding: string; queue: string }[] = [];
259
261
  const vectorizeIndexes: { binding: string; index_name: string }[] = [];
@@ -314,6 +316,7 @@ function processBindings(spec: WranglerJsonSpec, bindings: Bindings): void {
314
316
  binding: bindingName,
315
317
  database_id: binding.id,
316
318
  database_name: binding.name,
319
+ migrations_dir: binding.migrationsDir,
317
320
  });
318
321
  } else if (binding.type === "queue") {
319
322
  queues.push({