lemon-core 4.1.14 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/test-helper.d.ts +2 -2
- package/dist/common/test-helper.js +24 -26
- package/dist/common/test-helper.js.map +1 -1
- package/dist/controllers/dummy-controller.js +39 -46
- package/dist/controllers/dummy-controller.js.map +1 -1
- package/dist/controllers/general-api-controller.js +95 -100
- package/dist/controllers/general-api-controller.js.map +1 -1
- package/dist/controllers/general-controller.js +81 -82
- package/dist/controllers/general-controller.js.map +1 -1
- package/dist/cores/api/api-service.d.ts +1 -1
- package/dist/cores/api/api-service.js +228 -269
- package/dist/cores/api/api-service.js.map +1 -1
- package/dist/cores/aws/aws-kms-service.d.ts +1 -2
- package/dist/cores/aws/aws-kms-service.js +143 -153
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/aws/aws-s3-service.d.ts +2 -4
- package/dist/cores/aws/aws-s3-service.js +306 -330
- package/dist/cores/aws/aws-s3-service.js.map +1 -1
- package/dist/cores/aws/aws-sns-service.js +147 -153
- package/dist/cores/aws/aws-sns-service.js.map +1 -1
- package/dist/cores/aws/aws-sqs-service.js +149 -170
- package/dist/cores/aws/aws-sqs-service.js.map +1 -1
- package/dist/cores/aws/index.js +10 -20
- package/dist/cores/aws/index.js.map +1 -1
- package/dist/cores/cache/cache-service.d.ts +2 -2
- package/dist/cores/cache/cache-service.js +435 -499
- package/dist/cores/cache/cache-service.js.map +1 -1
- package/dist/cores/config/config-service.d.ts +1 -1
- package/dist/cores/config/config-service.js +56 -63
- package/dist/cores/config/config-service.js.map +1 -1
- package/dist/cores/config/index.js +14 -24
- package/dist/cores/config/index.js.map +1 -1
- package/dist/cores/core-services.d.ts +1 -1
- package/dist/cores/dynamo/dynamo-query-service.js +37 -51
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-scan-service.d.ts +2 -2
- package/dist/cores/dynamo/dynamo-scan-service.js +29 -40
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-service.d.ts +2 -2
- package/dist/cores/dynamo/dynamo-service.js +528 -601
- package/dist/cores/dynamo/dynamo-service.js.map +1 -1
- package/dist/cores/dynamo/tools/expressions.js +17 -7
- package/dist/cores/dynamo/tools/expressions.js.map +1 -1
- package/dist/cores/dynamo/tools/query.js +142 -127
- package/dist/cores/dynamo/tools/query.js.map +1 -1
- package/dist/cores/dynamo/tools/scan.js +111 -97
- package/dist/cores/dynamo/tools/scan.js.map +1 -1
- package/dist/cores/dynamo/tools/serializer.js +17 -7
- package/dist/cores/dynamo/tools/serializer.js.map +1 -1
- package/dist/cores/dynamo/tools/utils.d.ts +0 -2
- package/dist/cores/dynamo/tools/utils.js.map +1 -1
- package/dist/cores/elastic/elastic6-query-service.js +307 -324
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
- package/dist/cores/elastic/elastic6-service.d.ts +3 -3
- package/dist/cores/elastic/elastic6-service.js +568 -647
- package/dist/cores/elastic/elastic6-service.js.map +1 -1
- package/dist/cores/elastic/hangul-service.js +52 -54
- package/dist/cores/elastic/hangul-service.js.map +1 -1
- package/dist/cores/lambda/index.js +42 -36
- package/dist/cores/lambda/index.js.map +1 -1
- package/dist/cores/lambda/lambda-alb-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-alb-handler.js +59 -72
- package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-cognito-handler.js +10 -19
- package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-cron-handler.js +14 -23
- package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js +57 -67
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-handler.d.ts +22 -22
- package/dist/cores/lambda/lambda-handler.js +93 -106
- package/dist/cores/lambda/lambda-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-notification-handler.js +39 -50
- package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sns-handler.js +79 -88
- package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.js +79 -88
- package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-web-handler.d.ts +21 -43
- package/dist/cores/lambda/lambda-web-handler.js +392 -482
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-wss-handler.js +23 -32
- package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
- package/dist/cores/protocol/index.js +10 -20
- package/dist/cores/protocol/index.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +3 -3
- package/dist/cores/protocol/protocol-service.js +235 -227
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/storage/http-storage-service.js +65 -85
- package/dist/cores/storage/http-storage-service.js.map +1 -1
- package/dist/cores/storage/model-manager.js +66 -85
- package/dist/cores/storage/model-manager.js.map +1 -1
- package/dist/cores/storage/proxy-storage-service.d.ts +2 -2
- package/dist/cores/storage/proxy-storage-service.js +562 -599
- package/dist/cores/storage/proxy-storage-service.js.map +1 -1
- package/dist/cores/storage/redis-storage-service.js +163 -177
- package/dist/cores/storage/redis-storage-service.js.map +1 -1
- package/dist/cores/storage/storage-service.js +281 -322
- package/dist/cores/storage/storage-service.js.map +1 -1
- package/dist/engine/builder.d.ts +1 -1
- package/dist/engine/builder.js +59 -63
- package/dist/engine/builder.js.map +1 -1
- package/dist/engine/engine.d.ts +4 -4
- package/dist/engine/engine.js +9 -18
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/types.d.ts +1 -1
- package/dist/engine/utilities.d.ts +14 -10
- package/dist/engine/utilities.js +301 -280
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.js +4 -6
- package/dist/environ.js.map +1 -1
- package/dist/extended/abstract-service.js +595 -645
- package/dist/extended/abstract-service.js.map +1 -1
- package/dist/extended/libs/sig-v4.js.map +1 -1
- package/dist/generated/field-registry.d.ts +10 -0
- package/dist/generated/field-registry.js +17 -0
- package/dist/generated/field-registry.js.map +1 -0
- package/dist/helpers/helpers.d.ts +17 -9
- package/dist/helpers/helpers.js +88 -78
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/dynamodb-value.js +2 -3
- package/dist/lib/dynamodb-value.js.map +1 -1
- package/dist/tools/express.js +4 -5
- package/dist/tools/express.js.map +1 -1
- package/dist/tools/tools.d.ts +3 -1
- package/dist/tools/tools.js +14 -21
- package/dist/tools/tools.js.map +1 -1
- package/package.json +19 -18
- package/dist/exec-cli.d.ts +0 -2
- package/dist/exec-cli.js +0 -211
- package/dist/exec-cli.js.map +0 -1
- package/dist/lib/dynamo/expressions.d.ts +0 -14
- package/dist/lib/dynamo/expressions.js +0 -212
- package/dist/lib/dynamo/expressions.js.map +0 -1
- package/dist/lib/dynamo/query.d.ts +0 -43
- package/dist/lib/dynamo/query.js +0 -246
- package/dist/lib/dynamo/query.js.map +0 -1
- package/dist/lib/dynamo/scan.d.ts +0 -33
- package/dist/lib/dynamo/scan.js +0 -172
- package/dist/lib/dynamo/scan.js.map +0 -1
- package/dist/lib/dynamo/serializer.d.ts +0 -12
- package/dist/lib/dynamo/serializer.js +0 -243
- package/dist/lib/dynamo/serializer.js.map +0 -1
- package/dist/lib/dynamo/utils.d.ts +0 -15
- package/dist/lib/dynamo/utils.js +0 -129
- package/dist/lib/dynamo/utils.js.map +0 -1
- package/dist/tools/shared.d.ts +0 -37
- package/dist/tools/shared.js +0 -130
- package/dist/tools/shared.js.map +0 -1
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
-
var m = o[Symbol.asyncIterator], i;
|
|
14
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
-
};
|
|
18
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
@@ -74,339 +58,322 @@ const instance = () => {
|
|
|
74
58
|
* main service implement.
|
|
75
59
|
*/
|
|
76
60
|
class AWSS3Service {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
* ```js
|
|
137
|
-
* const res = $s3.putObject(JSON.stringify({ message }), 'test.json');
|
|
138
|
-
* // response would be like
|
|
139
|
-
* {
|
|
140
|
-
* "Bucket": "lemon-hello-www",
|
|
141
|
-
* "ETag": "5e206.....8bd4c",
|
|
142
|
-
* "Key": "test.json",
|
|
143
|
-
* "Location": "https://lemon-hello-www.s3.ap-northeast-2.amazonaws.com/test.json",
|
|
144
|
-
* }
|
|
145
|
-
* ```
|
|
146
|
-
*
|
|
147
|
-
* @param {string|Buffer} content content body
|
|
148
|
-
* @param {string} key (optional) S3 key to put
|
|
149
|
-
* @param {Metadata} metadata (optional) metadata to store
|
|
150
|
-
* @param {object} tags (optional) tag set
|
|
151
|
-
*/
|
|
152
|
-
this.putObject = (content, key, metadata, tags) => __awaiter(this, void 0, void 0, function* () {
|
|
153
|
-
if (!content)
|
|
154
|
-
throw new Error(`@content (buffer) is required - putObject()`);
|
|
155
|
-
const paramBuilder = new S3PutObjectRequestBuilder(this.bucket(), content);
|
|
156
|
-
key && paramBuilder.setKey(key);
|
|
157
|
-
metadata && paramBuilder.setMetadata(metadata);
|
|
158
|
-
tags && paramBuilder.setTags(tags);
|
|
159
|
-
const params = paramBuilder.asParams();
|
|
160
|
-
(0, engine_1._log)(NS, `> params.ContentType =`, params.ContentType);
|
|
161
|
-
(0, engine_1._log)(NS, `> params.ContentLength =`, params.ContentLength);
|
|
162
|
-
(0, engine_1._log)(NS, `> params.Metadata =`, params.Metadata);
|
|
163
|
-
(0, engine_1._log)(NS, `> params.Tagging =`, params.Tagging);
|
|
164
|
-
// call s3.upload()
|
|
165
|
-
const s3 = this.instance();
|
|
166
|
-
try {
|
|
167
|
-
const data = yield s3.send(new client_s3_2.PutObjectCommand(params));
|
|
168
|
-
delete data.key; // NOTE: remove undeclared property 'key' returned from aws-sdk
|
|
169
|
-
const location = `https://${params.Bucket}.s3.${region()}.amazonaws.com/${params.Key}`;
|
|
170
|
-
(0, engine_1._log)(NS, `> data[${params.Bucket}].Location =`, engine_1.$U.json(location));
|
|
171
|
-
const result = {
|
|
172
|
-
Bucket: params.Bucket,
|
|
173
|
-
Location: location,
|
|
174
|
-
Key: params.Key,
|
|
175
|
-
ETag: data.ETag,
|
|
176
|
-
ContentType: params.ContentType,
|
|
177
|
-
ContentLength: params.ContentLength,
|
|
178
|
-
Metadata: params.Metadata,
|
|
179
|
-
};
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
(0, engine_1._err)(NS, `! err[${params.Bucket}] =`, e);
|
|
184
|
-
throw e;
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
/**
|
|
188
|
-
* get a file from S3 Bucket
|
|
189
|
-
*
|
|
190
|
-
* @param {string} key
|
|
191
|
-
*/
|
|
192
|
-
this.getObject = (key) => __awaiter(this, void 0, void 0, function* () {
|
|
193
|
-
if (!key)
|
|
194
|
-
throw new Error(`@key (string) is required - getObject(${key !== null && key !== void 0 ? key : ''})`);
|
|
195
|
-
const Bucket = this.bucket();
|
|
196
|
-
const params = { Bucket, Key: key };
|
|
197
|
-
//* call s3.getObject.
|
|
198
|
-
const s3 = this.instance();
|
|
199
|
-
try {
|
|
200
|
-
const data = yield s3.send(new client_s3_2.GetObjectCommand(params));
|
|
201
|
-
(0, engine_1._log)(NS, '> data.type =', typeof data);
|
|
202
|
-
const { ContentType, ContentLength, Body, ETag, Metadata, TagCount } = data;
|
|
203
|
-
// convert stream to buffer for readable stream.
|
|
204
|
-
const buffer = Body && Body instanceof stream_1.Readable ? yield this.streamToBuffer(Body) : undefined;
|
|
205
|
-
const result = { ContentType, ContentLength, Body: buffer, ETag, Metadata };
|
|
206
|
-
if (TagCount)
|
|
207
|
-
result.TagCount = TagCount;
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
catch (e) {
|
|
211
|
-
(0, engine_1._err)(NS, '! err=', e);
|
|
212
|
-
throw e;
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
/**
|
|
216
|
-
* return decoded Object from bucket file.
|
|
217
|
-
*
|
|
218
|
-
* @param {string} key ex) 'hello-0001.json' , 'dist/hello-0001.json
|
|
219
|
-
*/
|
|
220
|
-
this.getDecodedObject = (key) => __awaiter(this, void 0, void 0, function* () {
|
|
221
|
-
if (!key)
|
|
222
|
-
throw new Error(`@key (string) is required - getDecodedObject(${key !== null && key !== void 0 ? key : ''})`);
|
|
223
|
-
const Bucket = this.bucket();
|
|
224
|
-
const params = { Bucket, Key: key };
|
|
225
|
-
//* call s3.getObject.
|
|
226
|
-
const s3 = this.instance();
|
|
227
|
-
try {
|
|
228
|
-
const data = yield s3.send(new client_s3_2.GetObjectCommand(params));
|
|
229
|
-
(0, engine_1._log)(NS, '> data.type =', typeof data);
|
|
230
|
-
const buffer = data.Body && data.Body instanceof stream_1.Readable ? yield this.streamToBuffer(data.Body) : undefined;
|
|
231
|
-
const content = buffer === null || buffer === void 0 ? void 0 : buffer.toString();
|
|
232
|
-
return JSON.parse(content);
|
|
233
|
-
}
|
|
234
|
-
catch (e) {
|
|
235
|
-
(0, engine_1._err)(NS, '! err=', e);
|
|
236
|
-
throw e;
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
/**
|
|
240
|
-
* get tag-set of object
|
|
241
|
-
*
|
|
242
|
-
* @param {string} key
|
|
243
|
-
*/
|
|
244
|
-
this.getObjectTagging = (key) => __awaiter(this, void 0, void 0, function* () {
|
|
245
|
-
var _b;
|
|
246
|
-
if (!key)
|
|
247
|
-
throw new Error(`@key (string) is required - getObjectTagging(${key !== null && key !== void 0 ? key : ''})`);
|
|
248
|
-
const Bucket = this.bucket();
|
|
249
|
-
const params = { Bucket, Key: key };
|
|
250
|
-
//* call s3.getObjectTagging.
|
|
251
|
-
const s3 = this.instance();
|
|
252
|
-
try {
|
|
253
|
-
const data = yield s3.send(new client_s3_2.GetObjectTaggingCommand(params));
|
|
254
|
-
(0, engine_1._log)(NS, `> data =`, engine_1.$U.json(data));
|
|
255
|
-
return (_b = data === null || data === void 0 ? void 0 : data.TagSet) === null || _b === void 0 ? void 0 : _b.reduce((tagSet, tag) => {
|
|
256
|
-
const { Key, Value } = tag;
|
|
257
|
-
tagSet[Key] = Value;
|
|
258
|
-
return tagSet;
|
|
259
|
-
}, {});
|
|
260
|
-
}
|
|
261
|
-
catch (e) {
|
|
262
|
-
(0, engine_1._err)(NS, '! err=', e);
|
|
263
|
-
throw e;
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
/**
|
|
267
|
-
* delete object from bucket
|
|
268
|
-
*
|
|
269
|
-
* @param {string} key
|
|
270
|
-
*/
|
|
271
|
-
this.deleteObject = (key) => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
-
if (!key)
|
|
273
|
-
throw new Error(`@key (string) is required - deleteObject(${key !== null && key !== void 0 ? key : ''})`);
|
|
274
|
-
const Bucket = this.bucket();
|
|
275
|
-
const params = { Bucket, Key: key };
|
|
276
|
-
//* call s3.deleteObject.
|
|
277
|
-
const s3 = this.instance();
|
|
278
|
-
try {
|
|
279
|
-
const data = yield s3.send(new client_s3_2.DeleteObjectCommand(params));
|
|
280
|
-
(0, engine_1._log)(NS, '> data =', engine_1.$U.json(data));
|
|
281
|
-
}
|
|
282
|
-
catch (e) {
|
|
283
|
-
(0, engine_1._err)(NS, '! err=', e);
|
|
284
|
-
throw e;
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
/**
|
|
288
|
-
* list objects in bucket
|
|
289
|
-
*/
|
|
290
|
-
this.listObjects = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
291
|
-
var _c, _d, _e, _f, _g, _h;
|
|
292
|
-
// if (!key) throw new Error('@key is required!');
|
|
293
|
-
const Prefix = (_c = options === null || options === void 0 ? void 0 : options.prefix) !== null && _c !== void 0 ? _c : '';
|
|
294
|
-
const Delimiter = (_d = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _d !== void 0 ? _d : '/';
|
|
295
|
-
const MaxKeys = Math.min((_e = options === null || options === void 0 ? void 0 : options.limit) !== null && _e !== void 0 ? _e : 10, 1000);
|
|
296
|
-
const unlimited = (_f = options === null || options === void 0 ? void 0 : options.unlimited) !== null && _f !== void 0 ? _f : false;
|
|
297
|
-
const nextToken = options === null || options === void 0 ? void 0 : options.nextToken;
|
|
298
|
-
const throwable = (_g = options === null || options === void 0 ? void 0 : options.throwable) !== null && _g !== void 0 ? _g : true;
|
|
299
|
-
//* build the req-params.
|
|
300
|
-
const Bucket = this.bucket();
|
|
301
|
-
const params = {
|
|
302
|
-
Bucket,
|
|
303
|
-
Prefix,
|
|
304
|
-
Delimiter,
|
|
305
|
-
MaxKeys,
|
|
61
|
+
/**
|
|
62
|
+
* environ name to use `bucket`
|
|
63
|
+
*/
|
|
64
|
+
static ENV_S3_NAME = 'MY_S3_BUCKET';
|
|
65
|
+
/**
|
|
66
|
+
* default `bucket` name
|
|
67
|
+
*/
|
|
68
|
+
static DEF_S3_BUCKET = 'lemon-hello-www';
|
|
69
|
+
/**
|
|
70
|
+
* get name of this
|
|
71
|
+
*/
|
|
72
|
+
name = () => `S3`;
|
|
73
|
+
/**
|
|
74
|
+
* hello
|
|
75
|
+
*/
|
|
76
|
+
hello = () => `aws-s3-service:${this.bucket()}`;
|
|
77
|
+
/**
|
|
78
|
+
* get target endpoint by name.
|
|
79
|
+
*/
|
|
80
|
+
bucket = (target) => environ(target, AWSS3Service.ENV_S3_NAME, AWSS3Service.DEF_S3_BUCKET);
|
|
81
|
+
/**
|
|
82
|
+
* get S3Client instance
|
|
83
|
+
* @return S3Client
|
|
84
|
+
*/
|
|
85
|
+
instance() {
|
|
86
|
+
return instance();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* retrieve metadata without returning the object
|
|
90
|
+
*
|
|
91
|
+
* @param {string} key
|
|
92
|
+
* @return metadata object / null if not exists
|
|
93
|
+
*/
|
|
94
|
+
headObject = async (key) => {
|
|
95
|
+
if (!key)
|
|
96
|
+
throw new Error(`@key (string) is required - headObject(${key ?? ''})`);
|
|
97
|
+
const Bucket = this.bucket();
|
|
98
|
+
const params = { Bucket, Key: key };
|
|
99
|
+
// call s3.headObject.
|
|
100
|
+
const s3 = this.instance();
|
|
101
|
+
try {
|
|
102
|
+
const data = await s3.send(new client_s3_2.HeadObjectCommand(params));
|
|
103
|
+
(0, engine_1._log)(NS, '> data =', engine_1.$U.json({ ...data, Contents: undefined }));
|
|
104
|
+
// const sample = {
|
|
105
|
+
// AcceptRanges: 'bytes',
|
|
106
|
+
// ContentLength: 47,
|
|
107
|
+
// ContentType: 'application/json; charset=utf-8',
|
|
108
|
+
// ETag: '"51f209a54902230ac3395826d7fa1851"',
|
|
109
|
+
// Expiration: 'expiry-date="Mon, 10 Apr 2023 00:00:00 GMT", rule-id="delete-old-json"',
|
|
110
|
+
// LastModified: '2023-02-08T14:53:12.000Z',
|
|
111
|
+
// Metadata: { contenttype: 'application/json; charset=utf8', md5: '51f209a54902230ac3395826d7fa1851' },
|
|
112
|
+
// ServerSideEncryption: 'AES256',
|
|
113
|
+
// };
|
|
114
|
+
const result = {
|
|
115
|
+
ContentType: data.ContentType,
|
|
116
|
+
ContentLength: data.ContentLength,
|
|
117
|
+
Metadata: data.Metadata,
|
|
118
|
+
ETag: data.ETag,
|
|
119
|
+
LastModified: engine_1.$U.ts(data.LastModified),
|
|
306
120
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
if (e?.$metadata?.httpStatusCode === 404 || e.name === 'NotFound')
|
|
125
|
+
return null;
|
|
126
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* upload a file to S3 Bucket
|
|
132
|
+
*
|
|
133
|
+
* ```js
|
|
134
|
+
* const res = $s3.putObject(JSON.stringify({ message }), 'test.json');
|
|
135
|
+
* // response would be like
|
|
136
|
+
* {
|
|
137
|
+
* "Bucket": "lemon-hello-www",
|
|
138
|
+
* "ETag": "5e206.....8bd4c",
|
|
139
|
+
* "Key": "test.json",
|
|
140
|
+
* "Location": "https://lemon-hello-www.s3.ap-northeast-2.amazonaws.com/test.json",
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @param {string|Buffer} content content body
|
|
145
|
+
* @param {string} key (optional) S3 key to put
|
|
146
|
+
* @param {Metadata} metadata (optional) metadata to store
|
|
147
|
+
* @param {object} tags (optional) tag set
|
|
148
|
+
*/
|
|
149
|
+
putObject = async (content, key, metadata, tags) => {
|
|
150
|
+
if (!content)
|
|
151
|
+
throw new Error(`@content (buffer) is required - putObject()`);
|
|
152
|
+
const paramBuilder = new S3PutObjectRequestBuilder(this.bucket(), content);
|
|
153
|
+
key && paramBuilder.setKey(key);
|
|
154
|
+
metadata && paramBuilder.setMetadata(metadata);
|
|
155
|
+
tags && paramBuilder.setTags(tags);
|
|
156
|
+
const params = paramBuilder.asParams();
|
|
157
|
+
(0, engine_1._log)(NS, `> params.ContentType =`, params.ContentType);
|
|
158
|
+
(0, engine_1._log)(NS, `> params.ContentLength =`, params.ContentLength);
|
|
159
|
+
(0, engine_1._log)(NS, `> params.Metadata =`, params.Metadata);
|
|
160
|
+
(0, engine_1._log)(NS, `> params.Tagging =`, params.Tagging);
|
|
161
|
+
// call s3.upload()
|
|
162
|
+
const s3 = this.instance();
|
|
163
|
+
try {
|
|
164
|
+
const data = await s3.send(new client_s3_2.PutObjectCommand(params));
|
|
165
|
+
delete data.key; // NOTE: remove undeclared property 'key' returned from aws-sdk
|
|
166
|
+
const location = `https://${params.Bucket}.s3.${region()}.amazonaws.com/${params.Key}`;
|
|
167
|
+
(0, engine_1._log)(NS, `> data[${params.Bucket}].Location =`, engine_1.$U.json(location));
|
|
311
168
|
const result = {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
169
|
+
Bucket: params.Bucket,
|
|
170
|
+
Location: location,
|
|
171
|
+
Key: params.Key,
|
|
172
|
+
ETag: data.ETag,
|
|
173
|
+
ContentType: params.ContentType,
|
|
174
|
+
ContentLength: params.ContentLength,
|
|
175
|
+
Metadata: params.Metadata,
|
|
315
176
|
};
|
|
316
|
-
try {
|
|
317
|
-
const data = yield s3.send(new client_s3_2.ListObjectsV2Command(params));
|
|
318
|
-
//INFO! - minimize log output....
|
|
319
|
-
(0, engine_1._log)(NS, '> data =', engine_1.$U.json(Object.assign(Object.assign({}, data), { Contents: undefined })));
|
|
320
|
-
(0, engine_1._log)(NS, '> data[0] =', engine_1.$U.json((_h = data === null || data === void 0 ? void 0 : data.Contents) === null || _h === void 0 ? void 0 : _h[0]));
|
|
321
|
-
if (data) {
|
|
322
|
-
result.Contents = data.Contents;
|
|
323
|
-
result.MaxKeys = data.MaxKeys;
|
|
324
|
-
result.KeyCount = data.KeyCount;
|
|
325
|
-
result.IsTruncated = data.IsTruncated;
|
|
326
|
-
result.NextContinuationToken = data.NextContinuationToken;
|
|
327
|
-
}
|
|
328
|
-
//* list all keys.
|
|
329
|
-
if (unlimited) {
|
|
330
|
-
while (result.IsTruncated) {
|
|
331
|
-
//* fetch next list.
|
|
332
|
-
const res2 = yield s3.send(new client_s3_2.ListObjectsV2Command(Object.assign(Object.assign({}, params), { ContinuationToken: result.NextContinuationToken })));
|
|
333
|
-
//* update contents.
|
|
334
|
-
result.Contents = result.Contents.concat(0 ? res2.Contents.slice(1) : res2.Contents);
|
|
335
|
-
result.IsTruncated = res2.IsTruncated;
|
|
336
|
-
result.KeyCount += engine_1.$U.N(res2.KeyCount, 0);
|
|
337
|
-
result.NextContinuationToken = res2.NextContinuationToken;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
catch (e) {
|
|
342
|
-
(0, engine_1._err)(NS, '! err=', e);
|
|
343
|
-
if (throwable)
|
|
344
|
-
throw e;
|
|
345
|
-
result.error = (0, test_helper_1.GETERR)(e);
|
|
346
|
-
}
|
|
347
|
-
// returns.
|
|
348
177
|
return result;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
(0, engine_1._err)(NS, `! err[${params.Bucket}] =`, e);
|
|
181
|
+
throw e;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* get a file from S3 Bucket
|
|
186
|
+
*
|
|
187
|
+
* @param {string} key
|
|
188
|
+
*/
|
|
189
|
+
getObject = async (key) => {
|
|
190
|
+
if (!key)
|
|
191
|
+
throw new Error(`@key (string) is required - getObject(${key ?? ''})`);
|
|
192
|
+
const Bucket = this.bucket();
|
|
193
|
+
const params = { Bucket, Key: key };
|
|
194
|
+
//* call s3.getObject.
|
|
195
|
+
const s3 = this.instance();
|
|
196
|
+
try {
|
|
197
|
+
const data = await s3.send(new client_s3_2.GetObjectCommand(params));
|
|
198
|
+
(0, engine_1._log)(NS, '> data.type =', typeof data);
|
|
199
|
+
const { ContentType, ContentLength, Body, ETag, Metadata, TagCount } = data;
|
|
200
|
+
// convert stream to buffer for readable stream.
|
|
201
|
+
const buffer = Body && Body instanceof stream_1.Readable ? await this.streamToBuffer(Body) : undefined;
|
|
202
|
+
const result = { ContentType, ContentLength, Body: buffer, ETag, Metadata };
|
|
203
|
+
if (TagCount)
|
|
204
|
+
result.TagCount = TagCount;
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
209
|
+
throw e;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* return decoded Object from bucket file.
|
|
214
|
+
*
|
|
215
|
+
* @param {string} key ex) 'hello-0001.json' , 'dist/hello-0001.json
|
|
216
|
+
*/
|
|
217
|
+
getDecodedObject = async (key) => {
|
|
218
|
+
if (!key)
|
|
219
|
+
throw new Error(`@key (string) is required - getDecodedObject(${key ?? ''})`);
|
|
220
|
+
const Bucket = this.bucket();
|
|
221
|
+
const params = { Bucket, Key: key };
|
|
222
|
+
//* call s3.getObject.
|
|
223
|
+
const s3 = this.instance();
|
|
224
|
+
try {
|
|
225
|
+
const data = await s3.send(new client_s3_2.GetObjectCommand(params));
|
|
226
|
+
(0, engine_1._log)(NS, '> data.type =', typeof data);
|
|
227
|
+
const buffer = data.Body && data.Body instanceof stream_1.Readable ? await this.streamToBuffer(data.Body) : undefined;
|
|
228
|
+
const content = buffer?.toString();
|
|
229
|
+
return JSON.parse(content);
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
233
|
+
throw e;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* get tag-set of object
|
|
238
|
+
*
|
|
239
|
+
* @param {string} key
|
|
240
|
+
*/
|
|
241
|
+
getObjectTagging = async (key) => {
|
|
242
|
+
if (!key)
|
|
243
|
+
throw new Error(`@key (string) is required - getObjectTagging(${key ?? ''})`);
|
|
244
|
+
const Bucket = this.bucket();
|
|
245
|
+
const params = { Bucket, Key: key };
|
|
246
|
+
//* call s3.getObjectTagging.
|
|
247
|
+
const s3 = this.instance();
|
|
248
|
+
try {
|
|
249
|
+
const data = await s3.send(new client_s3_2.GetObjectTaggingCommand(params));
|
|
250
|
+
(0, engine_1._log)(NS, `> data =`, engine_1.$U.json(data));
|
|
251
|
+
return data?.TagSet?.reduce((tagSet, tag) => {
|
|
252
|
+
const { Key, Value } = tag;
|
|
253
|
+
tagSet[Key] = Value;
|
|
254
|
+
return tagSet;
|
|
255
|
+
}, {});
|
|
256
|
+
}
|
|
257
|
+
catch (e) {
|
|
258
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
259
|
+
throw e;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* delete object from bucket
|
|
264
|
+
*
|
|
265
|
+
* @param {string} key
|
|
266
|
+
*/
|
|
267
|
+
deleteObject = async (key) => {
|
|
268
|
+
if (!key)
|
|
269
|
+
throw new Error(`@key (string) is required - deleteObject(${key ?? ''})`);
|
|
270
|
+
const Bucket = this.bucket();
|
|
271
|
+
const params = { Bucket, Key: key };
|
|
272
|
+
//* call s3.deleteObject.
|
|
273
|
+
const s3 = this.instance();
|
|
274
|
+
try {
|
|
275
|
+
const data = await s3.send(new client_s3_2.DeleteObjectCommand(params));
|
|
276
|
+
(0, engine_1._log)(NS, '> data =', engine_1.$U.json(data));
|
|
277
|
+
}
|
|
278
|
+
catch (e) {
|
|
279
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
280
|
+
throw e;
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* list objects in bucket
|
|
285
|
+
*/
|
|
286
|
+
listObjects = async (options) => {
|
|
287
|
+
// if (!key) throw new Error('@key is required!');
|
|
288
|
+
const Prefix = options?.prefix ?? '';
|
|
289
|
+
const Delimiter = options?.delimiter ?? '/';
|
|
290
|
+
const MaxKeys = Math.min(options?.limit ?? 10, 1000);
|
|
291
|
+
const unlimited = options?.unlimited ?? false;
|
|
292
|
+
const nextToken = options?.nextToken;
|
|
293
|
+
const throwable = options?.throwable ?? true;
|
|
294
|
+
//* build the req-params.
|
|
295
|
+
const Bucket = this.bucket();
|
|
296
|
+
const params = {
|
|
297
|
+
Bucket,
|
|
298
|
+
Prefix,
|
|
299
|
+
Delimiter,
|
|
300
|
+
MaxKeys,
|
|
301
|
+
};
|
|
302
|
+
if (nextToken)
|
|
303
|
+
params.ContinuationToken = nextToken;
|
|
304
|
+
//* call s3.listObjectsV2.
|
|
305
|
+
const s3 = this.instance();
|
|
306
|
+
const result = {
|
|
307
|
+
Contents: null,
|
|
308
|
+
MaxKeys,
|
|
309
|
+
KeyCount: 0,
|
|
310
|
+
};
|
|
311
|
+
try {
|
|
312
|
+
const data = await s3.send(new client_s3_2.ListObjectsV2Command(params));
|
|
313
|
+
//INFO! - minimize log output....
|
|
314
|
+
(0, engine_1._log)(NS, '> data =', engine_1.$U.json({ ...data, Contents: undefined }));
|
|
315
|
+
(0, engine_1._log)(NS, '> data[0] =', engine_1.$U.json(data?.Contents?.[0]));
|
|
316
|
+
if (data) {
|
|
317
|
+
result.Contents = data.Contents;
|
|
318
|
+
result.MaxKeys = data.MaxKeys;
|
|
319
|
+
result.KeyCount = data.KeyCount;
|
|
320
|
+
result.IsTruncated = data.IsTruncated;
|
|
321
|
+
result.NextContinuationToken = data.NextContinuationToken;
|
|
364
322
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
323
|
+
//* list all keys.
|
|
324
|
+
if (unlimited) {
|
|
325
|
+
while (result.IsTruncated) {
|
|
326
|
+
//* fetch next list.
|
|
327
|
+
const res2 = await s3.send(new client_s3_2.ListObjectsV2Command({ ...params, ContinuationToken: result.NextContinuationToken }));
|
|
328
|
+
//* update contents.
|
|
329
|
+
result.Contents = result.Contents.concat(0 ? res2.Contents.slice(1) : res2.Contents);
|
|
330
|
+
result.IsTruncated = res2.IsTruncated;
|
|
331
|
+
result.KeyCount += engine_1.$U.N(res2.KeyCount, 0);
|
|
332
|
+
result.NextContinuationToken = res2.NextContinuationToken;
|
|
369
333
|
}
|
|
370
|
-
finally { if (e_1) throw e_1.error; }
|
|
371
334
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
335
|
+
}
|
|
336
|
+
catch (e) {
|
|
337
|
+
(0, engine_1._err)(NS, '! err=', e);
|
|
338
|
+
if (throwable)
|
|
339
|
+
throw e;
|
|
340
|
+
result.error = (0, test_helper_1.GETERR)(e);
|
|
341
|
+
}
|
|
342
|
+
// returns.
|
|
343
|
+
return result;
|
|
344
|
+
};
|
|
375
345
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
346
|
+
* Convert a readable stream into a single Buffer.
|
|
347
|
+
* Required in AWS SDK v3, as S3.getObject() returns a stream instead of a Buffer.
|
|
348
|
+
*
|
|
349
|
+
* Used for JSON parsing in getDecodedObject() and getObject().
|
|
378
350
|
*/
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
351
|
+
streamToBuffer = async (stream) => {
|
|
352
|
+
const chunks = [];
|
|
353
|
+
for await (const chunk of stream) {
|
|
354
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
|
|
355
|
+
}
|
|
356
|
+
return Buffer.concat(chunks);
|
|
357
|
+
};
|
|
382
358
|
}
|
|
383
359
|
exports.AWSS3Service = AWSS3Service;
|
|
384
|
-
/**
|
|
385
|
-
* environ name to use `bucket`
|
|
386
|
-
*/
|
|
387
|
-
AWSS3Service.ENV_S3_NAME = 'MY_S3_BUCKET';
|
|
388
|
-
/**
|
|
389
|
-
* default `bucket` name
|
|
390
|
-
*/
|
|
391
|
-
AWSS3Service.DEF_S3_BUCKET = 'lemon-hello-www';
|
|
392
360
|
/**
|
|
393
361
|
* class `S3PutObjectRequestBuilder`
|
|
394
362
|
* - util class to build S3.PutObjectRequest parameter
|
|
395
363
|
*/
|
|
396
364
|
class S3PutObjectRequestBuilder {
|
|
365
|
+
// properties consisting S3.PutObjectRequest
|
|
366
|
+
Body;
|
|
367
|
+
Bucket;
|
|
368
|
+
ContentLength;
|
|
369
|
+
ContentType;
|
|
370
|
+
Key;
|
|
371
|
+
Metadata;
|
|
372
|
+
Tagging;
|
|
397
373
|
/**
|
|
398
374
|
* constructor
|
|
399
375
|
*/
|
|
400
376
|
constructor(bucket, content) {
|
|
401
|
-
/**
|
|
402
|
-
* guess content-type from filename
|
|
403
|
-
* @param filename
|
|
404
|
-
* @private
|
|
405
|
-
*/
|
|
406
|
-
this.getContentType = (filename) => {
|
|
407
|
-
const extname = path_1.default.extname(filename);
|
|
408
|
-
return mime_types_1.default.contentType(extname) || undefined;
|
|
409
|
-
};
|
|
410
377
|
const buffer = typeof content === 'string' ? Buffer.from(content) : content;
|
|
411
378
|
this.Body = buffer;
|
|
412
379
|
this.Bucket = bucket;
|
|
@@ -436,7 +403,7 @@ class S3PutObjectRequestBuilder {
|
|
|
436
403
|
else if (metadata.origin) {
|
|
437
404
|
this.ContentType = this.getContentType(metadata.origin);
|
|
438
405
|
}
|
|
439
|
-
this.Metadata =
|
|
406
|
+
this.Metadata = { md5: this.Metadata.md5, ...metadata }; // preserve 'md5' field
|
|
440
407
|
return this;
|
|
441
408
|
}
|
|
442
409
|
/**
|
|
@@ -465,5 +432,14 @@ class S3PutObjectRequestBuilder {
|
|
|
465
432
|
ContentType = this.getContentType(Key);
|
|
466
433
|
return { Bucket, Key, Body, ContentLength, ContentType, Metadata, Tagging };
|
|
467
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* guess content-type from filename
|
|
437
|
+
* @param filename
|
|
438
|
+
* @private
|
|
439
|
+
*/
|
|
440
|
+
getContentType = (filename) => {
|
|
441
|
+
const extname = path_1.default.extname(filename);
|
|
442
|
+
return mime_types_1.default.contentType(extname) || undefined;
|
|
443
|
+
};
|
|
468
444
|
}
|
|
469
445
|
//# sourceMappingURL=aws-s3-service.js.map
|