alchemy 0.1.18 → 0.2.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/alchemy.d.ts +67 -0
- package/lib/alchemy.js +40 -0
- package/lib/apply.d.ts +3 -20
- package/lib/apply.js +86 -82
- package/lib/aws/account-id.d.ts +0 -1
- package/lib/aws/account-id.js +0 -1
- package/lib/aws/bucket.d.ts +4 -7
- package/lib/aws/bucket.js +8 -12
- package/lib/aws/function.d.ts +4 -7
- package/lib/aws/function.js +9 -30
- package/lib/aws/index.d.ts +1 -1
- package/lib/aws/index.js +1 -1
- package/lib/aws/oidc/github-oidc-provider.d.ts +2 -6
- package/lib/aws/oidc/github-oidc-provider.js +10 -15
- package/lib/aws/oidc/index.d.ts +0 -1
- package/lib/aws/oidc/index.js +0 -1
- package/lib/aws/oidc/oidc-provider.d.ts +4 -6
- package/lib/aws/oidc/oidc-provider.js +9 -11
- package/lib/aws/policy-attachment.d.ts +9 -0
- package/lib/aws/policy-attachment.js +20 -0
- package/lib/aws/policy.d.ts +4 -16
- package/lib/aws/policy.js +9 -40
- package/lib/aws/queue.d.ts +4 -34
- package/lib/aws/queue.js +10 -20
- package/lib/aws/role.d.ts +4 -7
- package/lib/aws/role.js +17 -26
- package/lib/aws/ses.d.ts +4 -10
- package/lib/aws/ses.js +118 -131
- package/lib/aws/table.d.ts +4 -7
- package/lib/aws/table.js +8 -11
- package/lib/cloudflare/api.d.ts +0 -1
- package/lib/cloudflare/api.js +0 -1
- package/lib/cloudflare/asset-manifest.d.ts +0 -1
- package/lib/cloudflare/asset-manifest.js +0 -1
- package/lib/cloudflare/auth.d.ts +0 -1
- package/lib/cloudflare/auth.js +0 -1
- package/lib/cloudflare/bindings.d.ts +1 -1
- package/lib/cloudflare/bindings.js +3 -2
- package/lib/cloudflare/bound.d.ts +0 -1
- package/lib/cloudflare/bound.js +0 -1
- package/lib/cloudflare/bucket.d.ts +7 -15
- package/lib/cloudflare/bucket.js +12 -19
- package/lib/cloudflare/durable-object-namespace.d.ts +0 -3
- package/lib/cloudflare/durable-object-namespace.js +0 -4
- package/lib/cloudflare/generate-asset-manifest.d.ts +0 -1
- package/lib/cloudflare/generate-asset-manifest.js +1 -2
- package/lib/cloudflare/index.d.ts +0 -1
- package/lib/cloudflare/index.js +0 -1
- package/lib/cloudflare/kv-namespace.d.ts +6 -9
- package/lib/cloudflare/kv-namespace.js +16 -20
- package/lib/cloudflare/state.d.ts +0 -1
- package/lib/cloudflare/state.js +0 -1
- package/lib/cloudflare/static-site-router.d.ts +0 -1
- package/lib/cloudflare/static-site-router.js +0 -4
- package/lib/cloudflare/static-site.d.ts +5 -11
- package/lib/cloudflare/static-site.js +16 -28
- package/lib/cloudflare/types.d.ts +0 -1
- package/lib/cloudflare/types.js +0 -1
- package/lib/cloudflare/upload-asset-manifest.d.ts +0 -1
- package/lib/cloudflare/upload-asset-manifest.js +0 -1
- package/lib/cloudflare/worker-metadata.d.ts +0 -1
- package/lib/cloudflare/worker-metadata.js +0 -1
- package/lib/cloudflare/worker-migration.d.ts +0 -1
- package/lib/cloudflare/worker-migration.js +0 -1
- package/lib/cloudflare/worker.d.ts +8 -14
- package/lib/cloudflare/worker.js +37 -49
- package/lib/context.d.ts +58 -0
- package/lib/context.js +36 -0
- package/lib/destroy.d.ts +10 -13
- package/lib/destroy.js +104 -43
- package/lib/{esbuild.d.ts → esbuild/bundle.d.ts} +4 -18
- package/lib/{esbuild.js → esbuild/bundle.js} +10 -24
- package/lib/esbuild/index.d.ts +1 -0
- package/lib/esbuild/index.js +1 -0
- package/lib/fs/file.d.ts +13 -0
- package/lib/fs/file.js +20 -0
- package/lib/fs/folder.d.ts +10 -0
- package/lib/fs/folder.js +16 -0
- package/lib/fs/index.d.ts +2 -0
- package/lib/fs/index.js +2 -0
- package/lib/github/client.d.ts +0 -1
- package/lib/github/client.js +0 -1
- package/lib/github/index.d.ts +0 -1
- package/lib/github/index.js +0 -1
- package/lib/github/secret.d.ts +4 -6
- package/lib/github/secret.js +10 -12
- package/lib/index.d.ts +6 -10
- package/lib/index.js +5 -9
- package/lib/resource.d.ts +34 -62
- package/lib/resource.js +29 -270
- package/lib/scope.d.ts +35 -14
- package/lib/scope.js +78 -23
- package/lib/secret.d.ts +2 -7
- package/lib/secret.js +7 -20
- package/lib/state.d.ts +14 -10
- package/lib/state.js +15 -14
- package/lib/stripe/index.d.ts +0 -1
- package/lib/stripe/index.js +0 -1
- package/lib/stripe/price.d.ts +4 -5
- package/lib/stripe/price.js +10 -20
- package/lib/stripe/product.d.ts +4 -5
- package/lib/stripe/product.js +10 -20
- package/lib/stripe/webhook.d.ts +4 -6
- package/lib/stripe/webhook.js +12 -25
- package/lib/test/bun.d.ts +19 -0
- package/lib/test/bun.js +55 -0
- package/lib/{utils → util}/content-type.d.ts +0 -1
- package/lib/{utils → util}/content-type.js +0 -1
- package/lib/{encrypt.d.ts → util/encrypt.d.ts} +0 -1
- package/lib/{encrypt.js → util/encrypt.js} +0 -1
- package/lib/{error.d.ts → util/ignore.d.ts} +0 -1
- package/lib/{error.js → util/ignore.js} +0 -1
- package/lib/{utils → util}/retry.d.ts +0 -1
- package/lib/{utils → util}/retry.js +0 -1
- package/lib/util/serde.d.ts +3 -0
- package/lib/{serde.js → util/serde.js} +19 -10
- package/lib/util/slugify.d.ts +1 -0
- package/lib/util/slugify.js +3 -0
- package/package.json +5 -4
- package/src/alchemy.ts +120 -0
- package/src/apply.ts +109 -114
- package/src/aws/bucket.ts +11 -14
- package/src/aws/function.ts +13 -33
- package/src/aws/index.ts +1 -0
- package/src/aws/oidc/github-oidc-provider.ts +14 -19
- package/src/aws/oidc/oidc-provider.ts +19 -12
- package/src/aws/policy-attachment.ts +51 -0
- package/src/aws/policy.ts +15 -60
- package/src/aws/queue.ts +17 -21
- package/src/aws/role.ts +25 -28
- package/src/aws/ses.ts +150 -164
- package/src/aws/table.ts +15 -15
- package/src/cloudflare/bindings.ts +8 -0
- package/src/cloudflare/bucket.ts +39 -47
- package/src/cloudflare/durable-object-namespace.ts +0 -10
- package/src/cloudflare/generate-asset-manifest.ts +1 -1
- package/src/cloudflare/kv-namespace.ts +35 -33
- package/src/cloudflare/static-site-router.ts +0 -3
- package/src/cloudflare/static-site.ts +44 -60
- package/src/cloudflare/worker.ts +105 -111
- package/src/context.ts +122 -0
- package/src/destroy.ts +124 -73
- package/src/{esbuild.ts → esbuild/bundle.ts} +16 -28
- package/src/esbuild/index.ts +1 -0
- package/src/fs/file.ts +39 -0
- package/src/fs/folder.ts +32 -0
- package/src/fs/index.ts +2 -0
- package/src/github/secret.ts +19 -16
- package/src/index.ts +7 -15
- package/src/resource.ts +101 -462
- package/src/scope.ts +101 -36
- package/src/secret.ts +9 -32
- package/src/state.ts +30 -21
- package/src/stripe/price.ts +17 -22
- package/src/stripe/product.ts +17 -22
- package/src/stripe/webhook.ts +21 -27
- package/src/test/bun.ts +105 -0
- package/src/util/serde.ts +53 -0
- package/src/util/slugify.ts +3 -0
- package/lib/$.d.ts +0 -12
- package/lib/$.d.ts.map +0 -1
- package/lib/$.js +0 -42
- package/lib/$.js.map +0 -1
- package/lib/alchemize.d.ts +0 -47
- package/lib/alchemize.d.ts.map +0 -1
- package/lib/alchemize.js +0 -116
- package/lib/alchemize.js.map +0 -1
- package/lib/apply.d.ts.map +0 -1
- package/lib/apply.js.map +0 -1
- package/lib/aws/account-id.d.ts.map +0 -1
- package/lib/aws/account-id.js.map +0 -1
- package/lib/aws/bucket.d.ts.map +0 -1
- package/lib/aws/bucket.js.map +0 -1
- package/lib/aws/function.d.ts.map +0 -1
- package/lib/aws/function.js.map +0 -1
- package/lib/aws/index.d.ts.map +0 -1
- package/lib/aws/index.js.map +0 -1
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +0 -1
- package/lib/aws/oidc/github-oidc-provider.js.map +0 -1
- package/lib/aws/oidc/index.d.ts.map +0 -1
- package/lib/aws/oidc/index.js.map +0 -1
- package/lib/aws/oidc/oidc-provider.d.ts.map +0 -1
- package/lib/aws/oidc/oidc-provider.js.map +0 -1
- package/lib/aws/policy.d.ts.map +0 -1
- package/lib/aws/policy.js.map +0 -1
- package/lib/aws/queue.d.ts.map +0 -1
- package/lib/aws/queue.js.map +0 -1
- package/lib/aws/role.d.ts.map +0 -1
- package/lib/aws/role.js.map +0 -1
- package/lib/aws/ses.d.ts.map +0 -1
- package/lib/aws/ses.js.map +0 -1
- package/lib/aws/table.d.ts.map +0 -1
- package/lib/aws/table.js.map +0 -1
- package/lib/cloudflare/api.d.ts.map +0 -1
- package/lib/cloudflare/api.js.map +0 -1
- package/lib/cloudflare/asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/asset-manifest.js.map +0 -1
- package/lib/cloudflare/auth.d.ts.map +0 -1
- package/lib/cloudflare/auth.js.map +0 -1
- package/lib/cloudflare/bindings.d.ts.map +0 -1
- package/lib/cloudflare/bindings.js.map +0 -1
- package/lib/cloudflare/bound.d.ts.map +0 -1
- package/lib/cloudflare/bound.js.map +0 -1
- package/lib/cloudflare/bucket.d.ts.map +0 -1
- package/lib/cloudflare/bucket.js.map +0 -1
- package/lib/cloudflare/durable-object-namespace.d.ts.map +0 -1
- package/lib/cloudflare/durable-object-namespace.js.map +0 -1
- package/lib/cloudflare/generate-asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/generate-asset-manifest.js.map +0 -1
- package/lib/cloudflare/index.d.ts.map +0 -1
- package/lib/cloudflare/index.js.map +0 -1
- package/lib/cloudflare/kv-namespace.d.ts.map +0 -1
- package/lib/cloudflare/kv-namespace.js.map +0 -1
- package/lib/cloudflare/state.d.ts.map +0 -1
- package/lib/cloudflare/state.js.map +0 -1
- package/lib/cloudflare/static-site-router.d.ts.map +0 -1
- package/lib/cloudflare/static-site-router.js.map +0 -1
- package/lib/cloudflare/static-site.d.ts.map +0 -1
- package/lib/cloudflare/static-site.js.map +0 -1
- package/lib/cloudflare/types.d.ts.map +0 -1
- package/lib/cloudflare/types.js.map +0 -1
- package/lib/cloudflare/upload-asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/upload-asset-manifest.js.map +0 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +0 -1
- package/lib/cloudflare/worker-metadata.js.map +0 -1
- package/lib/cloudflare/worker-migration.d.ts.map +0 -1
- package/lib/cloudflare/worker-migration.js.map +0 -1
- package/lib/cloudflare/worker.d.ts.map +0 -1
- package/lib/cloudflare/worker.js.map +0 -1
- package/lib/destroy.d.ts.map +0 -1
- package/lib/destroy.js.map +0 -1
- package/lib/encrypt.d.ts.map +0 -1
- package/lib/encrypt.js.map +0 -1
- package/lib/error.d.ts.map +0 -1
- package/lib/error.js.map +0 -1
- package/lib/esbuild.d.ts.map +0 -1
- package/lib/esbuild.js.map +0 -1
- package/lib/fs.d.ts +0 -12
- package/lib/fs.d.ts.map +0 -1
- package/lib/fs.js +0 -41
- package/lib/fs.js.map +0 -1
- package/lib/github/client.d.ts.map +0 -1
- package/lib/github/client.js.map +0 -1
- package/lib/github/index.d.ts.map +0 -1
- package/lib/github/index.js.map +0 -1
- package/lib/github/secret.d.ts.map +0 -1
- package/lib/github/secret.js.map +0 -1
- package/lib/global.d.ts +0 -16
- package/lib/global.d.ts.map +0 -1
- package/lib/global.js +0 -42
- package/lib/global.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/input.d.ts +0 -7
- package/lib/input.d.ts.map +0 -1
- package/lib/input.js +0 -2
- package/lib/input.js.map +0 -1
- package/lib/main.d.ts +0 -3
- package/lib/main.d.ts.map +0 -1
- package/lib/main.js +0 -32
- package/lib/main.js.map +0 -1
- package/lib/output.d.ts +0 -25
- package/lib/output.d.ts.map +0 -1
- package/lib/output.js +0 -23
- package/lib/output.js.map +0 -1
- package/lib/print.d.ts +0 -7
- package/lib/print.d.ts.map +0 -1
- package/lib/print.js +0 -10
- package/lib/print.js.map +0 -1
- package/lib/resource.d.ts.map +0 -1
- package/lib/resource.js.map +0 -1
- package/lib/scope.d.ts.map +0 -1
- package/lib/scope.js.map +0 -1
- package/lib/secret.d.ts.map +0 -1
- package/lib/secret.js.map +0 -1
- package/lib/serde.d.ts +0 -3
- package/lib/serde.d.ts.map +0 -1
- package/lib/serde.js.map +0 -1
- package/lib/slug.d.ts +0 -2
- package/lib/slug.d.ts.map +0 -1
- package/lib/slug.js +0 -4
- package/lib/slug.js.map +0 -1
- package/lib/state.d.ts.map +0 -1
- package/lib/state.js.map +0 -1
- package/lib/stripe/index.d.ts.map +0 -1
- package/lib/stripe/index.js.map +0 -1
- package/lib/stripe/price.d.ts.map +0 -1
- package/lib/stripe/price.js.map +0 -1
- package/lib/stripe/product.d.ts.map +0 -1
- package/lib/stripe/product.js.map +0 -1
- package/lib/stripe/webhook.d.ts.map +0 -1
- package/lib/stripe/webhook.js.map +0 -1
- package/lib/utils/content-type.d.ts.map +0 -1
- package/lib/utils/content-type.js.map +0 -1
- package/lib/utils/retry.d.ts.map +0 -1
- package/lib/utils/retry.js.map +0 -1
- package/src/$.ts +0 -69
- package/src/alchemize.ts +0 -195
- package/src/fs.ts +0 -47
- package/src/global.ts +0 -63
- package/src/input.ts +0 -19
- package/src/main.ts +0 -34
- package/src/output.ts +0 -75
- package/src/print.ts +0 -18
- package/src/serde.ts +0 -46
- package/src/slug.ts +0 -3
- /package/src/{utils → util}/content-type.ts +0 -0
- /package/src/{encrypt.ts → util/encrypt.ts} +0 -0
- /package/src/{error.ts → util/ignore.ts} +0 -0
- /package/src/{utils → util}/retry.ts +0 -0
package/src/aws/ses.ts
CHANGED
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
type SuppressionOptions,
|
|
20
20
|
type TrackingOptions,
|
|
21
21
|
} from "@aws-sdk/client-sesv2";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
22
|
+
import type { Context } from "../context";
|
|
23
|
+
import { Resource } from "../resource";
|
|
24
|
+
import { ignore } from "../util/ignore";
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Properties for configuring AWS SES resources
|
|
@@ -75,12 +76,7 @@ export interface SESProps {
|
|
|
75
76
|
/**
|
|
76
77
|
* Output returned after SES resource creation/update
|
|
77
78
|
*/
|
|
78
|
-
export interface
|
|
79
|
-
/**
|
|
80
|
-
* Resource ID
|
|
81
|
-
*/
|
|
82
|
-
id: string;
|
|
83
|
-
|
|
79
|
+
export interface SES extends Resource<"aws::SES">, SESProps {
|
|
84
80
|
/**
|
|
85
81
|
* ARN of the configuration set if created
|
|
86
82
|
*/
|
|
@@ -105,19 +101,23 @@ export interface SESOutput extends SESProps {
|
|
|
105
101
|
/**
|
|
106
102
|
* AWS SES resource for creating and configuring Simple Email Service
|
|
107
103
|
*/
|
|
108
|
-
export
|
|
104
|
+
export const SES = Resource(
|
|
109
105
|
"aws::SES",
|
|
110
|
-
async (
|
|
106
|
+
async function (
|
|
107
|
+
this: Context<SES>,
|
|
108
|
+
id: string,
|
|
109
|
+
props: SESProps,
|
|
110
|
+
): Promise<SES> {
|
|
111
111
|
// Create SES client
|
|
112
112
|
const client = new SESv2Client({});
|
|
113
113
|
|
|
114
114
|
// Resource ID is either based on the configuration set name or email identity
|
|
115
|
-
const id =
|
|
116
|
-
|
|
115
|
+
// const id =
|
|
116
|
+
// props.configurationSetName || props.emailIdentity || this.resourceID;
|
|
117
117
|
|
|
118
118
|
// Handle deletion
|
|
119
|
-
if (
|
|
120
|
-
const output =
|
|
119
|
+
if (this.phase === "delete") {
|
|
120
|
+
const output = this.output;
|
|
121
121
|
|
|
122
122
|
// Delete configuration set if it exists
|
|
123
123
|
if (output?.configurationSetName) {
|
|
@@ -142,7 +142,7 @@ export class SES extends Resource(
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// Return empty output for delete
|
|
145
|
-
return;
|
|
145
|
+
return this.destroy();
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// Created resources
|
|
@@ -153,190 +153,176 @@ export class SES extends Resource(
|
|
|
153
153
|
|
|
154
154
|
// Create or update configuration set if specified
|
|
155
155
|
if (props.configurationSetName) {
|
|
156
|
+
// Check if configuration set exists
|
|
157
|
+
let configSetExists = false;
|
|
156
158
|
try {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
await client.send(
|
|
160
|
+
new GetConfigurationSetCommand({
|
|
161
|
+
ConfigurationSetName: props.configurationSetName,
|
|
162
|
+
}),
|
|
163
|
+
);
|
|
164
|
+
configSetExists = true;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
if (error instanceof NotFoundException) {
|
|
167
|
+
configSetExists = false;
|
|
168
|
+
} else {
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (configSetExists) {
|
|
174
|
+
// Update existing configuration set using appropriate update commands
|
|
175
|
+
if (props.sendingOptions) {
|
|
160
176
|
await client.send(
|
|
161
|
-
new
|
|
177
|
+
new PutConfigurationSetSendingOptionsCommand({
|
|
162
178
|
ConfigurationSetName: props.configurationSetName,
|
|
179
|
+
SendingEnabled: props.sendingOptions.SendingEnabled,
|
|
163
180
|
}),
|
|
164
181
|
);
|
|
165
|
-
configSetExists = true;
|
|
166
|
-
} catch (error) {
|
|
167
|
-
if (error instanceof NotFoundException) {
|
|
168
|
-
configSetExists = false;
|
|
169
|
-
} else {
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
182
|
}
|
|
173
183
|
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (props.reputationOptions) {
|
|
186
|
-
await client.send(
|
|
187
|
-
new PutConfigurationSetReputationOptionsCommand({
|
|
188
|
-
ConfigurationSetName: props.configurationSetName,
|
|
189
|
-
ReputationMetricsEnabled:
|
|
190
|
-
props.reputationOptions.ReputationMetricsEnabled,
|
|
191
|
-
}),
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (props.trackingOptions) {
|
|
196
|
-
await client.send(
|
|
197
|
-
new PutConfigurationSetTrackingOptionsCommand({
|
|
198
|
-
ConfigurationSetName: props.configurationSetName,
|
|
199
|
-
CustomRedirectDomain:
|
|
200
|
-
props.trackingOptions.CustomRedirectDomain,
|
|
201
|
-
}),
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (props.suppressionOptions) {
|
|
206
|
-
await client.send(
|
|
207
|
-
new PutConfigurationSetSuppressionOptionsCommand({
|
|
208
|
-
ConfigurationSetName: props.configurationSetName,
|
|
209
|
-
SuppressedReasons: props.suppressionOptions.SuppressedReasons,
|
|
210
|
-
}),
|
|
211
|
-
);
|
|
212
|
-
}
|
|
184
|
+
if (props.reputationOptions) {
|
|
185
|
+
await client.send(
|
|
186
|
+
new PutConfigurationSetReputationOptionsCommand({
|
|
187
|
+
ConfigurationSetName: props.configurationSetName,
|
|
188
|
+
ReputationMetricsEnabled:
|
|
189
|
+
props.reputationOptions.ReputationMetricsEnabled,
|
|
190
|
+
}),
|
|
191
|
+
);
|
|
192
|
+
}
|
|
213
193
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
194
|
+
if (props.trackingOptions) {
|
|
195
|
+
await client.send(
|
|
196
|
+
new PutConfigurationSetTrackingOptionsCommand({
|
|
197
|
+
ConfigurationSetName: props.configurationSetName,
|
|
198
|
+
CustomRedirectDomain: props.trackingOptions.CustomRedirectDomain,
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
201
|
+
}
|
|
223
202
|
|
|
224
|
-
|
|
225
|
-
configurationSetArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:configuration-set/${props.configurationSetName}`;
|
|
226
|
-
} else {
|
|
227
|
-
// Create new configuration set
|
|
203
|
+
if (props.suppressionOptions) {
|
|
228
204
|
await client.send(
|
|
229
|
-
new
|
|
205
|
+
new PutConfigurationSetSuppressionOptionsCommand({
|
|
230
206
|
ConfigurationSetName: props.configurationSetName,
|
|
231
|
-
|
|
232
|
-
ReputationOptions: props.reputationOptions,
|
|
233
|
-
TrackingOptions: props.trackingOptions,
|
|
234
|
-
SuppressionOptions: props.suppressionOptions,
|
|
235
|
-
DeliveryOptions: props.deliveryOptions,
|
|
236
|
-
Tags: Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
237
|
-
Key,
|
|
238
|
-
Value,
|
|
239
|
-
})),
|
|
207
|
+
SuppressedReasons: props.suppressionOptions.SuppressedReasons,
|
|
240
208
|
}),
|
|
241
209
|
);
|
|
210
|
+
}
|
|
242
211
|
|
|
243
|
-
|
|
244
|
-
|
|
212
|
+
if (props.deliveryOptions) {
|
|
213
|
+
await client.send(
|
|
214
|
+
new PutConfigurationSetDeliveryOptionsCommand({
|
|
215
|
+
ConfigurationSetName: props.configurationSetName,
|
|
216
|
+
TlsPolicy: props.deliveryOptions.TlsPolicy,
|
|
217
|
+
SendingPoolName: props.deliveryOptions.SendingPoolName,
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
245
220
|
}
|
|
246
|
-
|
|
247
|
-
|
|
221
|
+
|
|
222
|
+
// In SESv2, the ARN isn't directly returned in the response
|
|
223
|
+
configurationSetArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:configuration-set/${props.configurationSetName}`;
|
|
224
|
+
} else {
|
|
225
|
+
// Create new configuration set
|
|
226
|
+
await client.send(
|
|
227
|
+
new CreateConfigurationSetCommand({
|
|
228
|
+
ConfigurationSetName: props.configurationSetName,
|
|
229
|
+
SendingOptions: props.sendingOptions,
|
|
230
|
+
ReputationOptions: props.reputationOptions,
|
|
231
|
+
TrackingOptions: props.trackingOptions,
|
|
232
|
+
SuppressionOptions: props.suppressionOptions,
|
|
233
|
+
DeliveryOptions: props.deliveryOptions,
|
|
234
|
+
Tags: Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
235
|
+
Key,
|
|
236
|
+
Value,
|
|
237
|
+
})),
|
|
238
|
+
}),
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// In SESv2, the ARN isn't directly returned in the response
|
|
242
|
+
configurationSetArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:configuration-set/${props.configurationSetName}`;
|
|
248
243
|
}
|
|
249
244
|
}
|
|
250
245
|
|
|
251
246
|
// Create or verify email identity if specified
|
|
252
247
|
if (props.emailIdentity) {
|
|
248
|
+
// Check if identity exists
|
|
249
|
+
let getIdentityResult;
|
|
253
250
|
try {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
getIdentityResult = null;
|
|
265
|
-
} else {
|
|
266
|
-
throw error;
|
|
267
|
-
}
|
|
251
|
+
getIdentityResult = await client.send(
|
|
252
|
+
new GetEmailIdentityCommand({
|
|
253
|
+
EmailIdentity: props.emailIdentity,
|
|
254
|
+
}),
|
|
255
|
+
);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (error instanceof NotFoundException) {
|
|
258
|
+
getIdentityResult = null;
|
|
259
|
+
} else {
|
|
260
|
+
throw error;
|
|
268
261
|
}
|
|
262
|
+
}
|
|
269
263
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
264
|
+
if (!getIdentityResult) {
|
|
265
|
+
// Create new email identity
|
|
266
|
+
const createIdentityResult = await client.send(
|
|
267
|
+
new CreateEmailIdentityCommand({
|
|
268
|
+
EmailIdentity: props.emailIdentity,
|
|
269
|
+
Tags: Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
270
|
+
Key,
|
|
271
|
+
Value,
|
|
272
|
+
})),
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
// If it's an email address, we don't need to explicitly verify in v2
|
|
277
|
+
// The verification email is automatically sent by SES in v2
|
|
278
|
+
|
|
279
|
+
// Store the identity information
|
|
280
|
+
emailIdentityArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:identity/${props.emailIdentity}`;
|
|
281
|
+
emailIdentityVerificationStatus =
|
|
282
|
+
createIdentityResult.VerifiedForSendingStatus
|
|
283
|
+
? "VERIFIED"
|
|
284
|
+
: "PENDING";
|
|
285
|
+
} else {
|
|
286
|
+
// Store the identity information
|
|
287
|
+
emailIdentityArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:identity/${props.emailIdentity}`;
|
|
288
|
+
emailIdentityVerificationStatus =
|
|
289
|
+
getIdentityResult.VerifiedForSendingStatus ? "VERIFIED" : "PENDING";
|
|
290
|
+
|
|
291
|
+
// Update DKIM settings if requested
|
|
292
|
+
if (props.enableDkim !== undefined) {
|
|
293
|
+
if (props.enableDkim) {
|
|
294
|
+
await client.send(
|
|
295
|
+
new PutEmailIdentityDkimAttributesCommand({
|
|
296
|
+
EmailIdentity: props.emailIdentity,
|
|
297
|
+
SigningEnabled: true,
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
281
300
|
|
|
282
|
-
|
|
283
|
-
|
|
301
|
+
// We can check the current status of DKIM
|
|
302
|
+
dkimVerificationStatus = "PENDING"; // Default to pending
|
|
284
303
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
emailIdentityVerificationStatus =
|
|
295
|
-
getIdentityResult.VerifiedForSendingStatus ? "VERIFIED" : "PENDING";
|
|
296
|
-
|
|
297
|
-
// Update DKIM settings if requested
|
|
298
|
-
if (props.enableDkim !== undefined) {
|
|
299
|
-
if (props.enableDkim) {
|
|
300
|
-
await client.send(
|
|
301
|
-
new PutEmailIdentityDkimAttributesCommand({
|
|
302
|
-
EmailIdentity: props.emailIdentity,
|
|
303
|
-
SigningEnabled: true,
|
|
304
|
-
}),
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
// We can check the current status of DKIM
|
|
308
|
-
dkimVerificationStatus = "PENDING"; // Default to pending
|
|
309
|
-
|
|
310
|
-
// Get the updated identity to check DKIM status
|
|
311
|
-
const updatedIdentity = await client.send(
|
|
312
|
-
new GetEmailIdentityCommand({
|
|
313
|
-
EmailIdentity: props.emailIdentity,
|
|
314
|
-
}),
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
if (updatedIdentity.DkimAttributes?.Status) {
|
|
318
|
-
dkimVerificationStatus = updatedIdentity.DkimAttributes.Status;
|
|
319
|
-
}
|
|
304
|
+
// Get the updated identity to check DKIM status
|
|
305
|
+
const updatedIdentity = await client.send(
|
|
306
|
+
new GetEmailIdentityCommand({
|
|
307
|
+
EmailIdentity: props.emailIdentity,
|
|
308
|
+
}),
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
if (updatedIdentity.DkimAttributes?.Status) {
|
|
312
|
+
dkimVerificationStatus = updatedIdentity.DkimAttributes.Status;
|
|
320
313
|
}
|
|
321
314
|
}
|
|
322
315
|
}
|
|
323
|
-
} catch (error) {
|
|
324
|
-
console.error(
|
|
325
|
-
`Error configuring email identity ${props.emailIdentity}:`,
|
|
326
|
-
error,
|
|
327
|
-
);
|
|
328
|
-
throw error;
|
|
329
316
|
}
|
|
330
317
|
}
|
|
331
318
|
|
|
332
319
|
// Return the resource output
|
|
333
|
-
return {
|
|
320
|
+
return this({
|
|
334
321
|
...props,
|
|
335
|
-
id,
|
|
336
322
|
configurationSetArn,
|
|
337
323
|
emailIdentityArn,
|
|
338
324
|
emailIdentityVerificationStatus,
|
|
339
325
|
dkimVerificationStatus,
|
|
340
|
-
};
|
|
326
|
+
});
|
|
341
327
|
},
|
|
342
|
-
)
|
|
328
|
+
);
|
package/src/aws/table.ts
CHANGED
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
ResourceInUseException,
|
|
9
9
|
ResourceNotFoundException,
|
|
10
10
|
} from "@aws-sdk/client-dynamodb";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import type { Context } from "../context";
|
|
12
|
+
import { Resource } from "../resource";
|
|
13
|
+
import { ignore } from "../util/ignore";
|
|
14
|
+
import { withExponentialBackoff } from "../util/retry";
|
|
14
15
|
|
|
15
16
|
export interface TableProps {
|
|
16
17
|
tableName: string;
|
|
@@ -28,22 +29,22 @@ export interface TableProps {
|
|
|
28
29
|
tags?: Record<string, string>;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
export interface
|
|
32
|
-
id: string; // Same as tableName
|
|
32
|
+
export interface Table extends Resource<"dynamo::Table">, TableProps {
|
|
33
33
|
arn: string;
|
|
34
34
|
streamArn?: string;
|
|
35
35
|
tableId: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export
|
|
38
|
+
export const Table = Resource(
|
|
39
39
|
"dynamo::Table",
|
|
40
|
-
async (
|
|
41
|
-
|
|
40
|
+
async function (
|
|
41
|
+
this: Context<Table>,
|
|
42
|
+
id: string,
|
|
42
43
|
props: TableProps,
|
|
43
|
-
): Promise<
|
|
44
|
+
): Promise<Table> {
|
|
44
45
|
const client = new DynamoDBClient({});
|
|
45
46
|
|
|
46
|
-
if (
|
|
47
|
+
if (this.phase === "delete") {
|
|
47
48
|
await withExponentialBackoff(
|
|
48
49
|
async () => {
|
|
49
50
|
await ignore(ResourceNotFoundException.name, () =>
|
|
@@ -93,7 +94,7 @@ export class Table extends Resource(
|
|
|
93
94
|
);
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
return;
|
|
97
|
+
return this.destroy();
|
|
97
98
|
} else {
|
|
98
99
|
// Setup for table creation
|
|
99
100
|
const attributeDefinitions = [
|
|
@@ -213,13 +214,12 @@ export class Table extends Resource(
|
|
|
213
214
|
);
|
|
214
215
|
}
|
|
215
216
|
|
|
216
|
-
return {
|
|
217
|
+
return this({
|
|
217
218
|
...props,
|
|
218
|
-
id: props.tableName,
|
|
219
219
|
arn: tableDescription!.TableArn!,
|
|
220
220
|
streamArn: tableDescription!.LatestStreamArn,
|
|
221
221
|
tableId: tableDescription!.TableId!,
|
|
222
|
-
};
|
|
222
|
+
});
|
|
223
223
|
}
|
|
224
224
|
},
|
|
225
|
-
)
|
|
225
|
+
);
|
|
@@ -24,6 +24,14 @@ export type Binding =
|
|
|
24
24
|
| Secret
|
|
25
25
|
| string;
|
|
26
26
|
|
|
27
|
+
export function isDurableObjectNamespace(
|
|
28
|
+
binding: Binding,
|
|
29
|
+
): binding is DurableObjectNamespace {
|
|
30
|
+
return (
|
|
31
|
+
typeof binding === "object" && binding.type === "durable_object_namespace"
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
/**
|
|
28
36
|
* Union type for all Worker binding types (API spec)
|
|
29
37
|
*/
|
package/src/cloudflare/bucket.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
1
|
+
import type { Context } from "../context";
|
|
2
|
+
import { Resource } from "../resource";
|
|
3
3
|
import { createCloudflareApi } from "./api";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -11,7 +11,7 @@ export interface BucketProps {
|
|
|
11
11
|
* Names can only contain lowercase letters (a-z), numbers (0-9), and hyphens (-)
|
|
12
12
|
* Cannot begin or end with a hyphen
|
|
13
13
|
*/
|
|
14
|
-
name
|
|
14
|
+
name: string;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Optional location hint for the bucket
|
|
@@ -35,11 +35,13 @@ export interface BucketProps {
|
|
|
35
35
|
/**
|
|
36
36
|
* Output returned after R2 Bucket creation/update
|
|
37
37
|
*/
|
|
38
|
-
export interface
|
|
38
|
+
export interface R2Bucket
|
|
39
|
+
extends Resource<"cloudflare::R2Bucket">,
|
|
40
|
+
BucketProps {
|
|
39
41
|
/**
|
|
40
|
-
*
|
|
42
|
+
* Resource type identifier
|
|
41
43
|
*/
|
|
42
|
-
|
|
44
|
+
type: "r2_bucket";
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Location of the bucket
|
|
@@ -50,44 +52,23 @@ export interface BucketOutput extends BucketProps {
|
|
|
50
52
|
* Time at which the bucket was created (Unix timestamp in seconds)
|
|
51
53
|
*/
|
|
52
54
|
creationDate: number;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Resource type identifier
|
|
56
|
-
*/
|
|
57
|
-
type: "r2_bucket";
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Cloudflare R2 bucket API response
|
|
62
|
-
*/
|
|
63
|
-
interface CloudflareBucketResponse {
|
|
64
|
-
result: {
|
|
65
|
-
name: string;
|
|
66
|
-
location?: string;
|
|
67
|
-
creation_date: string;
|
|
68
|
-
};
|
|
69
|
-
success: boolean;
|
|
70
|
-
errors: Array<{ code: number; message: string }>;
|
|
71
|
-
messages: string[];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function isBucket(resource: any): resource is Resolved<R2Bucket> {
|
|
75
|
-
return (
|
|
76
|
-
resource && typeof resource === "object" && resource.id && resource.location
|
|
77
|
-
);
|
|
78
55
|
}
|
|
79
56
|
|
|
80
|
-
export
|
|
57
|
+
export const R2Bucket = Resource(
|
|
81
58
|
"cloudflare::R2Bucket",
|
|
82
|
-
async (
|
|
59
|
+
async function (
|
|
60
|
+
this: Context<R2Bucket>,
|
|
61
|
+
id: string,
|
|
62
|
+
props: BucketProps,
|
|
63
|
+
): Promise<R2Bucket> {
|
|
83
64
|
// Create Cloudflare API client with automatic account discovery
|
|
84
65
|
const api = await createCloudflareApi();
|
|
85
66
|
|
|
86
67
|
// Resource ID defaults to bucket name if provided
|
|
87
|
-
const bucketName = props.name ||
|
|
68
|
+
const bucketName = props.name || this.id;
|
|
88
69
|
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
70
|
+
if (this.phase === "delete") {
|
|
71
|
+
if (this.output?.name) {
|
|
91
72
|
// Delete R2 bucket
|
|
92
73
|
const headers: Record<string, string> = {};
|
|
93
74
|
if (props.jurisdiction && props.jurisdiction !== "default") {
|
|
@@ -95,7 +76,7 @@ export class R2Bucket extends Resource(
|
|
|
95
76
|
}
|
|
96
77
|
|
|
97
78
|
const deleteResponse = await api.delete(
|
|
98
|
-
`/accounts/${api.accountId}/r2/buckets/${
|
|
79
|
+
`/accounts/${api.accountId}/r2/buckets/${this.output.name}`,
|
|
99
80
|
{ headers },
|
|
100
81
|
);
|
|
101
82
|
|
|
@@ -110,12 +91,25 @@ export class R2Bucket extends Resource(
|
|
|
110
91
|
}
|
|
111
92
|
|
|
112
93
|
// Return void (a deleted bucket has no content)
|
|
113
|
-
return;
|
|
94
|
+
return this.destroy();
|
|
114
95
|
} else {
|
|
96
|
+
/**
|
|
97
|
+
* Cloudflare R2 bucket API response
|
|
98
|
+
*/
|
|
99
|
+
interface CloudflareBucketResponse {
|
|
100
|
+
result: {
|
|
101
|
+
name: string;
|
|
102
|
+
location?: string;
|
|
103
|
+
creation_date: string;
|
|
104
|
+
};
|
|
105
|
+
success: boolean;
|
|
106
|
+
errors: Array<{ code: number; message: string }>;
|
|
107
|
+
messages: string[];
|
|
108
|
+
}
|
|
115
109
|
try {
|
|
116
|
-
let bucketOutput:
|
|
110
|
+
let bucketOutput: R2Bucket;
|
|
117
111
|
|
|
118
|
-
if (
|
|
112
|
+
if (this.phase === "update" && this.output?.name) {
|
|
119
113
|
// Get bucket details to verify it exists
|
|
120
114
|
const headers: Record<string, string> = {};
|
|
121
115
|
if (props.jurisdiction && props.jurisdiction !== "default") {
|
|
@@ -137,8 +131,7 @@ export class R2Bucket extends Resource(
|
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
const result = (await getResponse.json()) as CloudflareBucketResponse;
|
|
140
|
-
bucketOutput = {
|
|
141
|
-
id: result.result.name,
|
|
134
|
+
bucketOutput = this({
|
|
142
135
|
name: result.result.name,
|
|
143
136
|
location: result.result.location || "default",
|
|
144
137
|
creationDate: Math.floor(
|
|
@@ -146,7 +139,7 @@ export class R2Bucket extends Resource(
|
|
|
146
139
|
),
|
|
147
140
|
jurisdiction: props.jurisdiction || "default",
|
|
148
141
|
type: "r2_bucket",
|
|
149
|
-
};
|
|
142
|
+
});
|
|
150
143
|
|
|
151
144
|
// Update public access setting if it has changed
|
|
152
145
|
if (props.allowPublicAccess !== undefined) {
|
|
@@ -184,8 +177,7 @@ export class R2Bucket extends Resource(
|
|
|
184
177
|
|
|
185
178
|
const result =
|
|
186
179
|
(await createResponse.json()) as CloudflareBucketResponse;
|
|
187
|
-
bucketOutput = {
|
|
188
|
-
id: result.result.name,
|
|
180
|
+
bucketOutput = this({
|
|
189
181
|
name: result.result.name,
|
|
190
182
|
location: result.result.location || "default",
|
|
191
183
|
creationDate: Math.floor(
|
|
@@ -193,7 +185,7 @@ export class R2Bucket extends Resource(
|
|
|
193
185
|
),
|
|
194
186
|
jurisdiction: props.jurisdiction || "default",
|
|
195
187
|
type: "r2_bucket",
|
|
196
|
-
};
|
|
188
|
+
});
|
|
197
189
|
|
|
198
190
|
// Set public access if requested
|
|
199
191
|
if (props.allowPublicAccess) {
|
|
@@ -208,7 +200,7 @@ export class R2Bucket extends Resource(
|
|
|
208
200
|
}
|
|
209
201
|
}
|
|
210
202
|
},
|
|
211
|
-
)
|
|
203
|
+
);
|
|
212
204
|
|
|
213
205
|
/**
|
|
214
206
|
* Helper function to update the public access setting for a bucket
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { Resolved } from "../output";
|
|
2
|
-
|
|
3
1
|
export interface DurableObjectNamespaceInput {
|
|
4
2
|
className: string;
|
|
5
3
|
scriptName?: string | undefined;
|
|
@@ -8,14 +6,6 @@ export interface DurableObjectNamespaceInput {
|
|
|
8
6
|
namespaceId?: string | undefined;
|
|
9
7
|
}
|
|
10
8
|
|
|
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
9
|
export class DurableObjectNamespace implements DurableObjectNamespaceInput {
|
|
20
10
|
public readonly type = "durable_object_namespace" as const;
|
|
21
11
|
// alias for bindingName to be consistent with other bindings
|
|
@@ -2,7 +2,7 @@ import crypto from "crypto";
|
|
|
2
2
|
import { promises as fs } from "fs";
|
|
3
3
|
import { glob } from "glob";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { getContentType } from "../
|
|
5
|
+
import { getContentType } from "../util/content-type";
|
|
6
6
|
import type {
|
|
7
7
|
AssetManifest,
|
|
8
8
|
AssetManifestEntry,
|