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.
Files changed (154) hide show
  1. package/dist/common/test-helper.d.ts +2 -2
  2. package/dist/common/test-helper.js +24 -26
  3. package/dist/common/test-helper.js.map +1 -1
  4. package/dist/controllers/dummy-controller.js +39 -46
  5. package/dist/controllers/dummy-controller.js.map +1 -1
  6. package/dist/controllers/general-api-controller.js +95 -100
  7. package/dist/controllers/general-api-controller.js.map +1 -1
  8. package/dist/controllers/general-controller.js +81 -82
  9. package/dist/controllers/general-controller.js.map +1 -1
  10. package/dist/cores/api/api-service.d.ts +1 -1
  11. package/dist/cores/api/api-service.js +228 -269
  12. package/dist/cores/api/api-service.js.map +1 -1
  13. package/dist/cores/aws/aws-kms-service.d.ts +1 -2
  14. package/dist/cores/aws/aws-kms-service.js +143 -153
  15. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  16. package/dist/cores/aws/aws-s3-service.d.ts +2 -4
  17. package/dist/cores/aws/aws-s3-service.js +306 -330
  18. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  19. package/dist/cores/aws/aws-sns-service.js +147 -153
  20. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  21. package/dist/cores/aws/aws-sqs-service.js +149 -170
  22. package/dist/cores/aws/aws-sqs-service.js.map +1 -1
  23. package/dist/cores/aws/index.js +10 -20
  24. package/dist/cores/aws/index.js.map +1 -1
  25. package/dist/cores/cache/cache-service.d.ts +2 -2
  26. package/dist/cores/cache/cache-service.js +435 -499
  27. package/dist/cores/cache/cache-service.js.map +1 -1
  28. package/dist/cores/config/config-service.d.ts +1 -1
  29. package/dist/cores/config/config-service.js +56 -63
  30. package/dist/cores/config/config-service.js.map +1 -1
  31. package/dist/cores/config/index.js +14 -24
  32. package/dist/cores/config/index.js.map +1 -1
  33. package/dist/cores/core-services.d.ts +1 -1
  34. package/dist/cores/dynamo/dynamo-query-service.js +37 -51
  35. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
  36. package/dist/cores/dynamo/dynamo-scan-service.d.ts +2 -2
  37. package/dist/cores/dynamo/dynamo-scan-service.js +29 -40
  38. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
  39. package/dist/cores/dynamo/dynamo-service.d.ts +2 -2
  40. package/dist/cores/dynamo/dynamo-service.js +528 -601
  41. package/dist/cores/dynamo/dynamo-service.js.map +1 -1
  42. package/dist/cores/dynamo/tools/expressions.js +17 -7
  43. package/dist/cores/dynamo/tools/expressions.js.map +1 -1
  44. package/dist/cores/dynamo/tools/query.js +142 -127
  45. package/dist/cores/dynamo/tools/query.js.map +1 -1
  46. package/dist/cores/dynamo/tools/scan.js +111 -97
  47. package/dist/cores/dynamo/tools/scan.js.map +1 -1
  48. package/dist/cores/dynamo/tools/serializer.js +17 -7
  49. package/dist/cores/dynamo/tools/serializer.js.map +1 -1
  50. package/dist/cores/dynamo/tools/utils.d.ts +0 -2
  51. package/dist/cores/dynamo/tools/utils.js.map +1 -1
  52. package/dist/cores/elastic/elastic6-query-service.js +307 -324
  53. package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
  54. package/dist/cores/elastic/elastic6-service.d.ts +3 -3
  55. package/dist/cores/elastic/elastic6-service.js +568 -647
  56. package/dist/cores/elastic/elastic6-service.js.map +1 -1
  57. package/dist/cores/elastic/hangul-service.js +52 -54
  58. package/dist/cores/elastic/hangul-service.js.map +1 -1
  59. package/dist/cores/lambda/index.js +42 -36
  60. package/dist/cores/lambda/index.js.map +1 -1
  61. package/dist/cores/lambda/lambda-alb-handler.d.ts +2 -2
  62. package/dist/cores/lambda/lambda-alb-handler.js +59 -72
  63. package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
  64. package/dist/cores/lambda/lambda-cognito-handler.js +10 -19
  65. package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
  66. package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
  67. package/dist/cores/lambda/lambda-cron-handler.js +14 -23
  68. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  69. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
  70. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +57 -67
  71. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  72. package/dist/cores/lambda/lambda-handler.d.ts +22 -22
  73. package/dist/cores/lambda/lambda-handler.js +93 -106
  74. package/dist/cores/lambda/lambda-handler.js.map +1 -1
  75. package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
  76. package/dist/cores/lambda/lambda-notification-handler.js +39 -50
  77. package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
  78. package/dist/cores/lambda/lambda-sns-handler.js +79 -88
  79. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  80. package/dist/cores/lambda/lambda-sqs-handler.js +79 -88
  81. package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
  82. package/dist/cores/lambda/lambda-web-handler.d.ts +21 -43
  83. package/dist/cores/lambda/lambda-web-handler.js +392 -482
  84. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  85. package/dist/cores/lambda/lambda-wss-handler.js +23 -32
  86. package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
  87. package/dist/cores/protocol/index.js +10 -20
  88. package/dist/cores/protocol/index.js.map +1 -1
  89. package/dist/cores/protocol/protocol-service.d.ts +3 -3
  90. package/dist/cores/protocol/protocol-service.js +235 -227
  91. package/dist/cores/protocol/protocol-service.js.map +1 -1
  92. package/dist/cores/storage/http-storage-service.js +65 -85
  93. package/dist/cores/storage/http-storage-service.js.map +1 -1
  94. package/dist/cores/storage/model-manager.js +66 -85
  95. package/dist/cores/storage/model-manager.js.map +1 -1
  96. package/dist/cores/storage/proxy-storage-service.d.ts +2 -2
  97. package/dist/cores/storage/proxy-storage-service.js +562 -599
  98. package/dist/cores/storage/proxy-storage-service.js.map +1 -1
  99. package/dist/cores/storage/redis-storage-service.js +163 -177
  100. package/dist/cores/storage/redis-storage-service.js.map +1 -1
  101. package/dist/cores/storage/storage-service.js +281 -322
  102. package/dist/cores/storage/storage-service.js.map +1 -1
  103. package/dist/engine/builder.d.ts +1 -1
  104. package/dist/engine/builder.js +59 -63
  105. package/dist/engine/builder.js.map +1 -1
  106. package/dist/engine/engine.d.ts +4 -4
  107. package/dist/engine/engine.js +9 -18
  108. package/dist/engine/engine.js.map +1 -1
  109. package/dist/engine/types.d.ts +1 -1
  110. package/dist/engine/utilities.d.ts +14 -10
  111. package/dist/engine/utilities.js +301 -280
  112. package/dist/engine/utilities.js.map +1 -1
  113. package/dist/environ.js +4 -6
  114. package/dist/environ.js.map +1 -1
  115. package/dist/extended/abstract-service.js +595 -645
  116. package/dist/extended/abstract-service.js.map +1 -1
  117. package/dist/extended/libs/sig-v4.js.map +1 -1
  118. package/dist/generated/field-registry.d.ts +10 -0
  119. package/dist/generated/field-registry.js +17 -0
  120. package/dist/generated/field-registry.js.map +1 -0
  121. package/dist/helpers/helpers.d.ts +17 -9
  122. package/dist/helpers/helpers.js +88 -78
  123. package/dist/helpers/helpers.js.map +1 -1
  124. package/dist/index.js +17 -7
  125. package/dist/index.js.map +1 -1
  126. package/dist/lib/dynamodb-value.js +2 -3
  127. package/dist/lib/dynamodb-value.js.map +1 -1
  128. package/dist/tools/express.js +4 -5
  129. package/dist/tools/express.js.map +1 -1
  130. package/dist/tools/tools.d.ts +3 -1
  131. package/dist/tools/tools.js +14 -21
  132. package/dist/tools/tools.js.map +1 -1
  133. package/package.json +19 -18
  134. package/dist/exec-cli.d.ts +0 -2
  135. package/dist/exec-cli.js +0 -211
  136. package/dist/exec-cli.js.map +0 -1
  137. package/dist/lib/dynamo/expressions.d.ts +0 -14
  138. package/dist/lib/dynamo/expressions.js +0 -212
  139. package/dist/lib/dynamo/expressions.js.map +0 -1
  140. package/dist/lib/dynamo/query.d.ts +0 -43
  141. package/dist/lib/dynamo/query.js +0 -246
  142. package/dist/lib/dynamo/query.js.map +0 -1
  143. package/dist/lib/dynamo/scan.d.ts +0 -33
  144. package/dist/lib/dynamo/scan.js +0 -172
  145. package/dist/lib/dynamo/scan.js.map +0 -1
  146. package/dist/lib/dynamo/serializer.d.ts +0 -12
  147. package/dist/lib/dynamo/serializer.js +0 -243
  148. package/dist/lib/dynamo/serializer.js.map +0 -1
  149. package/dist/lib/dynamo/utils.d.ts +0 -15
  150. package/dist/lib/dynamo/utils.js +0 -129
  151. package/dist/lib/dynamo/utils.js.map +0 -1
  152. package/dist/tools/shared.d.ts +0 -37
  153. package/dist/tools/shared.js +0 -130
  154. 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
- constructor() {
78
- /**
79
- * get name of this
80
- */
81
- this.name = () => `S3`;
82
- /**
83
- * hello
84
- */
85
- this.hello = () => `aws-s3-service:${this.bucket()}`;
86
- /**
87
- * get target endpoint by name.
88
- */
89
- this.bucket = (target) => environ(target, AWSS3Service.ENV_S3_NAME, AWSS3Service.DEF_S3_BUCKET);
90
- /**
91
- * retrieve metadata without returning the object
92
- *
93
- * @param {string} key
94
- * @return metadata object / null if not exists
95
- */
96
- this.headObject = (key) => __awaiter(this, void 0, void 0, function* () {
97
- var _a;
98
- if (!key)
99
- throw new Error(`@key (string) is required - headObject(${key !== null && key !== void 0 ? key : ''})`);
100
- const Bucket = this.bucket();
101
- const params = { Bucket, Key: key };
102
- // call s3.headObject.
103
- const s3 = this.instance();
104
- try {
105
- const data = yield s3.send(new client_s3_2.HeadObjectCommand(params));
106
- (0, engine_1._log)(NS, '> data =', engine_1.$U.json(Object.assign(Object.assign({}, data), { Contents: undefined })));
107
- // const sample = {
108
- // AcceptRanges: 'bytes',
109
- // ContentLength: 47,
110
- // ContentType: 'application/json; charset=utf-8',
111
- // ETag: '"51f209a54902230ac3395826d7fa1851"',
112
- // Expiration: 'expiry-date="Mon, 10 Apr 2023 00:00:00 GMT", rule-id="delete-old-json"',
113
- // LastModified: '2023-02-08T14:53:12.000Z',
114
- // Metadata: { contenttype: 'application/json; charset=utf8', md5: '51f209a54902230ac3395826d7fa1851' },
115
- // ServerSideEncryption: 'AES256',
116
- // };
117
- const result = {
118
- ContentType: data.ContentType,
119
- ContentLength: data.ContentLength,
120
- Metadata: data.Metadata,
121
- ETag: data.ETag,
122
- LastModified: engine_1.$U.ts(data.LastModified),
123
- };
124
- return result;
125
- }
126
- catch (e) {
127
- if (((_a = e === null || e === void 0 ? void 0 : e.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 404 || e.name === 'NotFound')
128
- return null;
129
- (0, engine_1._err)(NS, '! err=', e);
130
- throw e;
131
- }
132
- });
133
- /**
134
- * upload a file to S3 Bucket
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
- if (nextToken)
308
- params.ContinuationToken = nextToken;
309
- //* call s3.listObjectsV2.
310
- const s3 = this.instance();
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
- Contents: null,
313
- MaxKeys,
314
- KeyCount: 0,
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
- * Convert a readable stream into a single Buffer.
352
- * Required in AWS SDK v3, as S3.getObject() returns a stream instead of a Buffer.
353
- *
354
- * Used for JSON parsing in getDecodedObject() and getObject().
355
- */
356
- this.streamToBuffer = (stream) => { var stream_2, stream_2_1; return __awaiter(this, void 0, void 0, function* () {
357
- var e_1, _a;
358
- const chunks = [];
359
- try {
360
- for (stream_2 = __asyncValues(stream); stream_2_1 = yield stream_2.next(), !stream_2_1.done;) {
361
- const chunk = stream_2_1.value;
362
- chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
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
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
366
- finally {
367
- try {
368
- if (stream_2_1 && !stream_2_1.done && (_a = stream_2.return)) yield _a.call(stream_2);
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
- return Buffer.concat(chunks);
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
- * get S3Client instance
377
- * @return S3Client
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
- instance() {
380
- return instance();
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 = Object.assign({ md5: this.Metadata.md5 }, metadata); // preserve 'md5' field
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