@rsdk/s3 4.2.0-next.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/client/index.d.ts +2 -0
  3. package/dist/client/index.js +19 -0
  4. package/dist/client/index.js.map +1 -0
  5. package/dist/client/s3.client.d.ts +89 -0
  6. package/dist/client/s3.client.js +216 -0
  7. package/dist/client/s3.client.js.map +1 -0
  8. package/dist/client/types.d.ts +68 -0
  9. package/dist/client/types.js +3 -0
  10. package/dist/client/types.js.map +1 -0
  11. package/dist/constants.d.ts +1 -0
  12. package/dist/constants.js +5 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/decorators/index.d.ts +1 -0
  15. package/dist/decorators/index.js +18 -0
  16. package/dist/decorators/index.js.map +1 -0
  17. package/dist/decorators/inject-client.decorator.d.ts +8 -0
  18. package/dist/decorators/inject-client.decorator.js +19 -0
  19. package/dist/decorators/inject-client.decorator.js.map +1 -0
  20. package/dist/decorators/set-client-metadata.fn.d.ts +1 -0
  21. package/dist/decorators/set-client-metadata.fn.js +12 -0
  22. package/dist/decorators/set-client-metadata.fn.js.map +1 -0
  23. package/dist/generate-key.fn.d.ts +5 -0
  24. package/dist/generate-key.fn.js +13 -0
  25. package/dist/generate-key.fn.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.js +21 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/module/index.d.ts +2 -0
  30. package/dist/module/index.js +19 -0
  31. package/dist/module/index.js.map +1 -0
  32. package/dist/module/s3-clients.config.d.ts +5 -0
  33. package/dist/module/s3-clients.config.js +32 -0
  34. package/dist/module/s3-clients.config.js.map +1 -0
  35. package/dist/module/s3-clients.indicator.d.ts +13 -0
  36. package/dist/module/s3-clients.indicator.js +52 -0
  37. package/dist/module/s3-clients.indicator.js.map +1 -0
  38. package/dist/module/s3-clients.module.d.ts +6 -0
  39. package/dist/module/s3-clients.module.js +27 -0
  40. package/dist/module/s3-clients.module.js.map +1 -0
  41. package/dist/module/s3-clients.plugin.d.ts +10 -0
  42. package/dist/module/s3-clients.plugin.js +17 -0
  43. package/dist/module/s3-clients.plugin.js.map +1 -0
  44. package/dist/module/s3-clients.service.d.ts +25 -0
  45. package/dist/module/s3-clients.service.js +101 -0
  46. package/dist/module/s3-clients.service.js.map +1 -0
  47. package/dist/module.generator.d.ts +9 -0
  48. package/dist/module.generator.js +55 -0
  49. package/dist/module.generator.js.map +1 -0
  50. package/dist/s3-clients.autodoc.d.ts +6 -0
  51. package/dist/s3-clients.autodoc.js +19 -0
  52. package/dist/s3-clients.autodoc.js.map +1 -0
  53. package/dist/token.factories.d.ts +2 -0
  54. package/dist/token.factories.js +9 -0
  55. package/dist/token.factories.js.map +1 -0
  56. package/package.json +30 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [4.2.0-next.0](https://github.com/R-Vision/rsdk/compare/v4.1.0...v4.2.0-next.0) (2024-02-02)
7
+
8
+ ### Features
9
+
10
+ * **s3:** added @rsdk/s3 package ([03bd9ea](https://github.com/R-Vision/rsdk/commit/03bd9ea7e5f78be6c93b1a2547fe7c2639ca0146))
@@ -0,0 +1,2 @@
1
+ export * from './s3.client';
2
+ export * from './types';
@@ -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("./s3.client"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,0CAAwB"}
@@ -0,0 +1,89 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import type { Timespan } from '@rsdk/common';
4
+ import { Readable } from 'node:stream';
5
+ import type { File, ObjectInfo, S3ClientOptions, UploadOptions } from './types';
6
+ /**
7
+ * Object storage client
8
+ */
9
+ export declare class S3Client {
10
+ readonly storageName: string;
11
+ readonly bucket: string;
12
+ private readonly s3;
13
+ private readonly defaultTTL;
14
+ private readonly logger;
15
+ constructor({ url, defaultTTL, bucket, storageName, logger, }: S3ClientOptions);
16
+ /**
17
+ * Throws error if server is not responding
18
+ * or bucket doesn't exist
19
+ */
20
+ checkBucket(): Promise<void>;
21
+ /**
22
+ * Returns true if bucket is reachable
23
+ * @returns Promise<boolean>
24
+ */
25
+ isHealthy(): Promise<boolean>;
26
+ /**
27
+ * Creates temporary download link for object
28
+ * @param key Object key
29
+ * @param ttl Time too live for the presigned url (defaults to 48h)
30
+ * @returns Promise<string>
31
+ */
32
+ getPresignedUrl(key: string, ttl?: Timespan): Promise<string>;
33
+ /**
34
+ * Get object metadata
35
+ * @param key Key to save object to
36
+ * @returns Promise<ObjectInfo>
37
+ */
38
+ getObjectInfo(key: string): Promise<ObjectInfo>;
39
+ /**
40
+ * Retrieves object from storage
41
+ * @param key string
42
+ * @returns Promise<File>
43
+ */
44
+ getObject(key: string): Promise<File>;
45
+ /**
46
+ * Get object stream from storage
47
+ * @param key Object key
48
+ * @returns Promise<Readable>
49
+ */
50
+ getObjectStream(key: string): Promise<Readable>;
51
+ /**
52
+ * Upload object to storage
53
+ * @param key Object key
54
+ * @param content Buffer
55
+ * @param options UploadOptions
56
+ */
57
+ addObject(key: string, content: Buffer | Readable, options?: UploadOptions): Promise<void>;
58
+ /**
59
+ * Removes object by key
60
+ * @param key Object key
61
+ */
62
+ removeObject(key: string): Promise<void>;
63
+ /**
64
+ * Tries to determine content type by file name
65
+ * @param filename filename
66
+ * @returns string
67
+ */
68
+ private tryGetContentType;
69
+ /**
70
+ * Parses metadata from S3 response
71
+ * @param key Object key
72
+ * @param response Object storage response
73
+ * @returns
74
+ */
75
+ private parseMetadata;
76
+ /**
77
+ * S3 storage can reply with different kinds of body
78
+ * @param key Object key
79
+ * @param response Object storage response
80
+ * @returns
81
+ */
82
+ private parseBody;
83
+ /**
84
+ * Create short hash of object key if there is no filename
85
+ * @param key Object key
86
+ * @returns string
87
+ */
88
+ private hashKey;
89
+ }
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.S3Client = void 0;
7
+ const common_1 = require("@rsdk/common");
8
+ const common_node_1 = require("@rsdk/common.node");
9
+ const aws_sdk_1 = require("aws-sdk");
10
+ const mime_types_1 = __importDefault(require("mime-types"));
11
+ const node_assert_1 = __importDefault(require("node:assert"));
12
+ const node_crypto_1 = require("node:crypto");
13
+ const node_stream_1 = require("node:stream");
14
+ const DEFAULT_CONTENT_TYPE = 'application/octet-stream';
15
+ /**
16
+ * Object storage client
17
+ */
18
+ class S3Client {
19
+ storageName;
20
+ bucket;
21
+ s3;
22
+ defaultTTL;
23
+ logger;
24
+ constructor({ url, defaultTTL, bucket, storageName, logger, }) {
25
+ this.s3 = new aws_sdk_1.S3({
26
+ accessKeyId: url.username,
27
+ secretAccessKey: url.password,
28
+ endpoint: `${url.protocol}//${url.host}${url.pathname}`,
29
+ s3ForcePathStyle: true,
30
+ });
31
+ this.bucket = bucket;
32
+ this.defaultTTL = defaultTTL;
33
+ this.storageName = storageName;
34
+ this.logger = logger;
35
+ }
36
+ /**
37
+ * Throws error if server is not responding
38
+ * or bucket doesn't exist
39
+ */
40
+ async checkBucket() {
41
+ await this.s3.headBucket({ Bucket: this.bucket }).promise();
42
+ /**
43
+ * TODO: Добавить более информативную обработку ошибок.
44
+ * Сейчас в целом терпимо, но может быть лучше.
45
+ */
46
+ }
47
+ /**
48
+ * Returns true if bucket is reachable
49
+ * @returns Promise<boolean>
50
+ */
51
+ async isHealthy() {
52
+ try {
53
+ await this.checkBucket();
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ /**
61
+ * Creates temporary download link for object
62
+ * @param key Object key
63
+ * @param ttl Time too live for the presigned url (defaults to 48h)
64
+ * @returns Promise<string>
65
+ */
66
+ async getPresignedUrl(key, ttl = this.defaultTTL) {
67
+ return this.s3.getSignedUrlPromise('getObject', {
68
+ Bucket: this.bucket,
69
+ Key: key,
70
+ Expires: ttl.millis(),
71
+ });
72
+ }
73
+ /**
74
+ * Get object metadata
75
+ * @param key Key to save object to
76
+ * @returns Promise<ObjectInfo>
77
+ */
78
+ async getObjectInfo(key) {
79
+ const response = await this.s3
80
+ .headObject({ Bucket: this.bucket, Key: key })
81
+ .promise();
82
+ return this.parseMetadata(key, response);
83
+ }
84
+ /**
85
+ * Retrieves object from storage
86
+ * @param key string
87
+ * @returns Promise<File>
88
+ */
89
+ async getObject(key) {
90
+ const response = await this.s3
91
+ .getObject({
92
+ Bucket: this.bucket,
93
+ Key: key,
94
+ })
95
+ .promise();
96
+ return {
97
+ ...this.parseMetadata(key, response),
98
+ content: await this.parseBody(key, response),
99
+ };
100
+ }
101
+ /**
102
+ * Get object stream from storage
103
+ * @param key Object key
104
+ * @returns Promise<Readable>
105
+ */
106
+ async getObjectStream(key) {
107
+ const stream = this.s3
108
+ .getObject({
109
+ Bucket: this.bucket,
110
+ Key: key,
111
+ })
112
+ .createReadStream();
113
+ return stream;
114
+ }
115
+ /**
116
+ * Upload object to storage
117
+ * @param key Object key
118
+ * @param content Buffer
119
+ * @param options UploadOptions
120
+ */
121
+ async addObject(key, content, options) {
122
+ const { filename, contentType, metadata = {}, isAttachment = false, } = options || {};
123
+ const encodedFilenameOrHash = filename
124
+ ? encodeURIComponent(filename)
125
+ : this.hashKey(key);
126
+ await this.s3
127
+ .upload({
128
+ Key: key,
129
+ Body: content,
130
+ Bucket: this.bucket,
131
+ ContentType: contentType ||
132
+ this.tryGetContentType(encodedFilenameOrHash) ||
133
+ DEFAULT_CONTENT_TYPE,
134
+ ContentDisposition: `${isAttachment ? 'attachment; ' : ''}filename=${encodedFilenameOrHash}`,
135
+ Metadata: { ...metadata, filename: encodedFilenameOrHash },
136
+ })
137
+ .promise();
138
+ }
139
+ /**
140
+ * Removes object by key
141
+ * @param key Object key
142
+ */
143
+ async removeObject(key) {
144
+ await this.s3
145
+ .deleteObject({
146
+ Bucket: this.bucket,
147
+ Key: key,
148
+ })
149
+ .promise();
150
+ }
151
+ /**
152
+ * Tries to determine content type by file name
153
+ * @param filename filename
154
+ * @returns string
155
+ */
156
+ tryGetContentType(filename) {
157
+ const contentType = mime_types_1.default.contentType(filename);
158
+ if (contentType === false) {
159
+ this.logger.warn(`Can not detect content type of file: ${filename}`);
160
+ return undefined;
161
+ }
162
+ return contentType;
163
+ }
164
+ /**
165
+ * Parses metadata from S3 response
166
+ * @param key Object key
167
+ * @param response Object storage response
168
+ * @returns
169
+ */
170
+ parseMetadata(key, response) {
171
+ const { Metadata, ContentLength, ContentType } = response;
172
+ (0, node_assert_1.default)(Metadata, `Object <${key}> missing Metadata`);
173
+ (0, node_assert_1.default)(ContentLength, `Object <${key}> missing ContentLength`);
174
+ const { filename, ...metadata } = Metadata;
175
+ return {
176
+ size: new common_1.Size(ContentLength, 'b'),
177
+ contentType: ContentType,
178
+ filename: filename ? decodeURIComponent(filename) : this.hashKey(key),
179
+ metadata,
180
+ };
181
+ }
182
+ /**
183
+ * S3 storage can reply with different kinds of body
184
+ * @param key Object key
185
+ * @param response Object storage response
186
+ * @returns
187
+ */
188
+ async parseBody(key, response) {
189
+ const { Body } = response;
190
+ if (Buffer.isBuffer(Body)) {
191
+ return Body;
192
+ }
193
+ if (typeof Body === 'string' || Body instanceof Uint8Array) {
194
+ return Buffer.from(Body);
195
+ }
196
+ if (Body instanceof Blob) {
197
+ return Buffer.from(await Body.text());
198
+ }
199
+ if (Body instanceof node_stream_1.Readable) {
200
+ return (0, common_node_1.streamToBuffer)(Body);
201
+ }
202
+ throw new Error(`Object <${key}> missing Body or it is invalid`);
203
+ }
204
+ /**
205
+ * Create short hash of object key if there is no filename
206
+ * @param key Object key
207
+ * @returns string
208
+ */
209
+ hashKey(key) {
210
+ return (0, node_crypto_1.createHash)('shake256', { outputLength: 4 })
211
+ .update(key)
212
+ .digest('hex');
213
+ }
214
+ }
215
+ exports.S3Client = S3Client;
216
+ //# sourceMappingURL=s3.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.client.js","sourceRoot":"","sources":["../../src/client/s3.client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /// <reference types="node" />
2
+ import type { Size, Timespan } from '@rsdk/common';
3
+ import type { ILogger } from '@rsdk/logging';
4
+ export interface UploadOptions {
5
+ /**
6
+ * File name that will be added to object metadata.
7
+ * If not provided, filename will be calculated from
8
+ * object key
9
+ */
10
+ filename?: string;
11
+ /**
12
+ * File attachment flag that will be added to object metadata.
13
+ * If provided, the browser will interpret the file as downloadable
14
+ * object key
15
+ */
16
+ isAttachment?: string;
17
+ /**
18
+ * Mime type of the object. If not provided, client
19
+ * will try to determine content type from filename.
20
+ * Default: application/octet-stream
21
+ */
22
+ contentType?: string | undefined;
23
+ /**
24
+ * Key/value data that will be attached to object
25
+ * and returned as headers
26
+ *
27
+ * NOTE: All keys will be lowercase'ed. So use
28
+ * snake_case or kebab-case for keys
29
+ */
30
+ metadata?: Record<string, string>;
31
+ }
32
+ export interface S3ClientOptions {
33
+ storageName: string;
34
+ url: URL;
35
+ bucket: string;
36
+ defaultTTL: Timespan;
37
+ logger: ILogger;
38
+ }
39
+ /**
40
+ * Object metadata
41
+ */
42
+ export interface ObjectInfo {
43
+ /**
44
+ * File name of object
45
+ */
46
+ filename: string;
47
+ /**
48
+ * Content type of object
49
+ */
50
+ contentType: string | undefined;
51
+ /**
52
+ * Size of object
53
+ */
54
+ size: Size;
55
+ /**
56
+ * Key/value data attached to object
57
+ */
58
+ metadata: Record<string, string>;
59
+ }
60
+ /**
61
+ * Object metadata with the object itself
62
+ */
63
+ export interface File extends ObjectInfo {
64
+ /**
65
+ * Blob
66
+ */
67
+ content: Buffer;
68
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export declare const S3_CLIENTS_RSDK_METADATA_SCOPE = "s3-clients";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.S3_CLIENTS_RSDK_METADATA_SCOPE = void 0;
4
+ exports.S3_CLIENTS_RSDK_METADATA_SCOPE = 's3-clients';
5
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,8BAA8B,GAAG,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './inject-client.decorator';
@@ -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("./inject-client.decorator"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C"}
@@ -0,0 +1,8 @@
1
+ export interface InjectBucketOptions {
2
+ storageName?: string;
3
+ }
4
+ /**
5
+ * @returns ParameterDecorator
6
+ * @param connectionName
7
+ */
8
+ export declare const InjectBucket: (bucketName: string, options?: InjectBucketOptions) => ParameterDecorator;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InjectBucket = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const token_factories_1 = require("../token.factories");
6
+ const set_client_metadata_fn_1 = require("./set-client-metadata.fn");
7
+ /**
8
+ * @returns ParameterDecorator
9
+ * @param connectionName
10
+ */
11
+ const InjectBucket = (bucketName, options) => {
12
+ return (target, propertyKey, parameterIndex) => {
13
+ const storageName = options?.storageName ?? 'default';
14
+ (0, common_1.Inject)((0, token_factories_1.getClientToken)(storageName, bucketName))(target, propertyKey, parameterIndex);
15
+ (0, set_client_metadata_fn_1.setClientMetadata)(target, storageName, bucketName);
16
+ };
17
+ };
18
+ exports.InjectBucket = InjectBucket;
19
+ //# sourceMappingURL=inject-client.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-client.decorator.js","sourceRoot":"","sources":["../../src/decorators/inject-client.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,wDAAoD;AAEpD,qEAA6D;AAM7D;;;GAGG;AACI,MAAM,YAAY,GAAG,CAC1B,UAAkB,EAClB,OAA6B,EACT,EAAE;IACtB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QAC7C,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,SAAS,CAAC;QAEtD,IAAA,eAAM,EAAC,IAAA,gCAAc,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAC7C,MAAM,EACN,WAAW,EACX,cAAc,CACf,CAAC;QACF,IAAA,0CAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC;AACJ,CAAC,CAAC;AAdW,QAAA,YAAY,gBAcvB"}
@@ -0,0 +1 @@
1
+ export declare const setClientMetadata: (target: object, storageName: string, bucketName: string) => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setClientMetadata = void 0;
4
+ const metadata_1 = require("@rsdk/metadata");
5
+ const module_generator_1 = require("../module.generator");
6
+ const setClientMetadata = (target, storageName, bucketName) => {
7
+ const key = `s3:${storageName}:${bucketName}`;
8
+ const moduleDefinition = module_generator_1.ModuleGenerator.createClientModuleDefinition(target, storageName, bucketName);
9
+ metadata_1.RsdkMetadata.setWithScope(target, metadata_1.PLATFORM_RAW_GLOBAL_METADATA_SCOPE, key, moduleDefinition, true);
10
+ };
11
+ exports.setClientMetadata = setClientMetadata;
12
+ //# sourceMappingURL=set-client-metadata.fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-client-metadata.fn.js","sourceRoot":"","sources":["../../src/decorators/set-client-metadata.fn.ts"],"names":[],"mappings":";;;AAAA,6CAGwB;AAExB,0DAAsD;AAE/C,MAAM,iBAAiB,GAAG,CAC/B,MAAc,EACd,WAAmB,EACnB,UAAkB,EACZ,EAAE;IACR,MAAM,GAAG,GAAG,MAAM,WAAW,IAAI,UAAU,EAAE,CAAC;IAC9C,MAAM,gBAAgB,GAAG,kCAAe,CAAC,4BAA4B,CACnE,MAAM,EACN,WAAW,EACX,UAAU,CACX,CAAC;IAEF,uBAAY,CAAC,YAAY,CACvB,MAAM,EACN,6CAAkC,EAClC,GAAG,EACH,gBAAgB,EAChB,IAAI,CACL,CAAC;AACJ,CAAC,CAAC;AAnBW,QAAA,iBAAiB,qBAmB5B"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Генерирует ключ для S3 из текущей даты и случайного UUID
3
+ * @returns string
4
+ */
5
+ export declare const generateKey: () => string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateKey = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ /**
6
+ * Генерирует ключ для S3 из текущей даты и случайного UUID
7
+ * @returns string
8
+ */
9
+ const generateKey = () => {
10
+ return `${Date.now()}/${(0, node_crypto_1.randomUUID)()}`;
11
+ };
12
+ exports.generateKey = generateKey;
13
+ //# sourceMappingURL=generate-key.fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-key.fn.js","sourceRoot":"","sources":["../src/generate-key.fn.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAEzC;;;GAGG;AACI,MAAM,WAAW,GAAG,GAAW,EAAE;IACtC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAA,wBAAU,GAAE,EAAE,CAAC;AACzC,CAAC,CAAC;AAFW,QAAA,WAAW,eAEtB"}
@@ -0,0 +1,4 @@
1
+ export * from './decorators';
2
+ export * from './module';
3
+ export * from './client';
4
+ export * from './generate-key.fn';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
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("./decorators"), exports);
18
+ __exportStar(require("./module"), exports);
19
+ __exportStar(require("./client"), exports);
20
+ __exportStar(require("./generate-key.fn"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,2CAAyB;AACzB,2CAAyB;AACzB,oDAAkC"}
@@ -0,0 +1,2 @@
1
+ export * from './s3-clients.plugin';
2
+ export * from './s3-clients.service';
@@ -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("./s3-clients.plugin"), exports);
18
+ __exportStar(require("./s3-clients.service"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/module/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,uDAAqC"}
@@ -0,0 +1,5 @@
1
+ import { Timespan } from '@rsdk/common';
2
+ import { Config } from '@rsdk/core';
3
+ export declare class S3ClientsConfig extends Config {
4
+ readonly defaultTTL: Timespan;
5
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.S3ClientsConfig = void 0;
13
+ const common_1 = require("@rsdk/common");
14
+ const core_1 = require("@rsdk/core");
15
+ let S3ClientsConfig = class S3ClientsConfig extends core_1.Config {
16
+ defaultTTL;
17
+ };
18
+ exports.S3ClientsConfig = S3ClientsConfig;
19
+ __decorate([
20
+ (0, core_1.Property)('S3_PRESIGNED_URL_DEFAULT_TTL', new core_1.TimespanParser(), {
21
+ description: (0, common_1.text) `
22
+ Время валидности подписанных ссылок по умолчанию. Может быть
23
+ переопределено при создании отдельных ссылок.
24
+ `,
25
+ defaultValue: new common_1.Timespan(48, 'h'),
26
+ }),
27
+ __metadata("design:type", common_1.Timespan)
28
+ ], S3ClientsConfig.prototype, "defaultTTL", void 0);
29
+ exports.S3ClientsConfig = S3ClientsConfig = __decorate([
30
+ (0, core_1.ConfigSection)()
31
+ ], S3ClientsConfig);
32
+ //# sourceMappingURL=s3-clients.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.config.js","sourceRoot":"","sources":["../../src/module/s3-clients.config.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAA8C;AAC9C,qCAA6E;AAGtE,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,aAAM;IAQhC,UAAU,CAAY;CAChC,CAAA;AATY,0CAAe;AAQjB;IAPR,IAAA,eAAQ,EAAC,8BAA8B,EAAE,IAAI,qBAAc,EAAE,EAAE;QAC9D,WAAW,EAAE,IAAA,aAAI,EAAA;;;KAGhB;QACD,YAAY,EAAE,IAAI,iBAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;KACpC,CAAC;8BACoB,iBAAQ;mDAAC;0BARpB,eAAe;IAD3B,IAAA,oBAAa,GAAE;GACH,eAAe,CAS3B"}
@@ -0,0 +1,13 @@
1
+ import type { OnApplicationBootstrap } from '@nestjs/common';
2
+ import type { HealthIndicator } from '@rsdk/core';
3
+ import { CheckResult } from '@rsdk/core';
4
+ import { ILogger } from '@rsdk/logging';
5
+ import { S3ClientsService } from './s3-clients.service';
6
+ export declare class S3HealthIndicator implements HealthIndicator, OnApplicationBootstrap {
7
+ private readonly logger;
8
+ private readonly service;
9
+ private clients;
10
+ constructor(logger: ILogger, service: S3ClientsService);
11
+ onApplicationBootstrap(): void;
12
+ check(): Promise<CheckResult>;
13
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.S3HealthIndicator = void 0;
16
+ const core_1 = require("@rsdk/core");
17
+ const s3_clients_service_1 = require("./s3-clients.service");
18
+ let S3HealthIndicator = class S3HealthIndicator {
19
+ logger;
20
+ service;
21
+ clients;
22
+ constructor(logger, service) {
23
+ this.logger = logger;
24
+ this.service = service;
25
+ }
26
+ onApplicationBootstrap() {
27
+ this.clients = this.service.clients();
28
+ }
29
+ async check() {
30
+ if (!this.clients) {
31
+ throw new core_1.InternalException('S3 healthchecks are not ready!');
32
+ }
33
+ this.logger.trace('Checking S3 clients health...');
34
+ this.logger.trace(`Found ${this.clients.length} clients.`);
35
+ const results = await Promise.all([...this.clients].map(async (client) => ({
36
+ client: `${client.storageName}`,
37
+ isHealty: await client.isHealthy(),
38
+ })));
39
+ const isHealthy = results.every((r) => r.isHealty);
40
+ this.logger.trace(`Is up: ${isHealthy}`);
41
+ return isHealthy
42
+ ? core_1.CheckResult.up({ results })
43
+ : core_1.CheckResult.down({ results });
44
+ }
45
+ };
46
+ exports.S3HealthIndicator = S3HealthIndicator;
47
+ exports.S3HealthIndicator = S3HealthIndicator = __decorate([
48
+ (0, core_1.Indicator)('s3'),
49
+ __param(0, (0, core_1.InjectLogger)(S3HealthIndicator)),
50
+ __metadata("design:paramtypes", [Object, s3_clients_service_1.S3ClientsService])
51
+ ], S3HealthIndicator);
52
+ //# sourceMappingURL=s3-clients.indicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.indicator.js","sourceRoot":"","sources":["../../src/module/s3-clients.indicator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,qCAKoB;AAKpB,6DAAwD;AAGjD,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAMwB;IACjC;IAJX,OAAO,CAA6C;IAE5D,YACoD,MAAe,EAChD,OAAyB;QADQ,WAAM,GAAN,MAAM,CAAS;QAChD,YAAO,GAAP,OAAO,CAAkB;IACzC,CAAC;IAEJ,sBAAsB;QACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,wBAAiB,CAAC,gCAAgC,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;QAE3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;YACvC,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE;YAC/B,QAAQ,EAAE,MAAM,MAAM,CAAC,SAAS,EAAE;SACnC,CAAC,CAAC,CACJ,CAAC;QAEF,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;QAEzC,OAAO,SAAS;YACd,CAAC,CAAC,kBAAW,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7B,CAAC,CAAC,kBAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC;CACF,CAAA;AArCY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,gBAAS,EAAC,IAAI,CAAC;IAOX,WAAA,IAAA,mBAAY,EAAC,iBAAiB,CAAC,CAAA;6CACN,qCAAgB;GAPjC,iBAAiB,CAqC7B"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Вынесено в отдельный модуль для того чтобы не было дублирования внутри DI
3
+ * Но при этом чтобы не надо было делать `forRoot` в корне приложения
4
+ */
5
+ export declare class S3ClientsModule {
6
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.S3ClientsModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const s3_clients_indicator_1 = require("./s3-clients.indicator");
12
+ const s3_clients_service_1 = require("./s3-clients.service");
13
+ /**
14
+ * Вынесено в отдельный модуль для того чтобы не было дублирования внутри DI
15
+ * Но при этом чтобы не надо было делать `forRoot` в корне приложения
16
+ */
17
+ let S3ClientsModule = class S3ClientsModule {
18
+ };
19
+ exports.S3ClientsModule = S3ClientsModule;
20
+ exports.S3ClientsModule = S3ClientsModule = __decorate([
21
+ (0, common_1.Global)(),
22
+ (0, common_1.Module)({
23
+ providers: [s3_clients_service_1.S3ClientsService, s3_clients_indicator_1.S3HealthIndicator],
24
+ exports: [s3_clients_service_1.S3ClientsService],
25
+ })
26
+ ], S3ClientsModule);
27
+ //# sourceMappingURL=s3-clients.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.module.js","sourceRoot":"","sources":["../../src/module/s3-clients.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAEhD,iEAA2D;AAC3D,6DAAwD;AAExD;;;GAGG;AAMI,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IAL3B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,qCAAgB,EAAE,wCAAiB,CAAC;QAChD,OAAO,EAAE,CAAC,qCAAgB,CAAC;KAC5B,CAAC;GACW,eAAe,CAAG"}
@@ -0,0 +1,10 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { Constructor } from '@rsdk/common';
3
+ import type { AppropriateTransports, PlatformAppPlugin } from '@rsdk/core';
4
+ /**
5
+ * На данный момент требуется только для работы хелсчеков
6
+ */
7
+ export declare class S3Plugin implements PlatformAppPlugin {
8
+ forTransports(): AppropriateTransports;
9
+ modules?(): (DynamicModule | Constructor)[];
10
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.S3Plugin = void 0;
4
+ const s3_clients_module_1 = require("./s3-clients.module");
5
+ /**
6
+ * На данный момент требуется только для работы хелсчеков
7
+ */
8
+ class S3Plugin {
9
+ forTransports() {
10
+ return 'any';
11
+ }
12
+ modules() {
13
+ return [s3_clients_module_1.S3ClientsModule];
14
+ }
15
+ }
16
+ exports.S3Plugin = S3Plugin;
17
+ //# sourceMappingURL=s3-clients.plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.plugin.js","sourceRoot":"","sources":["../../src/module/s3-clients.plugin.ts"],"names":[],"mappings":";;;AAIA,2DAAsD;AAEtD;;GAEG;AACH,MAAa,QAAQ;IACnB,aAAa;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO;QACL,OAAO,CAAC,mCAAe,CAAC,CAAC;IAC3B,CAAC;CACF;AARD,4BAQC"}
@@ -0,0 +1,25 @@
1
+ import type { OnApplicationBootstrap } from '@nestjs/common';
2
+ import { ILogger } from '@rsdk/logging';
3
+ import { S3Client } from '../client/s3.client';
4
+ import { S3ClientsConfig } from './s3-clients.config';
5
+ /**
6
+ * Простое кеш хранилище внутри DI для кеширования на замену статике
7
+ */
8
+ export declare class S3ClientsService implements OnApplicationBootstrap {
9
+ private readonly config;
10
+ private readonly logger;
11
+ private readonly cache;
12
+ constructor(config: S3ClientsConfig, logger: ILogger);
13
+ /**
14
+ * Blocking application start if one of storages is unreachable.
15
+ *
16
+ * NOTE: Not sure that this is correct. Maybe it's better to
17
+ * print errors if exist and start app.
18
+ */
19
+ onApplicationBootstrap(): Promise<void>;
20
+ clients(): Readonly<Readonly<S3Client>[]>;
21
+ resolveClient(storageUrl: URL, storageName: string, bucket: string): S3Client;
22
+ getClient(storageName: string, bucket: string): S3Client | undefined;
23
+ private getExisting;
24
+ private setCache;
25
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.S3ClientsService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const common_2 = require("@rsdk/common");
18
+ const core_1 = require("@rsdk/core");
19
+ const logging_1 = require("@rsdk/logging");
20
+ const s3_client_1 = require("../client/s3.client");
21
+ const s3_clients_config_1 = require("./s3-clients.config");
22
+ /**
23
+ * Простое кеш хранилище внутри DI для кеширования на замену статике
24
+ */
25
+ let S3ClientsService = class S3ClientsService {
26
+ config;
27
+ logger;
28
+ cache = new Map();
29
+ constructor(config, logger) {
30
+ this.config = config;
31
+ this.logger = logger;
32
+ }
33
+ /**
34
+ * Blocking application start if one of storages is unreachable.
35
+ *
36
+ * NOTE: Not sure that this is correct. Maybe it's better to
37
+ * print errors if exist and start app.
38
+ */
39
+ async onApplicationBootstrap() {
40
+ const clients = this.clients();
41
+ const interval = new common_2.Timespan(1, 's');
42
+ this.logger.debug(`Checking connections to ${clients.length} S3 buckets.`);
43
+ for (const client of clients) {
44
+ const metadata = {
45
+ storage: client.storageName,
46
+ bucket: client.bucket,
47
+ };
48
+ while (true) {
49
+ try {
50
+ this.logger.debug('Checking connection to bucket...', metadata);
51
+ await client.checkBucket();
52
+ break;
53
+ }
54
+ catch (error) {
55
+ common_2.Assert.isError(error);
56
+ this.logger.fatal(`Connection check failed. Retry in ${interval.millis()}ms`, error);
57
+ }
58
+ await (0, common_2.delay)(interval);
59
+ }
60
+ }
61
+ }
62
+ clients() {
63
+ const clients = [];
64
+ for (const buckets of this.cache.values()) {
65
+ for (const client of buckets.values()) {
66
+ clients.push(client);
67
+ }
68
+ }
69
+ return clients;
70
+ }
71
+ resolveClient(storageUrl, storageName, bucket) {
72
+ const client = this.getExisting(storageName, bucket) ??
73
+ new s3_client_1.S3Client({
74
+ storageName,
75
+ bucket,
76
+ url: storageUrl,
77
+ defaultTTL: this.config.defaultTTL,
78
+ logger: logging_1.LoggerFactory.create(`s3/${storageName}/${bucket}`),
79
+ });
80
+ this.setCache(storageName, bucket, client);
81
+ return client;
82
+ }
83
+ getClient(storageName, bucket) {
84
+ return this.getExisting(storageName, bucket);
85
+ }
86
+ getExisting(storageName, bucket) {
87
+ return this.cache.get(storageName)?.get(bucket);
88
+ }
89
+ setCache(storageName, bucket, client) {
90
+ const existing = this.cache.get(storageName);
91
+ const updated = (existing || new Map())?.set(bucket, client);
92
+ this.cache.set(storageName, updated);
93
+ }
94
+ };
95
+ exports.S3ClientsService = S3ClientsService;
96
+ exports.S3ClientsService = S3ClientsService = __decorate([
97
+ (0, common_1.Injectable)(),
98
+ __param(1, (0, core_1.InjectLogger)(S3ClientsService)),
99
+ __metadata("design:paramtypes", [s3_clients_config_1.S3ClientsConfig, Object])
100
+ ], S3ClientsService);
101
+ //# sourceMappingURL=s3-clients.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.service.js","sourceRoot":"","sources":["../../src/module/s3-clients.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ export type S3ClientMetadataValue = {
3
+ storageName: string;
4
+ bucketName: string;
5
+ };
6
+ export declare class ModuleGenerator {
7
+ static createClientModuleDefinition(target: object, storageName: string, bucketName: string): DynamicModule;
8
+ private static createClientProvider;
9
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModuleGenerator = void 0;
4
+ const common_1 = require("@rsdk/common");
5
+ const core_1 = require("@rsdk/core");
6
+ const metadata_1 = require("@rsdk/metadata");
7
+ const s3_clients_module_1 = require("./module/s3-clients.module");
8
+ const s3_clients_service_1 = require("./module/s3-clients.service");
9
+ const constants_1 = require("./constants");
10
+ const token_factories_1 = require("./token.factories");
11
+ class ModuleGenerator {
12
+ static createClientModuleDefinition(target, storageName, bucketName) {
13
+ const CONFIG_PROPERTY_ALIAS = (0, token_factories_1.getPropertyKey)(storageName);
14
+ const propertyToken = (0, core_1.getPropertyToken)(CONFIG_PROPERTY_ALIAS);
15
+ const provider = ModuleGenerator.createClientProvider(storageName, bucketName, propertyToken);
16
+ const moduleDefinition = {
17
+ global: true,
18
+ imports: [
19
+ core_1.PlatformConfigModule.forProperty(CONFIG_PROPERTY_ALIAS),
20
+ s3_clients_module_1.S3ClientsModule,
21
+ ],
22
+ module: ModuleGenerator,
23
+ providers: [provider],
24
+ exports: [provider],
25
+ };
26
+ const key = (0, token_factories_1.getPropertyKey)(storageName);
27
+ core_1.ConfigMetadataRegistry.registerProperty(target, key, {
28
+ key: key,
29
+ parser: new core_1.UrlParser(),
30
+ description: (0, common_1.text) `
31
+ URL S3-совместимого хранилища (${storageName}),
32
+ включая access key и secret key (в username и password соответственно).
33
+ Например: https://{ACCESS_KEY}:{SECRET_KEY}@s3.domain.cloud
34
+ `,
35
+ expectedInEnv: false,
36
+ });
37
+ metadata_1.RsdkMetadata.add(target, { storageName, bucketName }, constants_1.S3_CLIENTS_RSDK_METADATA_SCOPE);
38
+ // AutodocMetadata.defineResolver(
39
+ // moduleDefinition,
40
+ // REDIS_CLIENTS_RSDK_METADATA_SCOPE,
41
+ // new RedisClientsAutodocResolver(),
42
+ // );
43
+ return moduleDefinition;
44
+ }
45
+ static createClientProvider(storageName, bucketName, propertyToken) {
46
+ const clientToken = (0, token_factories_1.getClientToken)(storageName, bucketName);
47
+ return {
48
+ provide: clientToken,
49
+ inject: [propertyToken, s3_clients_service_1.S3ClientsService, core_1.APP_SCOPE],
50
+ useFactory: (url, clients, appScope) => clients.resolveClient(url, storageName, `${appScope.toLowerCase()}.${bucketName}`),
51
+ };
52
+ }
53
+ }
54
+ exports.ModuleGenerator = ModuleGenerator;
55
+ //# sourceMappingURL=module.generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.generator.js","sourceRoot":"","sources":["../src/module.generator.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,qCAMoB;AACpB,6CAA8C;AAG9C,kEAA6D;AAC7D,oEAA+D;AAC/D,2CAA6D;AAC7D,uDAAmE;AAOnE,MAAa,eAAe;IAC1B,MAAM,CAAC,4BAA4B,CACjC,MAAc,EACd,WAAmB,EACnB,UAAkB;QAElB,MAAM,qBAAqB,GAAG,IAAA,gCAAc,EAAC,WAAW,CAAC,CAAC;QAC1D,MAAM,aAAa,GAAG,IAAA,uBAAgB,EAAC,qBAAqB,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,eAAe,CAAC,oBAAoB,CACnD,WAAW,EACX,UAAU,EACV,aAAa,CACd,CAAC;QAEF,MAAM,gBAAgB,GAAkB;YACtC,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,2BAAoB,CAAC,WAAW,CAAC,qBAAqB,CAAC;gBACvD,mCAAe;aAChB;YACD,MAAM,EAAE,eAAe;YACvB,SAAS,EAAE,CAAC,QAAQ,CAAC;YACrB,OAAO,EAAE,CAAC,QAAQ,CAAC;SACpB,CAAC;QAEF,MAAM,GAAG,GAAG,IAAA,gCAAc,EAAC,WAAW,CAAC,CAAC;QAExC,6BAAsB,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;YACnD,GAAG,EAAE,GAAG;YACR,MAAM,EAAE,IAAI,gBAAS,EAAE;YACvB,WAAW,EAAE,IAAA,aAAI,EAAA;yCACkB,WAAW;;;OAG7C;YACD,aAAa,EAAE,KAAK;SACrB,CAAC,CAAC;QAEH,uBAAY,CAAC,GAAG,CACd,MAAM,EACN,EAAE,WAAW,EAAE,UAAU,EAAE,EAC3B,0CAA8B,CAC/B,CAAC;QAEF,kCAAkC;QAClC,sBAAsB;QACtB,uCAAuC;QACvC,uCAAuC;QACvC,KAAK;QAEL,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,WAAmB,EACnB,UAAkB,EAClB,aAAqD;QAErD,MAAM,WAAW,GAAG,IAAA,gCAAc,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAE5D,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,CAAC,aAAa,EAAE,qCAAgB,EAAE,gBAAS,CAAC;YACpD,UAAU,EAAE,CACV,GAAQ,EACR,OAAyB,EACzB,QAAgB,EACN,EAAE,CACZ,OAAO,CAAC,aAAa,CACnB,GAAG,EACH,WAAW,EACX,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAC1C;SACJ,CAAC;IACJ,CAAC;CACF;AA5ED,0CA4EC"}
@@ -0,0 +1,6 @@
1
+ import type { DocumentNode, DocumentResolver } from '@rsdk/autodoc.protocol';
2
+ import type { RsdkMetadataProvider } from '@rsdk/metadata';
3
+ import type { Promisable } from 'type-fest';
4
+ export declare class S3ClientsAutodocResolver implements DocumentResolver {
5
+ getNode(rsdkMetadata: RsdkMetadataProvider): Promisable<DocumentNode | null>;
6
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.S3ClientsAutodocResolver = void 0;
4
+ const autodoc_protocol_1 = require("@rsdk/autodoc.protocol");
5
+ const constants_1 = require("./constants");
6
+ class S3ClientsAutodocResolver {
7
+ getNode(rsdkMetadata) {
8
+ const resources = rsdkMetadata.get(constants_1.S3_CLIENTS_RSDK_METADATA_SCOPE);
9
+ if (!resources) {
10
+ return null;
11
+ }
12
+ return new autodoc_protocol_1.Composite(new autodoc_protocol_1.Table(resources.map(({ value: { storageName, bucketName } }) => ({
13
+ storageName,
14
+ bucketName,
15
+ }))), 'S3 clients');
16
+ }
17
+ }
18
+ exports.S3ClientsAutodocResolver = S3ClientsAutodocResolver;
19
+ //# sourceMappingURL=s3-clients.autodoc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-clients.autodoc.js","sourceRoot":"","sources":["../src/s3-clients.autodoc.ts"],"names":[],"mappings":";;;AACA,6DAA0D;AAI1D,2CAA6D;AAG7D,MAAa,wBAAwB;IACnC,OAAO,CAAC,YAAkC;QACxC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAChC,0CAA8B,CAC/B,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,4BAAS,CAClB,IAAI,wBAAK,CACP,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YACzD,WAAW;YACX,UAAU;SACX,CAAC,CAAC,CACJ,EACD,YAAY,CACb,CAAC;IACJ,CAAC;CACF;AApBD,4DAoBC"}
@@ -0,0 +1,2 @@
1
+ export declare const getClientToken: (storageName: string, bucketName: string) => string;
2
+ export declare const getPropertyKey: (storageName: string) => string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPropertyKey = exports.getClientToken = void 0;
4
+ const common_1 = require("@rsdk/common");
5
+ const getClientToken = (storageName, bucketName) => `S3_CLIENT_${storageName}:${bucketName}`;
6
+ exports.getClientToken = getClientToken;
7
+ const getPropertyKey = (storageName) => `S3_URL_${common_1.Case.toUpperSnake(storageName)}`;
8
+ exports.getPropertyKey = getPropertyKey;
9
+ //# sourceMappingURL=token.factories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.factories.js","sourceRoot":"","sources":["../src/token.factories.ts"],"names":[],"mappings":";;;AAAA,yCAAoC;AAE7B,MAAM,cAAc,GAAG,CAC5B,WAAmB,EACnB,UAAkB,EACV,EAAE,CAAC,aAAa,WAAW,IAAI,UAAU,EAAE,CAAC;AAHzC,QAAA,cAAc,kBAG2B;AAE/C,MAAM,cAAc,GAAG,CAAC,WAAmB,EAAU,EAAE,CAC5D,UAAU,aAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;AADhC,QAAA,cAAc,kBACkB"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@rsdk/s3",
3
+ "version": "4.2.0-next.0",
4
+ "description": "Toolkit for S3 interface",
5
+ "license": "Apache License 2.0",
6
+ "main": "dist/index.js",
7
+ "files": [
8
+ "dist",
9
+ "*.md"
10
+ ],
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "dependencies": {
15
+ "aws-sdk": "^2.1468.0",
16
+ "mime-types": "^2.1.35"
17
+ },
18
+ "peerDependencies": {
19
+ "@nestjs/common": "^10.0.0",
20
+ "@rsdk/autodoc.protocol": "^4.2.0-next.0",
21
+ "@rsdk/common": "^4.2.0-next.0",
22
+ "@rsdk/common.node": "^4.2.0-next.0",
23
+ "@rsdk/core": "^4.2.0-next.0",
24
+ "@rsdk/logging": "^4.2.0-next.0",
25
+ "@rsdk/metadata": "^4.2.0-next.0",
26
+ "reflect-metadata": "^0.1.13",
27
+ "rxjs": "^7.0.0"
28
+ },
29
+ "gitHead": "e4b95e1971841f8492f9df493fa4fe4f13f9bb5f"
30
+ }