@lafken/bucket 0.10.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.
Files changed (37) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +259 -0
  3. package/lib/index.d.ts +3 -0
  4. package/lib/index.js +19 -0
  5. package/lib/main/bucket/bucket.d.ts +30 -0
  6. package/lib/main/bucket/bucket.js +40 -0
  7. package/lib/main/bucket/bucket.types.d.ts +237 -0
  8. package/lib/main/bucket/bucket.types.js +8 -0
  9. package/lib/main/bucket/index.d.ts +2 -0
  10. package/lib/main/bucket/index.js +18 -0
  11. package/lib/main/index.d.ts +1 -0
  12. package/lib/main/index.js +17 -0
  13. package/lib/resolver/bucket/bucket.types.d.ts +10 -0
  14. package/lib/resolver/bucket/bucket.types.js +2 -0
  15. package/lib/resolver/bucket/external/external.d.ts +14 -0
  16. package/lib/resolver/bucket/external/external.js +15 -0
  17. package/lib/resolver/bucket/internal/internal.d.ts +14 -0
  18. package/lib/resolver/bucket/internal/internal.js +94 -0
  19. package/lib/resolver/index.d.ts +1 -0
  20. package/lib/resolver/index.js +17 -0
  21. package/lib/resolver/resolver.d.ts +14 -0
  22. package/lib/resolver/resolver.js +52 -0
  23. package/lib/resolver/resolver.types.d.ts +13 -0
  24. package/lib/resolver/resolver.types.js +2 -0
  25. package/lib/service/client/client.d.ts +3 -0
  26. package/lib/service/client/client.js +10 -0
  27. package/lib/service/index.d.ts +1 -0
  28. package/lib/service/index.js +17 -0
  29. package/lib/service/repository/index.d.ts +3 -0
  30. package/lib/service/repository/index.js +19 -0
  31. package/lib/service/repository/repository.d.ts +3 -0
  32. package/lib/service/repository/repository.js +62 -0
  33. package/lib/service/repository/repository.types.d.ts +13 -0
  34. package/lib/service/repository/repository.types.js +2 -0
  35. package/lib/service/repository/repository.utils.d.ts +2 -0
  36. package/lib/service/repository/repository.utils.js +9 -0
  37. package/package.json +96 -0
package/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aníbal Emilio Jorquera Cornejo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # @lafken/bucket
2
+
3
+ Define and manage Amazon S3 buckets using TypeScript decorators. `@lafken/bucket` lets you declare bucket configuration — versioning, ACL, lifecycle rules, transfer acceleration, and EventBridge integration — directly on a class. A built-in repository provides type-safe S3 operations at runtime.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @lafken/bucket
9
+ ```
10
+
11
+ ## Getting Started
12
+
13
+ Define a bucket class with `@Bucket`, register it in the `BucketResolver`, and use `createRepository` to interact with it:
14
+
15
+ ```typescript
16
+ import { createApp } from '@lafken/main';
17
+ import { BucketResolver } from '@lafken/bucket/resolver';
18
+ import { Bucket } from '@lafken/bucket/main';
19
+ import { createRepository } from '@lafken/bucket/service';
20
+
21
+ // 1. Define the bucket
22
+ @Bucket({ name: 'project-assets', versioned: true })
23
+ export class AssetsBucket {}
24
+
25
+ // 2. Create a repository for runtime operations
26
+ export const assetsRepository = createRepository(AssetsBucket);
27
+
28
+ // 3. Register the bucket in the resolver
29
+ createApp({
30
+ name: 'my-app',
31
+ resolvers: [new BucketResolver([AssetsBucket])],
32
+ });
33
+ ```
34
+
35
+ ## Features
36
+
37
+ ### Defining a Bucket
38
+
39
+ Use the `@Bucket` decorator on a class to declare an S3 bucket. If `name` is omitted, the class name is used:
40
+
41
+ ```typescript
42
+ import { Bucket } from '@lafken/bucket/main';
43
+
44
+ @Bucket({
45
+ name: 'upload-storage',
46
+ versioned: true,
47
+ acl: 'private',
48
+ forceDestroy: true,
49
+ tags: { environment: 'production' },
50
+ })
51
+ export class UploadBucket {}
52
+ ```
53
+
54
+ #### Bucket Options
55
+
56
+ | Option | Type | Default | Description |
57
+ | --------------------- | --------------------------------------------- | ------------ | --------------------------------------------------------- |
58
+ | `name` | `string` | class name | S3 bucket name |
59
+ | `versioned` | `boolean` | `false` | Enable object versioning |
60
+ | `acl` | `'private' \| 'public-read' \| 'public-read-write'` | — | Access control list |
61
+ | `forceDestroy` | `boolean` | `false` | Delete all objects when the bucket is destroyed |
62
+ | `eventBridgeEnabled` | `boolean` | `false` | Send bucket events to Amazon EventBridge |
63
+ | `transferAcceleration`| `boolean` | `false` | Enable CloudFront-based transfer acceleration |
64
+ | `tracing` | `boolean` | `false` | Enable AWS X-Ray tracing on repository operations |
65
+ | `tags` | `Record<string, string>` | — | Tags applied to the bucket resource |
66
+ | `lifeCycleRules` | `Record<string, KeyLifeCycleRule>` | — | Object lifecycle management rules |
67
+
68
+ ### Lifecycle Rules
69
+
70
+ Define rules to automatically transition or expire objects based on age and size. Each key in `lifeCycleRules` represents an object prefix filter:
71
+
72
+ ```typescript
73
+ @Bucket({
74
+ name: 'log-archive',
75
+ lifeCycleRules: {
76
+ 'logs/': {
77
+ condition: {
78
+ objectSizeGreaterThan: 1024,
79
+ },
80
+ expiration: {
81
+ days: 90,
82
+ },
83
+ transitions: [
84
+ { days: 30, storage: 'standard_ia' },
85
+ { days: 60, storage: 'glacier' },
86
+ ],
87
+ },
88
+ 'tmp/': {
89
+ expiration: {
90
+ days: 7,
91
+ },
92
+ },
93
+ },
94
+ })
95
+ export class LogBucket {}
96
+ ```
97
+
98
+ #### Expiration Options
99
+
100
+ | Option | Type | Description |
101
+ | ---------------------------- | --------- | ------------------------------------------------- |
102
+ | `days` | `number` | Delete objects after this many days |
103
+ | `date` | `Date` | Delete objects after a specific date |
104
+ | `expiredObjectDeleteMarker` | `boolean` | Remove expired object delete markers |
105
+
106
+ > [!NOTE]
107
+ > Only one expiration option can be set per rule.
108
+
109
+ #### Condition Options
110
+
111
+ | Option | Type | Description |
112
+ | ------------------------ | -------- | --------------------------------------------- |
113
+ | `objectSizeGreaterThan` | `number` | Apply rule only to objects larger than (bytes) |
114
+ | `objectSizeLessThan` | `number` | Apply rule only to objects smaller than (bytes)|
115
+
116
+ #### Available Storage Classes
117
+
118
+ | Storage Class | Description |
119
+ | ---------------------- | ------------------------------------------------ |
120
+ | `standard_ia` | Infrequent access, lower cost |
121
+ | `onezone_ia` | Single-AZ infrequent access |
122
+ | `intelligent_tiering` | Automatic cost optimization by access patterns |
123
+ | `glacier` | Long-term archive (minutes to hours retrieval) |
124
+ | `glacier_ir` | Instant retrieval archive |
125
+ | `deep_archive` | Lowest cost (12+ hours retrieval) |
126
+
127
+ ### EventBridge Integration
128
+
129
+ Enable `eventBridgeEnabled` to send bucket events (object created, deleted, etc.) to Amazon EventBridge. Combine with `@lafken/event` to process these events:
130
+
131
+ ```typescript
132
+ @Bucket({
133
+ name: 'document-uploads',
134
+ eventBridgeEnabled: true,
135
+ })
136
+ export class DocumentBucket {}
137
+ ```
138
+
139
+ ### Repository
140
+
141
+ `createRepository` provides a type-safe API for S3 operations at runtime. The bucket name is automatically injected into every command:
142
+
143
+ ```typescript
144
+ import { createRepository } from '@lafken/bucket/service';
145
+
146
+ export const docsRepository = createRepository(DocumentBucket);
147
+ ```
148
+
149
+ #### Put Object
150
+
151
+ Upload an object to the bucket:
152
+
153
+ ```typescript
154
+ await docsRepository.putObject({
155
+ Key: 'reports/monthly.json',
156
+ Body: JSON.stringify({ revenue: 50000 }),
157
+ ContentType: 'application/json',
158
+ });
159
+ ```
160
+
161
+ #### Get Object
162
+
163
+ Retrieve an object from the bucket:
164
+
165
+ ```typescript
166
+ const response = await docsRepository.getObject({
167
+ Key: 'reports/monthly.json',
168
+ });
169
+
170
+ const body = await response.Body?.transformToString();
171
+ ```
172
+
173
+ #### Delete Object
174
+
175
+ Remove an object from the bucket:
176
+
177
+ ```typescript
178
+ await docsRepository.deleteObject({
179
+ Key: 'reports/old-report.json',
180
+ });
181
+ ```
182
+
183
+ #### Copy Object
184
+
185
+ Copy an object within or across buckets:
186
+
187
+ ```typescript
188
+ await docsRepository.copyObject({
189
+ Key: 'archive/monthly.json',
190
+ CopySource: 'document-uploads/reports/monthly.json',
191
+ });
192
+ ```
193
+
194
+ #### Move Object
195
+
196
+ Copy an object to a new key and delete the original in a single operation:
197
+
198
+ ```typescript
199
+ await docsRepository.moveObject({
200
+ Key: 'processed/monthly.json',
201
+ CopySource: 'document-uploads/reports/monthly.json',
202
+ });
203
+ ```
204
+
205
+ #### List Objects
206
+
207
+ List all objects matching a prefix. Pagination is handled automatically:
208
+
209
+ ```typescript
210
+ const result = await docsRepository.listObjects({
211
+ Prefix: 'reports/',
212
+ });
213
+
214
+ for (const object of result.Contents) {
215
+ console.log(object.Key, object.Size);
216
+ }
217
+ ```
218
+
219
+ ### X-Ray Tracing
220
+
221
+ Enable `tracing` in the `@Bucket` decorator to instrument all repository operations with AWS X-Ray:
222
+
223
+ ```typescript
224
+ @Bucket({
225
+ name: 'traced-bucket',
226
+ tracing: true,
227
+ })
228
+ export class TracedBucket {}
229
+ ```
230
+
231
+ ### Global Configuration
232
+
233
+ The `BucketResolver` accepts a second argument with global defaults applied to all buckets. Per-bucket options override global ones:
234
+
235
+ ```typescript
236
+ new BucketResolver(
237
+ [AssetsBucket, LogBucket],
238
+ {
239
+ forceDestroy: true,
240
+ versioned: true,
241
+ tags: { team: 'platform' },
242
+ }
243
+ );
244
+ ```
245
+
246
+ ### Extending Buckets
247
+
248
+ Apply advanced CDKTN configuration to a bucket using the `extends` callback:
249
+
250
+ ```typescript
251
+ new BucketResolver([
252
+ {
253
+ bucket: AssetsBucket,
254
+ extends: ({ bucket, scope }) => {
255
+ // Add CORS rules, policies, or any CDKTN construct
256
+ },
257
+ },
258
+ ]);
259
+ ```
package/lib/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './main';
2
+ export * from './resolver';
3
+ export * from './service';
package/lib/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./main"), exports);
18
+ __exportStar(require("./resolver"), exports);
19
+ __exportStar(require("./service"), exports);
@@ -0,0 +1,30 @@
1
+ import { type BucketProps } from './bucket.types';
2
+ /**
3
+ * Class decorator that registers a class as an S3 bucket resource.
4
+ *
5
+ * The decorated class represents an Amazon S3 bucket and its configuration.
6
+ * Options such as versioning, lifecycle rules, ACL, transfer acceleration,
7
+ * and EventBridge integration can be set through the decorator props.
8
+ *
9
+ * @param props - Optional bucket configuration. If omitted, defaults are used
10
+ * and the class name becomes the bucket resource name.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * @Bucket({ versioned: true, acl: 'private' })
15
+ * export class UserUploadsBucket {}
16
+ * ```
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * @Bucket({
21
+ * lifeCycleRules: {
22
+ * 'tmp/': {
23
+ * expiration: { days: 7 },
24
+ * },
25
+ * },
26
+ * })
27
+ * export class TempFilesBucket {}
28
+ * ```
29
+ */
30
+ export declare const Bucket: (props?: BucketProps) => (target: Function) => void;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Bucket = void 0;
4
+ const bucket_types_1 = require("./bucket.types");
5
+ /**
6
+ * Class decorator that registers a class as an S3 bucket resource.
7
+ *
8
+ * The decorated class represents an Amazon S3 bucket and its configuration.
9
+ * Options such as versioning, lifecycle rules, ACL, transfer acceleration,
10
+ * and EventBridge integration can be set through the decorator props.
11
+ *
12
+ * @param props - Optional bucket configuration. If omitted, defaults are used
13
+ * and the class name becomes the bucket resource name.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * @Bucket({ versioned: true, acl: 'private' })
18
+ * export class UserUploadsBucket {}
19
+ * ```
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * @Bucket({
24
+ * lifeCycleRules: {
25
+ * 'tmp/': {
26
+ * expiration: { days: 7 },
27
+ * },
28
+ * },
29
+ * })
30
+ * export class TempFilesBucket {}
31
+ * ```
32
+ */
33
+ const Bucket = (props = {}) => (target) => {
34
+ const { name = target.name } = props;
35
+ Reflect.defineMetadata(bucket_types_1.BucketMetadataKeys.bucket, {
36
+ name,
37
+ ...props,
38
+ }, target);
39
+ };
40
+ exports.Bucket = Bucket;
@@ -0,0 +1,237 @@
1
+ import type { BucketNames, OnlyOne, ResourceOutputType } from '@lafken/common';
2
+ import 'reflect-metadata';
3
+ export declare enum BucketMetadataKeys {
4
+ bucket = "s3:bucket"
5
+ }
6
+ export type TransitionStorage = 'glacier' | 'standard_ia' | 'onezone_ia' | 'intelligent_tiering' | 'deep_archive' | 'glacier_ir';
7
+ export type BucketOutputAttributes = 'id' | 'arn' | 'bucketDomainName' | 'bucketRegionalDomainName';
8
+ export interface Transition {
9
+ /**
10
+ * Target storage class for the transition.
11
+ *
12
+ * This defines the S3 storage class to which the objects will be moved.
13
+ */
14
+ storage: TransitionStorage;
15
+ /**
16
+ * Number of days after object creation when the transition occurs.
17
+ *
18
+ * The object will be moved to the specified storage class after this
19
+ * number of days.
20
+ */
21
+ days: number;
22
+ }
23
+ export interface Expiration {
24
+ days?: number;
25
+ date?: Date;
26
+ expiredObjectDeleteMarker?: boolean;
27
+ }
28
+ export interface KeyLifeCycleRule {
29
+ /**
30
+ * Defines the expiration configuration for objects stored in the S3 bucket.
31
+ *
32
+ * This property specifies when the objects that match the lifecycle rule
33
+ * should be automatically deleted by Amazon S3.
34
+ * @example
35
+ * ```
36
+ * // one of
37
+ * {
38
+ * expiration: {
39
+ * days: 10
40
+ * }
41
+ * }
42
+ * // or
43
+ * {
44
+ * expiration: {
45
+ * date: new Date()
46
+ * }
47
+ * }
48
+ * // or
49
+ * {
50
+ * expiration: {
51
+ * expiredObjectDeleteMarker: true
52
+ * }
53
+ * }
54
+ * ```
55
+ */
56
+ expiration?: OnlyOne<Expiration>;
57
+ /**
58
+ * Optional conditions to apply the lifecycle rule only to objects
59
+ * that match certain size thresholds.
60
+ *
61
+ * @example
62
+ * ```
63
+ * {
64
+ * condition: {
65
+ * objectSizeGreaterThan: 10000,
66
+ * objectSizeLessThan: 100
67
+ * }
68
+ * }
69
+ * ```
70
+ */
71
+ condition?: {
72
+ /**
73
+ * Minimum object size in bytes for the lifecycle rule to apply.
74
+ *
75
+ * The rule will only apply to objects larger than this value.
76
+ */
77
+ objectSizeGreaterThan?: number;
78
+ /**
79
+ * Maximum object size in bytes for the lifecycle rule to apply.
80
+ *
81
+ * The rule will only apply to objects smaller than this value.
82
+ */
83
+ objectSizeLessThan?: number;
84
+ };
85
+ /**
86
+ * Transition rules that define how and when objects are moved
87
+ * to different S3 storage classes (e.g., GLACIER, INTELLIGENT_TIERING).
88
+ *
89
+ * @example
90
+ * ```
91
+ * {
92
+ * transitions: [
93
+ * {
94
+ * storage: 'standard_ia'
95
+ * days: 10,
96
+ * }
97
+ * ]
98
+ * }
99
+ * ```
100
+ */
101
+ transitions?: Transition[];
102
+ }
103
+ export interface BaseBucketProps {
104
+ /**
105
+ * Bucket resource name.
106
+ *
107
+ * Defines the logical name of the bucket resource.
108
+ * If not specified, the name of the decorated class will be used.
109
+ */
110
+ name?: BucketNames;
111
+ /**
112
+ * Enable X-Ray tracing.
113
+ *
114
+ * When enabled, AWS X-Ray tracing is activated for the bucket-related
115
+ * operations. This allows you to trace and analyze requests as they
116
+ * pass through AWS services, useful for debugging and performance
117
+ * monitoring.
118
+ */
119
+ tracing?: boolean;
120
+ }
121
+ export interface InternalBucketProps extends BaseBucketProps {
122
+ isExternal?: never;
123
+ /**
124
+ * Enable EventBridge events.
125
+ *
126
+ * When enabled, Amazon S3 automatically sends events for this bucket
127
+ * to Amazon EventBridge. This allows you to capture S3 bucket events
128
+ * (such as object created, deleted, etc.).
129
+ */
130
+ eventBridgeEnabled?: boolean;
131
+ /**
132
+ * Defines the Access Control List (ACL) configuration for the S3 bucket.
133
+ *
134
+ * This property determines the default access level applied to all objects
135
+ * within the bucket unless overridden at the object level.
136
+ *
137
+ * - `'private'`: Grants access only to the bucket owner. This is the most secure option
138
+ * and the default behavior in most cases.
139
+ * - `'public-read'`: Allows anyone on the internet to read objects in the bucket,
140
+ * but only the bucket owner can write or modify them.
141
+ * - `'public-read-write'`: Grants both read and write access to everyone.
142
+ * This setting is **not recommended** for production use, as it exposes your bucket
143
+ * to public writes and potential misuse.
144
+ */
145
+ acl?: 'private' | 'public-read' | 'public-read-write';
146
+ /**
147
+ * Enable transfer acceleration for the S3 bucket.
148
+ *
149
+ * Transfer acceleration leverages Amazon CloudFront's globally distributed
150
+ * edge locations to accelerate data transfers between clients and the bucket.
151
+ * This reduces latency and improves throughput, particularly when
152
+ * users are geographically distant from the bucket's AWS region.
153
+ */
154
+ transferAcceleration?: boolean;
155
+ /**
156
+ * Enable versioning for the S3 bucket.
157
+ *
158
+ * When enabled, the bucket keeps multiple versions of an object,
159
+ * allowing recovery from accidental overwrites or deletions.
160
+ * Versioning provides a safeguard for data protection and
161
+ * can also be used for auditing and historical tracking.
162
+ */
163
+ versioned?: boolean;
164
+ /**
165
+ * Lifecycle rules for the S3 bucket.
166
+ *
167
+ * Defines rules to automatically manage the lifecycle of objects in the bucket,
168
+ * such as transitioning them to different storage classes, expiring them after
169
+ * a given time, or cleaning up incomplete multipart uploads.
170
+ *
171
+ * @example
172
+ * ```
173
+ * {
174
+ * lifeCycleRules: {
175
+ * 'key-path': { // represents an object in the bucket
176
+ * expiration: {
177
+ * days: 20,
178
+ * },
179
+ * condition: {
180
+ * objectSizeGreaterThan: 2024 // value in bytes
181
+ * }
182
+ * }
183
+ * }
184
+ * }
185
+ * ```
186
+ */
187
+ lifeCycleRules?: Record<string, KeyLifeCycleRule>;
188
+ /**
189
+ * Indicates all objects from bucket should be deleted when bucket is destroyed
190
+ */
191
+ forceDestroy?: boolean;
192
+ /**
193
+ * tags.
194
+ *
195
+ * Specifies a set of tags that will be applied to s3 bucket.
196
+ */
197
+ tags?: Record<string, string>;
198
+ /**
199
+ * Defines which S3 Bucket attributes should be exported.
200
+ *
201
+ * Supported attributes are based on Terraform `aws_s3_bucket`
202
+ * exported attributes and currently include:
203
+ * - `id`: Name of the bucket.
204
+ * - `arn`: ARN of the bucket (`arn:aws:s3:::bucketname`).
205
+ * - `bucketDomainName`: Bucket domain name (`bucketname.s3.amazonaws.com`).
206
+ * - `bucketRegionalDomainName`: Region-specific bucket domain name.
207
+ *
208
+ * Each selected attribute can be exported through SSM Parameter Store (`type: 'ssm'`)
209
+ * or Terraform outputs (`type: 'output'`).
210
+ *
211
+ * @example
212
+ * {
213
+ * outputs: [
214
+ * { type: 'ssm', name: '/my-bucket/arn', value: 'arn' },
215
+ * { type: 'output', name: 'bucket_regional_domain', value: 'bucketRegionalDomainName' }
216
+ * ]
217
+ * }
218
+ */
219
+ outputs?: ResourceOutputType<BucketOutputAttributes>;
220
+ }
221
+ export interface ExternalBucketProps extends BaseBucketProps {
222
+ /**
223
+ * Marks the bucket as an external resource.
224
+ *
225
+ * When set to `true`, the bucket is not created by the framework.
226
+ * Instead, it references an existing S3 bucket using the provided `name`.
227
+ */
228
+ isExternal: true;
229
+ }
230
+ export type BucketProps = InternalBucketProps | ExternalBucketProps;
231
+ export interface InternalBucketMetadataProps extends Omit<InternalBucketProps, 'name'> {
232
+ name: string;
233
+ }
234
+ export interface ExternalBucketMetadataProps extends Omit<ExternalBucketProps, 'name'> {
235
+ name: string;
236
+ }
237
+ export type BucketMetadata = InternalBucketMetadataProps | ExternalBucketMetadataProps;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BucketMetadataKeys = void 0;
4
+ require("reflect-metadata");
5
+ var BucketMetadataKeys;
6
+ (function (BucketMetadataKeys) {
7
+ BucketMetadataKeys["bucket"] = "s3:bucket";
8
+ })(BucketMetadataKeys || (exports.BucketMetadataKeys = BucketMetadataKeys = {}));
@@ -0,0 +1,2 @@
1
+ export * from './bucket';
2
+ export * from './bucket.types';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./bucket"), exports);
18
+ __exportStar(require("./bucket.types"), exports);
@@ -0,0 +1 @@
1
+ export * from './bucket';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./bucket"), exports);
@@ -0,0 +1,10 @@
1
+ import type { ClassResource } from '@lafken/common';
2
+ import type { InternalBucketProps as MainInternalBucketProps } from '../../main';
3
+ export interface BucketGlobalConfig extends Omit<MainInternalBucketProps, 'name' | 'tracing'> {
4
+ }
5
+ export interface InternalBucketProps extends BucketGlobalConfig {
6
+ classResource: ClassResource;
7
+ }
8
+ export interface ExternalBucketProps {
9
+ classResource: ClassResource;
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ import { DataAwsS3Bucket } from '@cdktn/provider-aws/lib/data-aws-s3-bucket';
2
+ import type { Construct } from 'constructs';
3
+ import type { ExternalBucketMetadataProps } from '../../../main';
4
+ declare const ExternalBucket_base: (new (...args: any[]) => {
5
+ isGlobal(module: import("@lafken/common").ModuleGlobalReferenceNames | (string & {}), id: string): void;
6
+ isDependent(resolveDependency: () => void): void;
7
+ readonly node: import("constructs").Node;
8
+ with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
9
+ toString(): string;
10
+ }) & typeof DataAwsS3Bucket;
11
+ export declare class ExternalBucket extends ExternalBucket_base {
12
+ constructor(scope: Construct, props: ExternalBucketMetadataProps);
13
+ }
14
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExternalBucket = void 0;
4
+ const data_aws_s3_bucket_1 = require("@cdktn/provider-aws/lib/data-aws-s3-bucket");
5
+ const resolver_1 = require("@lafken/resolver");
6
+ class ExternalBucket extends resolver_1.lafkenResource.make(data_aws_s3_bucket_1.DataAwsS3Bucket) {
7
+ constructor(scope, props) {
8
+ const { name } = props;
9
+ super(scope, `${name}-bucket`, {
10
+ bucket: name,
11
+ });
12
+ this.isGlobal('bucket', name);
13
+ }
14
+ }
15
+ exports.ExternalBucket = ExternalBucket;
@@ -0,0 +1,14 @@
1
+ import { S3Bucket } from '@cdktn/provider-aws/lib/s3-bucket';
2
+ import type { Construct } from 'constructs';
3
+ import type { InternalBucketMetadataProps } from '../../../main';
4
+ declare const InternalBucket_base: (new (...args: any[]) => {
5
+ isGlobal(module: import("@lafken/common").ModuleGlobalReferenceNames | (string & {}), id: string): void;
6
+ isDependent(resolveDependency: () => void): void;
7
+ readonly node: import("constructs").Node;
8
+ with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
9
+ toString(): string;
10
+ }) & typeof S3Bucket;
11
+ export declare class InternalBucket extends InternalBucket_base {
12
+ constructor(scope: Construct, props: InternalBucketMetadataProps);
13
+ }
14
+ export {};
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InternalBucket = void 0;
4
+ const s3_bucket_1 = require("@cdktn/provider-aws/lib/s3-bucket");
5
+ const s3_bucket_accelerate_configuration_1 = require("@cdktn/provider-aws/lib/s3-bucket-accelerate-configuration");
6
+ const s3_bucket_acl_1 = require("@cdktn/provider-aws/lib/s3-bucket-acl");
7
+ const s3_bucket_lifecycle_configuration_1 = require("@cdktn/provider-aws/lib/s3-bucket-lifecycle-configuration");
8
+ const s3_bucket_notification_1 = require("@cdktn/provider-aws/lib/s3-bucket-notification");
9
+ const s3_bucket_versioning_1 = require("@cdktn/provider-aws/lib/s3-bucket-versioning");
10
+ const common_1 = require("@lafken/common");
11
+ const resolver_1 = require("@lafken/resolver");
12
+ class InternalBucket extends resolver_1.lafkenResource.make(s3_bucket_1.S3Bucket) {
13
+ constructor(scope, props) {
14
+ const { name, eventBridgeEnabled, acl, forceDestroy, transferAcceleration, versioned, lifeCycleRules, tags, } = props;
15
+ super(scope, `${name}-bucket`, {
16
+ bucket: name,
17
+ forceDestroy: forceDestroy ?? props.forceDestroy,
18
+ tags: tags ?? {
19
+ ...(tags || {}),
20
+ ...(props.tags || {}),
21
+ },
22
+ });
23
+ this.isGlobal('bucket', name);
24
+ if (eventBridgeEnabled ?? props.eventBridgeEnabled) {
25
+ new s3_bucket_notification_1.S3BucketNotification(this, `${name}-notification`, {
26
+ bucket: this.id,
27
+ eventbridge: true,
28
+ });
29
+ }
30
+ if (acl || props.acl) {
31
+ new s3_bucket_acl_1.S3BucketAcl(this, `${name}-acl`, {
32
+ bucket: this.id,
33
+ acl: acl || props.acl,
34
+ });
35
+ }
36
+ if (versioned ?? props.versioned) {
37
+ new s3_bucket_versioning_1.S3BucketVersioningA(this, `${name}-versioned`, {
38
+ bucket: this.id,
39
+ versioningConfiguration: {
40
+ status: 'Enabled',
41
+ },
42
+ });
43
+ }
44
+ if (transferAcceleration ?? props.transferAcceleration) {
45
+ new s3_bucket_accelerate_configuration_1.S3BucketAccelerateConfiguration(this, `${name}-accelerate-config`, {
46
+ bucket: this.id,
47
+ status: 'Enabled',
48
+ });
49
+ }
50
+ const lifeCycle = lifeCycleRules || props.lifeCycleRules || {};
51
+ if (Object.keys(lifeCycle).length > 0) {
52
+ new s3_bucket_lifecycle_configuration_1.S3BucketLifecycleConfiguration(this, `${name}-lifecycle`, {
53
+ bucket: this.id,
54
+ rule: Object.keys(lifeCycle).map((key) => {
55
+ const rule = lifeCycle[key];
56
+ return {
57
+ id: `${name}-lc-rule-${(0, common_1.cleanString)(key)}`,
58
+ status: 'Enabled',
59
+ filter: [
60
+ {
61
+ prefix: key,
62
+ objectSizeGreaterThan: rule.condition?.objectSizeGreaterThan,
63
+ objectSizeLessThan: rule.condition?.objectSizeLessThan,
64
+ },
65
+ ],
66
+ expiration: rule.expiration
67
+ ? [
68
+ {
69
+ days: rule.expiration.days,
70
+ date: rule.expiration.date
71
+ ? rule.expiration.date
72
+ .toLocaleDateString('en-GB', {
73
+ day: '2-digit',
74
+ month: '2-digit',
75
+ year: 'numeric',
76
+ })
77
+ .replace(/\//g, '-')
78
+ : undefined,
79
+ expiredObjectDeleteMarker: rule.expiration.expiredObjectDeleteMarker,
80
+ },
81
+ ]
82
+ : undefined,
83
+ transition: (rule.transitions || []).map((transition) => ({
84
+ days: transition.days,
85
+ storageClass: transition.storage,
86
+ })),
87
+ };
88
+ }),
89
+ });
90
+ }
91
+ new resolver_1.ResourceOutput(this, props.outputs);
92
+ }
93
+ }
94
+ exports.InternalBucket = InternalBucket;
@@ -0,0 +1 @@
1
+ export * from './resolver';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./resolver"), exports);
@@ -0,0 +1,14 @@
1
+ import type { ClassResource } from '@lafken/common';
2
+ import type { AppModule, AppStack, ResolverType } from '@lafken/resolver';
3
+ import type { BucketGlobalConfig } from './bucket/bucket.types';
4
+ import type { ClassResourceExtends } from './resolver.types';
5
+ export declare class BucketResolver implements ResolverType {
6
+ private buckets;
7
+ private config;
8
+ type: string;
9
+ private extensibleBuckets;
10
+ constructor(buckets: (ClassResource | ClassResourceExtends)[], config?: BucketGlobalConfig);
11
+ beforeCreate(scope: AppModule): void;
12
+ create(): void;
13
+ afterCreate(scope: AppStack): void;
14
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BucketResolver = void 0;
4
+ const main_1 = require("../main");
5
+ const external_1 = require("./bucket/external/external");
6
+ const internal_1 = require("./bucket/internal/internal");
7
+ class BucketResolver {
8
+ buckets;
9
+ config;
10
+ type = 'BUCKET';
11
+ extensibleBuckets = [];
12
+ constructor(buckets, config = {}) {
13
+ this.buckets = buckets;
14
+ this.config = config;
15
+ }
16
+ beforeCreate(scope) {
17
+ for (const bucket of this.buckets) {
18
+ const isExtensible = 'bucket' in bucket;
19
+ const bucketProps = Reflect.getMetadata(main_1.BucketMetadataKeys.bucket, isExtensible ? bucket.bucket : bucket);
20
+ let bucketResource;
21
+ if (bucketProps.isExternal) {
22
+ bucketResource = new external_1.ExternalBucket(scope, {
23
+ ...bucketProps,
24
+ });
25
+ }
26
+ else {
27
+ bucketResource = new internal_1.InternalBucket(scope, {
28
+ ...bucketProps,
29
+ ...this.config,
30
+ });
31
+ }
32
+ if (isExtensible) {
33
+ this.extensibleBuckets.push({
34
+ bucket: bucketResource,
35
+ extends: bucket.extends,
36
+ });
37
+ }
38
+ }
39
+ }
40
+ create() {
41
+ throw new Error('It is not possible to parse this service');
42
+ }
43
+ afterCreate(scope) {
44
+ for (const extendBucket of this.extensibleBuckets) {
45
+ extendBucket.extends({
46
+ scope,
47
+ bucket: extendBucket.bucket,
48
+ });
49
+ }
50
+ }
51
+ }
52
+ exports.BucketResolver = BucketResolver;
@@ -0,0 +1,13 @@
1
+ import type { DataAwsS3Bucket } from '@cdktn/provider-aws/lib/data-aws-s3-bucket';
2
+ import type { S3Bucket } from '@cdktn/provider-aws/lib/s3-bucket';
3
+ import type { ClassResource } from '@lafken/common';
4
+ import type { AppStack } from '@lafken/resolver';
5
+ interface ExtendProps {
6
+ scope: AppStack;
7
+ bucket: S3Bucket | DataAwsS3Bucket;
8
+ }
9
+ export interface ClassResourceExtends {
10
+ bucket: ClassResource;
11
+ extends: (props: ExtendProps) => void;
12
+ }
13
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ import { S3Client } from '@aws-sdk/client-s3';
2
+ export declare const client: S3Client;
3
+ export declare const getClientWithXRay: () => S3Client;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getClientWithXRay = exports.client = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const aws_xray_sdk_1 = require("aws-xray-sdk");
6
+ exports.client = new client_s3_1.S3Client();
7
+ const getClientWithXRay = () => {
8
+ return (0, aws_xray_sdk_1.captureAWSv3Client)(exports.client);
9
+ };
10
+ exports.getClientWithXRay = getClientWithXRay;
@@ -0,0 +1 @@
1
+ export * from './repository';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./repository"), exports);
@@ -0,0 +1,3 @@
1
+ export * from './repository';
2
+ export * from './repository.types';
3
+ export * from './repository.utils';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./repository"), exports);
18
+ __exportStar(require("./repository.types"), exports);
19
+ __exportStar(require("./repository.utils"), exports);
@@ -0,0 +1,3 @@
1
+ import type { ClassResource } from '@lafken/common';
2
+ import type { RepositoryReturn } from './repository.types';
3
+ export declare const createRepository: <E extends ClassResource>(bucket: E) => RepositoryReturn<E>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRepository = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const client_1 = require("../client/client");
6
+ const repository_utils_1 = require("./repository.utils");
7
+ const createRepository = (bucket) => {
8
+ const { name, tracing } = (0, repository_utils_1.getBucketInformation)(bucket);
9
+ const bucketClient = tracing ? (0, client_1.getClientWithXRay)() : client_1.client;
10
+ return {
11
+ putObject(props) {
12
+ const command = new client_s3_1.PutObjectCommand({
13
+ Bucket: name,
14
+ ...props,
15
+ });
16
+ return bucketClient.send(command);
17
+ },
18
+ getObject(props) {
19
+ const command = new client_s3_1.GetObjectCommand({
20
+ Bucket: name,
21
+ ...props,
22
+ });
23
+ return bucketClient.send(command);
24
+ },
25
+ deleteObject(props) {
26
+ const command = new client_s3_1.DeleteObjectCommand({
27
+ Bucket: name,
28
+ ...props,
29
+ });
30
+ return bucketClient.send(command);
31
+ },
32
+ copyObject(props) {
33
+ const command = new client_s3_1.CopyObjectCommand({
34
+ Bucket: name,
35
+ ...props,
36
+ });
37
+ return bucketClient.send(command);
38
+ },
39
+ async moveObject(props) {
40
+ await this.copyObject(props);
41
+ await this.deleteObject({
42
+ Key: props.Key,
43
+ });
44
+ },
45
+ async listObjects(props) {
46
+ let allContents = [];
47
+ let nextToken;
48
+ do {
49
+ const command = new client_s3_1.ListObjectsV2Command({
50
+ Bucket: name,
51
+ ...props,
52
+ ContinuationToken: nextToken,
53
+ });
54
+ const response = await bucketClient.send(command);
55
+ allContents = [...allContents, ...(response.Contents || [])];
56
+ nextToken = response.IsTruncated ? response.ContinuationToken : undefined;
57
+ } while (nextToken);
58
+ return { Contents: allContents };
59
+ },
60
+ };
61
+ };
62
+ exports.createRepository = createRepository;
@@ -0,0 +1,13 @@
1
+ import type { _Object, CopyObjectCommandInput, CopyObjectCommandOutput, DeleteObjectCommandInput, DeleteObjectCommandOutput, GetObjectCommandInput, GetObjectCommandOutput, ListObjectsV2CommandInput, PutObjectCommandInput, PutObjectCommandOutput } from '@aws-sdk/client-s3';
2
+ import type { ClassResource } from '@lafken/common';
3
+ export type InputWithoutBucket<T> = Omit<T, 'Bucket'>;
4
+ export type RepositoryReturn<_E extends ClassResource> = {
5
+ putObject(props: InputWithoutBucket<PutObjectCommandInput>): Promise<PutObjectCommandOutput>;
6
+ getObject(props: InputWithoutBucket<GetObjectCommandInput>): Promise<GetObjectCommandOutput>;
7
+ deleteObject(props: InputWithoutBucket<DeleteObjectCommandInput>): Promise<DeleteObjectCommandOutput>;
8
+ copyObject(props: InputWithoutBucket<CopyObjectCommandInput>): Promise<CopyObjectCommandOutput>;
9
+ moveObject(props: InputWithoutBucket<CopyObjectCommandInput>): Promise<void>;
10
+ listObjects(props: InputWithoutBucket<ListObjectsV2CommandInput>): Promise<{
11
+ Contents: _Object[];
12
+ }>;
13
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { ClassResource } from '@lafken/common';
2
+ export declare const getBucketInformation: <T>(bucket: ClassResource) => T;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBucketInformation = void 0;
4
+ const bucket_1 = require("../../main/bucket");
5
+ const getBucketInformation = (bucket) => {
6
+ const bucketProps = Reflect.getMetadata(bucket_1.BucketMetadataKeys.bucket, bucket);
7
+ return bucketProps;
8
+ };
9
+ exports.getBucketInformation = getBucketInformation;
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@lafken/bucket",
3
+ "version": "0.10.1",
4
+ "private": false,
5
+ "description": "Define S3 buckets using TypeScript decorators - automatic infrastructure generation with Lafken",
6
+ "keywords": [
7
+ "aws",
8
+ "s3",
9
+ "storage",
10
+ "object storage",
11
+ "serverless",
12
+ "typescript",
13
+ "decorators",
14
+ "lafken"
15
+ ],
16
+ "homepage": "https://github.com/Hero64/lafken#readme",
17
+ "bugs": "https://github.com/Hero64/lafken/issues",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/Hero64/lafken",
21
+ "directory": "packages/bucket"
22
+ },
23
+ "license": "MIT",
24
+ "author": "Aníbal Jorquera",
25
+ "exports": {
26
+ "./main": {
27
+ "types": "./lib/main/index.d.ts",
28
+ "import": "./lib/main/index.js",
29
+ "require": "./lib/main/index.js"
30
+ },
31
+ "./service": {
32
+ "types": "./lib/service/index.d.ts",
33
+ "import": "./lib/service/index.js",
34
+ "require": "./lib/service/index.js"
35
+ },
36
+ "./resolver": {
37
+ "types": "./lib/resolver/index.d.ts",
38
+ "import": "./lib/resolver/index.js",
39
+ "require": "./lib/resolver/index.js"
40
+ }
41
+ },
42
+ "typesVersions": {
43
+ "*": {
44
+ "main": [
45
+ "./lib/main/index.d.ts"
46
+ ],
47
+ "service": [
48
+ "./lib/service/index.d.ts"
49
+ ],
50
+ "resolver": [
51
+ "./lib/resolver/index.d.ts"
52
+ ]
53
+ }
54
+ },
55
+ "files": [
56
+ "lib"
57
+ ],
58
+ "dependencies": {
59
+ "aws-xray-sdk": "^3.12.0",
60
+ "reflect-metadata": "^0.2.2",
61
+ "@lafken/resolver": "0.10.1"
62
+ },
63
+ "devDependencies": {
64
+ "@aws-sdk/client-s3": "^3.1020.0",
65
+ "@cdktn/provider-aws": "^23.5.0",
66
+ "@swc/core": "^1.15.21",
67
+ "@swc/helpers": "^0.5.20",
68
+ "@vitest/runner": "^4.1.2",
69
+ "cdktn": "^0.22.1",
70
+ "cdktn-vitest": "^1.0.0",
71
+ "constructs": "^10.6.0",
72
+ "typescript": "6.0.2",
73
+ "unplugin-swc": "^1.5.9",
74
+ "vitest": "^4.1.2",
75
+ "@lafken/common": "0.10.1"
76
+ },
77
+ "peerDependencies": {
78
+ "@cdktn/provider-aws": ">=23.0.0",
79
+ "cdktn": ">=0.22.0",
80
+ "constructs": "^10.4.5",
81
+ "@lafken/common": "0.10.1"
82
+ },
83
+ "engines": {
84
+ "node": ">=20.19"
85
+ },
86
+ "publishConfig": {
87
+ "access": "public"
88
+ },
89
+ "scripts": {
90
+ "build": "pnpm clean && tsc -p ./tsconfig.build.json",
91
+ "check-types": "tsc --noEmit -p ./tsconfig.build.json",
92
+ "clean": "rm -rf ./lib",
93
+ "dev": "tsc -w",
94
+ "test": "vitest"
95
+ }
96
+ }