alchemy 0.22.4 → 0.24.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/aws/bucket.d.ts.map +1 -1
- package/lib/aws/bucket.js +13 -12
- package/lib/aws/bucket.js.map +1 -1
- package/lib/aws/control/client.d.ts.map +1 -1
- package/lib/aws/control/client.js +5 -3
- package/lib/aws/control/client.js.map +1 -1
- package/lib/aws/control/properties.d.ts +11 -2
- package/lib/aws/control/properties.d.ts.map +1 -1
- package/lib/aws/control/properties.js +96 -19
- package/lib/aws/control/properties.js.map +1 -1
- package/lib/aws/control/resource.d.ts.map +1 -1
- package/lib/aws/control/resource.js +13 -4
- package/lib/aws/control/resource.js.map +1 -1
- package/lib/aws/control/types.d.ts +81069 -0
- package/lib/aws/control/types.d.ts.map +1 -0
- package/lib/aws/control/types.js +4 -0
- package/lib/aws/control/types.js.map +1 -0
- package/lib/aws/function.d.ts.map +1 -1
- package/lib/aws/function.js +51 -42
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/index.d.ts +1 -0
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +1 -0
- package/lib/aws/index.js.map +1 -1
- package/lib/aws/policy-attachment.d.ts.map +1 -1
- package/lib/aws/policy-attachment.js +5 -4
- package/lib/aws/policy-attachment.js.map +1 -1
- package/lib/aws/policy.d.ts.map +1 -1
- package/lib/aws/policy.js +21 -20
- package/lib/aws/policy.js.map +1 -1
- package/lib/aws/queue.d.ts.map +1 -1
- package/lib/aws/queue.js +19 -15
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/retry.d.ts +5 -0
- package/lib/aws/retry.d.ts.map +1 -0
- package/lib/aws/retry.js +27 -0
- package/lib/aws/retry.js.map +1 -0
- package/lib/aws/role.d.ts.map +1 -1
- package/lib/aws/role.js +31 -30
- package/lib/aws/role.js.map +1 -1
- package/lib/aws/ses.d.ts.map +1 -1
- package/lib/aws/ses.js +27 -26
- package/lib/aws/ses.js.map +1 -1
- package/lib/aws/ssm-parameter.d.ts +150 -0
- package/lib/aws/ssm-parameter.d.ts.map +1 -0
- package/lib/aws/ssm-parameter.js +184 -0
- package/lib/aws/ssm-parameter.js.map +1 -0
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +9 -27
- package/lib/aws/table.js.map +1 -1
- package/lib/cloudflare/account-id.d.ts +1 -0
- package/lib/cloudflare/account-id.d.ts.map +1 -1
- package/lib/cloudflare/account-id.js.map +1 -1
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +22 -2
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/bound.d.ts +1 -1
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/index.d.ts +2 -1
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +2 -1
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +7 -1
- package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
- package/lib/cloudflare/queue-consumer.js +14 -0
- package/lib/cloudflare/queue-consumer.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +27 -0
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +23 -0
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/route.d.ts +7 -0
- package/lib/cloudflare/route.d.ts.map +1 -1
- package/lib/cloudflare/route.js +44 -2
- package/lib/cloudflare/route.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +1 -2
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +2 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +20 -9
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +7 -0
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +2 -0
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +1 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +1 -0
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/destroy.js +1 -1
- package/lib/destroy.js.map +1 -1
- package/lib/dns/godaddy.d.ts.map +1 -1
- package/lib/dns/godaddy.js +2 -1
- package/lib/dns/godaddy.js.map +1 -1
- package/lib/fs/file-system-state-store.d.ts.map +1 -1
- package/lib/fs/file-system-state-store.js +14 -2
- package/lib/fs/file-system-state-store.js.map +1 -1
- package/lib/github/secret.d.ts.map +1 -1
- package/lib/github/secret.js +1 -0
- package/lib/github/secret.js.map +1 -1
- package/lib/neon/api.d.ts.map +1 -1
- package/lib/neon/api.js +2 -1
- package/lib/neon/api.js.map +1 -1
- package/lib/runtime/shims.d.ts +6 -0
- package/lib/runtime/shims.d.ts.map +1 -0
- package/lib/runtime/shims.js +27 -0
- package/lib/runtime/shims.js.map +1 -0
- package/lib/sentry/api.d.ts.map +1 -1
- package/lib/sentry/api.js +2 -1
- package/lib/sentry/api.js.map +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -7
- package/lib/test/bun.js.map +1 -1
- package/lib/test/prune.d.ts +2 -1
- package/lib/test/prune.d.ts.map +1 -1
- package/lib/test/prune.js +29 -5
- package/lib/test/prune.js.map +1 -1
- package/lib/test/vitest.d.ts +92 -0
- package/lib/test/vitest.d.ts.map +1 -0
- package/lib/test/vitest.js +94 -0
- package/lib/test/vitest.js.map +1 -0
- package/lib/upstash/api.d.ts.map +1 -1
- package/lib/upstash/api.js +2 -1
- package/lib/upstash/api.js.map +1 -1
- package/lib/util/retry.js +2 -2
- package/lib/util/retry.js.map +1 -1
- package/lib/util/safe-fetch.d.ts +2 -0
- package/lib/util/safe-fetch.d.ts.map +1 -0
- package/lib/util/safe-fetch.js +49 -0
- package/lib/util/safe-fetch.js.map +1 -0
- package/lib/vercel/api.d.ts.map +1 -1
- package/lib/vercel/api.js +2 -1
- package/lib/vercel/api.js.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.d.ts.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.js +11 -7
- package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
- package/package.json +10 -6
- package/src/alchemy.ts +2 -2
- package/src/aws/bucket.ts +55 -36
- package/src/aws/control/client.ts +13 -13
- package/src/aws/control/properties.ts +96 -19
- package/src/aws/control/resource.ts +19 -3
- package/src/aws/control/types.ts +87235 -0
- package/src/aws/function.ts +233 -178
- package/src/aws/index.ts +1 -0
- package/src/aws/policy-attachment.ts +15 -10
- package/src/aws/policy.ts +75 -54
- package/src/aws/queue.ts +53 -36
- package/src/aws/retry.ts +38 -0
- package/src/aws/role.ts +121 -90
- package/src/aws/ses.ts +101 -73
- package/src/aws/ssm-parameter.ts +315 -0
- package/src/aws/table.ts +61 -90
- package/src/cloudflare/account-id.ts +2 -0
- package/src/cloudflare/api.ts +26 -3
- package/src/cloudflare/bound.ts +1 -1
- package/src/cloudflare/index.ts +2 -1
- package/src/cloudflare/queue-consumer.ts +27 -1
- package/src/cloudflare/queue.ts +29 -0
- package/src/cloudflare/route.ts +86 -2
- package/src/cloudflare/worker-metadata.ts +1 -2
- package/src/cloudflare/worker.ts +24 -10
- package/src/cloudflare/workflow.ts +8 -0
- package/src/cloudflare/wrangler.json.ts +8 -1
- package/src/destroy.ts +1 -1
- package/src/dns/godaddy.ts +3 -1
- package/src/fs/file-system-state-store.ts +16 -2
- package/src/github/secret.ts +2 -0
- package/src/neon/api.ts +2 -1
- package/src/sentry/api.ts +2 -1
- package/src/test/bun.ts +1 -7
- package/src/test/prune.ts +31 -4
- package/src/test/vitest.ts +209 -0
- package/src/upstash/api.ts +2 -1
- package/src/util/retry.ts +3 -3
- package/src/util/safe-fetch.ts +62 -0
- package/src/vercel/api.ts +2 -1
- package/src/web/vitepress/process-front-matter-files.ts +15 -7
- package/src/aws/control/types.d.ts +0 -85129
package/src/aws/policy.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "@aws-sdk/client-iam";
|
|
12
12
|
import type { Context } from "../context.ts";
|
|
13
13
|
import { Resource } from "../resource.ts";
|
|
14
|
+
import { retry } from "./retry.ts";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Type of effect for a policy statement
|
|
@@ -238,28 +239,34 @@ export const Policy = Resource(
|
|
|
238
239
|
if (this.phase === "delete") {
|
|
239
240
|
try {
|
|
240
241
|
// List and delete all non-default versions first
|
|
241
|
-
const versions = await
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
242
|
+
const versions = await retry(() =>
|
|
243
|
+
client.send(
|
|
244
|
+
new ListPolicyVersionsCommand({
|
|
245
|
+
PolicyArn: policyArn,
|
|
246
|
+
}),
|
|
247
|
+
),
|
|
245
248
|
);
|
|
246
249
|
|
|
247
250
|
for (const version of versions.Versions || []) {
|
|
248
251
|
if (!version.IsDefaultVersion) {
|
|
249
|
-
await
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
await retry(() =>
|
|
253
|
+
client.send(
|
|
254
|
+
new DeletePolicyVersionCommand({
|
|
255
|
+
PolicyArn: policyArn,
|
|
256
|
+
VersionId: version.VersionId,
|
|
257
|
+
}),
|
|
258
|
+
),
|
|
254
259
|
);
|
|
255
260
|
}
|
|
256
261
|
}
|
|
257
262
|
|
|
258
263
|
// Delete the policy
|
|
259
|
-
await
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
264
|
+
await retry(() =>
|
|
265
|
+
client.send(
|
|
266
|
+
new DeletePolicyCommand({
|
|
267
|
+
PolicyArn: policyArn,
|
|
268
|
+
}),
|
|
269
|
+
),
|
|
263
270
|
);
|
|
264
271
|
} catch (error: any) {
|
|
265
272
|
if (error.name !== NoSuchEntityException.name) {
|
|
@@ -270,18 +277,22 @@ export const Policy = Resource(
|
|
|
270
277
|
}
|
|
271
278
|
try {
|
|
272
279
|
// Check if policy exists
|
|
273
|
-
const existingPolicy = await
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
280
|
+
const existingPolicy = await retry(() =>
|
|
281
|
+
client.send(
|
|
282
|
+
new GetPolicyCommand({
|
|
283
|
+
PolicyArn: policyArn,
|
|
284
|
+
}),
|
|
285
|
+
),
|
|
277
286
|
);
|
|
278
287
|
|
|
279
288
|
// Get current policy version
|
|
280
|
-
const currentVersion = await
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
289
|
+
const currentVersion = await retry(() =>
|
|
290
|
+
client.send(
|
|
291
|
+
new GetPolicyVersionCommand({
|
|
292
|
+
PolicyArn: policyArn,
|
|
293
|
+
VersionId: existingPolicy.Policy!.DefaultVersionId!,
|
|
294
|
+
}),
|
|
295
|
+
),
|
|
285
296
|
);
|
|
286
297
|
|
|
287
298
|
const currentDocument = JSON.parse(
|
|
@@ -291,10 +302,12 @@ export const Policy = Resource(
|
|
|
291
302
|
// If policy document changed, create new version
|
|
292
303
|
if (JSON.stringify(currentDocument) !== JSON.stringify(props.document)) {
|
|
293
304
|
// List versions to check if we need to delete old ones
|
|
294
|
-
const versions = await
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
305
|
+
const versions = await retry(() =>
|
|
306
|
+
client.send(
|
|
307
|
+
new ListPolicyVersionsCommand({
|
|
308
|
+
PolicyArn: policyArn,
|
|
309
|
+
}),
|
|
310
|
+
),
|
|
298
311
|
);
|
|
299
312
|
|
|
300
313
|
// Delete oldest version if we have 5 versions (maximum allowed)
|
|
@@ -304,29 +317,35 @@ export const Policy = Resource(
|
|
|
304
317
|
)[0];
|
|
305
318
|
|
|
306
319
|
if (!oldestVersion.IsDefaultVersion) {
|
|
307
|
-
await
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
320
|
+
await retry(() =>
|
|
321
|
+
client.send(
|
|
322
|
+
new DeletePolicyVersionCommand({
|
|
323
|
+
PolicyArn: policyArn,
|
|
324
|
+
VersionId: oldestVersion.VersionId!,
|
|
325
|
+
}),
|
|
326
|
+
),
|
|
312
327
|
);
|
|
313
328
|
}
|
|
314
329
|
}
|
|
315
330
|
|
|
316
331
|
// Create new version
|
|
317
|
-
await
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
332
|
+
await retry(() =>
|
|
333
|
+
client.send(
|
|
334
|
+
new CreatePolicyVersionCommand({
|
|
335
|
+
PolicyArn: policyArn,
|
|
336
|
+
PolicyDocument: JSON.stringify(props.document),
|
|
337
|
+
SetAsDefault: true,
|
|
338
|
+
}),
|
|
339
|
+
),
|
|
323
340
|
);
|
|
324
341
|
}
|
|
325
342
|
|
|
326
|
-
const policy = await
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
343
|
+
const policy = await retry(() =>
|
|
344
|
+
client.send(
|
|
345
|
+
new GetPolicyCommand({
|
|
346
|
+
PolicyArn: policyArn,
|
|
347
|
+
}),
|
|
348
|
+
),
|
|
330
349
|
);
|
|
331
350
|
|
|
332
351
|
return this({
|
|
@@ -341,19 +360,21 @@ export const Policy = Resource(
|
|
|
341
360
|
} catch (error: any) {
|
|
342
361
|
if (error.name === "NoSuchEntity") {
|
|
343
362
|
// Create new policy
|
|
344
|
-
const newPolicy = await
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
363
|
+
const newPolicy = await retry(() =>
|
|
364
|
+
client.send(
|
|
365
|
+
new CreatePolicyCommand({
|
|
366
|
+
PolicyName: props.policyName,
|
|
367
|
+
PolicyDocument: JSON.stringify(props.document),
|
|
368
|
+
Description: props.description,
|
|
369
|
+
Path: props.path,
|
|
370
|
+
Tags: props.tags
|
|
371
|
+
? Object.entries(props.tags).map(([Key, Value]) => ({
|
|
372
|
+
Key,
|
|
373
|
+
Value,
|
|
374
|
+
}))
|
|
375
|
+
: undefined,
|
|
376
|
+
}),
|
|
377
|
+
),
|
|
357
378
|
);
|
|
358
379
|
|
|
359
380
|
return this({
|
package/src/aws/queue.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "@aws-sdk/client-sqs";
|
|
10
10
|
import type { Context } from "../context.ts";
|
|
11
11
|
import { Resource } from "../resource.ts";
|
|
12
|
+
import { retry } from "./retry.ts";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Properties for creating or updating an SQS queue
|
|
@@ -153,28 +154,34 @@ export const Queue = Resource(
|
|
|
153
154
|
if (this.phase === "delete") {
|
|
154
155
|
try {
|
|
155
156
|
// Get queue URL first
|
|
156
|
-
const urlResponse = await
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
const urlResponse = await retry(() =>
|
|
158
|
+
client.send(
|
|
159
|
+
new GetQueueUrlCommand({
|
|
160
|
+
QueueName: queueName,
|
|
161
|
+
}),
|
|
162
|
+
),
|
|
160
163
|
);
|
|
161
164
|
|
|
162
165
|
// Delete the queue
|
|
163
|
-
await
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
await retry(() =>
|
|
167
|
+
client.send(
|
|
168
|
+
new DeleteQueueCommand({
|
|
169
|
+
QueueUrl: urlResponse.QueueUrl,
|
|
170
|
+
}),
|
|
171
|
+
),
|
|
167
172
|
);
|
|
168
173
|
|
|
169
174
|
// Wait for queue to be deleted
|
|
170
175
|
let queueDeleted = false;
|
|
171
176
|
while (!queueDeleted) {
|
|
172
177
|
try {
|
|
173
|
-
await
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
await retry(() => {
|
|
179
|
+
return client.send(
|
|
180
|
+
new GetQueueUrlCommand({
|
|
181
|
+
QueueName: queueName,
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
});
|
|
178
185
|
// If we get here, queue still exists
|
|
179
186
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
180
187
|
} catch (error: any) {
|
|
@@ -186,11 +193,11 @@ export const Queue = Resource(
|
|
|
186
193
|
}
|
|
187
194
|
}
|
|
188
195
|
} catch (error: any) {
|
|
196
|
+
console.log(error.message);
|
|
189
197
|
if (!isQueueDoesNotExist(error)) {
|
|
190
198
|
throw error;
|
|
191
199
|
}
|
|
192
200
|
}
|
|
193
|
-
|
|
194
201
|
return this.destroy();
|
|
195
202
|
}
|
|
196
203
|
// Create queue with attributes
|
|
@@ -238,20 +245,26 @@ export const Queue = Resource(
|
|
|
238
245
|
|
|
239
246
|
try {
|
|
240
247
|
// Create the queue
|
|
241
|
-
const createResponse = await
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
248
|
+
const createResponse = await retry(
|
|
249
|
+
() =>
|
|
250
|
+
client.send(
|
|
251
|
+
new CreateQueueCommand({
|
|
252
|
+
QueueName: queueName,
|
|
253
|
+
Attributes: attributes,
|
|
254
|
+
tags,
|
|
255
|
+
}),
|
|
256
|
+
),
|
|
257
|
+
(err) => isQueueDeletedRecently(err),
|
|
247
258
|
);
|
|
248
259
|
|
|
249
260
|
// Get queue attributes
|
|
250
|
-
const attributesResponse = await
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
261
|
+
const attributesResponse = await retry(() =>
|
|
262
|
+
client.send(
|
|
263
|
+
new GetQueueAttributesCommand({
|
|
264
|
+
QueueUrl: createResponse.QueueUrl,
|
|
265
|
+
AttributeNames: ["QueueArn"],
|
|
266
|
+
}),
|
|
267
|
+
),
|
|
255
268
|
);
|
|
256
269
|
|
|
257
270
|
return this({
|
|
@@ -274,20 +287,24 @@ export const Queue = Resource(
|
|
|
274
287
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
275
288
|
|
|
276
289
|
// Retry creating the queue
|
|
277
|
-
const createResponse = await
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
290
|
+
const createResponse = await retry(() =>
|
|
291
|
+
client.send(
|
|
292
|
+
new CreateQueueCommand({
|
|
293
|
+
QueueName: queueName,
|
|
294
|
+
Attributes: attributes,
|
|
295
|
+
tags,
|
|
296
|
+
}),
|
|
297
|
+
),
|
|
283
298
|
);
|
|
284
299
|
|
|
285
300
|
// Get queue attributes
|
|
286
|
-
const attributesResponse = await
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
301
|
+
const attributesResponse = await retry(() =>
|
|
302
|
+
client.send(
|
|
303
|
+
new GetQueueAttributesCommand({
|
|
304
|
+
QueueUrl: createResponse.QueueUrl,
|
|
305
|
+
AttributeNames: ["QueueArn"],
|
|
306
|
+
}),
|
|
307
|
+
),
|
|
291
308
|
);
|
|
292
309
|
|
|
293
310
|
return this({
|
package/src/aws/retry.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { withExponentialBackoff } from "../util/retry.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Check if an error is retryable (throttling/rate limiting)
|
|
5
|
+
*/
|
|
6
|
+
function isRetryableError(error: any): boolean {
|
|
7
|
+
if (!error) return false;
|
|
8
|
+
|
|
9
|
+
const errorCode = error.name || error.code || "";
|
|
10
|
+
const errorMessage = error.message || "";
|
|
11
|
+
|
|
12
|
+
// Check for common AWS throttling error codes and messages
|
|
13
|
+
return (
|
|
14
|
+
errorCode === "Throttling" ||
|
|
15
|
+
errorCode === "ThrottlingException" ||
|
|
16
|
+
errorCode === "TooManyRequestsException" ||
|
|
17
|
+
errorCode === "RequestLimitExceeded" ||
|
|
18
|
+
errorMessage.includes("Rate exceeded") ||
|
|
19
|
+
errorMessage.includes("throttling") ||
|
|
20
|
+
errorMessage.includes("Throttling") ||
|
|
21
|
+
errorMessage.includes("Internal server error")
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Retry function with standardized parameters for AWS throttling
|
|
27
|
+
*/
|
|
28
|
+
export function retry<T>(
|
|
29
|
+
operation: () => Promise<T>,
|
|
30
|
+
extraIsRetryableError?: (error: any) => boolean,
|
|
31
|
+
): Promise<T> {
|
|
32
|
+
return withExponentialBackoff(
|
|
33
|
+
operation,
|
|
34
|
+
(err) => isRetryableError(err) || extraIsRetryableError?.(err) || false,
|
|
35
|
+
10, // max attempts
|
|
36
|
+
1000, // initial delay ms
|
|
37
|
+
);
|
|
38
|
+
}
|