lemon-core 3.0.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/README.md +13 -21
  2. package/dist/common/test-helper.js +19 -11
  3. package/dist/common/test-helper.js.map +1 -1
  4. package/dist/controllers/dummy-controller.d.ts +1 -1
  5. package/dist/controllers/dummy-controller.js +2 -2
  6. package/dist/controllers/dummy-controller.js.map +1 -1
  7. package/dist/controllers/general-api-controller.d.ts +1 -1
  8. package/dist/controllers/general-api-controller.js +5 -5
  9. package/dist/controllers/general-api-controller.js.map +1 -1
  10. package/dist/controllers/general-controller.js +2 -1
  11. package/dist/controllers/general-controller.js.map +1 -1
  12. package/dist/controllers/index.js +6 -2
  13. package/dist/controllers/index.js.map +1 -1
  14. package/dist/cores/api/api-service.d.ts +239 -0
  15. package/dist/cores/api/api-service.js +674 -0
  16. package/dist/cores/api/api-service.js.map +1 -0
  17. package/dist/cores/api/index.d.ts +10 -0
  18. package/dist/cores/api/index.js +27 -0
  19. package/dist/cores/api/index.js.map +1 -0
  20. package/dist/cores/api-service.js +19 -18
  21. package/dist/cores/api-service.js.map +1 -1
  22. package/dist/cores/aws/aws-kms-service.d.ts +53 -2
  23. package/dist/cores/aws/aws-kms-service.js +112 -29
  24. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  25. package/dist/cores/aws/aws-s3-service.js +19 -18
  26. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  27. package/dist/cores/aws/aws-sns-service.js +10 -10
  28. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  29. package/dist/cores/aws/aws-sqs-service.js +12 -12
  30. package/dist/cores/aws/aws-sqs-service.js.map +1 -1
  31. package/dist/cores/aws/index.js +1 -1
  32. package/dist/cores/cache/cache-service.d.ts +440 -0
  33. package/dist/cores/cache/cache-service.js +967 -0
  34. package/dist/cores/cache/cache-service.js.map +1 -0
  35. package/dist/cores/cache/index.d.ts +10 -0
  36. package/dist/cores/cache/index.js +27 -0
  37. package/dist/cores/cache/index.js.map +1 -0
  38. package/dist/cores/cache-service.d.ts +54 -18
  39. package/dist/cores/cache-service.js +56 -45
  40. package/dist/cores/cache-service.js.map +1 -1
  41. package/dist/cores/config/config-service.js +11 -10
  42. package/dist/cores/config/config-service.js.map +1 -1
  43. package/dist/cores/core-services.js +6 -2
  44. package/dist/cores/core-services.js.map +1 -1
  45. package/dist/cores/core-types.d.ts +42 -12
  46. package/dist/cores/dynamo/dynamo-query-service.d.ts +52 -0
  47. package/dist/cores/dynamo/dynamo-query-service.js +127 -0
  48. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -0
  49. package/dist/cores/dynamo/dynamo-scan-service.d.ts +70 -0
  50. package/dist/cores/dynamo/dynamo-scan-service.js +164 -0
  51. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -0
  52. package/dist/cores/dynamo/dynamo-service.d.ts +192 -0
  53. package/dist/cores/dynamo/dynamo-service.js +525 -0
  54. package/dist/cores/dynamo/dynamo-service.js.map +1 -0
  55. package/dist/cores/dynamo/index.d.ts +12 -0
  56. package/dist/cores/dynamo/index.js +29 -0
  57. package/dist/cores/dynamo/index.js.map +1 -0
  58. package/dist/cores/dynamo-query-service.js +7 -7
  59. package/dist/cores/dynamo-query-service.js.map +1 -1
  60. package/dist/cores/dynamo-scan-service.js +8 -8
  61. package/dist/cores/dynamo-scan-service.js.map +1 -1
  62. package/dist/cores/dynamo-service.js +19 -19
  63. package/dist/cores/dynamo-service.js.map +1 -1
  64. package/dist/cores/elastic/elastic6-query-service.d.ts +104 -0
  65. package/dist/cores/elastic/elastic6-query-service.js +510 -0
  66. package/dist/cores/elastic/elastic6-query-service.js.map +1 -0
  67. package/dist/cores/elastic/elastic6-service.d.ts +273 -0
  68. package/dist/cores/elastic/elastic6-service.js +903 -0
  69. package/dist/cores/elastic/elastic6-service.js.map +1 -0
  70. package/dist/cores/elastic/hangul-service.d.ts +102 -0
  71. package/dist/cores/elastic/hangul-service.js +205 -0
  72. package/dist/cores/elastic/hangul-service.js.map +1 -0
  73. package/dist/cores/elastic/index.d.ts +12 -0
  74. package/dist/cores/elastic/index.js +29 -0
  75. package/dist/cores/elastic/index.js.map +1 -0
  76. package/dist/cores/elastic6-query-service.js +7 -7
  77. package/dist/cores/elastic6-query-service.js.map +1 -1
  78. package/dist/cores/elastic6-service.js +57 -65
  79. package/dist/cores/elastic6-service.js.map +1 -1
  80. package/dist/cores/hangul-service.d.ts +17 -3
  81. package/dist/cores/hangul-service.js +17 -8
  82. package/dist/cores/hangul-service.js.map +1 -1
  83. package/dist/cores/http-storage-service.js +1 -1
  84. package/dist/cores/http-storage-service.js.map +1 -1
  85. package/dist/cores/index.d.ts +9 -15
  86. package/dist/cores/index.js +14 -15
  87. package/dist/cores/index.js.map +1 -1
  88. package/dist/cores/lambda/index.js +8 -4
  89. package/dist/cores/lambda/index.js.map +1 -1
  90. package/dist/cores/lambda/lambda-cognito-handler.js +2 -2
  91. package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
  92. package/dist/cores/lambda/lambda-cron-handler.js +2 -2
  93. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  94. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
  95. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +20 -20
  96. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  97. package/dist/cores/lambda/lambda-handler.js +12 -11
  98. package/dist/cores/lambda/lambda-handler.js.map +1 -1
  99. package/dist/cores/lambda/lambda-notification-handler.js +10 -10
  100. package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
  101. package/dist/cores/lambda/lambda-sns-handler.js +13 -13
  102. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  103. package/dist/cores/lambda/lambda-sqs-handler.js +13 -13
  104. package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
  105. package/dist/cores/lambda/lambda-web-handler.d.ts +158 -8
  106. package/dist/cores/lambda/lambda-web-handler.js +330 -119
  107. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  108. package/dist/cores/lambda/lambda-wss-handler.js +16 -12
  109. package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
  110. package/dist/cores/model-manager.js +11 -11
  111. package/dist/cores/model-manager.js.map +1 -1
  112. package/dist/cores/protocol/protocol-service.d.ts +4 -0
  113. package/dist/cores/protocol/protocol-service.js +46 -40
  114. package/dist/cores/protocol/protocol-service.js.map +1 -1
  115. package/dist/cores/proxy-storage-service.js +7 -10
  116. package/dist/cores/proxy-storage-service.js.map +1 -1
  117. package/dist/cores/redis-storage-service.js +13 -13
  118. package/dist/cores/redis-storage-service.js.map +1 -1
  119. package/dist/cores/storage/http-storage-service.d.ts +22 -0
  120. package/dist/cores/storage/http-storage-service.js +129 -0
  121. package/dist/cores/storage/http-storage-service.js.map +1 -0
  122. package/dist/cores/storage/index.d.ts +14 -0
  123. package/dist/cores/storage/index.js +31 -0
  124. package/dist/cores/storage/index.js.map +1 -0
  125. package/dist/cores/storage/model-manager.d.ts +93 -0
  126. package/dist/cores/storage/model-manager.js +192 -0
  127. package/dist/cores/storage/model-manager.js.map +1 -0
  128. package/dist/cores/storage/proxy-storage-service.d.ts +573 -0
  129. package/dist/cores/storage/proxy-storage-service.js +913 -0
  130. package/dist/cores/storage/proxy-storage-service.js.map +1 -0
  131. package/dist/cores/storage/redis-storage-service.d.ts +183 -0
  132. package/dist/cores/storage/redis-storage-service.js +391 -0
  133. package/dist/cores/storage/redis-storage-service.js.map +1 -0
  134. package/dist/cores/storage/storage-service.d.ts +169 -0
  135. package/dist/cores/storage/storage-service.js +374 -0
  136. package/dist/cores/storage/storage-service.js.map +1 -0
  137. package/dist/cores/storage-service.d.ts +1 -1
  138. package/dist/cores/storage-service.js +10 -8
  139. package/dist/cores/storage-service.js.map +1 -1
  140. package/dist/engine/builder.js +27 -20
  141. package/dist/engine/builder.js.map +1 -1
  142. package/dist/engine/engine.js +53 -44
  143. package/dist/engine/engine.js.map +1 -1
  144. package/dist/engine/index.js +8 -4
  145. package/dist/engine/index.js.map +1 -1
  146. package/dist/engine/utilities.d.ts +4 -3
  147. package/dist/engine/utilities.js +32 -37
  148. package/dist/engine/utilities.js.map +1 -1
  149. package/dist/environ.d.ts +2 -2
  150. package/dist/environ.js +20 -10
  151. package/dist/environ.js.map +1 -1
  152. package/dist/exec-cli.js +26 -26
  153. package/dist/exec-cli.js.map +1 -1
  154. package/dist/extended/abstract-service.d.ts +533 -0
  155. package/dist/extended/abstract-service.js +915 -0
  156. package/dist/extended/abstract-service.js.map +1 -0
  157. package/dist/extended/index.d.ts +10 -0
  158. package/dist/extended/index.js +27 -0
  159. package/dist/extended/index.js.map +1 -0
  160. package/dist/helpers/helpers.d.ts +273 -0
  161. package/dist/helpers/helpers.js +613 -0
  162. package/dist/helpers/helpers.js.map +1 -0
  163. package/dist/helpers/index.d.ts +10 -0
  164. package/dist/helpers/index.js +27 -0
  165. package/dist/helpers/index.js.map +1 -0
  166. package/dist/index.d.ts +7 -5
  167. package/dist/index.js +11 -4
  168. package/dist/index.js.map +1 -1
  169. package/dist/lib/dynamo/expressions.js +35 -27
  170. package/dist/lib/dynamo/expressions.js.map +1 -1
  171. package/dist/lib/dynamo/query.js +24 -20
  172. package/dist/lib/dynamo/query.js.map +1 -1
  173. package/dist/lib/dynamo/scan.js +17 -13
  174. package/dist/lib/dynamo/scan.js.map +1 -1
  175. package/dist/lib/dynamo/serializer.js +11 -7
  176. package/dist/lib/dynamo/serializer.js.map +1 -1
  177. package/dist/lib/dynamo/utils.js +19 -14
  178. package/dist/lib/dynamo/utils.js.map +1 -1
  179. package/dist/lib/dynamodb-value.js +3 -3
  180. package/dist/lib/dynamodb-value.js.map +1 -1
  181. package/dist/lib/index.js +6 -2
  182. package/dist/lib/index.js.map +1 -1
  183. package/dist/tools/express.js +21 -15
  184. package/dist/tools/express.js.map +1 -1
  185. package/dist/tools/index.js +6 -2
  186. package/dist/tools/index.js.map +1 -1
  187. package/dist/tools/shared.js +12 -6
  188. package/dist/tools/shared.js.map +1 -1
  189. package/package.json +16 -15
@@ -0,0 +1,915 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
35
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
36
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
37
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
38
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
39
+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
40
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
41
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
42
+ function fulfill(value) { resume("next", value); }
43
+ function reject(value) { resume("throw", value); }
44
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
45
+ };
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.$ES6 = exports.sourceToItem = exports.Elastic6Instance = exports.Elastic6Synchronizer = exports.AbstractProxy = exports.ManagerProxy = exports.CoreManager = exports.CoreService = exports.filterFields = exports.asIdentityId = void 0;
48
+ /**
49
+ * `abstract-service.ts`
50
+ * - common service design pattern to build micro-service backend.
51
+ *
52
+ * @author Tim Hong <tim@lemoncloud.io>
53
+ * @date 2021-02-23 initial version
54
+ * @author Steve <steve@lemoncloud.io>
55
+ * @date 2022-02-18 optimized search w/ ES6.8
56
+ * @date 2022-02-22 optimized w/ `lemon-core#3.0` and `@elastic/elasticsearch`
57
+ * @date 2022-02-24 use `$id` in elastic-search as `_id` in dynamo-table.
58
+ * @date 2022-03-15 optimized w/ `AbstractProxy`
59
+ * @date 2022-03-17 optimized w/ `lemon-core#3.0.2` and use `env.ES6_DOCTYPE`
60
+ * @date 2022-03-31 optimized w/ unit test spec.
61
+ * @date 2022-05-19 optimized `CacheService` w/ typed key.
62
+ *
63
+ * @origin see `lemon-accounts-api/src/service/core-service.ts`
64
+ * @copyright (C) 2021 LemonCloud Co Ltd. - All Rights Reserved.
65
+ */
66
+ const cores_1 = __importStar(require("../cores/"));
67
+ const engine_1 = require("../engine/");
68
+ const test_helper_1 = require("../common/test-helper");
69
+ const helpers_1 = require("../helpers");
70
+ const NS = engine_1.$U.NS('back', 'blue'); // NAMESPACE TO BE PRINTED.
71
+ /**
72
+ * authentication helper - get identity-id from context
73
+ * @param context the current request context.
74
+ */
75
+ function asIdentityId(context) {
76
+ var _a;
77
+ return (_a = context === null || context === void 0 ? void 0 : context.identity) === null || _a === void 0 ? void 0 : _a.identityId;
78
+ }
79
+ exports.asIdentityId = asIdentityId;
80
+ /**
81
+ * extract field names from models
82
+ * - only fields start with lowercase, or all upper.
83
+ */
84
+ const filterFields = (fields, base = []) => fields
85
+ .filter(field => /^[a-z]+/.test(field) || /^[A-Z_]+$/.test(field))
86
+ .reduce((L, k) => {
87
+ if (k && !L.includes(k))
88
+ L.push(k);
89
+ return L;
90
+ }, [...base]);
91
+ exports.filterFields = filterFields;
92
+ /**
93
+ * abstract class `CoreService`
94
+ * - common abstract to build user service
95
+ *
96
+ * @abstract
97
+ */
98
+ class CoreService extends cores_1.GeneralKeyMaker {
99
+ /**
100
+ * constructor
101
+ * @param tableName target table-name (or .yml dummy file-name)
102
+ * @param ns namespace of dataset
103
+ * @param idName must be `_id` unless otherwise
104
+ */
105
+ constructor(tableName, ns, idName) {
106
+ super(ns || engine_1.$U.env('NS', 'TT'));
107
+ /** (optional) current timestamp */
108
+ this.current = 0; // for unit-test. set the current time-stamp.
109
+ /**
110
+ * override current time
111
+ */
112
+ this.setCurrent = (current) => (this.current = current);
113
+ this.tableName = tableName || engine_1.$U.env('MY_DYNAMO_TABLE', 'Test');
114
+ this.idName = idName || '_id';
115
+ }
116
+ /**
117
+ * get the current dynamo-options.
118
+ */
119
+ get dynamoOptions() {
120
+ return {
121
+ tableName: this.tableName,
122
+ idName: this.idName,
123
+ };
124
+ }
125
+ /**
126
+ * create storage-service w/ fields list.
127
+ */
128
+ makeStorageService(type, fields, filter) {
129
+ //! use proxy-storage-service for both dynamo-table and dummy-data.
130
+ const storage = new cores_1.ProxyStorageService(this, this.tableName, fields, filter, this.idName);
131
+ storage.setTimer(() => (this.current ? this.current : new Date().getTime()));
132
+ return storage.makeTypedStorageService(type);
133
+ }
134
+ }
135
+ exports.CoreService = CoreService;
136
+ /**
137
+ * class: `CoreManager`
138
+ * - shared core manager for all model
139
+ *
140
+ * @abstract
141
+ */
142
+ class CoreManager extends cores_1.AbstractManager {
143
+ /**
144
+ * constructor
145
+ * @protected
146
+ */
147
+ constructor(type, parent, fields, uniqueField) {
148
+ super(type, parent, fields, uniqueField);
149
+ /**
150
+ * say hello()
151
+ */
152
+ this.hello = () => `${this.storage.hello()}`;
153
+ }
154
+ /**
155
+ * get existence of model
156
+ * @param id
157
+ */
158
+ exists(id) {
159
+ return __awaiter(this, void 0, void 0, function* () {
160
+ return (yield this.find(id)) !== null;
161
+ });
162
+ }
163
+ /**
164
+ * find model - retrieve or null
165
+ * @param id model-id
166
+ */
167
+ find(id) {
168
+ return __awaiter(this, void 0, void 0, function* () {
169
+ return this.retrieve(id).catch(e => {
170
+ if ((0, test_helper_1.GETERR)(e).startsWith('404 NOT FOUND'))
171
+ return null;
172
+ throw e;
173
+ });
174
+ });
175
+ }
176
+ /**
177
+ * get model by key
178
+ * @param key global id(like primary-key)
179
+ */
180
+ findByKey(key) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ return this.storage.storage.read(key).catch(e => {
183
+ if ((0, test_helper_1.GETERR)(e).startsWith('404 NOT FOUND'))
184
+ return null;
185
+ throw e;
186
+ });
187
+ });
188
+ }
189
+ /**
190
+ * batch get models
191
+ * - retrieve multi models per each id
192
+ * - must be matched with idList in sequence order.
193
+ *
194
+ * @param idList list of id
195
+ * @param parrallel (optional) in parrallel size
196
+ */
197
+ getMulti(idList, parrallel) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ const $map = yield this.getMulti$(idList, 'id', parrallel);
200
+ return idList.map(id => { var _a; return (_a = $map[id]) !== null && _a !== void 0 ? _a : null; }).map(N => { var _a; return (((_a = N === null || N === void 0 ? void 0 : N.error) === null || _a === void 0 ? void 0 : _a.startsWith('404 NOT FOUND')) ? null : N); });
201
+ });
202
+ }
203
+ /**
204
+ * batch get models in map by idName
205
+ */
206
+ getMulti$(idList, idName = 'id', parrallel) {
207
+ return __awaiter(this, void 0, void 0, function* () {
208
+ // 1. find items in unique
209
+ const ids = idList.reduce((L, id) => {
210
+ if (id && !L.includes(id))
211
+ L.push(id);
212
+ return L;
213
+ }, []);
214
+ // 2. find from storage.
215
+ const list = yield (0, helpers_1.my_parrallel)(ids.map(id => ({ id })), N => this.retrieve(N.id), parrallel);
216
+ // 3. convert to map
217
+ return helpers_1.$T.asMap(list, idName);
218
+ });
219
+ }
220
+ /**
221
+ * get by unique field value
222
+ * @param uniqueValue
223
+ */
224
+ getByUniqueField(uniqueValue) {
225
+ return __awaiter(this, void 0, void 0, function* () {
226
+ return this.$unique.findOrCreate(uniqueValue);
227
+ });
228
+ }
229
+ /**
230
+ * find model by unique field value - retrieve or null
231
+ * @param uniqueValue
232
+ */
233
+ findByUniqueField(uniqueValue) {
234
+ return __awaiter(this, void 0, void 0, function* () {
235
+ return this.getByUniqueField(uniqueValue).catch(e => {
236
+ if ((0, test_helper_1.GETERR)(e).startsWith('404 NOT FOUND'))
237
+ return null;
238
+ throw e;
239
+ });
240
+ });
241
+ }
242
+ /**
243
+ * prepare model
244
+ * - override `AbstractManager.prepare()`
245
+ */
246
+ prepare(id, $def, isCreate = true) {
247
+ return __awaiter(this, void 0, void 0, function* () {
248
+ const $org = yield this.find(id);
249
+ if ($org)
250
+ return $org;
251
+ if (!isCreate || $def === undefined)
252
+ throw new Error(`404 NOT FOUND - ${this.type}:${id}`);
253
+ const model = this.prepareDefault($def);
254
+ // create or update lookup
255
+ if (this.$unique)
256
+ yield this.updateLookup(id, model, $org);
257
+ // save target model
258
+ const $saved = yield this.storage.save(id, Object.assign(Object.assign({}, model), { id }));
259
+ return Object.assign(Object.assign(Object.assign({}, model), $saved), { id });
260
+ });
261
+ }
262
+ /**
263
+ * update model
264
+ * - override 'AbstractManager.insert()'
265
+ *
266
+ * @deprecated use `AbstractProxy`
267
+ */
268
+ insert(model, initSeq) {
269
+ return __awaiter(this, void 0, void 0, function* () {
270
+ const id = helpers_1.$T.S(yield this.storage.storage.nextSeq(this.type, initSeq));
271
+ return this.save(id, model);
272
+ });
273
+ }
274
+ /**
275
+ * create or update model
276
+ * @param id model id
277
+ * @param model model data
278
+ */
279
+ save(id, model) {
280
+ return __awaiter(this, void 0, void 0, function* () {
281
+ if (!id)
282
+ throw new Error(`@id is requird - save()`);
283
+ const $org = yield this.find(id);
284
+ if (!$org)
285
+ model = this.prepareDefault(model);
286
+ // create or update lookup
287
+ if (this.$unique)
288
+ yield this.updateLookup(id, model, $org);
289
+ // save target model
290
+ const $saved = yield this.storage.save(id, model);
291
+ return Object.assign(Object.assign(Object.assign({}, $org), $saved), { id });
292
+ });
293
+ }
294
+ /**
295
+ * update model
296
+ * - override 'AbstractManager.update()'
297
+ */
298
+ update(id, model, $inc) {
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ if (!id)
301
+ throw new Error(`@id is requird - update()`);
302
+ const $org = yield this.retrieve(id);
303
+ // update lookup
304
+ if (this.$unique)
305
+ yield this.updateLookup(id, model, $org);
306
+ // update target model
307
+ model = this.beforeSave(model, $org);
308
+ const $updated = yield this.storage.update(id, model, $inc);
309
+ return Object.assign(Object.assign(Object.assign({}, $org), $updated), { id });
310
+ });
311
+ }
312
+ /**
313
+ * update or create model
314
+ * - override 'AbstractManager.updateOrCreate()'
315
+ */
316
+ updateOrCreate(id, model, $inc) {
317
+ return __awaiter(this, void 0, void 0, function* () {
318
+ if (!id)
319
+ throw new Error(`@id is requird - updateOrCreate()`);
320
+ const $org = yield this.prepare(id, model);
321
+ // update lookup
322
+ if (this.$unique)
323
+ yield this.updateLookup(id, model, $org);
324
+ // update target model
325
+ model = this.beforeSave(model, $org);
326
+ const $updated = yield this.storage.update(id, model, $inc);
327
+ return Object.assign(Object.assign(Object.assign({}, $org), $updated), { id });
328
+ });
329
+ }
330
+ /**
331
+ * delete model
332
+ * - override 'AbstractManager.delete()'
333
+ */
334
+ delete(id, destroy) {
335
+ const _super = Object.create(null, {
336
+ delete: { get: () => super.delete }
337
+ });
338
+ var _a;
339
+ return __awaiter(this, void 0, void 0, function* () {
340
+ if (!id)
341
+ throw new Error(`@id is requird - delete()`);
342
+ // delete target model
343
+ const $org = yield _super.delete.call(this, id, destroy);
344
+ // delete lookup
345
+ const uniqueField = (_a = this.$unique) === null || _a === void 0 ? void 0 : _a.field;
346
+ const uniqueValue = uniqueField && $org[uniqueField];
347
+ if (uniqueValue)
348
+ yield this.storage.delete(this.$unique.asLookupId(uniqueValue));
349
+ return $org;
350
+ });
351
+ }
352
+ /**
353
+ * prepare default-model when creation
354
+ * @param $def base-model
355
+ */
356
+ prepareDefault($def) {
357
+ return Object.assign({}, $def);
358
+ }
359
+ /**
360
+ * update lookup and delete old one if exists
361
+ */
362
+ updateLookup(id, model, $org) {
363
+ var _a;
364
+ return __awaiter(this, void 0, void 0, function* () {
365
+ const uniqueField = (_a = this.$unique) === null || _a === void 0 ? void 0 : _a.field;
366
+ const newUniqueValue = uniqueField && model[uniqueField];
367
+ const oldUniqueValue = uniqueField && ($org === null || $org === void 0 ? void 0 : $org[uniqueField]);
368
+ // update lookup.
369
+ if (newUniqueValue && newUniqueValue !== oldUniqueValue) {
370
+ yield this.$unique.updateLookup(Object.assign({ id }, model));
371
+ // remove old lookup
372
+ if (oldUniqueValue) {
373
+ yield this.storage.delete(this.$unique.asLookupId(oldUniqueValue));
374
+ }
375
+ }
376
+ });
377
+ }
378
+ }
379
+ exports.CoreManager = CoreManager;
380
+ /**
381
+ * proxy of manager
382
+ * - save model internally, and update only if changed properties.
383
+ * Model extends CoreModel<ModelType>, ModelType extends string
384
+ */
385
+ // export class ManagerProxy<T, U extends CoreManager<T, any, any>> {
386
+ class ManagerProxy {
387
+ constructor(proxy, mgr) {
388
+ /**
389
+ * store the origin model.
390
+ * - `null` means `404 not found`
391
+ */
392
+ this._org = {};
393
+ /**
394
+ * store the updated one.
395
+ */
396
+ this._new = {};
397
+ /**
398
+ * 객체 정규화 시킴.
399
+ * - null 에 대해서는 특별히 처리.
400
+ */
401
+ this.normal = (N) => Object.keys(N || {}).reduce((M, k) => {
402
+ if (k.startsWith('_') || k.startsWith('$'))
403
+ return M;
404
+ const v = N[k];
405
+ //! `null` 은 DynamoDB에서 비어있는 문자임.
406
+ M[k] = v === null ? '' : v;
407
+ return M;
408
+ }, {});
409
+ /**
410
+ * override w/ model
411
+ * @param $org the origin model by `.get(id)`
412
+ * @param model the new model.
413
+ */
414
+ this.override = ($org, model) => {
415
+ const fields = this.$mgr.FIELDS;
416
+ //! update(set) all properties.
417
+ Object.entries(model).forEach(([key, val]) => {
418
+ if (!fields || fields.includes(key)) {
419
+ $org[key] = val;
420
+ }
421
+ });
422
+ return $org;
423
+ };
424
+ this.$mgr = mgr;
425
+ proxy.register(this);
426
+ }
427
+ /**
428
+ * get storage linked.
429
+ */
430
+ get storage() {
431
+ return this.$mgr.storage;
432
+ }
433
+ /**
434
+ * read the origin node (cloned not to change).
435
+ */
436
+ org(id, raw = false) {
437
+ const O = this._org[id];
438
+ return O === undefined ? null : raw ? O : Object.assign({}, O);
439
+ }
440
+ /**
441
+ * check if already read.
442
+ */
443
+ has(id) {
444
+ return this.org(id) ? true : false;
445
+ }
446
+ /**
447
+ * read the node.
448
+ * @param id object-id
449
+ * @param defaultOrThrow (optional) create if not exists, or flag to throw error
450
+ */
451
+ get(id, defaultOrThrow) {
452
+ return __awaiter(this, void 0, void 0, function* () {
453
+ const err404 = `404 NOT FOUND - proxy/${this.$mgr.type}/id:${id}`;
454
+ const throwable = typeof defaultOrThrow === 'boolean' ? defaultOrThrow : true;
455
+ const $def = typeof defaultOrThrow === 'boolean' ? null : defaultOrThrow;
456
+ // STEP.0 validate if null (404 error)
457
+ if (this._org[id] === null && !$def) {
458
+ if (throwable)
459
+ throw new Error(err404);
460
+ return null;
461
+ }
462
+ // STEP.1 find from `new`
463
+ const N = this._new[id];
464
+ if (N !== undefined)
465
+ return N;
466
+ // OR, READ (or CREATE) from storage.
467
+ const M = !$def ? yield this.$mgr.retrieve(id).catch(test_helper_1.NUL404) : yield this.$mgr.prepare(id, $def, true);
468
+ if (M === null) {
469
+ this._org[id] = null; //! null 로 저장해두고, 다음에 호출할때 에러 발생.
470
+ if (throwable)
471
+ throw new Error(err404);
472
+ return null;
473
+ }
474
+ const M2 = this.normal(M);
475
+ this._org[id] = M2; //! 원본 저장.
476
+ // const M3 = { ...M2 }; //! 클론 생성.
477
+ const M3 = JSON.parse(engine_1.$U.json(M2)); //! deep clone.
478
+ this._new[id] = M3; //! 클론 저장.
479
+ return M3;
480
+ });
481
+ }
482
+ /**
483
+ * update the node.
484
+ */
485
+ set(id, model) {
486
+ return __awaiter(this, void 0, void 0, function* () {
487
+ if (!model)
488
+ throw new Error(`@model (object) is required - proxy/${this.$mgr.type}/id:${id}!`);
489
+ const O = yield this.get(id);
490
+ return this.override(O, model);
491
+ });
492
+ }
493
+ /**
494
+ * increment the field of Object[id]
495
+ * !WARN! this incremented properties should NOT be updated later.
496
+ */
497
+ inc(id, model) {
498
+ return __awaiter(this, void 0, void 0, function* () {
499
+ if (!model)
500
+ throw new Error(`@model (object) is required - proxy/${this.$mgr.type}/id:${id}!`);
501
+ const $inc = Object.entries(model).reduce((M, [k, v]) => {
502
+ if (typeof v === 'number')
503
+ M[k] = v;
504
+ return M;
505
+ }, {});
506
+ const keys = Object.keys($inc);
507
+ if (!keys.length)
508
+ throw new Error(`@model (object) is empty to inc() - proxy/${this.$mgr.type}/id:${id}!`);
509
+ //! try to increment, and update the latest to both org and new.
510
+ const $res = yield this.$mgr.storage.update(id, null, $inc);
511
+ const $new = yield this.get(id);
512
+ const $org = this.org(id, true);
513
+ return keys.reduce((N, k) => {
514
+ const key = k;
515
+ N[key] = $org[key] = $res[key];
516
+ return N;
517
+ }, $new);
518
+ });
519
+ }
520
+ /**
521
+ * get all the updated node.
522
+ *
523
+ * @param onlyUpdated flag to return the only updated set. (useful to check whether to update really!)
524
+ */
525
+ alls(onlyUpdated = true, onlyValid = true) {
526
+ const ids = Object.keys(this._new).sort();
527
+ return ids.reduce((M, id) => {
528
+ const O = this._org[id];
529
+ const N = this._new[id];
530
+ const N2 = this.$mgr.onBeforeSave(Object.assign({}, N), O);
531
+ const N3 = onlyUpdated ? helpers_1.$T.diff(O, N2, onlyValid) : N2;
532
+ M[id] = N3;
533
+ return M;
534
+ }, {});
535
+ }
536
+ }
537
+ exports.ManagerProxy = ManagerProxy;
538
+ /**
539
+ * class: `AbstractProxy`
540
+ * - common abstract based class for Proxy
541
+ */
542
+ class AbstractProxy {
543
+ /**
544
+ * constructor of proxy.
545
+ * @param service user service instance
546
+ * @param parrallel parrallel count (default 2)
547
+ * @param cacheScope prefix of cache-key (like `lemon:SS:` or `lemon:SS:user`)
548
+ */
549
+ constructor(context, service, parrallel = 2, cacheScope) {
550
+ /**
551
+ * say hello().
552
+ */
553
+ this.hello = () => `manager-proxy:${this.service.NS}/${this.service.tableName}`;
554
+ /**
555
+ * list of manager-proxy
556
+ */
557
+ this._proxies = [];
558
+ /**
559
+ * report via slack.
560
+ */
561
+ this.report = (title, data) => __awaiter(this, void 0, void 0, function* () {
562
+ const context = this.context;
563
+ return (0, helpers_1.$slack)(title, data, null, { context }).catch(e => `ERR:${(0, test_helper_1.GETERR)(e)}`);
564
+ });
565
+ /**
566
+ * the cached identity model
567
+ */
568
+ this._identity = {};
569
+ this.context = context;
570
+ this.service = service;
571
+ this.parrallel = parrallel;
572
+ // create cache
573
+ const endpoint = engine_1.$U.env('CACHE_ENDPOINT', '');
574
+ if (cacheScope && endpoint.startsWith('redis:')) {
575
+ this.cache = cores_1.CacheService.create({ type: 'redis', endpoint, ns: cacheScope });
576
+ }
577
+ }
578
+ /**
579
+ * get all proxies in list.
580
+ */
581
+ get allProxies() {
582
+ return this._proxies;
583
+ }
584
+ /**
585
+ * register this.
586
+ */
587
+ register(mgr) {
588
+ this._proxies.push(mgr);
589
+ }
590
+ /**
591
+ * 업데이트할 항목을 모두 저장함
592
+ */
593
+ saveAllUpdates(parrallel) {
594
+ return __awaiter(this, void 0, void 0, function* () {
595
+ parrallel = engine_1.$U.N(parrallel, this.parrallel);
596
+ // STEP.1 prepare the list of updater.
597
+ const list = this.allProxies.reduce((L, $p) => {
598
+ const $set = $p.alls(true);
599
+ return Object.entries($set).reduce((L, [id, N]) => {
600
+ const hasUpdate = Object.keys(N).length > 0;
601
+ if (hasUpdate) {
602
+ (0, engine_1._log)(NS, `>> ${$p.$mgr.type}/${id} =`, engine_1.$U.json(N));
603
+ const _ = () => $p.$mgr.storage.update(id, N);
604
+ L.push({ id, N, _ });
605
+ }
606
+ return L;
607
+ }, L);
608
+ }, []);
609
+ // STEP.2 finally update storage.
610
+ return (0, helpers_1.my_parrallel)(list, (N) => __awaiter(this, void 0, void 0, function* () {
611
+ return typeof N._ === 'function' ? N._() : null;
612
+ }), parrallel);
613
+ });
614
+ }
615
+ /**
616
+ * featch identity-acess from `lemon-accounts-api`
617
+ */
618
+ fetchIdentityAccess(identityId, domain) {
619
+ return __awaiter(this, void 0, void 0, function* () {
620
+ domain = helpers_1.$T.S(domain, this.context.domain);
621
+ if (!identityId)
622
+ throw new Error(`.identityId (string) is required - fetchAccess(${domain})`);
623
+ // 1. get user detail by invoking 'lemon-accounts-api/pack-context'
624
+ const service = '//lemon-accounts-api/oauth/0/pack-context';
625
+ const body = { domain, identityId };
626
+ const $identity = yield (0, helpers_1.$protocol)(this.context, service)
627
+ .execute({}, body, 'POST')
628
+ .catch(test_helper_1.NUL404);
629
+ (0, engine_1._log)(NS, `> identity[${domain}] =`, engine_1.$U.json($identity));
630
+ //WARN! - $identity can be null (or .Account can be null)
631
+ // if (!$identity?.Account)
632
+ // throw new Error(`.Account(NextIdentityAccess) is invalid - fetchAccess(${domain}/${identityId})`);
633
+ return { identityId, $identity };
634
+ });
635
+ }
636
+ getIdentity$(identityId) {
637
+ return __awaiter(this, void 0, void 0, function* () {
638
+ // STEP.1 check if in stock.
639
+ const val = this._identity[identityId];
640
+ if (val !== undefined)
641
+ return val;
642
+ // STEP.2 fetch remotely, and save
643
+ const { $identity } = yield this.fetchIdentityAccess(identityId);
644
+ this._identity[identityId] = $identity;
645
+ return $identity;
646
+ });
647
+ }
648
+ /**
649
+ * get current identity-id
650
+ */
651
+ getCurrentIdentityId(throwable = true) {
652
+ return __awaiter(this, void 0, void 0, function* () {
653
+ const identityId = asIdentityId(this.context) || '';
654
+ if (!identityId && throwable)
655
+ throw new Error(`400 NOT ALLOWED - getCurrentIdentity(${identityId || ''})`);
656
+ return identityId;
657
+ });
658
+ }
659
+ /**
660
+ * get the current identity object (or throw access-error)
661
+ */
662
+ getCurrentIdentity$(throwable = true) {
663
+ return __awaiter(this, void 0, void 0, function* () {
664
+ const identityId = yield this.getCurrentIdentityId(throwable);
665
+ if (!identityId && !throwable)
666
+ return null;
667
+ return this.getIdentity$(identityId);
668
+ });
669
+ }
670
+ }
671
+ exports.AbstractProxy = AbstractProxy;
672
+ /**
673
+ * class `Elastic6Synchronizer`
674
+ * - listen DynamoDBStream events and index into Elasticsearch
675
+ */
676
+ class Elastic6Synchronizer {
677
+ /**
678
+ * constructor
679
+ * @param elastic elastic6-service instance
680
+ * @param dynamoOptions dynamo options
681
+ */
682
+ constructor(elastic, dynamoOptions) {
683
+ /**
684
+ * internal callback for filtering
685
+ * @private
686
+ */
687
+ this.filter = (id, item) => {
688
+ var _a, _b;
689
+ const handler = this.synchronizerMap.get(item.type);
690
+ if (handler)
691
+ return (_b = (_a = handler.filter) === null || _a === void 0 ? void 0 : _a.call(handler, id, item)) !== null && _b !== void 0 ? _b : true; // 핸들러를 등록했다면 filter 메서드를 정의하지 않았더라도 sync 한다.
692
+ return false; // 핸들러가 등록되지 않았다면 sync하지 않는다.
693
+ };
694
+ /**
695
+ * internal callback on before synchronization
696
+ * @private
697
+ */
698
+ this.onBeforeSync = (id, eventName, item, diff, prev) => __awaiter(this, void 0, void 0, function* () {
699
+ var _a;
700
+ const handler = this.synchronizerMap.get(item.type);
701
+ if (handler)
702
+ yield ((_a = handler.onBeforeSync) === null || _a === void 0 ? void 0 : _a.call(handler, id, eventName, item, diff, prev));
703
+ });
704
+ /**
705
+ * internal callback on after synchronization
706
+ * @private
707
+ */
708
+ this.onAfterSync = (id, eventName, item, diff, prev) => __awaiter(this, void 0, void 0, function* () {
709
+ var _b;
710
+ const handler = this.synchronizerMap.get(item.type);
711
+ if (handler)
712
+ yield ((_b = handler.onAfterSync) === null || _b === void 0 ? void 0 : _b.call(handler, id, eventName, item, diff, prev));
713
+ });
714
+ if (!elastic)
715
+ throw new Error(`@elastic (elastic-service) is required!`);
716
+ if (!dynamoOptions)
717
+ throw new Error(`@dynamoOptions (object) is required!`);
718
+ //! build dynamo-options as default.
719
+ const options = Object.assign(Object.assign({}, dynamoOptions), { idName: dynamoOptions.idName || '_id' });
720
+ //! create sync-handler w/ this.
721
+ const listener = cores_1.LambdaDynamoStreamHandler.createSyncToElastic6(options, elastic, this.filter.bind(this), this.onBeforeSync.bind(this), this.onAfterSync.bind(this));
722
+ cores_1.default.lambda.dynamos.addListener(listener); // register DynamoStream event listener
723
+ //! prepare default synchro
724
+ this.synchronizerMap = new Map();
725
+ this.defModelSynchronizer = new (class {
726
+ filter(id, item) {
727
+ const type = `${(item === null || item === void 0 ? void 0 : item.type) || ''}`;
728
+ const stereo = `${(item === null || item === void 0 ? void 0 : item.stereo) || ''}`;
729
+ return !(type.startsWith('#') || stereo.startsWith('#')); // special purpose item. do not index.
730
+ }
731
+ })();
732
+ }
733
+ /**
734
+ * set synchronizer for the model
735
+ * @param type the model-type
736
+ * @param handler (optional) custom synchronizer.
737
+ */
738
+ enableSynchronization(type, handler) {
739
+ this.synchronizerMap.set(type, handler !== null && handler !== void 0 ? handler : this.defModelSynchronizer);
740
+ }
741
+ }
742
+ exports.Elastic6Synchronizer = Elastic6Synchronizer;
743
+ /**
744
+ * class `ElasticInstance`
745
+ * - to manipulate the shared Elasticsearch resources.
746
+ */
747
+ class Elastic6Instance {
748
+ /**
749
+ * default constructor
750
+ */
751
+ constructor({ endpoint, indexName, esVersion, esDocType, tableName, autocompleteFields, }) {
752
+ // const endpoint = $U.env('ES6_ENDPOINT', '');
753
+ // const indexName = $U.env('ES6_INDEX', 'test-v1');
754
+ // const esVersion = $U.env('ES6_VERSION', '6.8'); //! version of elastic server (default 6.8)
755
+ // const esDocType = $U.env('ES6_DOCTYPE', ''); //! version of elastic server (default `_doc`)
756
+ // const tableName = $U.env('MY_DYNAMO_TABLE', 'Test');
757
+ // const autocompleteFields = $T.SS($U.env('ES6_AUTOCOMPLETE_FIELDS', ''));
758
+ // initialize Elasticsearch only if valid endpoint.
759
+ if (endpoint && indexName) {
760
+ const options = {
761
+ endpoint,
762
+ indexName,
763
+ version: esVersion,
764
+ autocompleteFields,
765
+ };
766
+ if (esDocType)
767
+ options.docType = esDocType;
768
+ this.elastic = new cores_1.Elastic6Service(options);
769
+ this.client = this.elastic.client;
770
+ this.query = new cores_1.Elastic6QueryService(this.elastic);
771
+ this.synchronizer = new Elastic6Synchronizer(this.elastic, { tableName });
772
+ }
773
+ }
774
+ /**
775
+ * read the current elastic6-option.
776
+ */
777
+ get options() {
778
+ if (!this.elastic)
779
+ return null;
780
+ return this.elastic.options;
781
+ }
782
+ /**
783
+ * create Elasticsearch index w/ custom settings
784
+ */
785
+ createIndex() {
786
+ var _a, _b;
787
+ return __awaiter(this, void 0, void 0, function* () {
788
+ if (this.elastic) {
789
+ const { docType, idName } = this.options;
790
+ const settings = cores_1.Elastic6Service.prepareSettings({ docType, idName }); // default setting
791
+ const { version } = this.elastic.options;
792
+ // force set type of 'score_' field
793
+ const ver = engine_1.$U.F(version, 7.0);
794
+ const $set = { score_: { type: 'half_float' } };
795
+ if (ver < 7.0) {
796
+ settings.mappings[docType].properties = Object.assign(Object.assign({}, (((_a = settings.mappings[docType]) === null || _a === void 0 ? void 0 : _a.properties) || {})), $set);
797
+ }
798
+ else {
799
+ settings.mappings.properties = Object.assign(Object.assign({}, (((_b = settings.mappings) === null || _b === void 0 ? void 0 : _b.properties) || {})), $set);
800
+ }
801
+ return this.elastic.createIndex(settings);
802
+ }
803
+ return null;
804
+ });
805
+ }
806
+ /**
807
+ * destroy Elasticsearch index
808
+ */
809
+ destroyIndex() {
810
+ return __awaiter(this, void 0, void 0, function* () {
811
+ return this.elastic && (yield this.elastic.destroyIndex());
812
+ });
813
+ }
814
+ /**
815
+ * display index settings and mappings
816
+ */
817
+ describeIndex() {
818
+ return __awaiter(this, void 0, void 0, function* () {
819
+ return this.elastic && (yield this.elastic.describe());
820
+ });
821
+ }
822
+ /**
823
+ * multi get
824
+ * @param _ids _id list
825
+ */
826
+ mget(_ids) {
827
+ return __awaiter(this, void 0, void 0, function* () {
828
+ const $res = yield this.client.mget({
829
+ index: this.options.indexName,
830
+ type: this.options.docType,
831
+ body: {
832
+ docs: _ids.map(_id => ({ _id })),
833
+ },
834
+ });
835
+ // _log(NS, `> res =`, $U.json({ ...$res, meta: undefined }));
836
+ const { docs } = $res.body;
837
+ const idName = this.options.idName;
838
+ return docs.map((doc) => (doc.found ? sourceToItem(doc._source, idName) : null));
839
+ });
840
+ }
841
+ /**
842
+ * search raw query
843
+ * @param body Elasticsearch Query DSL
844
+ * @param params see 'search_type' in Elasticsearch documentation
845
+ */
846
+ search(body, params) {
847
+ return __awaiter(this, void 0, void 0, function* () {
848
+ if (!this.elastic)
849
+ throw new Error(`Could not read Elasticsearch endpoint or index setting.`);
850
+ const searchType = params === null || params === void 0 ? void 0 : params.searchType;
851
+ const elastic = (params === null || params === void 0 ? void 0 : params.indexName)
852
+ ? new cores_1.Elastic6Service(Object.assign(Object.assign({}, this.options), { indexName: params.indexName }))
853
+ : this.elastic;
854
+ return elastic.search(body, searchType);
855
+ });
856
+ }
857
+ /**
858
+ * create async generator that yields items queried until last
859
+ * @param body Elasticsearch Query DSL
860
+ * @param searchType see 'search_type' in Elasticsearch documentation
861
+ */
862
+ generateSearchResult(body, searchType) {
863
+ return __asyncGenerator(this, arguments, function* generateSearchResult_1() {
864
+ if (!body.sort)
865
+ body.sort = '_doc';
866
+ do {
867
+ const { list, last } = yield __await(this.search(body, { searchType }));
868
+ body.search_after = last;
869
+ yield yield __await(list);
870
+ } while (body.search_after);
871
+ });
872
+ }
873
+ }
874
+ exports.Elastic6Instance = Elastic6Instance;
875
+ /**
876
+ * from Elasticsearch document to model item
877
+ * - replace the elastic's `$id` field to `_id` of dynamo-table.
878
+ *
879
+ * @param _source from elastic-search
880
+ * @param idName (optional) global id of elastic. (default is `$id`)
881
+ */
882
+ function sourceToItem(_source, idName = '$id') {
883
+ const item = Object.assign({}, _source);
884
+ if (idName in item) {
885
+ item._id = item[idName];
886
+ delete item[idName];
887
+ }
888
+ return item;
889
+ }
890
+ exports.sourceToItem = sourceToItem;
891
+ /**
892
+ * const `$ES6`
893
+ * - default instance as a singleton by env configuration.
894
+ */
895
+ exports.$ES6 = new (class extends Elastic6Instance {
896
+ constructor() {
897
+ // 0. load from env configuration.
898
+ const endpoint = engine_1.$U.env('ES6_ENDPOINT', '');
899
+ const indexName = engine_1.$U.env('ES6_INDEX', 'test-v1');
900
+ const esVersion = engine_1.$U.env('ES6_VERSION', '6.8'); //! version of elastic server (default 6.8)
901
+ const esDocType = engine_1.$U.env('ES6_DOCTYPE', ''); //! version of elastic server (default `_doc`)
902
+ const tableName = engine_1.$U.env('MY_DYNAMO_TABLE', 'Test');
903
+ const autocompleteFields = helpers_1.$T.SS(engine_1.$U.env('ES6_AUTOCOMPLETE_FIELDS', ''));
904
+ // 1. initialize instance.
905
+ super({
906
+ endpoint,
907
+ indexName,
908
+ esVersion,
909
+ esDocType,
910
+ tableName,
911
+ autocompleteFields,
912
+ });
913
+ }
914
+ })();
915
+ //# sourceMappingURL=abstract-service.js.map