@russ-b/nestjs-common-tools 1.14.0 → 1.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -11
- package/dist/class-transformer/index.d.ts +1 -1
- package/dist/class-transformer/index.js +1 -1
- package/dist/class-transformer/index.js.map +1 -1
- package/dist/class-transformer/to-boolean-from-string.decorator.d.ts +3 -0
- package/dist/class-transformer/{to-optional-boolean.decorator.js → to-boolean-from-string.decorator.js} +8 -8
- package/dist/class-transformer/to-boolean-from-string.decorator.js.map +1 -0
- package/dist/modules/s3/index.d.ts +1 -0
- package/dist/modules/s3/index.js +1 -0
- package/dist/modules/s3/index.js.map +1 -1
- package/dist/modules/s3/s3.interface.d.ts +14 -1
- package/dist/modules/s3/s3.service.d.ts +5 -1
- package/dist/modules/s3/s3.service.js +58 -2
- package/dist/modules/s3/s3.service.js.map +1 -1
- package/package.json +1 -1
- package/dist/class-transformer/to-optional-boolean.decorator.d.ts +0 -3
- package/dist/class-transformer/to-optional-boolean.decorator.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# nestjs-common-tools
|
|
2
|
-
NestJS Common Tools
|
|
3
2
|
|
|
4
3
|
A small toolbox for NestJS with helpers that often come up in day-to-day development.
|
|
5
4
|
|
|
@@ -15,9 +14,25 @@ npm install @russ-b/nestjs-common-tools
|
|
|
15
14
|
|
|
16
15
|
Depending on which features you use, make sure the relevant peer dependencies are also installed in your project.
|
|
17
16
|
|
|
17
|
+
## Public entrypoints
|
|
18
|
+
|
|
19
|
+
This package uses subpath exports for most features.
|
|
20
|
+
|
|
21
|
+
| Import path | What it contains |
|
|
22
|
+
|-------------|------------------|
|
|
23
|
+
| `@russ-b/nestjs-common-tools` | root exports such as `services` |
|
|
24
|
+
| `@russ-b/nestjs-common-tools/class-transformer` | reusable `class-transformer` decorators and helpers |
|
|
25
|
+
| `@russ-b/nestjs-common-tools/modules` | NestJS modules such as `S3Module` |
|
|
26
|
+
| `@russ-b/nestjs-common-tools/validators` | validation decorators and constraints |
|
|
27
|
+
| `@russ-b/nestjs-common-tools/typeorm` | TypeORM filters, helpers, transformers, and types |
|
|
28
|
+
| `@russ-b/nestjs-common-tools/logger` | logger builder and logger-related interfaces/types |
|
|
29
|
+
| `@russ-b/nestjs-common-tools/common/util` | generic utility helpers |
|
|
30
|
+
| `@russ-b/nestjs-common-tools/common/pagination` | pagination DTOs and helpers |
|
|
31
|
+
| `@russ-b/nestjs-common-tools/common/filters` | shared filter exports |
|
|
32
|
+
|
|
18
33
|
## Class Transformer Helpers
|
|
19
34
|
|
|
20
|
-
This package
|
|
35
|
+
This package also exposes small reusable decorators for `class-transformer`.
|
|
21
36
|
|
|
22
37
|
### `ToStringArray`
|
|
23
38
|
|
|
@@ -37,17 +52,17 @@ It will:
|
|
|
37
52
|
- split string values by comma
|
|
38
53
|
- trim extra spaces around items
|
|
39
54
|
- remove empty values
|
|
40
|
-
-
|
|
55
|
+
- normalize a string like `'cars, bikes, boats'` into `['cars', 'bikes', 'boats']`
|
|
41
56
|
|
|
42
|
-
### `
|
|
57
|
+
### `ToBooleanFromString`
|
|
43
58
|
|
|
44
|
-
`
|
|
59
|
+
`ToBooleanFromString()` is useful for DTO fields that may arrive as `'true'` or `'false'` strings and should become real booleans.
|
|
45
60
|
|
|
46
61
|
```typescript
|
|
47
|
-
import {
|
|
62
|
+
import { ToBooleanFromString } from '@russ-b/nestjs-common-tools/class-transformer';
|
|
48
63
|
|
|
49
64
|
export class SearchDto {
|
|
50
|
-
@
|
|
65
|
+
@ToBooleanFromString()
|
|
51
66
|
archived?: boolean;
|
|
52
67
|
}
|
|
53
68
|
```
|
|
@@ -92,9 +107,8 @@ import { S3Module } from '@russ-b/nestjs-common-tools/modules';
|
|
|
92
107
|
inject: [ConfigService],
|
|
93
108
|
useFactory: (config: ConfigService) => ({
|
|
94
109
|
region: config.get<string>('AWS_REGION') ?? 'eu-central-1',
|
|
95
|
-
|
|
110
|
+
defaultBucket: config.get<string>('S3_BUCKET'),
|
|
96
111
|
endpoint: config.get<string>('S3_ENDPOINT'),
|
|
97
|
-
forcePathStyle: config.get<string>('S3_FORCE_PATH_STYLE') === 'true',
|
|
98
112
|
logger: config.get<string>('S3_DEBUG') === 'true',
|
|
99
113
|
}),
|
|
100
114
|
}),
|
|
@@ -120,8 +134,14 @@ AWS_SECRET_ACCESS_KEY=your-secret-key
|
|
|
120
134
|
S3_BUCKET=my-app-bucket
|
|
121
135
|
```
|
|
122
136
|
|
|
137
|
+
The AWS SDK reads values from process environment, not directly from a `.env` file, so make sure your application loads those variables before creating the client.
|
|
138
|
+
|
|
123
139
|
`endpoint` is optional and is mostly useful for S3-compatible providers such as MinIO or LocalStack.
|
|
124
140
|
|
|
141
|
+
`forcePathStyle` defaults to `true` in this module. That is usually convenient for MinIO and LocalStack. If you want standard AWS virtual-hosted URLs, set `forcePathStyle: false`.
|
|
142
|
+
|
|
143
|
+
`defaultBucket` is the module-level fallback bucket. You can still override it per method call with `options.bucket`.
|
|
144
|
+
|
|
125
145
|
### Optional logging
|
|
126
146
|
|
|
127
147
|
By default, the module stays silent and does not write S3 operation logs.
|
|
@@ -131,7 +151,7 @@ If you want extra visibility while testing connectivity with S3 or MinIO, set `l
|
|
|
131
151
|
```typescript
|
|
132
152
|
S3Module.forRootAsync({
|
|
133
153
|
useFactory: () => ({
|
|
134
|
-
|
|
154
|
+
defaultBucket: 'my-app-bucket',
|
|
135
155
|
endpoint: 'http://localhost:9000',
|
|
136
156
|
forcePathStyle: true,
|
|
137
157
|
logger: true,
|
|
@@ -186,6 +206,17 @@ export class FilesService {
|
|
|
186
206
|
async deleteAvatar(key: string) {
|
|
187
207
|
return this.s3Service.deleteObject(key);
|
|
188
208
|
}
|
|
209
|
+
|
|
210
|
+
async duplicateAvatar(sourceKey: string, destinationKey: string) {
|
|
211
|
+
return this.s3Service.copyObject(sourceKey, destinationKey);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async listAvatars() {
|
|
215
|
+
return this.s3Service.listObjects({
|
|
216
|
+
prefix: 'avatars/',
|
|
217
|
+
maxKeys: 50,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
189
220
|
}
|
|
190
221
|
```
|
|
191
222
|
|
|
@@ -225,10 +256,53 @@ When generating a signed `putObject` URL, make sure the client sends the same he
|
|
|
225
256
|
| `upload(key, body, options)` | Managed upload using `@aws-sdk/lib-storage`, useful for larger or streaming payloads |
|
|
226
257
|
| `getObject(key, options)` | Returns the readable stream together with object metadata |
|
|
227
258
|
| `deleteObject(key, options)` | Deletes an object from the configured bucket |
|
|
259
|
+
| `copyObject(sourceKey, destinationKey, options)` | Copies an object, optionally across buckets |
|
|
260
|
+
| `listObjects(options)` | Lists objects with `prefix`, `maxKeys`, `continuationToken`, and `delimiter` support |
|
|
228
261
|
| `getSignedUrl(key, options)` | Creates a presigned URL for `getObject` or `putObject` |
|
|
229
262
|
|
|
230
263
|
`uploadObject` is still available as a compatibility alias, but `putObject` is the preferred method name going forward.
|
|
231
264
|
|
|
265
|
+
### Inject the raw S3 client
|
|
266
|
+
|
|
267
|
+
If you need lower-level S3 commands that are not covered by `S3Service`, you can inject the configured AWS client directly.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
271
|
+
import {
|
|
272
|
+
DeleteObjectsCommand,
|
|
273
|
+
HeadObjectCommand,
|
|
274
|
+
S3Client,
|
|
275
|
+
} from '@aws-sdk/client-s3';
|
|
276
|
+
import { S3_CLIENT } from '@russ-b/nestjs-common-tools/modules';
|
|
277
|
+
|
|
278
|
+
@Injectable()
|
|
279
|
+
export class CarPhotoService {
|
|
280
|
+
constructor(
|
|
281
|
+
@Inject(S3_CLIENT) private readonly s3Client: S3Client,
|
|
282
|
+
) {}
|
|
283
|
+
|
|
284
|
+
async getPhotoMetadata(key: string) {
|
|
285
|
+
return this.s3Client.send(
|
|
286
|
+
new HeadObjectCommand({
|
|
287
|
+
Bucket: 'car-photos',
|
|
288
|
+
Key: key,
|
|
289
|
+
}),
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async deleteMany(keys: string[]) {
|
|
294
|
+
return this.s3Client.send(
|
|
295
|
+
new DeleteObjectsCommand({
|
|
296
|
+
Bucket: 'car-photos',
|
|
297
|
+
Delete: {
|
|
298
|
+
Objects: keys.map((key) => ({ Key: key })),
|
|
299
|
+
},
|
|
300
|
+
}),
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
232
306
|
## Entity Validator
|
|
233
307
|
|
|
234
308
|
A custom validator for NestJS that validates if an entity exists in the database using TypeORM.
|
|
@@ -239,7 +313,9 @@ A custom validator for NestJS that validates if an entity exists in the database
|
|
|
239
313
|
|
|
240
314
|
```typescript
|
|
241
315
|
// main.ts
|
|
316
|
+
import { NestFactory } from '@nestjs/core';
|
|
242
317
|
import { useContainer } from 'class-validator';
|
|
318
|
+
import { AppModule } from './app.module';
|
|
243
319
|
|
|
244
320
|
async function bootstrap() {
|
|
245
321
|
const app = await NestFactory.create(AppModule);
|
|
@@ -257,7 +333,6 @@ async function bootstrap() {
|
|
|
257
333
|
```typescript
|
|
258
334
|
// app.module.ts
|
|
259
335
|
import { Module } from '@nestjs/common';
|
|
260
|
-
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
261
336
|
import { EntityConstraint } from '@russ-b/nestjs-common-tools/validators';
|
|
262
337
|
|
|
263
338
|
@Module({
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './to-string-array.decorator';
|
|
2
|
-
export * from './to-
|
|
2
|
+
export * from './to-boolean-from-string.decorator';
|
|
@@ -15,5 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./to-string-array.decorator"), exports);
|
|
18
|
-
__exportStar(require("./to-
|
|
18
|
+
__exportStar(require("./to-boolean-from-string.decorator"), exports);
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/class-transformer/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/class-transformer/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA4C;AAC5C,qEAAmD"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.parseBooleanFromStringTransformer = void 0;
|
|
4
|
+
exports.ToBooleanFromString = ToBooleanFromString;
|
|
5
5
|
const class_transformer_1 = require("class-transformer");
|
|
6
|
-
function
|
|
7
|
-
return (0, class_transformer_1.Transform)(exports.
|
|
6
|
+
function ToBooleanFromString() {
|
|
7
|
+
return (0, class_transformer_1.Transform)(exports.parseBooleanFromStringTransformer);
|
|
8
8
|
}
|
|
9
|
-
const
|
|
10
|
-
exports.
|
|
11
|
-
function
|
|
9
|
+
const parseBooleanFromStringTransformer = ({ value, }) => normalizeBooleanFromString(value);
|
|
10
|
+
exports.parseBooleanFromStringTransformer = parseBooleanFromStringTransformer;
|
|
11
|
+
function normalizeBooleanFromString(value) {
|
|
12
12
|
if (value === undefined) {
|
|
13
13
|
return undefined;
|
|
14
14
|
}
|
|
@@ -26,4 +26,4 @@ function normalizeOptionalBoolean(value) {
|
|
|
26
26
|
}
|
|
27
27
|
return value;
|
|
28
28
|
}
|
|
29
|
-
//# sourceMappingURL=to-
|
|
29
|
+
//# sourceMappingURL=to-boolean-from-string.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-boolean-from-string.decorator.js","sourceRoot":"","sources":["../../src/class-transformer/to-boolean-from-string.decorator.ts"],"names":[],"mappings":";;;AAEA,kDAEC;AAJD,yDAAiE;AAEjE,SAAgB,mBAAmB;IACjC,OAAO,IAAA,6BAAS,EAAC,yCAAiC,CAAC,CAAC;AACtD,CAAC;AAEM,MAAM,iCAAiC,GAAG,CAAC,EAChD,KAAK,GACa,EAAW,EAAE,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;AAFvD,QAAA,iCAAiC,qCAEsB;AAEpE,SAAS,0BAA0B,CAAC,KAAc;IAChD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAEnD,IAAI,eAAe,KAAK,MAAM,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/modules/s3/index.js
CHANGED
|
@@ -17,4 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./s3.module"), exports);
|
|
18
18
|
__exportStar(require("./s3.service"), exports);
|
|
19
19
|
__exportStar(require("./s3.interface"), exports);
|
|
20
|
+
__exportStar(require("./s3.constants"), exports);
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/s3/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,+CAA6B;AAC7B,iDAA+B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/s3/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,+CAA6B;AAC7B,iDAA+B;AAC/B,iDAA+B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LoggerService, ModuleMetadata } from '@nestjs/common';
|
|
2
|
-
import type { DeleteObjectCommandOutput, GetObjectCommandOutput, ObjectCannedACL, PutObjectCommandInput, PutObjectCommandOutput } from '@aws-sdk/client-s3';
|
|
2
|
+
import type { CopyObjectCommandInput, CopyObjectCommandOutput, DeleteObjectCommandOutput, GetObjectCommandOutput, ListObjectsV2CommandInput, ListObjectsV2CommandOutput, ObjectCannedACL, PutObjectCommandInput, PutObjectCommandOutput } from '@aws-sdk/client-s3';
|
|
3
3
|
import type { CompleteMultipartUploadCommandOutput } from '@aws-sdk/client-s3';
|
|
4
4
|
import type { Readable } from 'stream';
|
|
5
5
|
export type S3ModuleLogger = Pick<LoggerService, 'log' | 'error'>;
|
|
@@ -7,6 +7,7 @@ export interface S3ModuleOptions {
|
|
|
7
7
|
region?: string;
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
forcePathStyle?: boolean;
|
|
10
|
+
defaultBucket?: string;
|
|
10
11
|
bucket?: string;
|
|
11
12
|
logger?: boolean | S3ModuleLogger;
|
|
12
13
|
}
|
|
@@ -28,6 +29,16 @@ export interface S3SignedUrlOptions extends S3UploadOptions {
|
|
|
28
29
|
expiresIn?: number;
|
|
29
30
|
operation?: 'getObject' | 'putObject';
|
|
30
31
|
}
|
|
32
|
+
export interface S3CopyObjectOptions extends S3UploadOptions {
|
|
33
|
+
metadataDirective?: CopyObjectCommandInput['MetadataDirective'];
|
|
34
|
+
sourceBucket?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface S3ListObjectsOptions extends S3ObjectOptions {
|
|
37
|
+
continuationToken?: ListObjectsV2CommandInput['ContinuationToken'];
|
|
38
|
+
delimiter?: ListObjectsV2CommandInput['Delimiter'];
|
|
39
|
+
maxKeys?: ListObjectsV2CommandInput['MaxKeys'];
|
|
40
|
+
prefix?: ListObjectsV2CommandInput['Prefix'];
|
|
41
|
+
}
|
|
31
42
|
export interface S3GetObjectResult {
|
|
32
43
|
body: Readable;
|
|
33
44
|
cacheControl?: GetObjectCommandOutput['CacheControl'];
|
|
@@ -40,5 +51,7 @@ export interface S3GetObjectResult {
|
|
|
40
51
|
export type S3UploadResult = CompleteMultipartUploadCommandOutput;
|
|
41
52
|
export type S3PutObjectResult = PutObjectCommandOutput;
|
|
42
53
|
export type S3DeleteObjectResult = DeleteObjectCommandOutput;
|
|
54
|
+
export type S3CopyObjectResult = CopyObjectCommandOutput;
|
|
55
|
+
export type S3ListObjectsResult = ListObjectsV2CommandOutput;
|
|
43
56
|
export type S3Body = NonNullable<PutObjectCommandInput['Body']>;
|
|
44
57
|
export type UploadParams = S3UploadOptions;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
2
|
-
import { S3Body, S3DeleteObjectResult, S3GetObjectResult, S3ModuleOptions, S3ObjectOptions, S3PutObjectResult, S3SignedUrlOptions, S3UploadOptions, S3UploadResult } from './s3.interface';
|
|
2
|
+
import { S3Body, S3CopyObjectOptions, S3CopyObjectResult, S3DeleteObjectResult, S3GetObjectResult, S3ListObjectsOptions, S3ListObjectsResult, S3ModuleOptions, S3ObjectOptions, S3PutObjectResult, S3SignedUrlOptions, S3UploadOptions, S3UploadResult } from './s3.interface';
|
|
3
3
|
export declare class S3Service {
|
|
4
4
|
private readonly options;
|
|
5
5
|
private readonly s3Client;
|
|
@@ -9,9 +9,13 @@ export declare class S3Service {
|
|
|
9
9
|
putObject(key: string, body: S3Body, options?: S3UploadOptions): Promise<S3PutObjectResult>;
|
|
10
10
|
uploadObject(key: string, body: S3Body, options?: S3UploadOptions): Promise<S3PutObjectResult>;
|
|
11
11
|
deleteObject(key: string, options?: S3ObjectOptions): Promise<S3DeleteObjectResult>;
|
|
12
|
+
copyObject(sourceKey: string, destinationKey: string, options?: S3CopyObjectOptions): Promise<S3CopyObjectResult>;
|
|
12
13
|
getObject(key: string, options?: S3ObjectOptions): Promise<S3GetObjectResult>;
|
|
14
|
+
listObjects(options?: S3ListObjectsOptions): Promise<S3ListObjectsResult>;
|
|
13
15
|
getSignedUrl(key: string, options?: S3SignedUrlOptions): Promise<string>;
|
|
16
|
+
private createCopyObjectParams;
|
|
14
17
|
private createPutObjectParams;
|
|
18
|
+
private buildCopySource;
|
|
15
19
|
private resolveBucket;
|
|
16
20
|
private log;
|
|
17
21
|
private logError;
|
|
@@ -66,6 +66,18 @@ let S3Service = S3Service_1 = class S3Service {
|
|
|
66
66
|
throw error;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
async copyObject(sourceKey, destinationKey, options) {
|
|
70
|
+
const command = new client_s3_1.CopyObjectCommand(this.createCopyObjectParams(sourceKey, destinationKey, options));
|
|
71
|
+
try {
|
|
72
|
+
const response = await this.s3Client.send(command);
|
|
73
|
+
this.log(`Copied object: ${sourceKey} -> ${destinationKey}`);
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
this.logError(`Failed to copy object: ${sourceKey} -> ${destinationKey}`, error);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
69
81
|
async getObject(key, options) {
|
|
70
82
|
const command = new client_s3_1.GetObjectCommand({
|
|
71
83
|
Bucket: this.resolveBucket(options?.bucket),
|
|
@@ -95,6 +107,26 @@ let S3Service = S3Service_1 = class S3Service {
|
|
|
95
107
|
throw error;
|
|
96
108
|
}
|
|
97
109
|
}
|
|
110
|
+
async listObjects(options) {
|
|
111
|
+
const command = new client_s3_1.ListObjectsV2Command({
|
|
112
|
+
Bucket: this.resolveBucket(options?.bucket),
|
|
113
|
+
...(options?.continuationToken
|
|
114
|
+
? { ContinuationToken: options.continuationToken }
|
|
115
|
+
: {}),
|
|
116
|
+
...(options?.delimiter ? { Delimiter: options.delimiter } : {}),
|
|
117
|
+
...(options?.maxKeys ? { MaxKeys: options.maxKeys } : {}),
|
|
118
|
+
...(options?.prefix ? { Prefix: options.prefix } : {}),
|
|
119
|
+
});
|
|
120
|
+
try {
|
|
121
|
+
const response = await this.s3Client.send(command);
|
|
122
|
+
this.log(`Listed objects for bucket: ${command.input.Bucket}`);
|
|
123
|
+
return response;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
this.logError(`Failed to list objects for bucket: ${command.input.Bucket}`, error);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
98
130
|
async getSignedUrl(key, options) {
|
|
99
131
|
const expiresIn = options?.expiresIn ?? 900;
|
|
100
132
|
const operation = options?.operation ?? 'getObject';
|
|
@@ -106,6 +138,24 @@ let S3Service = S3Service_1 = class S3Service {
|
|
|
106
138
|
});
|
|
107
139
|
return (0, s3_request_presigner_1.getSignedUrl)(this.s3Client, command, { expiresIn });
|
|
108
140
|
}
|
|
141
|
+
createCopyObjectParams(sourceKey, destinationKey, options) {
|
|
142
|
+
const destinationBucket = this.resolveBucket(options?.bucket);
|
|
143
|
+
const sourceBucket = this.resolveBucket(options?.sourceBucket ?? options?.bucket);
|
|
144
|
+
const shouldReplaceMetadata = !!(options?.cacheControl ||
|
|
145
|
+
options?.contentType ||
|
|
146
|
+
options?.metadata);
|
|
147
|
+
const metadataDirective = options?.metadataDirective ?? (shouldReplaceMetadata ? 'REPLACE' : undefined);
|
|
148
|
+
return {
|
|
149
|
+
Bucket: destinationBucket,
|
|
150
|
+
CopySource: this.buildCopySource(sourceBucket, sourceKey),
|
|
151
|
+
Key: destinationKey,
|
|
152
|
+
...(options?.acl ? { ACL: options.acl } : {}),
|
|
153
|
+
...(options?.cacheControl ? { CacheControl: options.cacheControl } : {}),
|
|
154
|
+
...(options?.contentType ? { ContentType: options.contentType } : {}),
|
|
155
|
+
...(metadataDirective ? { MetadataDirective: metadataDirective } : {}),
|
|
156
|
+
...(options?.metadata ? { Metadata: options.metadata } : {}),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
109
159
|
createPutObjectParams(key, body, options, useDefaultContentType = false) {
|
|
110
160
|
const contentType = options?.contentType ??
|
|
111
161
|
(useDefaultContentType ? 'application/octet-stream' : undefined);
|
|
@@ -119,10 +169,16 @@ let S3Service = S3Service_1 = class S3Service {
|
|
|
119
169
|
...(options?.metadata ? { Metadata: options.metadata } : {}),
|
|
120
170
|
};
|
|
121
171
|
}
|
|
172
|
+
buildCopySource(bucket, key) {
|
|
173
|
+
return `${encodeURIComponent(bucket)}/${key
|
|
174
|
+
.split('/')
|
|
175
|
+
.map((part) => encodeURIComponent(part))
|
|
176
|
+
.join('/')}`;
|
|
177
|
+
}
|
|
122
178
|
resolveBucket(bucket) {
|
|
123
|
-
const resolvedBucket = bucket ?? this.options.bucket;
|
|
179
|
+
const resolvedBucket = bucket ?? this.options.defaultBucket ?? this.options.bucket;
|
|
124
180
|
if (!resolvedBucket) {
|
|
125
|
-
throw new Error('S3 bucket is not configured. Pass a bucket to the method call or set S3ModuleOptions.
|
|
181
|
+
throw new Error('S3 bucket is not configured. Pass a bucket to the method call or set S3ModuleOptions.defaultBucket.');
|
|
126
182
|
}
|
|
127
183
|
return resolvedBucket;
|
|
128
184
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"s3.service.js","sourceRoot":"","sources":["../../../src/modules/s3/s3.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,
|
|
1
|
+
{"version":3,"file":"s3.service.js","sourceRoot":"","sources":["../../../src/modules/s3/s3.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"to-optional-boolean.decorator.js","sourceRoot":"","sources":["../../src/class-transformer/to-optional-boolean.decorator.ts"],"names":[],"mappings":";;;AAEA,8CAEC;AAJD,yDAAiE;AAEjE,SAAgB,iBAAiB;IAC/B,OAAO,IAAA,6BAAS,EAAC,uCAA+B,CAAC,CAAC;AACpD,CAAC;AAEM,MAAM,+BAA+B,GAAG,CAAC,EAC9C,KAAK,GACa,EAAW,EAAE,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;AAFrD,QAAA,+BAA+B,mCAEsB;AAElE,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAEnD,IAAI,eAAe,KAAK,MAAM,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|