alchemy 0.1.12 → 0.1.14
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/README.md +12 -2
- package/lib/$.d.ts +12 -0
- package/lib/$.d.ts.map +1 -0
- package/lib/$.js +42 -0
- package/lib/$.js.map +1 -0
- package/lib/alchemize.d.ts.map +1 -1
- package/lib/alchemize.js +7 -0
- package/lib/alchemize.js.map +1 -1
- package/lib/apply.d.ts +2 -2
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +1 -1
- package/lib/apply.js.map +1 -1
- package/lib/aws/account-id.d.ts +5 -0
- package/lib/aws/account-id.d.ts.map +1 -0
- package/lib/aws/account-id.js +10 -0
- package/lib/aws/account-id.js.map +1 -0
- 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/oidc/github-oidc-provider.d.ts +11 -0
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/github-oidc-provider.js +22 -0
- package/lib/aws/oidc/github-oidc-provider.js.map +1 -0
- package/lib/aws/oidc/index.d.ts +3 -0
- package/lib/aws/oidc/index.d.ts.map +1 -0
- package/lib/aws/oidc/index.js +3 -0
- package/lib/aws/oidc/index.js.map +1 -0
- package/lib/aws/oidc/oidc-provider.d.ts +60 -0
- package/lib/aws/oidc/oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/oidc-provider.js +140 -0
- package/lib/aws/oidc/oidc-provider.js.map +1 -0
- package/lib/aws/queue.d.ts +24 -0
- package/lib/aws/queue.d.ts.map +1 -1
- package/lib/aws/queue.js +6 -1
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/role.d.ts.map +1 -1
- package/lib/aws/role.js +49 -1
- package/lib/aws/role.js.map +1 -1
- package/lib/aws/ses.d.ts.map +1 -1
- package/lib/aws/ses.js +20 -28
- package/lib/aws/ses.js.map +1 -1
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +95 -73
- package/lib/aws/table.js.map +1 -1
- package/lib/cloudflare/api.d.ts +4 -0
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +6 -0
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +19 -4
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bindings.js +0 -5
- package/lib/cloudflare/bindings.js.map +1 -1
- package/lib/cloudflare/durable-object-namespace.d.ts +20 -0
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -0
- package/lib/cloudflare/durable-object-namespace.js +21 -0
- package/lib/cloudflare/durable-object-namespace.js.map +1 -0
- package/lib/cloudflare/index.d.ts +1 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +3 -0
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +5 -1
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/static-site-router.d.ts +11 -2
- package/lib/cloudflare/static-site-router.d.ts.map +1 -1
- package/lib/cloudflare/static-site-router.js +98 -76
- package/lib/cloudflare/static-site-router.js.map +1 -1
- package/lib/cloudflare/static-site.d.ts +15 -15
- package/lib/cloudflare/static-site.d.ts.map +1 -1
- package/lib/cloudflare/static-site.js +45 -47
- package/lib/cloudflare/static-site.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +130 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -0
- package/lib/cloudflare/worker-metadata.js +2 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -0
- package/lib/cloudflare/worker-migration.d.ts +110 -0
- package/lib/cloudflare/worker-migration.d.ts.map +1 -0
- package/lib/cloudflare/worker-migration.js +11 -0
- package/lib/cloudflare/worker-migration.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +34 -13
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +341 -321
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/destroy.d.ts +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +2 -1
- package/lib/destroy.js.map +1 -1
- package/lib/esbuild.d.ts +1 -1
- package/lib/esbuild.d.ts.map +1 -1
- package/lib/esbuild.js +3 -1
- package/lib/esbuild.js.map +1 -1
- package/lib/github/client.d.ts +34 -0
- package/lib/github/client.d.ts.map +1 -0
- package/lib/github/client.js +91 -0
- package/lib/github/client.js.map +1 -0
- package/lib/github/index.d.ts +2 -0
- package/lib/github/index.d.ts.map +1 -0
- package/lib/github/index.js +2 -0
- package/lib/github/index.js.map +1 -0
- package/lib/github/secret.d.ts +46 -0
- package/lib/github/secret.d.ts.map +1 -0
- package/lib/github/secret.js +103 -0
- package/lib/github/secret.js.map +1 -0
- package/lib/global.d.ts +0 -2
- package/lib/global.d.ts.map +1 -1
- package/lib/global.js +0 -2
- package/lib/global.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/output.d.ts +4 -3
- package/lib/output.d.ts.map +1 -1
- package/lib/output.js +10 -3
- package/lib/output.js.map +1 -1
- package/lib/print.d.ts +7 -0
- package/lib/print.d.ts.map +1 -0
- package/lib/print.js +10 -0
- package/lib/print.js.map +1 -0
- package/lib/resource.d.ts +8 -4
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js +125 -91
- package/lib/resource.js.map +1 -1
- package/lib/scope.d.ts +3 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +4 -12
- package/lib/scope.js.map +1 -1
- package/lib/utils/retry.d.ts +13 -0
- package/lib/utils/retry.d.ts.map +1 -0
- package/lib/utils/retry.js +31 -0
- package/lib/utils/retry.js.map +1 -0
- package/package.json +12 -3
- package/src/$.ts +69 -0
- package/src/alchemize.ts +12 -0
- package/src/apply.ts +4 -4
- package/src/aws/account-id.ts +11 -0
- package/src/aws/index.ts +1 -0
- package/src/aws/oidc/github-oidc-provider.ts +34 -0
- package/src/aws/oidc/index.ts +2 -0
- package/src/aws/oidc/oidc-provider.ts +253 -0
- package/src/aws/queue.ts +23 -1
- package/src/aws/role.ts +69 -0
- package/src/aws/ses.ts +27 -31
- package/src/aws/table.ts +113 -82
- package/src/cloudflare/api.ts +6 -0
- package/src/cloudflare/bindings.ts +43 -26
- package/src/cloudflare/durable-object-namespace.ts +37 -0
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/kv-namespace.ts +12 -1
- package/src/cloudflare/static-site-router.ts +124 -82
- package/src/cloudflare/static-site.ts +66 -69
- package/src/cloudflare/worker-metadata.ts +154 -0
- package/src/cloudflare/worker-migration.ts +145 -0
- package/src/cloudflare/worker.ts +557 -429
- package/src/destroy.ts +2 -2
- package/src/esbuild.ts +3 -0
- package/src/github/client.ts +115 -0
- package/src/github/index.ts +1 -0
- package/src/github/secret.ts +172 -0
- package/src/global.ts +0 -3
- package/src/index.ts +2 -1
- package/src/output.ts +24 -8
- package/src/print.ts +18 -0
- package/src/resource.ts +156 -115
- package/src/scope.ts +7 -12
- package/src/utils/retry.ts +36 -0
package/src/aws/ses.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AlreadyExistsException,
|
|
3
2
|
CreateConfigurationSetCommand,
|
|
4
3
|
CreateEmailIdentityCommand,
|
|
5
4
|
DeleteConfigurationSetCommand,
|
|
@@ -8,6 +7,11 @@ import {
|
|
|
8
7
|
GetConfigurationSetCommand,
|
|
9
8
|
GetEmailIdentityCommand,
|
|
10
9
|
NotFoundException,
|
|
10
|
+
PutConfigurationSetDeliveryOptionsCommand,
|
|
11
|
+
PutConfigurationSetReputationOptionsCommand,
|
|
12
|
+
PutConfigurationSetSendingOptionsCommand,
|
|
13
|
+
PutConfigurationSetSuppressionOptionsCommand,
|
|
14
|
+
PutConfigurationSetTrackingOptionsCommand,
|
|
11
15
|
PutEmailIdentityDkimAttributesCommand,
|
|
12
16
|
type ReputationOptions,
|
|
13
17
|
SESv2Client,
|
|
@@ -103,7 +107,7 @@ export interface SESOutput extends SESProps {
|
|
|
103
107
|
*/
|
|
104
108
|
export class SES extends Resource(
|
|
105
109
|
"aws::SES",
|
|
106
|
-
async (ctx: Context<SESOutput>, props: SESProps)
|
|
110
|
+
async (ctx: Context<SESOutput>, props: SESProps) => {
|
|
107
111
|
// Create SES client
|
|
108
112
|
const client = new SESv2Client({});
|
|
109
113
|
|
|
@@ -138,10 +142,7 @@ export class SES extends Resource(
|
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
// Return empty output for delete
|
|
141
|
-
return
|
|
142
|
-
...props,
|
|
143
|
-
id,
|
|
144
|
-
};
|
|
145
|
+
return;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
// Created resources
|
|
@@ -154,66 +155,68 @@ export class SES extends Resource(
|
|
|
154
155
|
if (props.configurationSetName) {
|
|
155
156
|
try {
|
|
156
157
|
// Check if configuration set exists
|
|
157
|
-
let
|
|
158
|
+
let configSetExists = false;
|
|
158
159
|
try {
|
|
159
|
-
|
|
160
|
+
await client.send(
|
|
160
161
|
new GetConfigurationSetCommand({
|
|
161
162
|
ConfigurationSetName: props.configurationSetName,
|
|
162
163
|
}),
|
|
163
164
|
);
|
|
165
|
+
configSetExists = true;
|
|
164
166
|
} catch (error) {
|
|
165
167
|
if (error instanceof NotFoundException) {
|
|
166
|
-
|
|
168
|
+
configSetExists = false;
|
|
167
169
|
} else {
|
|
168
170
|
throw error;
|
|
169
171
|
}
|
|
170
172
|
}
|
|
171
173
|
|
|
172
|
-
if (
|
|
173
|
-
//
|
|
174
|
-
// since there's no unified UpdateConfigurationSetCommand
|
|
175
|
-
|
|
174
|
+
if (configSetExists) {
|
|
175
|
+
// Update existing configuration set using appropriate update commands
|
|
176
176
|
if (props.sendingOptions) {
|
|
177
177
|
await client.send(
|
|
178
|
-
new
|
|
178
|
+
new PutConfigurationSetSendingOptionsCommand({
|
|
179
179
|
ConfigurationSetName: props.configurationSetName,
|
|
180
|
-
|
|
180
|
+
SendingEnabled: props.sendingOptions.SendingEnabled,
|
|
181
181
|
}),
|
|
182
182
|
);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
if (props.reputationOptions) {
|
|
186
186
|
await client.send(
|
|
187
|
-
new
|
|
187
|
+
new PutConfigurationSetReputationOptionsCommand({
|
|
188
188
|
ConfigurationSetName: props.configurationSetName,
|
|
189
|
-
|
|
189
|
+
ReputationMetricsEnabled:
|
|
190
|
+
props.reputationOptions.ReputationMetricsEnabled,
|
|
190
191
|
}),
|
|
191
192
|
);
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
if (props.trackingOptions) {
|
|
195
196
|
await client.send(
|
|
196
|
-
new
|
|
197
|
+
new PutConfigurationSetTrackingOptionsCommand({
|
|
197
198
|
ConfigurationSetName: props.configurationSetName,
|
|
198
|
-
|
|
199
|
+
CustomRedirectDomain:
|
|
200
|
+
props.trackingOptions.CustomRedirectDomain,
|
|
199
201
|
}),
|
|
200
202
|
);
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
if (props.suppressionOptions) {
|
|
204
206
|
await client.send(
|
|
205
|
-
new
|
|
207
|
+
new PutConfigurationSetSuppressionOptionsCommand({
|
|
206
208
|
ConfigurationSetName: props.configurationSetName,
|
|
207
|
-
|
|
209
|
+
SuppressedReasons: props.suppressionOptions.SuppressedReasons,
|
|
208
210
|
}),
|
|
209
211
|
);
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
if (props.deliveryOptions) {
|
|
213
215
|
await client.send(
|
|
214
|
-
new
|
|
216
|
+
new PutConfigurationSetDeliveryOptionsCommand({
|
|
215
217
|
ConfigurationSetName: props.configurationSetName,
|
|
216
|
-
|
|
218
|
+
TlsPolicy: props.deliveryOptions.TlsPolicy,
|
|
219
|
+
SendingPoolName: props.deliveryOptions.SendingPoolName,
|
|
217
220
|
}),
|
|
218
221
|
);
|
|
219
222
|
}
|
|
@@ -241,14 +244,7 @@ export class SES extends Resource(
|
|
|
241
244
|
configurationSetArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:configuration-set/${props.configurationSetName}`;
|
|
242
245
|
}
|
|
243
246
|
} catch (error: any) {
|
|
244
|
-
|
|
245
|
-
// If it already exists but we couldn't get it (permissions issue), continue
|
|
246
|
-
console.warn(
|
|
247
|
-
`Configuration set ${props.configurationSetName} already exists but cannot be retrieved`,
|
|
248
|
-
);
|
|
249
|
-
} else {
|
|
250
|
-
throw error;
|
|
251
|
-
}
|
|
247
|
+
throw error;
|
|
252
248
|
}
|
|
253
249
|
}
|
|
254
250
|
|
package/src/aws/table.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "@aws-sdk/client-dynamodb";
|
|
10
10
|
import { ignore } from "../error";
|
|
11
11
|
import { type Context, Resource } from "../resource";
|
|
12
|
+
import { withExponentialBackoff } from "../utils/retry";
|
|
12
13
|
|
|
13
14
|
export interface TableProps {
|
|
14
15
|
tableName: string;
|
|
@@ -38,7 +39,7 @@ export class Table extends Resource(
|
|
|
38
39
|
async (
|
|
39
40
|
ctx: Context<TableOutput>,
|
|
40
41
|
props: TableProps,
|
|
41
|
-
): Promise<TableOutput> => {
|
|
42
|
+
): Promise<TableOutput | void> => {
|
|
42
43
|
const client = new DynamoDBClient({});
|
|
43
44
|
|
|
44
45
|
if (ctx.event === "delete") {
|
|
@@ -70,103 +71,133 @@ export class Table extends Resource(
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
return
|
|
74
|
-
...props,
|
|
75
|
-
id: props.tableName,
|
|
76
|
-
arn: `arn:aws:dynamodb:${client.config.region}:${process.env.AWS_ACCOUNT_ID}:table/${props.tableName}`,
|
|
77
|
-
tableId: "",
|
|
78
|
-
};
|
|
74
|
+
return;
|
|
79
75
|
} else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const keySchema: KeySchemaElement[] = [
|
|
89
|
-
{
|
|
90
|
-
AttributeName: props.partitionKey.name,
|
|
91
|
-
KeyType: "HASH",
|
|
92
|
-
},
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
if (props.sortKey) {
|
|
96
|
-
attributeDefinitions.push({
|
|
97
|
-
AttributeName: props.sortKey.name,
|
|
98
|
-
AttributeType: props.sortKey.type,
|
|
99
|
-
});
|
|
100
|
-
keySchema.push({
|
|
101
|
-
AttributeName: props.sortKey.name,
|
|
102
|
-
KeyType: "RANGE",
|
|
103
|
-
});
|
|
104
|
-
}
|
|
76
|
+
// Setup for table creation
|
|
77
|
+
const attributeDefinitions = [
|
|
78
|
+
{
|
|
79
|
+
AttributeName: props.partitionKey.name,
|
|
80
|
+
AttributeType: props.partitionKey.type,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
105
83
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
84
|
+
const keySchema: KeySchemaElement[] = [
|
|
85
|
+
{
|
|
86
|
+
AttributeName: props.partitionKey.name,
|
|
87
|
+
KeyType: "HASH",
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
if (props.sortKey) {
|
|
92
|
+
attributeDefinitions.push({
|
|
93
|
+
AttributeName: props.sortKey.name,
|
|
94
|
+
AttributeType: props.sortKey.type,
|
|
95
|
+
});
|
|
96
|
+
keySchema.push({
|
|
97
|
+
AttributeName: props.sortKey.name,
|
|
98
|
+
KeyType: "RANGE",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Attempt to create the table with exponential backoff for ResourceInUseException
|
|
103
|
+
await withExponentialBackoff(
|
|
104
|
+
async () => {
|
|
105
|
+
try {
|
|
106
|
+
// First check if table already exists
|
|
107
|
+
const describeResponse = await client.send(
|
|
108
|
+
new DescribeTableCommand({
|
|
109
|
+
TableName: props.tableName,
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// If table exists and is ACTIVE, no need to create it
|
|
114
|
+
if (describeResponse.Table?.TableStatus === "ACTIVE") {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
127
117
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
// If table exists but not ACTIVE, wait for it in the polling loop below
|
|
119
|
+
if (describeResponse.Table) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
if (error instanceof ResourceNotFoundException) {
|
|
124
|
+
// Table doesn't exist, try to create it
|
|
125
|
+
await client.send(
|
|
126
|
+
new CreateTableCommand({
|
|
127
|
+
TableName: props.tableName,
|
|
128
|
+
AttributeDefinitions: attributeDefinitions,
|
|
129
|
+
KeySchema: keySchema,
|
|
130
|
+
BillingMode: props.billingMode || "PAY_PER_REQUEST",
|
|
131
|
+
ProvisionedThroughput:
|
|
132
|
+
props.billingMode === "PROVISIONED"
|
|
133
|
+
? {
|
|
134
|
+
ReadCapacityUnits: props.readCapacity || 5,
|
|
135
|
+
WriteCapacityUnits: props.writeCapacity || 5,
|
|
136
|
+
}
|
|
137
|
+
: undefined,
|
|
138
|
+
Tags: props.tags
|
|
139
|
+
? Object.entries(props.tags).map(([Key, Value]) => ({
|
|
140
|
+
Key,
|
|
141
|
+
Value,
|
|
142
|
+
}))
|
|
143
|
+
: undefined,
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
146
|
+
} else {
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
(error) => error instanceof ResourceInUseException,
|
|
152
|
+
10, // Max attempts
|
|
153
|
+
200, // Initial delay in ms
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Wait for table to be active with timeout
|
|
157
|
+
let tableActive = false;
|
|
158
|
+
let tableDescription;
|
|
159
|
+
let retryCount = 0;
|
|
160
|
+
const maxRetries = 60; // Wait up to 60 seconds
|
|
161
|
+
|
|
162
|
+
while (!tableActive && retryCount < maxRetries) {
|
|
163
|
+
try {
|
|
132
164
|
const response = await client.send(
|
|
133
165
|
new DescribeTableCommand({
|
|
134
166
|
TableName: props.tableName,
|
|
135
167
|
}),
|
|
136
168
|
);
|
|
169
|
+
|
|
137
170
|
tableActive = response.Table?.TableStatus === "ACTIVE";
|
|
138
171
|
if (tableActive) {
|
|
139
172
|
tableDescription = response.Table;
|
|
140
173
|
} else {
|
|
141
|
-
|
|
174
|
+
retryCount++;
|
|
175
|
+
// Increasing delay for each retry with some jitter
|
|
176
|
+
const delay = Math.min(1000 * (1 + 0.1 * Math.random()), 5000);
|
|
177
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
142
178
|
}
|
|
179
|
+
} catch (error) {
|
|
180
|
+
retryCount++;
|
|
181
|
+
if (!(error instanceof ResourceNotFoundException)) {
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
143
185
|
}
|
|
186
|
+
}
|
|
144
187
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
streamArn: tableDescription!.LatestStreamArn,
|
|
150
|
-
tableId: tableDescription!.TableId!,
|
|
151
|
-
};
|
|
152
|
-
} catch (error) {
|
|
153
|
-
if (error instanceof ResourceInUseException) {
|
|
154
|
-
// Table already exists, get its details
|
|
155
|
-
const response = await client.send(
|
|
156
|
-
new DescribeTableCommand({
|
|
157
|
-
TableName: props.tableName,
|
|
158
|
-
}),
|
|
159
|
-
);
|
|
160
|
-
return {
|
|
161
|
-
...props,
|
|
162
|
-
id: props.tableName,
|
|
163
|
-
arn: response.Table!.TableArn!,
|
|
164
|
-
streamArn: response.Table!.LatestStreamArn,
|
|
165
|
-
tableId: response.Table!.TableId!,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
throw error;
|
|
188
|
+
if (!tableActive) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`Timed out waiting for table ${props.tableName} to become active`,
|
|
191
|
+
);
|
|
169
192
|
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
...props,
|
|
196
|
+
id: props.tableName,
|
|
197
|
+
arn: tableDescription!.TableArn!,
|
|
198
|
+
streamArn: tableDescription!.LatestStreamArn,
|
|
199
|
+
tableId: tableDescription!.TableId!,
|
|
200
|
+
};
|
|
170
201
|
}
|
|
171
202
|
},
|
|
172
203
|
) {}
|
package/src/cloudflare/api.ts
CHANGED
|
@@ -183,6 +183,12 @@ export class CloudflareApi {
|
|
|
183
183
|
return this.fetch(path, { ...init, method: "GET" });
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Helper for HEAD requests
|
|
188
|
+
*/
|
|
189
|
+
async head(path: string, init: RequestInit = {}): Promise<Response> {
|
|
190
|
+
return this.fetch(path, { ...init, method: "HEAD" });
|
|
191
|
+
}
|
|
186
192
|
/**
|
|
187
193
|
* Helper for POST requests
|
|
188
194
|
*/
|
|
@@ -3,6 +3,44 @@
|
|
|
3
3
|
* Based on Cloudflare API documentation:
|
|
4
4
|
* https://developers.cloudflare.com/api/resources/workers/subresources/scripts/methods/update/
|
|
5
5
|
*/
|
|
6
|
+
import type { DurableObjectNamespace } from "./durable-object-namespace";
|
|
7
|
+
import type { KVNamespace } from "./kv-namespace";
|
|
8
|
+
import type { Worker } from "./worker";
|
|
9
|
+
|
|
10
|
+
export type Bindings = {
|
|
11
|
+
[bindingName: string]: Binding;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* L2 Binding Resources.
|
|
16
|
+
*/
|
|
17
|
+
export type Binding = DurableObjectNamespace | KVNamespace | Worker | string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Union type for all Worker binding types (API spec)
|
|
21
|
+
*/
|
|
22
|
+
export type WorkerBindingSpec =
|
|
23
|
+
| WorkerBindingAI
|
|
24
|
+
| WorkerBindingAnalyticsEngine
|
|
25
|
+
| WorkerBindingAssets
|
|
26
|
+
| WorkerBindingBrowserRendering
|
|
27
|
+
| WorkerBindingD1
|
|
28
|
+
| WorkerBindingDispatchNamespace
|
|
29
|
+
| WorkerBindingDurableObjectNamespace
|
|
30
|
+
| WorkerBindingHyperdrive
|
|
31
|
+
| WorkerBindingJson
|
|
32
|
+
| WorkerBindingKVNamespace
|
|
33
|
+
| WorkerBindingMTLSCertificate
|
|
34
|
+
| WorkerBindingPlainText
|
|
35
|
+
| WorkerBindingQueue
|
|
36
|
+
| WorkerBindingR2Bucket
|
|
37
|
+
| WorkerBindingSecretText
|
|
38
|
+
| WorkerBindingService
|
|
39
|
+
| WorkerBindingStaticContent
|
|
40
|
+
| WorkerBindingTailConsumer
|
|
41
|
+
| WorkerBindingVectorize
|
|
42
|
+
| WorkerBindingVersionMetadata
|
|
43
|
+
| WorkerBindingWasmModule;
|
|
6
44
|
|
|
7
45
|
/**
|
|
8
46
|
* AI binding type
|
|
@@ -76,6 +114,11 @@ export interface WorkerBindingDispatchNamespace {
|
|
|
76
114
|
* Durable Object Namespace binding type
|
|
77
115
|
*/
|
|
78
116
|
export interface WorkerBindingDurableObjectNamespace {
|
|
117
|
+
/**
|
|
118
|
+
* The stable ID of the binding
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
stableId?: string;
|
|
79
122
|
/** The name of the binding */
|
|
80
123
|
name: string;
|
|
81
124
|
/** Type identifier for Durable Object Namespace binding */
|
|
@@ -258,29 +301,3 @@ export interface WorkerBindingStaticContent {
|
|
|
258
301
|
/** Type identifier for Static Content binding */
|
|
259
302
|
type: "static_content";
|
|
260
303
|
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Union type for all Worker binding types
|
|
264
|
-
*/
|
|
265
|
-
export type WorkerBinding =
|
|
266
|
-
| WorkerBindingAI
|
|
267
|
-
| WorkerBindingAnalyticsEngine
|
|
268
|
-
| WorkerBindingAssets
|
|
269
|
-
| WorkerBindingBrowserRendering
|
|
270
|
-
| WorkerBindingD1
|
|
271
|
-
| WorkerBindingDispatchNamespace
|
|
272
|
-
| WorkerBindingDurableObjectNamespace
|
|
273
|
-
| WorkerBindingHyperdrive
|
|
274
|
-
| WorkerBindingJson
|
|
275
|
-
| WorkerBindingKVNamespace
|
|
276
|
-
| WorkerBindingMTLSCertificate
|
|
277
|
-
| WorkerBindingPlainText
|
|
278
|
-
| WorkerBindingQueue
|
|
279
|
-
| WorkerBindingR2Bucket
|
|
280
|
-
| WorkerBindingSecretText
|
|
281
|
-
| WorkerBindingService
|
|
282
|
-
| WorkerBindingStaticContent
|
|
283
|
-
| WorkerBindingTailConsumer
|
|
284
|
-
| WorkerBindingVectorize
|
|
285
|
-
| WorkerBindingVersionMetadata
|
|
286
|
-
| WorkerBindingWasmModule;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Resolved } from "../output";
|
|
2
|
+
|
|
3
|
+
export interface DurableObjectNamespaceInput {
|
|
4
|
+
className: string;
|
|
5
|
+
scriptName?: string | undefined;
|
|
6
|
+
environment?: string | undefined;
|
|
7
|
+
sqlite?: boolean | undefined;
|
|
8
|
+
namespaceId?: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isDurableObjectNamespace(
|
|
12
|
+
binding: any,
|
|
13
|
+
): binding is Resolved<DurableObjectNamespace> {
|
|
14
|
+
return (
|
|
15
|
+
typeof binding === "object" && binding.type === "durable_object_namespace"
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class DurableObjectNamespace implements DurableObjectNamespaceInput {
|
|
20
|
+
public readonly type = "durable_object_namespace" as const;
|
|
21
|
+
// alias for bindingName to be consistent with other bindings
|
|
22
|
+
public readonly className: string;
|
|
23
|
+
public readonly scriptName?: string | undefined;
|
|
24
|
+
public readonly environment?: string | undefined;
|
|
25
|
+
public readonly sqlite?: boolean | undefined;
|
|
26
|
+
public readonly namespaceId?: string | undefined;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
public readonly id: string,
|
|
30
|
+
input: DurableObjectNamespaceInput,
|
|
31
|
+
) {
|
|
32
|
+
this.className = input.className;
|
|
33
|
+
this.scriptName = input.scriptName;
|
|
34
|
+
this.environment = input.environment;
|
|
35
|
+
this.sqlite = input.sqlite;
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/cloudflare/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Resolved } from "../output";
|
|
1
2
|
import { type Context, Resource } from "../resource";
|
|
2
3
|
import { createCloudflareApi } from "./api";
|
|
3
4
|
|
|
@@ -51,6 +52,7 @@ export interface KVPair {
|
|
|
51
52
|
* Output returned after KV Namespace creation/update
|
|
52
53
|
*/
|
|
53
54
|
export interface KVNamespaceOutput extends KVNamespaceProps {
|
|
55
|
+
type: "kv_namespace";
|
|
54
56
|
/**
|
|
55
57
|
* The ID of the namespace
|
|
56
58
|
*/
|
|
@@ -67,6 +69,14 @@ export interface KVNamespaceOutput extends KVNamespaceProps {
|
|
|
67
69
|
modifiedAt: number;
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
export function isKVNamespace(
|
|
73
|
+
resource: any,
|
|
74
|
+
): resource is Resolved<KVNamespace> {
|
|
75
|
+
return (
|
|
76
|
+
resource && typeof resource === "object" && resource.type === "kv_namespace"
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
export class KVNamespace extends Resource(
|
|
71
81
|
"cloudflare::KVNamespace",
|
|
72
82
|
async (ctx: Context<KVNamespaceOutput>, props: KVNamespaceProps) => {
|
|
@@ -121,7 +131,7 @@ export class KVNamespace extends Resource(
|
|
|
121
131
|
errors: [{ message: createResponse.statusText }],
|
|
122
132
|
}));
|
|
123
133
|
throw new Error(
|
|
124
|
-
`Error creating KV namespace: ${errorData.errors?.[0]?.message || createResponse.statusText}`,
|
|
134
|
+
`Error creating KV namespace '${props.title}': ${errorData.errors?.[0]?.message || createResponse.statusText}`,
|
|
125
135
|
);
|
|
126
136
|
}
|
|
127
137
|
|
|
@@ -182,6 +192,7 @@ export class KVNamespace extends Resource(
|
|
|
182
192
|
|
|
183
193
|
// Construct the output
|
|
184
194
|
const output: KVNamespaceOutput = {
|
|
195
|
+
type: "kv_namespace",
|
|
185
196
|
id: namespaceId,
|
|
186
197
|
title: props.title,
|
|
187
198
|
values: props.values,
|