lemon-core 3.1.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 (101) hide show
  1. package/README.md +1 -0
  2. package/dist/controllers/dummy-controller.d.ts +1 -1
  3. package/dist/controllers/dummy-controller.js +2 -2
  4. package/dist/controllers/dummy-controller.js.map +1 -1
  5. package/dist/controllers/general-api-controller.d.ts +1 -1
  6. package/dist/cores/api/api-service.d.ts +239 -0
  7. package/dist/cores/api/api-service.js +674 -0
  8. package/dist/cores/api/api-service.js.map +1 -0
  9. package/dist/cores/api/index.d.ts +10 -0
  10. package/dist/cores/api/index.js +27 -0
  11. package/dist/cores/api/index.js.map +1 -0
  12. package/dist/cores/aws/aws-kms-service.d.ts +53 -2
  13. package/dist/cores/aws/aws-kms-service.js +104 -17
  14. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  15. package/dist/cores/cache/cache-service.d.ts +440 -0
  16. package/dist/cores/cache/cache-service.js +967 -0
  17. package/dist/cores/cache/cache-service.js.map +1 -0
  18. package/dist/cores/cache/index.d.ts +10 -0
  19. package/dist/cores/cache/index.js +27 -0
  20. package/dist/cores/cache/index.js.map +1 -0
  21. package/dist/cores/cache-service.d.ts +54 -18
  22. package/dist/cores/cache-service.js +37 -26
  23. package/dist/cores/cache-service.js.map +1 -1
  24. package/dist/cores/core-types.d.ts +42 -12
  25. package/dist/cores/dynamo/dynamo-query-service.d.ts +52 -0
  26. package/dist/cores/dynamo/dynamo-query-service.js +127 -0
  27. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -0
  28. package/dist/cores/dynamo/dynamo-scan-service.d.ts +70 -0
  29. package/dist/cores/dynamo/dynamo-scan-service.js +164 -0
  30. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -0
  31. package/dist/cores/dynamo/dynamo-service.d.ts +192 -0
  32. package/dist/cores/dynamo/dynamo-service.js +525 -0
  33. package/dist/cores/dynamo/dynamo-service.js.map +1 -0
  34. package/dist/cores/dynamo/index.d.ts +12 -0
  35. package/dist/cores/dynamo/index.js +29 -0
  36. package/dist/cores/dynamo/index.js.map +1 -0
  37. package/dist/cores/elastic/elastic6-query-service.d.ts +104 -0
  38. package/dist/cores/elastic/elastic6-query-service.js +510 -0
  39. package/dist/cores/elastic/elastic6-query-service.js.map +1 -0
  40. package/dist/cores/elastic/elastic6-service.d.ts +273 -0
  41. package/dist/cores/elastic/elastic6-service.js +903 -0
  42. package/dist/cores/elastic/elastic6-service.js.map +1 -0
  43. package/dist/cores/elastic/hangul-service.d.ts +102 -0
  44. package/dist/cores/elastic/hangul-service.js +205 -0
  45. package/dist/cores/elastic/hangul-service.js.map +1 -0
  46. package/dist/cores/elastic/index.d.ts +12 -0
  47. package/dist/cores/elastic/index.js +29 -0
  48. package/dist/cores/elastic/index.js.map +1 -0
  49. package/dist/cores/hangul-service.d.ts +17 -3
  50. package/dist/cores/hangul-service.js +17 -8
  51. package/dist/cores/hangul-service.js.map +1 -1
  52. package/dist/cores/index.d.ts +5 -11
  53. package/dist/cores/index.js +8 -13
  54. package/dist/cores/index.js.map +1 -1
  55. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
  56. package/dist/cores/lambda/lambda-web-handler.d.ts +158 -8
  57. package/dist/cores/lambda/lambda-web-handler.js +283 -77
  58. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  59. package/dist/cores/protocol/protocol-service.d.ts +4 -0
  60. package/dist/cores/protocol/protocol-service.js +12 -7
  61. package/dist/cores/protocol/protocol-service.js.map +1 -1
  62. package/dist/cores/storage/http-storage-service.d.ts +22 -0
  63. package/dist/cores/storage/http-storage-service.js +129 -0
  64. package/dist/cores/storage/http-storage-service.js.map +1 -0
  65. package/dist/cores/storage/index.d.ts +14 -0
  66. package/dist/cores/storage/index.js +31 -0
  67. package/dist/cores/storage/index.js.map +1 -0
  68. package/dist/cores/storage/model-manager.d.ts +93 -0
  69. package/dist/cores/storage/model-manager.js +192 -0
  70. package/dist/cores/storage/model-manager.js.map +1 -0
  71. package/dist/cores/storage/proxy-storage-service.d.ts +573 -0
  72. package/dist/cores/storage/proxy-storage-service.js +913 -0
  73. package/dist/cores/storage/proxy-storage-service.js.map +1 -0
  74. package/dist/cores/storage/redis-storage-service.d.ts +183 -0
  75. package/dist/cores/storage/redis-storage-service.js +391 -0
  76. package/dist/cores/storage/redis-storage-service.js.map +1 -0
  77. package/dist/cores/storage/storage-service.d.ts +169 -0
  78. package/dist/cores/storage/storage-service.js +374 -0
  79. package/dist/cores/storage/storage-service.js.map +1 -0
  80. package/dist/cores/storage-service.d.ts +1 -1
  81. package/dist/cores/storage-service.js +2 -2
  82. package/dist/cores/storage-service.js.map +1 -1
  83. package/dist/engine/utilities.d.ts +4 -3
  84. package/dist/engine/utilities.js +6 -6
  85. package/dist/engine/utilities.js.map +1 -1
  86. package/dist/environ.d.ts +2 -2
  87. package/dist/environ.js +7 -4
  88. package/dist/environ.js.map +1 -1
  89. package/dist/extended/abstract-service.d.ts +533 -0
  90. package/dist/extended/abstract-service.js +915 -0
  91. package/dist/extended/abstract-service.js.map +1 -0
  92. package/dist/extended/index.d.ts +10 -0
  93. package/dist/extended/index.js +27 -0
  94. package/dist/extended/index.js.map +1 -0
  95. package/dist/helpers/helpers.d.ts +7 -0
  96. package/dist/helpers/helpers.js +7 -0
  97. package/dist/helpers/helpers.js.map +1 -1
  98. package/dist/index.d.ts +1 -0
  99. package/dist/index.js +3 -1
  100. package/dist/index.js.map +1 -1
  101. package/package.json +6 -4
@@ -0,0 +1,903 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DummyElastic6Service = exports.$ERROR = exports.Elastic6Service = void 0;
16
+ /**
17
+ * `elastic6-service.ts`
18
+ * - common service for elastic-search v6
19
+ *
20
+ * @author Steve Jung <steve@lemoncloud.io>
21
+ * @date 2019-11-20 initial version via backbone
22
+ * @date 2022-02-21 optimized error handler, and search.
23
+ * @date 2022-02-22 optimized w/ elastic client (elasticsearch-js)
24
+ *
25
+ * @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
26
+ */
27
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
+ const engine_1 = require("../../engine/");
29
+ const elasticsearch_1 = __importDefault(require("@elastic/elasticsearch"));
30
+ const hangul_service_1 = __importDefault(require("./hangul-service"));
31
+ const tools_1 = require("../../tools");
32
+ const test_helper_1 = require("../../common/test-helper");
33
+ const NS = engine_1.$U.NS('ES6', 'green'); // NAMESPACE TO BE PRINTED.
34
+ /**
35
+ * convert to string.
36
+ */
37
+ const _S = (v, def = '') => typeof v === 'string' ? v : v === undefined || v === null ? def : typeof v === 'object' ? engine_1.$U.json(v) : `${v}`;
38
+ /**
39
+ * class: `Elastic6Service`
40
+ * - basic CRUD service for Elastic Search 6
41
+ */
42
+ class Elastic6Service {
43
+ /**
44
+ * default constuctor w/ options.
45
+ * @param options { endpoint, indexName } is required.
46
+ */
47
+ constructor(options) {
48
+ /**
49
+ * say hello of identity.
50
+ */
51
+ this.hello = () => `elastic6-service:${this.options.indexName}:${this.version}`;
52
+ (0, engine_1._inf)(NS, `Elastic6Service(${options.indexName}/${options.idName})...`);
53
+ if (!options.endpoint)
54
+ throw new Error('.endpoint (URL) is required');
55
+ if (!options.indexName)
56
+ throw new Error('.indexName (string) is required');
57
+ // default option values: docType='_doc', idName='$id'
58
+ const { client } = Elastic6Service.instance(options.endpoint);
59
+ this._options = Object.assign({ docType: '_doc', idName: '$id', version: '6.8' }, options);
60
+ this._client = client;
61
+ }
62
+ /**
63
+ * simple instance maker.
64
+ *
65
+ * ```js
66
+ * const { client } = Elastic6Service.instance(endpoint);
67
+ * ```
68
+ *
69
+ * @param endpoint service-url
70
+ * @param version Elasticsearch version (default: '6.8')
71
+ * @see https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/16.x/configuration.html
72
+ */
73
+ static instance(endpoint) {
74
+ const client = new elasticsearch_1.default.Client({
75
+ node: endpoint,
76
+ ssl: {
77
+ ca: process.env.elasticsearch_certificate,
78
+ rejectUnauthorized: false,
79
+ },
80
+ });
81
+ return { client };
82
+ }
83
+ /**
84
+ * get the client instance.
85
+ */
86
+ get client() {
87
+ return this._client;
88
+ }
89
+ /**
90
+ * get the current options.
91
+ */
92
+ get options() {
93
+ return this._options;
94
+ }
95
+ get version() {
96
+ const ver = engine_1.$U.F(this.options.version, 6.8);
97
+ return ver;
98
+ }
99
+ /**
100
+ * list of index
101
+ */
102
+ listIndices() {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ (0, engine_1._log)(NS, `- listIndices()`);
105
+ //! call create index..
106
+ // const { client } = instance(endpoint);
107
+ const client = this.client;
108
+ const res = yield client.cat.indices({ format: 'json' });
109
+ (0, engine_1._log)(NS, `> indices =`, engine_1.$U.json(res));
110
+ // eslint-disable-next-line prettier/prettier
111
+ const list0 = Array.isArray(res) ? res : (res === null || res === void 0 ? void 0 : res.body) && Array.isArray(res === null || res === void 0 ? void 0 : res.body) ? res === null || res === void 0 ? void 0 : res.body : null;
112
+ if (!list0)
113
+ throw new Error(`@result<${typeof res}> is invalid - ${engine_1.$U.json(res)}!`);
114
+ // {"docs.count": "84", "docs.deleted": "7", "health": "green", "index": "dev-eureka-alarms-v1", "pri": "5", "pri.store.size": "234.3kb", "rep": "1", "status": "open", "store.size": "468.6kb", "uuid": "xPp-Sx86SgmhAWxT3cGAFw"}
115
+ const list = list0.map(N => ({
116
+ pri: engine_1.$U.N(N['pri']),
117
+ rep: engine_1.$U.N(N['rep']),
118
+ docsCount: engine_1.$U.N(N['docs.count']),
119
+ docsDeleted: engine_1.$U.N(N['docs.deleted']),
120
+ health: _S(N['health']),
121
+ index: _S(N['index']),
122
+ status: _S(N['status']),
123
+ uuid: _S(N['uuid']),
124
+ priStoreSize: _S(N['pri.store.size']),
125
+ storeSize: _S(N['store.size']),
126
+ }));
127
+ //! returns.
128
+ return { list };
129
+ });
130
+ }
131
+ /**
132
+ * find the index by name
133
+ */
134
+ findIndex(indexName) {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ indexName = indexName || this.options.indexName;
137
+ (0, engine_1._log)(NS, `- findIndex(${indexName})`);
138
+ const { list } = yield this.listIndices();
139
+ const found = list.findIndex(N => N.index == indexName);
140
+ return found >= 0 ? list[found] : null;
141
+ });
142
+ }
143
+ /**
144
+ * create index by name
145
+ *
146
+ * @param settings creating settings
147
+ */
148
+ createIndex(settings) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ const { indexName, docType, idName, timeSeries, version } = this.options;
151
+ settings = settings || Elastic6Service.prepareSettings({ docType, idName, timeSeries, version });
152
+ if (!indexName)
153
+ new Error('@index is required!');
154
+ (0, engine_1._log)(NS, `- createIndex(${indexName})`);
155
+ //! prepare payload
156
+ const payload = Object.assign({ settings: {
157
+ number_of_shards: 5,
158
+ number_of_replicas: 1,
159
+ } }, settings);
160
+ (0, engine_1._log)(NS, `> settings[${indexName}] = `, engine_1.$U.json(payload));
161
+ //! call create index..
162
+ // const { client } = instance(endpoint);
163
+ const client = this.client;
164
+ const res = yield client.indices.create({ index: indexName, body: payload }).catch(
165
+ // $ERROR.throwAsJson,
166
+ exports.$ERROR.handler('create', e => {
167
+ const msg = (0, test_helper_1.GETERR)(e);
168
+ if (msg.startsWith('400 RESOURCE ALREADY EXISTS'))
169
+ throw new Error(`400 IN USE - index:${indexName}`);
170
+ throw e;
171
+ }));
172
+ // if (res) throw res;
173
+ (0, engine_1._log)(NS, `> create[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
174
+ //! build result.
175
+ return {
176
+ status: res.statusCode,
177
+ index: indexName,
178
+ acknowledged: res.body.shards_acknowledged,
179
+ };
180
+ });
181
+ }
182
+ /**
183
+ * destroy search index
184
+ */
185
+ destroyIndex() {
186
+ return __awaiter(this, void 0, void 0, function* () {
187
+ const { indexName } = this.options;
188
+ if (!indexName)
189
+ new Error('@index is required!');
190
+ (0, engine_1._log)(NS, `- destroyIndex(${indexName})`);
191
+ //! call create index..
192
+ // const { client } = instance(endpoint);
193
+ const client = this.client;
194
+ const res = yield client.indices.delete({ index: indexName }).catch(
195
+ // $ERROR.throwAsJson,
196
+ exports.$ERROR.handler('destroy', e => {
197
+ const msg = (0, test_helper_1.GETERR)(e);
198
+ if (msg.startsWith('404 INDEX NOT FOUND'))
199
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
200
+ throw e;
201
+ }));
202
+ // if (res) throw res;
203
+ (0, engine_1._log)(NS, `> destroy[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
204
+ return {
205
+ status: res.statusCode,
206
+ index: indexName,
207
+ acknowledged: res.body.acknowledged,
208
+ };
209
+ });
210
+ }
211
+ /**
212
+ * refresh search index - refresh index to make all items searchable
213
+ */
214
+ refreshIndex() {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ const { indexName } = this.options;
217
+ if (!indexName)
218
+ throw new Error('.indexName is required!');
219
+ (0, engine_1._log)(NS, `- refreshIndex(${indexName})`);
220
+ //! call refresh index..
221
+ // const { client } = instance(endpoint);
222
+ const client = this.client;
223
+ const res = yield client.indices.refresh({ index: indexName }).catch(
224
+ // $ERROR.throwAsJson,
225
+ exports.$ERROR.handler('refresh', e => {
226
+ const msg = (0, test_helper_1.GETERR)(e);
227
+ if (msg.startsWith('404 INDEX NOT FOUND'))
228
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
229
+ throw e;
230
+ }));
231
+ (0, engine_1._log)(NS, `> refresh[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
232
+ return res.body;
233
+ });
234
+ }
235
+ /**
236
+ * flush search index - force store changes into search index immediately
237
+ */
238
+ flushIndex() {
239
+ return __awaiter(this, void 0, void 0, function* () {
240
+ const { indexName } = this.options;
241
+ if (!indexName)
242
+ throw new Error('.indexName is required!');
243
+ (0, engine_1._log)(NS, `- flushIndex(${indexName})`);
244
+ //! call flush index..
245
+ // const { client } = instance(endpoint);
246
+ const client = this.client;
247
+ const res = yield client.indices.flush({ index: indexName }).catch(
248
+ // $ERROR.throwAsJson,
249
+ exports.$ERROR.handler('flush', e => {
250
+ const msg = (0, test_helper_1.GETERR)(e);
251
+ if (msg.startsWith('404 INDEX NOT FOUND'))
252
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
253
+ throw e;
254
+ }));
255
+ (0, engine_1._log)(NS, `> flush[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
256
+ return res.body;
257
+ });
258
+ }
259
+ /**
260
+ * describe `settings` and `mappings` of index.
261
+ */
262
+ describe() {
263
+ return __awaiter(this, void 0, void 0, function* () {
264
+ const { indexName } = this.options;
265
+ //! call create index..
266
+ (0, engine_1._log)(NS, `- describe(${indexName})`);
267
+ //! read settings.
268
+ // const { client } = instance(endpoint);
269
+ const client = this.client;
270
+ const res = yield client.indices.getSettings({ index: indexName }).catch(
271
+ // $ERROR.throwAsJson,
272
+ exports.$ERROR.handler('describe', e => {
273
+ const msg = (0, test_helper_1.GETERR)(e);
274
+ if (msg.startsWith('404 INDEX NOT FOUND'))
275
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
276
+ throw e;
277
+ }));
278
+ (0, engine_1._log)(NS, `> settings[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
279
+ const settings = (res.body && res.body[indexName] && res.body[indexName].settings) || {};
280
+ (0, engine_1._log)(NS, `> number_of_shards =`, settings.index && settings.index.number_of_shards); // 5
281
+ (0, engine_1._log)(NS, `> number_of_replicas =`, settings.index && settings.index.number_of_replicas); // 1
282
+ //! read mappings.
283
+ const res2 = yield client.indices.getMapping({ index: indexName });
284
+ (0, engine_1._log)(NS, `> mappings[${indexName}] =`, engine_1.$U.json(res2));
285
+ const mappings = (res2.body && res2.body[indexName] && res2.body[indexName].mappings) || {};
286
+ //! returns
287
+ return { settings, mappings };
288
+ });
289
+ }
290
+ /**
291
+ * save single item
292
+ *
293
+ * @param id id
294
+ * @param item item to save
295
+ * @param type document type (default: doc-type given at construction time)
296
+ */
297
+ saveItem(id, item, type) {
298
+ var _a, _b;
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ const { indexName, docType, idName } = this.options;
301
+ (0, engine_1._log)(NS, `- saveItem(${id})`);
302
+ // const { client } = instance(endpoint);
303
+ const client = this.client;
304
+ // prepare item body and autocomplete fields
305
+ const body = Object.assign(Object.assign({}, item), { [idName]: id });
306
+ const body2 = this.popullateAutocompleteFields(body);
307
+ type = `${type || docType}`;
308
+ const params = { index: indexName, type, id, body: body2 };
309
+ if (idName === '_id')
310
+ delete params.body[idName]; //WARN! `_id` is reserved in ES6.
311
+ (0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
312
+ //NOTE - use npm `elasticsearch#13.2.0` for avoiding error.
313
+ const res = yield client.create(params).catch(
314
+ // $ERROR.throwAsJson,
315
+ exports.$ERROR.handler('save', e => {
316
+ const msg = (0, test_helper_1.GETERR)(e);
317
+ //! try to update document..
318
+ if (msg.startsWith('409 VERSION CONFLICT ENGINE')) {
319
+ delete body2[idName]; // do set id while update
320
+ // return this.updateItem(id, body2);
321
+ const param2 = { index: indexName, type, id, body: { doc: body2 } };
322
+ return client.update(param2);
323
+ }
324
+ throw e;
325
+ }));
326
+ (0, engine_1._log)(NS, `> create[${id}].res =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
327
+ const _version = engine_1.$U.N((_a = res.body) === null || _a === void 0 ? void 0 : _a._version, 0);
328
+ const _id = (_b = res.body) === null || _b === void 0 ? void 0 : _b._id;
329
+ const res2 = Object.assign(Object.assign({}, body), { _id, _version });
330
+ return res2;
331
+ });
332
+ }
333
+ /**
334
+ * push item for time-series data.
335
+ *
336
+ * @param item item to push
337
+ */
338
+ pushItem(item, type) {
339
+ var _a, _b;
340
+ return __awaiter(this, void 0, void 0, function* () {
341
+ const { indexName, docType } = this.options;
342
+ const id = '';
343
+ type = `${type || docType}`;
344
+ const body = Object.assign({}, item);
345
+ const body2 = this.popullateAutocompleteFields(body);
346
+ (0, engine_1._log)(NS, `- pushItem(${id})`);
347
+ const params = { index: indexName, type, body: body2 };
348
+ (0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
349
+ //NOTE - use npm `elasticsearch#13.2.0` for avoiding error.
350
+ // const { client } = instance(endpoint);
351
+ const client = this.client;
352
+ const res = yield client.index(params).catch(
353
+ // $ERROR.throwAsJson,
354
+ exports.$ERROR.handler('index', e => {
355
+ (0, engine_1._err)(NS, `> index[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
356
+ throw e;
357
+ }));
358
+ // {"_index":"test-v3","_type":"_doc","_id":"rTeHiW4BPb_liACrA9qa","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":2,"_primary_term":1}
359
+ (0, engine_1._log)(NS, `> create[${id}].res =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
360
+ const _id = (_a = res.body) === null || _a === void 0 ? void 0 : _a._id;
361
+ const _version = (_b = res.body) === null || _b === void 0 ? void 0 : _b._version;
362
+ const res2 = Object.assign(Object.assign({}, body), { _id, _version });
363
+ return res2;
364
+ });
365
+ }
366
+ /**
367
+ * read item with projections
368
+ *
369
+ * @param id item-id
370
+ * @param views projections
371
+ */
372
+ readItem(id, views) {
373
+ var _a, _b;
374
+ return __awaiter(this, void 0, void 0, function* () {
375
+ const { indexName, docType } = this.options;
376
+ const type = `${docType}`;
377
+ (0, engine_1._log)(NS, `- readItem(${id})`);
378
+ const params = { index: indexName, type, id };
379
+ if (views) {
380
+ const fields = [];
381
+ const keys = Array.isArray(views) ? views : Object.keys(views);
382
+ keys.forEach((k) => {
383
+ fields.push(k);
384
+ });
385
+ params._source = fields;
386
+ }
387
+ (0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
388
+ // const { client } = instance(endpoint);
389
+ const client = this.client;
390
+ const res = yield client.get(params).catch(
391
+ // $ERROR.throwAsJson,
392
+ exports.$ERROR.handler('read', e => {
393
+ const msg = (0, test_helper_1.GETERR)(e);
394
+ if (msg.startsWith('404 NOT FOUND'))
395
+ throw new Error(`404 NOT FOUND - id:${id}`);
396
+ throw e;
397
+ }));
398
+ (0, engine_1._log)(NS, `> read[${id}].res =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
399
+ const _id = (_a = res.body) === null || _a === void 0 ? void 0 : _a._id;
400
+ const _version = (_b = res.body) === null || _b === void 0 ? void 0 : _b._version;
401
+ const data = (res === null || res === void 0 ? void 0 : res._source) || {};
402
+ // delete internal (analyzed) field
403
+ delete data[Elastic6Service.DECOMPOSED_FIELD];
404
+ delete data[Elastic6Service.QWERTY_FIELD];
405
+ const res2 = Object.assign(Object.assign({}, data), { _id, _version });
406
+ return res2;
407
+ });
408
+ }
409
+ /**
410
+ * delete item with projections
411
+ *
412
+ * @param id item-id
413
+ */
414
+ deleteItem(id) {
415
+ var _a, _b, _c;
416
+ return __awaiter(this, void 0, void 0, function* () {
417
+ const { indexName, docType } = this.options;
418
+ const type = `${docType}`;
419
+ (0, engine_1._log)(NS, `- readItem(${id})`);
420
+ const params = { index: indexName, type, id };
421
+ (0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
422
+ // const { client } = instance(endpoint);
423
+ const client = this.client;
424
+ const res = yield client.delete(params).catch(exports.$ERROR.handler('read', e => {
425
+ const msg = (0, test_helper_1.GETERR)(e);
426
+ if (msg.startsWith('404 NOT FOUND'))
427
+ throw new Error(`404 NOT FOUND - id:${id}`);
428
+ throw e;
429
+ }));
430
+ // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":3,"result":"deleted","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":4,"_primary_term":1}
431
+ (0, engine_1._log)(NS, `> delete[${id}].res =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
432
+ const _id = (_a = res.body) === null || _a === void 0 ? void 0 : _a._id;
433
+ const _version = (_b = res.body) === null || _b === void 0 ? void 0 : _b._version;
434
+ const data = ((_c = res.body) === null || _c === void 0 ? void 0 : _c._source) || {};
435
+ const res2 = Object.assign(Object.assign({}, data), { _id, _version });
436
+ return res2;
437
+ });
438
+ }
439
+ /**
440
+ * update item
441
+ *
442
+ * @param id item-id
443
+ * @param item item to update
444
+ */
445
+ updateItem(id, item, increments) {
446
+ return __awaiter(this, void 0, void 0, function* () {
447
+ const { indexName, docType, idName } = this.options;
448
+ const type = `${docType}`;
449
+ (0, engine_1._log)(NS, `- updateItem(${id})`);
450
+ item = !item && increments ? undefined : item;
451
+ //! prepare params.
452
+ const params = { index: indexName, type, id, body: { doc: item } };
453
+ const version = this.version;
454
+ if (increments) {
455
+ //! it will create if not exists.
456
+ params.body.upsert = Object.assign(Object.assign({}, increments), { [idName]: id });
457
+ const scripts = Object.entries(increments).reduce((L, [key, val]) => {
458
+ L.push(`ctx._source.${key} += ${val}`);
459
+ return L;
460
+ }, []);
461
+ if (version < 7.0)
462
+ params.body.lang = 'painless';
463
+ params.body.script = scripts.join('; ');
464
+ }
465
+ (0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
466
+ // const { client } = instance(endpoint);
467
+ const client = this.client;
468
+ const res = yield client.update(params).catch(exports.$ERROR.handler('update', (e, E) => {
469
+ const msg = (0, test_helper_1.GETERR)(e);
470
+ //! id 아이템이 없을 경우 발생함.
471
+ if (msg.startsWith('404 DOCUMENT MISSING'))
472
+ throw new Error(`404 NOT FOUND - id:${id}`);
473
+ //! 해당 속성이 없을때 업데이트 하려면 생길 수 있음.
474
+ if (msg.startsWith('400 REMOTE TRANSPORT'))
475
+ throw new Error(`400 INVALID FIELD - id:${id}`);
476
+ if (msg.startsWith('404 NOT FOUND'))
477
+ throw new Error(`404 NOT FOUND - id:${id}`);
478
+ if (msg.startsWith('400 ACTION REQUEST VALIDATION'))
479
+ throw e;
480
+ if (msg.startsWith('400 INVALID FIELD'))
481
+ throw e; // at ES6.8
482
+ if (msg.startsWith('400 ILLEGAL ARGUMENT'))
483
+ throw e; // at ES7.1
484
+ throw E;
485
+ }));
486
+ // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":2,"result":"updated","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":8,"_primary_term":1}
487
+ // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":2,"result":"noop","_shards":{"total":0,"successful":0,"failed":0}}
488
+ (0, engine_1._log)(NS, `> update[${id}].res =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
489
+ const _id = res.body._id;
490
+ const _version = res.body._version;
491
+ const res2 = Object.assign(Object.assign({}, item), { _id, _version });
492
+ return res2;
493
+ });
494
+ }
495
+ /**
496
+ * run search and get the raw response.
497
+ */
498
+ searchRaw(body, searchType) {
499
+ return __awaiter(this, void 0, void 0, function* () {
500
+ if (!body)
501
+ throw new Error('@body (SearchBody) is required');
502
+ const { indexName, docType } = this.options;
503
+ (0, engine_1._log)(NS, `- search(${indexName}, ${searchType || ''})....`);
504
+ (0, engine_1._log)(NS, `> body =`, engine_1.$U.json(body));
505
+ const tmp = docType ? docType : '';
506
+ const type = docType ? `${docType}` : undefined;
507
+ const params = { index: indexName, type, body, searchType };
508
+ (0, engine_1._log)(NS, `> params[${tmp}] =`, engine_1.$U.json(Object.assign(Object.assign({}, params), { body: undefined })));
509
+ // const { client } = instance(endpoint);
510
+ const client = this.client;
511
+ const $res = yield client.search(params).catch(exports.$ERROR.handler('search', e => {
512
+ (0, engine_1._err)(NS, `> search[${indexName}].err =`, e);
513
+ throw e;
514
+ }));
515
+ // {"took":6,"timed_out":false,"_shards":{"total":4,"successful":4,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"test-v3","_type":"_doc","_id":"aaa","_score":0.2876821,"_source":{"name":"AAA","@id":"aaa","a":-3,"b":-2}}]}}
516
+ // _log(NS, `> search[${id}].res =`, $U.json({ ...res, meta: undefined }));
517
+ // _log(NS, `> search[${tmp}].took =`, $res.took);
518
+ // _log(NS, `> search[${tmp}].hits.total =`, $res.hits?.total);
519
+ // _log(NS, `> search[${tmp}].hits.max_score =`, $res.hits?.max_score);
520
+ // _log(NS, `> search[${tmp}].hits.hits[0] =`, $res.hits && $U.json($res.hits.hits[0]));
521
+ //! return raw results.
522
+ return $res === null || $res === void 0 ? void 0 : $res.body;
523
+ });
524
+ }
525
+ /**
526
+ * run search, and get the formatmted response.
527
+ */
528
+ search(body, searchType) {
529
+ var _a, _b, _c;
530
+ return __awaiter(this, void 0, void 0, function* () {
531
+ const size = engine_1.$U.N(body.size, 0);
532
+ const response = yield this.searchRaw(body, searchType);
533
+ // return w/ transformed id
534
+ const hits = response.hits;
535
+ if (typeof hits !== 'object')
536
+ throw new Error(`.hits (object) is required - hits:${engine_1.$U.json(hits)}`);
537
+ //NOTE - ES6.8 w/ OS1.1
538
+ return {
539
+ total: typeof ((_a = hits.total) === null || _a === void 0 ? void 0 : _a.value) === 'number' ? (_b = hits.total) === null || _b === void 0 ? void 0 : _b.value : hits.total,
540
+ list: hits.hits.map((hit) => (Object.assign(Object.assign({}, hit._source), { _id: hit._id, _score: hit._score }))),
541
+ last: hits.hits.length === size && size > 0 ? (_c = hits.hits[size - 1]) === null || _c === void 0 ? void 0 : _c.sort : undefined,
542
+ aggregations: response.aggregations,
543
+ };
544
+ });
545
+ }
546
+ /**
547
+ * prepare default setting
548
+ * - migrated from engine-v2.
549
+ *
550
+ * @param docType document type name
551
+ * @param idName id-name
552
+ * @param shards number of shards (default 4)
553
+ * @param replicas number of replicas (default 1)
554
+ * @param timeSeries flag of TIMESERIES (default false)
555
+ */
556
+ static prepareSettings(params) {
557
+ const docType = params.docType === undefined ? '_doc' : params.docType;
558
+ const idName = params.idName === undefined ? '$id' : params.idName;
559
+ const version = engine_1.$U.F(params.version === undefined ? '6.8' : params.version);
560
+ const shards = params.shards === undefined ? 4 : params.shards;
561
+ const replicas = params.replicas === undefined ? 1 : params.replicas;
562
+ const timeSeries = params.timeSeries === undefined ? false : params.timeSeries;
563
+ //! core config.
564
+ const CONF_ES_DOCTYPE = docType;
565
+ const CONF_ID_NAME = idName;
566
+ const CONF_ES_TIMESERIES = !!timeSeries;
567
+ const ES_MAPPINGS = {
568
+ // NOTE: the order of dynamic templates are important.
569
+ dynamic_templates: [
570
+ // 1. Search-as-You-Type (autocomplete search) - apply to '_decomposed.*' fields
571
+ {
572
+ autocomplete: {
573
+ path_match: `${Elastic6Service.DECOMPOSED_FIELD}.*`,
574
+ mapping: {
575
+ type: 'text',
576
+ analyzer: 'autocomplete_case_insensitive',
577
+ search_analyzer: 'standard',
578
+ },
579
+ },
580
+ },
581
+ // 2. Search-as-You-Type (Korean to Alphabet sequence in QWERTY/2벌식 keyboard) - apply to '_qwerty.*' fields
582
+ {
583
+ autocomplete_qwerty: {
584
+ path_match: `${Elastic6Service.QWERTY_FIELD}.*`,
585
+ mapping: {
586
+ type: 'text',
587
+ analyzer: 'autocomplete_case_sensitive',
588
+ search_analyzer: 'whitespace',
589
+ },
590
+ },
591
+ },
592
+ // 3. string type ID field
593
+ {
594
+ string_id: {
595
+ match_mapping_type: 'string',
596
+ match: CONF_ID_NAME,
597
+ mapping: {
598
+ type: 'keyword',
599
+ ignore_above: 256,
600
+ },
601
+ },
602
+ },
603
+ // 4. any other string fields - use Hangul analyzer and create 'keyword' sub-field
604
+ {
605
+ strings: {
606
+ match_mapping_type: 'string',
607
+ mapping: {
608
+ type: 'text',
609
+ analyzer: 'hangul',
610
+ search_analyzer: 'hangul',
611
+ fields: {
612
+ // keyword sub-field
613
+ // 문자열 타입에 대한 템플릿을 지정하지 않으면 기본으로 ES가 '.keyword' 서브필드를 생성하나
614
+ // 문자열 타입 템플릿 재정의 시 기본으로 생성되지 않으므로 명시적으로 선언함.
615
+ keyword: {
616
+ type: 'keyword',
617
+ ignore_above: 256,
618
+ },
619
+ },
620
+ },
621
+ },
622
+ },
623
+ ],
624
+ properties: {
625
+ '@version': {
626
+ type: 'keyword',
627
+ index: false,
628
+ },
629
+ created_at: {
630
+ type: 'date',
631
+ format: 'strict_date_optional_time||epoch_millis',
632
+ },
633
+ updated_at: {
634
+ type: 'date',
635
+ format: 'strict_date_optional_time||epoch_millis',
636
+ },
637
+ deleted_at: {
638
+ type: 'date',
639
+ format: 'strict_date_optional_time||epoch_millis',
640
+ },
641
+ },
642
+ };
643
+ //! default settings.
644
+ const ES_SETTINGS = {
645
+ settings: {
646
+ number_of_shards: shards,
647
+ number_of_replicas: replicas,
648
+ analysis: {
649
+ tokenizer: {
650
+ hangul: {
651
+ type: 'seunjeon_tokenizer',
652
+ decompound: true,
653
+ deinflect: true,
654
+ index_eojeol: true,
655
+ pos_tagging: false, // 품사 태깅
656
+ },
657
+ edge_30grams: {
658
+ type: 'edge_ngram',
659
+ min_gram: 1,
660
+ max_gram: 30,
661
+ token_chars: ['letter', 'digit', 'punctuation', 'symbol'],
662
+ },
663
+ },
664
+ analyzer: {
665
+ hangul: {
666
+ type: 'custom',
667
+ tokenizer: 'hangul',
668
+ filter: ['lowercase'],
669
+ },
670
+ autocomplete_case_insensitive: {
671
+ type: 'custom',
672
+ tokenizer: 'edge_30grams',
673
+ filter: ['lowercase'],
674
+ },
675
+ autocomplete_case_sensitive: {
676
+ type: 'custom',
677
+ tokenizer: 'edge_30grams',
678
+ filter: version < 7.0 ? ['standard'] : [], //! error - The [standard] token filter has been removed.
679
+ },
680
+ },
681
+ },
682
+ },
683
+ //! since 7.x. no mapping for types.
684
+ mappings: version < 7.0 ? { [CONF_ES_DOCTYPE]: ES_MAPPINGS } : ES_MAPPINGS,
685
+ };
686
+ //! timeseries 데이터로, 기본 timestamp 값을 넣어준다. (주의! save시 current-time 값 자동 저장)
687
+ if (!!CONF_ES_TIMESERIES) {
688
+ ES_SETTINGS.settings.refresh_interval = '5s';
689
+ if (version < 7.0) {
690
+ ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties['@timestamp'] = { type: 'date', doc_values: true };
691
+ ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties['ip'] = { type: 'ip' };
692
+ //! clear mappings.
693
+ const CLEANS = '@version,created_at,updated_at,deleted_at'.split(',');
694
+ CLEANS.map(key => delete ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties[key]);
695
+ }
696
+ else {
697
+ ES_SETTINGS.mappings.properties['@timestamp'] = { type: 'date', doc_values: true };
698
+ ES_SETTINGS.mappings.properties['ip'] = { type: 'ip' };
699
+ //! clear mappings.
700
+ const CLEANS = '@version,created_at,updated_at,deleted_at'.split(',');
701
+ CLEANS.map(key => delete ES_SETTINGS.properties[key]);
702
+ }
703
+ }
704
+ //! returns settings.
705
+ return ES_SETTINGS;
706
+ }
707
+ /**
708
+ * generate autocomplete fields into the item body to be indexed
709
+ * @param body item body to be saved into ES6 index
710
+ * @private
711
+ */
712
+ popullateAutocompleteFields(body) {
713
+ const { autocompleteFields } = this.options;
714
+ const isAutoComplete = autocompleteFields && Array.isArray(autocompleteFields) && autocompleteFields.length > 0;
715
+ if (!isAutoComplete)
716
+ return body;
717
+ return autocompleteFields.reduce((N, field) => {
718
+ const value = body[field];
719
+ if (typeof value == 'string' || value) {
720
+ // 한글의 경우 자모 분해 형태와 영자판 변형 형태를 제공하고, 영문의 경우 원본 텍스트만 제공한다.
721
+ // 다만 사용자가 공백/하이픈을 생략하고 입력하는 경우에 대응하기 위해 공백/하이픈을 제거한 형태를 공통으로 제공한다.
722
+ if (hangul_service_1.default.isHangul(value, true)) {
723
+ // 자모 분해 (e.g. '레몬' -> 'ㄹㅔㅁㅗㄴ')
724
+ const decomposed = hangul_service_1.default.asJamoSequence(value);
725
+ const recomposed = decomposed.replace(/[ -]/g, '');
726
+ N[Elastic6Service.DECOMPOSED_FIELD][field] = [decomposed, recomposed];
727
+ // 영자판 (e.g. '레몬' -> 'fpahs')
728
+ N[Elastic6Service.QWERTY_FIELD][field] = hangul_service_1.default.asAlphabetKeyStokes(value);
729
+ }
730
+ else {
731
+ const recomposed = value.replace(/[ -]/g, '');
732
+ N[Elastic6Service.DECOMPOSED_FIELD][field] = [value, recomposed];
733
+ }
734
+ }
735
+ return N;
736
+ }, Object.assign(Object.assign({}, body), { [Elastic6Service.DECOMPOSED_FIELD]: {}, [Elastic6Service.QWERTY_FIELD]: {} }));
737
+ }
738
+ }
739
+ exports.Elastic6Service = Elastic6Service;
740
+ // internal field name to store analyzed strings for autocomplete search
741
+ Elastic6Service.DECOMPOSED_FIELD = '_decomposed';
742
+ Elastic6Service.QWERTY_FIELD = '_qwerty';
743
+ /**
744
+ * error samples
745
+ */
746
+ exports.$ERROR = {
747
+ asJson: (e) => {
748
+ const _pack = (o) => JSON.parse(JSON.stringify(o, Object.getOwnPropertyNames(o)));
749
+ if (e instanceof Error) {
750
+ const err = e;
751
+ const meta = err.meta && typeof err.meta === 'object' ? err.meta : undefined;
752
+ const $err = _pack(err);
753
+ return Object.assign(Object.assign({}, $err), { meta });
754
+ }
755
+ return e;
756
+ },
757
+ throwAsJson: (e) => {
758
+ throw exports.$ERROR.asJson(e);
759
+ },
760
+ parseMeta: (meta) => {
761
+ if (typeof meta === 'string' && meta) {
762
+ try {
763
+ if (meta.startsWith('[') && meta.endsWith(']')) {
764
+ const list = JSON.parse(meta);
765
+ const $ret = { list };
766
+ return $ret;
767
+ }
768
+ else if (meta.startsWith('{') && meta.endsWith('}')) {
769
+ return JSON.parse(meta);
770
+ }
771
+ else {
772
+ const $ret = { type: 'string', value: meta };
773
+ return $ret;
774
+ }
775
+ }
776
+ catch (e) {
777
+ const $ret = { type: 'string', value: meta, error: (0, test_helper_1.GETERR)(e) };
778
+ return $ret;
779
+ }
780
+ }
781
+ else if (meta === null || meta === undefined) {
782
+ return null;
783
+ }
784
+ else if (typeof meta === 'object') {
785
+ return meta;
786
+ }
787
+ else {
788
+ const type = typeof meta;
789
+ const $ret = { type, value: meta };
790
+ return $ret;
791
+ }
792
+ },
793
+ asError: (e) => {
794
+ const E = exports.$ERROR.asJson(e);
795
+ const status = `${E.statusCode || ''}`;
796
+ const message = `${E.message || E.msg || ''}`;
797
+ const reason = ((E) => {
798
+ var _a, _b, _c, _d;
799
+ //! from ES7.1
800
+ if (E.meta && typeof E.meta == 'object') {
801
+ const type = _S(E === null || E === void 0 ? void 0 : E.message).toUpperCase().split('_').slice(0, -1).join(' ');
802
+ const status = engine_1.$U.N((_a = E.meta) === null || _a === void 0 ? void 0 : _a.statusCode, type.includes('NOT FOUND') ? 404 : 400);
803
+ return { status, type: type || (status === 404 ? 'NOT FOUND' : 'UNKNOWN') };
804
+ }
805
+ //! from ES6.2
806
+ if (!E.response)
807
+ return null;
808
+ const $res = exports.$ERROR.parseMeta(E.response);
809
+ //! find the root-cause.
810
+ const pic1 = (N, i = 0) => (N && Array.isArray(N) ? N[i] : N);
811
+ const cause = pic1((_b = $res === null || $res === void 0 ? void 0 : $res.error) === null || _b === void 0 ? void 0 : _b.root_cause);
812
+ const status = engine_1.$U.N(((_c = $res.error) === null || _c === void 0 ? void 0 : _c.status) || $res.status);
813
+ const reason = _S((_d = $res.error) === null || _d === void 0 ? void 0 : _d.reason, $res.found === false || $res.result === 'not_found' ? 'NOT FOUND' : '');
814
+ const type = _S(cause === null || cause === void 0 ? void 0 : cause.type).toUpperCase().split('_').slice(0, -1).join(' ');
815
+ return { status, reason, cause, type: type || reason };
816
+ })(E);
817
+ //! FINAL. convert to error-object.
818
+ return {
819
+ status: engine_1.$U.N(status, (reason === null || reason === void 0 ? void 0 : reason.status) || 0),
820
+ message: message || (reason === null || reason === void 0 ? void 0 : reason.reason),
821
+ reason,
822
+ };
823
+ },
824
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
825
+ handler: (name, cb) => (e) => {
826
+ const E = exports.$ERROR.asError(e);
827
+ //! unknown error found..
828
+ if (!(E === null || E === void 0 ? void 0 : E.status)) {
829
+ (0, engine_1._err)(NS, `! err[${name}]@handler =`, e instanceof Error, engine_1.$U.json(e));
830
+ throw e;
831
+ }
832
+ const $e = new Error(`${E.status} ${E.reason.type} - ${E.message}`);
833
+ if (cb)
834
+ return cb($e, E);
835
+ throw $e;
836
+ },
837
+ };
838
+ /** ****************************************************************************************************************
839
+ * Dummy Elastic6 Service
840
+ ** ****************************************************************************************************************/
841
+ /**
842
+ * class: `DummyElastic6Service`
843
+ * - service in-memory dummy data
844
+ */
845
+ class DummyElastic6Service extends Elastic6Service {
846
+ constructor(dataFile, options) {
847
+ super(options);
848
+ this.buffer = {};
849
+ /**
850
+ * say hello()
851
+ */
852
+ this.hello = () => `dummy-elastic6-service:${this.options.indexName}`;
853
+ (0, engine_1._log)(NS, `DummyElastic6Service(${dataFile || ''})...`);
854
+ if (!dataFile)
855
+ throw new Error('@dataFile(string) is required!');
856
+ const dummy = (0, tools_1.loadDataYml)(dataFile);
857
+ this.load(dummy.data);
858
+ }
859
+ load(data) {
860
+ const { idName } = this.options;
861
+ if (!data || !Array.isArray(data))
862
+ throw new Error('@data should be array!');
863
+ data.map(item => {
864
+ const id = `${item[idName] || ''}`;
865
+ this.buffer[id] = item;
866
+ });
867
+ }
868
+ readItem(id) {
869
+ return __awaiter(this, void 0, void 0, function* () {
870
+ const item = this.buffer[id];
871
+ if (item === undefined)
872
+ throw new Error(`404 NOT FOUND - id:${id}`);
873
+ return item;
874
+ });
875
+ }
876
+ saveItem(id, item) {
877
+ return __awaiter(this, void 0, void 0, function* () {
878
+ const { idName } = this.options;
879
+ this.buffer[id] = Object.assign({ id }, item);
880
+ return Object.assign(Object.assign({ [idName]: id }, item), { _version: 1 });
881
+ });
882
+ }
883
+ deleteItem(id, sort) {
884
+ return __awaiter(this, void 0, void 0, function* () {
885
+ const org = this.buffer[id];
886
+ delete this.buffer[id];
887
+ return Object.assign({}, org);
888
+ });
889
+ }
890
+ updateItem(id, updates, increments) {
891
+ return __awaiter(this, void 0, void 0, function* () {
892
+ const org = yield this.readItem(id);
893
+ const item = Object.assign(Object.assign(Object.assign({}, org), updates), { _version: Number(org._version || 0) + 1 });
894
+ if (increments) {
895
+ //TODO - support increments in dummy.
896
+ }
897
+ this.buffer[id] = item;
898
+ return item;
899
+ });
900
+ }
901
+ }
902
+ exports.DummyElastic6Service = DummyElastic6Service;
903
+ //# sourceMappingURL=elastic6-service.js.map