lemon-core 2.2.17 → 3.0.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 (237) hide show
  1. package/README.md +3 -1
  2. package/dist/common/test-helper.js +1 -1
  3. package/dist/common/test-helper.js.map +1 -1
  4. package/dist/controllers/dummy-controller.js.map +1 -1
  5. package/dist/cores/api-service.js.map +1 -1
  6. package/dist/cores/aws/aws-s3-service.d.ts +24 -46
  7. package/dist/cores/aws/aws-s3-service.js +103 -223
  8. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  9. package/dist/cores/aws/aws-sns-service.js +3 -3
  10. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  11. package/dist/cores/core-types.d.ts +98 -2
  12. package/dist/cores/core-types.js +1 -0
  13. package/dist/cores/core-types.js.map +1 -1
  14. package/dist/cores/dynamo-service.js +2 -2
  15. package/dist/cores/dynamo-service.js.map +1 -1
  16. package/dist/cores/elastic6-query-service.d.ts +42 -9
  17. package/dist/cores/elastic6-query-service.js +144 -127
  18. package/dist/cores/elastic6-query-service.js.map +1 -1
  19. package/dist/cores/elastic6-service.d.ts +144 -57
  20. package/dist/cores/elastic6-service.js +506 -321
  21. package/dist/cores/elastic6-service.js.map +1 -1
  22. package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
  23. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  24. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +3 -3
  25. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  26. package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
  27. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  28. package/dist/cores/lambda/lambda-web-handler.js +2 -4
  29. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  30. package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
  31. package/dist/cores/model-manager.d.ts +4 -1
  32. package/dist/cores/model-manager.js +9 -4
  33. package/dist/cores/model-manager.js.map +1 -1
  34. package/dist/cores/protocol/protocol-service.d.ts +1 -2
  35. package/dist/cores/protocol/protocol-service.js +5 -3
  36. package/dist/cores/protocol/protocol-service.js.map +1 -1
  37. package/dist/engine/builder.d.ts +1 -0
  38. package/dist/engine/builder.js +1 -1
  39. package/dist/engine/builder.js.map +1 -1
  40. package/dist/engine/engine.js +2 -1
  41. package/dist/engine/engine.js.map +1 -1
  42. package/dist/engine/index.d.ts +0 -1
  43. package/dist/engine/index.js +2 -4
  44. package/dist/engine/index.js.map +1 -1
  45. package/dist/engine/types.d.ts +0 -4
  46. package/dist/engine/types.js.map +1 -1
  47. package/dist/engine/utilities.d.ts +5 -1
  48. package/dist/engine/utilities.js +126 -11
  49. package/dist/engine/utilities.js.map +1 -1
  50. package/dist/tools/express.js +0 -3
  51. package/dist/tools/express.js.map +1 -1
  52. package/package.json +7 -13
  53. package/CHANGELOG.md +0 -61
  54. package/dist/docs/assets/css/main.css +0 -2321
  55. package/dist/docs/assets/images/icons.png +0 -0
  56. package/dist/docs/assets/images/icons@2x.png +0 -0
  57. package/dist/docs/assets/images/widgets.png +0 -0
  58. package/dist/docs/assets/images/widgets@2x.png +0 -0
  59. package/dist/docs/assets/js/main.js +0 -1
  60. package/dist/docs/assets/js/search.js +0 -3
  61. package/dist/docs/classes/abstractmanager.html +0 -1034
  62. package/dist/docs/classes/apiproxyclient.html +0 -509
  63. package/dist/docs/classes/apiservice.html +0 -805
  64. package/dist/docs/classes/awskmsservice.html +0 -468
  65. package/dist/docs/classes/awsmodule.html +0 -353
  66. package/dist/docs/classes/awss3service.html +0 -689
  67. package/dist/docs/classes/awssnsservice.html +0 -543
  68. package/dist/docs/classes/awssqsservice.html +0 -517
  69. package/dist/docs/classes/cacheservice.html +0 -996
  70. package/dist/docs/classes/configmodule.html +0 -311
  71. package/dist/docs/classes/dummycacheservice.html +0 -1000
  72. package/dist/docs/classes/dummycontroller.html +0 -709
  73. package/dist/docs/classes/dummydynamoservice.html +0 -915
  74. package/dist/docs/classes/dummyelastic6service.html +0 -791
  75. package/dist/docs/classes/dummyredisstorageservice.html +0 -804
  76. package/dist/docs/classes/dummystoragemaker.html +0 -383
  77. package/dist/docs/classes/dummystorageservice.html +0 -592
  78. package/dist/docs/classes/dynamoqueryservice.html +0 -413
  79. package/dist/docs/classes/dynamoscanservice.html +0 -358
  80. package/dist/docs/classes/dynamoservice.html +0 -844
  81. package/dist/docs/classes/dynamostorageservice.html +0 -623
  82. package/dist/docs/classes/elastic6queryservice.html +0 -458
  83. package/dist/docs/classes/elastic6service.html +0 -804
  84. package/dist/docs/classes/file.html +0 -579
  85. package/dist/docs/classes/generalapicontroller.html +0 -877
  86. package/dist/docs/classes/generalcontroller.html +0 -454
  87. package/dist/docs/classes/generalcontrollerlocal.html +0 -499
  88. package/dist/docs/classes/generalcontrollerlocal2.html +0 -523
  89. package/dist/docs/classes/generalkeymaker.html +0 -335
  90. package/dist/docs/classes/generalmodelfilter.html +0 -529
  91. package/dist/docs/classes/generalwebcontroller.html +0 -580
  92. package/dist/docs/classes/hangulservice.html +0 -636
  93. package/dist/docs/classes/httpstorageservice.html +0 -539
  94. package/dist/docs/classes/lambdacognitohandler.html +0 -355
  95. package/dist/docs/classes/lambdacronhandler.html +0 -390
  96. package/dist/docs/classes/lambdacronhandlerlocal.html +0 -371
  97. package/dist/docs/classes/lambdadynamostreamhandler.html +0 -472
  98. package/dist/docs/classes/lambdadynamostreamhandlerlocal.html +0 -455
  99. package/dist/docs/classes/lambdahandler.html +0 -479
  100. package/dist/docs/classes/lambdahandlerlocal.html +0 -472
  101. package/dist/docs/classes/lambdamodule.html +0 -433
  102. package/dist/docs/classes/lambdanotificationhandler.html +0 -474
  103. package/dist/docs/classes/lambdanotificationhandlerlocal.html +0 -457
  104. package/dist/docs/classes/lambdasnshandler.html +0 -394
  105. package/dist/docs/classes/lambdasnshandlerlocal.html +0 -397
  106. package/dist/docs/classes/lambdasqshandler.html +0 -394
  107. package/dist/docs/classes/lambdasqshandlerlocal.html +0 -397
  108. package/dist/docs/classes/lambdasubhandler.html +0 -305
  109. package/dist/docs/classes/lambdawebhandler.html +0 -603
  110. package/dist/docs/classes/lambdawebhandlerlocal.html +0 -581
  111. package/dist/docs/classes/lambdawsshandler.html +0 -359
  112. package/dist/docs/classes/memcachedbackend.html +0 -900
  113. package/dist/docs/classes/mocksapiservice.html +0 -691
  114. package/dist/docs/classes/modelutil.html +0 -311
  115. package/dist/docs/classes/myconfigservice.html +0 -561
  116. package/dist/docs/classes/myconfigservicetest.html +0 -527
  117. package/dist/docs/classes/myconfigservicetest2.html +0 -522
  118. package/dist/docs/classes/mydummysqsservice.html +0 -419
  119. package/dist/docs/classes/myenginemodules.html +0 -357
  120. package/dist/docs/classes/mygeneralapicontroller.html +0 -837
  121. package/dist/docs/classes/mylemonwebcontroller.html +0 -356
  122. package/dist/docs/classes/mymodelfilter.html +0 -479
  123. package/dist/docs/classes/myprotocolservice.html +0 -993
  124. package/dist/docs/classes/myprotocolservicetest.html +0 -983
  125. package/dist/docs/classes/myservice.html +0 -329
  126. package/dist/docs/classes/mystorage.html +0 -1370
  127. package/dist/docs/classes/nodecachebackend.html +0 -714
  128. package/dist/docs/classes/protocolmodule.html +0 -311
  129. package/dist/docs/classes/proxystorageservice.html +0 -1441
  130. package/dist/docs/classes/query.html +0 -850
  131. package/dist/docs/classes/redisbackend.html +0 -781
  132. package/dist/docs/classes/redisstorageservice.html +0 -867
  133. package/dist/docs/classes/scan.html +0 -685
  134. package/dist/docs/classes/snsprotocoltransformer.html +0 -334
  135. package/dist/docs/classes/sqsprotocoltransformer.html +0 -334
  136. package/dist/docs/classes/typedstorageservice.html +0 -914
  137. package/dist/docs/classes/uniquefieldmanager.html +0 -477
  138. package/dist/docs/classes/usermanager.html +0 -919
  139. package/dist/docs/classes/utilities.html +0 -1914
  140. package/dist/docs/classes/webprotocoltransformer.html +0 -330
  141. package/dist/docs/globals.html +0 -7477
  142. package/dist/docs/index.html +0 -1511
  143. package/dist/docs/interfaces/accountitem.html +0 -277
  144. package/dist/docs/interfaces/accountmodel.html +0 -306
  145. package/dist/docs/interfaces/adaptiveparam.html +0 -203
  146. package/dist/docs/interfaces/apiheaders.html +0 -183
  147. package/dist/docs/interfaces/apihttpproxy.html +0 -304
  148. package/dist/docs/interfaces/apiserviceclient.html +0 -448
  149. package/dist/docs/interfaces/autocompletesearchparam.html +0 -282
  150. package/dist/docs/interfaces/betweencondition.html +0 -226
  151. package/dist/docs/interfaces/cachebackend.html +0 -714
  152. package/dist/docs/interfaces/cacheentry.html +0 -248
  153. package/dist/docs/interfaces/cacheoptions.html +0 -267
  154. package/dist/docs/interfaces/callbackdata.html +0 -279
  155. package/dist/docs/interfaces/callbackparam.html +0 -252
  156. package/dist/docs/interfaces/comparisoncondition.html +0 -226
  157. package/dist/docs/interfaces/coreconfigservice.html +0 -342
  158. package/dist/docs/interfaces/corekey.html +0 -278
  159. package/dist/docs/interfaces/corekeymakeable.html +0 -292
  160. package/dist/docs/interfaces/corekmsservice.html +0 -311
  161. package/dist/docs/interfaces/coremodel.html +0 -499
  162. package/dist/docs/interfaces/coremodelfilterable.html +0 -281
  163. package/dist/docs/interfaces/cores3service.html +0 -485
  164. package/dist/docs/interfaces/coreservices.html +0 -232
  165. package/dist/docs/interfaces/coresnsservice.html +0 -317
  166. package/dist/docs/interfaces/corewebcontroller.html +0 -271
  167. package/dist/docs/interfaces/cronevent.html +0 -223
  168. package/dist/docs/interfaces/cronparam.html +0 -212
  169. package/dist/docs/interfaces/dynamooption.html +0 -254
  170. package/dist/docs/interfaces/dynamoqueryresult.html +0 -244
  171. package/dist/docs/interfaces/dynamoscanresult.html +0 -244
  172. package/dist/docs/interfaces/dynamosimplequeriable.html +0 -308
  173. package/dist/docs/interfaces/dynamosimplescannable.html +0 -255
  174. package/dist/docs/interfaces/dynamostreambody.html +0 -268
  175. package/dist/docs/interfaces/dynamostreamcallback.html +0 -209
  176. package/dist/docs/interfaces/dynamostreamfilter.html +0 -218
  177. package/dist/docs/interfaces/dynamostreamparam.html +0 -240
  178. package/dist/docs/interfaces/elastic6item.html +0 -221
  179. package/dist/docs/interfaces/elastic6option.html +0 -275
  180. package/dist/docs/interfaces/elastic6simplequeriable.html +0 -284
  181. package/dist/docs/interfaces/engineconsole.html +0 -292
  182. package/dist/docs/interfaces/enginecore.html +0 -344
  183. package/dist/docs/interfaces/enginemodule.html +0 -269
  184. package/dist/docs/interfaces/enginemodules.html +0 -316
  185. package/dist/docs/interfaces/engineoption.html +0 -244
  186. package/dist/docs/interfaces/enginescope.html +0 -220
  187. package/dist/docs/interfaces/existencecondition.html +0 -212
  188. package/dist/docs/interfaces/filter.html +0 -253
  189. package/dist/docs/interfaces/generalfuntion.html +0 -207
  190. package/dist/docs/interfaces/generalitem.html +0 -212
  191. package/dist/docs/interfaces/handlermap.html +0 -171
  192. package/dist/docs/interfaces/incrementable.html +0 -190
  193. package/dist/docs/interfaces/internalkey.html +0 -210
  194. package/dist/docs/interfaces/internalmodel.html +0 -226
  195. package/dist/docs/interfaces/itementry.html +0 -241
  196. package/dist/docs/interfaces/jwtcommon.html +0 -242
  197. package/dist/docs/interfaces/lambdahandlerservice.html +0 -340
  198. package/dist/docs/interfaces/lemonengine.html +0 -593
  199. package/dist/docs/interfaces/metricpostbody.html +0 -220
  200. package/dist/docs/interfaces/mygeneral.html +0 -271
  201. package/dist/docs/interfaces/mymodel.html +0 -554
  202. package/dist/docs/interfaces/myprotocolparam.html +0 -359
  203. package/dist/docs/interfaces/nextcontext.html +0 -381
  204. package/dist/docs/interfaces/nextidentity.html +0 -325
  205. package/dist/docs/interfaces/nextidentityaccess.html +0 -495
  206. package/dist/docs/interfaces/nextidentitycognito.html +0 -422
  207. package/dist/docs/interfaces/notificationbody.html +0 -171
  208. package/dist/docs/interfaces/notificationparam.html +0 -304
  209. package/dist/docs/interfaces/options.html +0 -226
  210. package/dist/docs/interfaces/parrallelcallback.html +0 -203
  211. package/dist/docs/interfaces/parrallelparam.html +0 -285
  212. package/dist/docs/interfaces/protocolbody.html +0 -183
  213. package/dist/docs/interfaces/protocolparam.html +0 -336
  214. package/dist/docs/interfaces/protocolservice.html +0 -548
  215. package/dist/docs/interfaces/protocoltransformer.html +0 -295
  216. package/dist/docs/interfaces/proxyparams.html +0 -212
  217. package/dist/docs/interfaces/putobjectresult.html +0 -282
  218. package/dist/docs/interfaces/queryresult.html +0 -272
  219. package/dist/docs/interfaces/redisoptions.html +0 -248
  220. package/dist/docs/interfaces/simplesearchparam.html +0 -351
  221. package/dist/docs/interfaces/slackaction.html +0 -240
  222. package/dist/docs/interfaces/slackattachment.html +0 -459
  223. package/dist/docs/interfaces/slackpostbody.html +0 -240
  224. package/dist/docs/interfaces/sqsattribute.html +0 -171
  225. package/dist/docs/interfaces/sqsmessage.html +0 -254
  226. package/dist/docs/interfaces/sqsrecord.html +0 -324
  227. package/dist/docs/interfaces/sqsservice.html +0 -333
  228. package/dist/docs/interfaces/sqsstatistics.html +0 -240
  229. package/dist/docs/interfaces/storagemakeable.html +0 -258
  230. package/dist/docs/interfaces/storagemodel.html +0 -285
  231. package/dist/docs/interfaces/storageservice.html +0 -497
  232. package/dist/docs/interfaces/stringcondition.html +0 -226
  233. package/dist/docs/interfaces/tagset.html +0 -171
  234. package/dist/docs/interfaces/testmodel.html +0 -334
  235. package/dist/docs/interfaces/timeout.html +0 -233
  236. package/dist/docs/interfaces/updatable.html +0 -193
  237. package/dist/docs/interfaces/user.html +0 -534
@@ -19,47 +19,127 @@ exports.DummyElastic6Service = exports.$ERROR = exports.Elastic6Service = void 0
19
19
  *
20
20
  * @author Steve Jung <steve@lemoncloud.io>
21
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)
22
24
  *
23
25
  * @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
24
26
  */
25
27
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
28
  const engine_1 = require("../engine/");
27
- const NS = engine_1.$U.NS('ES6', 'green'); // NAMESPACE TO BE PRINTED.
28
- const elasticsearch_1 = __importDefault(require("elasticsearch"));
29
+ const elasticsearch_1 = __importDefault(require("@elastic/elasticsearch"));
29
30
  const hangul_service_1 = __importDefault(require("./hangul-service"));
30
31
  const tools_1 = require("../tools");
31
- //! create(or get) instance.
32
- const instance = (endpoint) => {
33
- return Elastic6Service.instance(endpoint);
34
- };
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}`;
35
38
  /**
36
39
  * class: `Elastic6Service`
37
40
  * - basic CRUD service for Elastic Search 6
38
41
  */
39
42
  class Elastic6Service {
43
+ /**
44
+ * default constuctor w/ options.
45
+ * @param options { endpoint, indexName } is required.
46
+ */
40
47
  constructor(options) {
41
48
  /**
42
49
  * say hello of identity.
43
50
  */
44
- this.hello = () => `elastic6-service:${this.options.indexName}`;
51
+ this.hello = () => `elastic6-service:${this.options.indexName}:${this.version}`;
45
52
  engine_1._inf(NS, `Elastic6Service(${options.indexName}/${options.idName})...`);
46
53
  if (!options.endpoint)
47
54
  throw new Error('.endpoint (URL) is required');
48
55
  if (!options.indexName)
49
56
  throw new Error('.indexName (string) is required');
50
57
  // default option values: docType='_doc', idName='$id'
51
- this.options = Object.assign({ docType: '_doc', idName: '$id' }, options);
58
+ const { client } = Elastic6Service.instance(options.endpoint);
59
+ this._options = Object.assign({ docType: '_doc', idName: '$id', version: '6.8' }, options);
60
+ this._client = client;
52
61
  }
53
62
  /**
54
63
  * simple instance maker.
64
+ *
65
+ * ```js
66
+ * const { client } = Elastic6Service.instance(endpoint);
67
+ * ```
68
+ *
55
69
  * @param endpoint service-url
56
70
  * @param version Elasticsearch version (default: '6.8')
57
71
  * @see https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/16.x/configuration.html
58
72
  */
59
73
  static instance(endpoint) {
60
- const client = new elasticsearch_1.default.Client({ host: 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
+ });
61
81
  return { client };
62
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
+ 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
+ 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
+ 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
+ }
63
143
  /**
64
144
  * create index by name
65
145
  *
@@ -67,12 +147,11 @@ class Elastic6Service {
67
147
  */
68
148
  createIndex(settings) {
69
149
  return __awaiter(this, void 0, void 0, function* () {
70
- const { endpoint, indexName, docType, idName, timeSeries } = this.options;
71
- settings = settings || Elastic6Service.prepareSettings(docType, idName, timeSeries);
150
+ const { indexName, docType, idName, timeSeries, version } = this.options;
151
+ settings = settings || Elastic6Service.prepareSettings({ docType, idName, timeSeries, version });
72
152
  if (!indexName)
73
153
  new Error('@index is required!');
74
154
  engine_1._log(NS, `- createIndex(${indexName})`);
75
- settings = settings || {};
76
155
  //! prepare payload
77
156
  const payload = Object.assign({ settings: {
78
157
  number_of_shards: 5,
@@ -80,18 +159,24 @@ class Elastic6Service {
80
159
  } }, settings);
81
160
  engine_1._log(NS, `> settings[${indexName}] = `, engine_1.$U.json(payload));
82
161
  //! call create index..
83
- const { client } = instance(endpoint);
84
- const res = yield client.indices.create({ index: indexName, body: payload }).catch(exports.$ERROR.handler('create', e => {
85
- engine_1._err(NS, `> create[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
86
- if (`${e.message}`.startsWith('400 resource_already_exists_exception'))
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 = test_helper_1.GETERR(e);
168
+ if (msg.startsWith('400 RESOURCE ALREADY EXISTS'))
87
169
  throw new Error(`400 IN USE - index:${indexName}`);
88
170
  throw e;
89
171
  }));
90
- engine_1._log(NS, `> create[${indexName}] =`, engine_1.$U.json(res));
91
- engine_1._log(NS, `> create[${indexName}].acknowledged =`, res.acknowledged); // true
92
- engine_1._log(NS, `> create[${indexName}].index =`, res.index); // index
93
- engine_1._log(NS, `> create[${indexName}].shards_acknowledged =`, res.shards_acknowledged); // true
94
- return res;
172
+ // if (res) throw res;
173
+ 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
+ };
95
180
  });
96
181
  }
97
182
  /**
@@ -99,21 +184,28 @@ class Elastic6Service {
99
184
  */
100
185
  destroyIndex() {
101
186
  return __awaiter(this, void 0, void 0, function* () {
102
- const { endpoint, indexName } = this.options;
187
+ const { indexName } = this.options;
103
188
  if (!indexName)
104
189
  new Error('@index is required!');
105
190
  engine_1._log(NS, `- destroyIndex(${indexName})`);
106
191
  //! call create index..
107
- const { client } = instance(endpoint);
108
- const res = yield client.indices.delete({ index: indexName }).catch(exports.$ERROR.handler('destroy', e => {
109
- engine_1._err(NS, `> destory[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
110
- if (`${e.message}`.startsWith('404 index_not_found_exception'))
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 = test_helper_1.GETERR(e);
198
+ if (msg.startsWith('404 INDEX NOT FOUND'))
111
199
  throw new Error(`404 NOT FOUND - index:${indexName}`);
112
200
  throw e;
113
201
  }));
114
- engine_1._log(NS, `> destroy[${indexName}] =`, engine_1.$U.json(res));
115
- engine_1._log(NS, `> destroy[${indexName}].acknowledged =`, res.acknowledged); // true
116
- return res;
202
+ // if (res) throw res;
203
+ 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
+ };
117
209
  });
118
210
  }
119
211
  /**
@@ -121,18 +213,23 @@ class Elastic6Service {
121
213
  */
122
214
  refreshIndex() {
123
215
  return __awaiter(this, void 0, void 0, function* () {
124
- const { endpoint, indexName } = this.options;
216
+ const { indexName } = this.options;
125
217
  if (!indexName)
126
218
  throw new Error('.indexName is required!');
127
219
  engine_1._log(NS, `- refreshIndex(${indexName})`);
128
220
  //! call refresh index..
129
- const { client } = instance(endpoint);
130
- const res = yield client.indices.refresh({ index: indexName }).catch(exports.$ERROR.handler('refresh', e => {
131
- engine_1._err(NS, `> refresh[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
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 = test_helper_1.GETERR(e);
227
+ if (msg.startsWith('404 INDEX NOT FOUND'))
228
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
132
229
  throw e;
133
230
  }));
134
- engine_1._log(NS, `> refresh[${indexName}] =`, engine_1.$U.json(res));
135
- return res;
231
+ engine_1._log(NS, `> refresh[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
232
+ return res.body;
136
233
  });
137
234
  }
138
235
  /**
@@ -140,18 +237,23 @@ class Elastic6Service {
140
237
  */
141
238
  flushIndex() {
142
239
  return __awaiter(this, void 0, void 0, function* () {
143
- const { endpoint, indexName } = this.options;
240
+ const { indexName } = this.options;
144
241
  if (!indexName)
145
242
  throw new Error('.indexName is required!');
146
243
  engine_1._log(NS, `- flushIndex(${indexName})`);
147
244
  //! call flush index..
148
- const { client } = instance(endpoint);
149
- const res = yield client.indices.flush({ index: indexName }).catch(exports.$ERROR.handler('flush', e => {
150
- engine_1._err(NS, `> flush[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
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 = test_helper_1.GETERR(e);
251
+ if (msg.startsWith('404 INDEX NOT FOUND'))
252
+ throw new Error(`404 NOT FOUND - index:${indexName}`);
151
253
  throw e;
152
254
  }));
153
- engine_1._log(NS, `> flush[${indexName}] =`, engine_1.$U.json(res));
154
- return res;
255
+ engine_1._log(NS, `> flush[${indexName}] =`, engine_1.$U.json(Object.assign(Object.assign({}, res), { meta: undefined })));
256
+ return res.body;
155
257
  });
156
258
  }
157
259
  /**
@@ -159,25 +261,28 @@ class Elastic6Service {
159
261
  */
160
262
  describe() {
161
263
  return __awaiter(this, void 0, void 0, function* () {
162
- const { endpoint, indexName } = this.options;
264
+ const { indexName } = this.options;
163
265
  //! call create index..
164
- const { client } = instance(endpoint);
165
266
  engine_1._log(NS, `- describe(${indexName})`);
166
267
  //! read settings.
167
- const res = yield client.indices.getSettings({ index: indexName }).catch(exports.$ERROR.handler('describe', e => {
168
- engine_1._err(NS, `> describe[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
169
- if (`${e.message}`.startsWith('404 index_not_found_exception'))
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 = test_helper_1.GETERR(e);
274
+ if (msg.startsWith('404 INDEX NOT FOUND'))
170
275
  throw new Error(`404 NOT FOUND - index:${indexName}`);
171
276
  throw e;
172
277
  }));
173
- engine_1._log(NS, `> settings[${indexName}] =`, engine_1.$U.json(res));
174
- const settings = (res[indexName] && res[indexName].settings) || {};
278
+ 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) || {};
175
280
  engine_1._log(NS, `> number_of_shards =`, settings.index && settings.index.number_of_shards); // 5
176
281
  engine_1._log(NS, `> number_of_replicas =`, settings.index && settings.index.number_of_replicas); // 1
177
282
  //! read mappings.
178
283
  const res2 = yield client.indices.getMapping({ index: indexName });
179
284
  engine_1._log(NS, `> mappings[${indexName}] =`, engine_1.$U.json(res2));
180
- const mappings = (res2[indexName] && res2[indexName].mappings) || {};
285
+ const mappings = (res2.body && res2.body[indexName] && res2.body[indexName].mappings) || {};
181
286
  //! returns
182
287
  return { settings, mappings };
183
288
  });
@@ -190,42 +295,38 @@ class Elastic6Service {
190
295
  * @param type document type (default: doc-type given at construction time)
191
296
  */
192
297
  saveItem(id, item, type) {
298
+ var _a, _b;
193
299
  return __awaiter(this, void 0, void 0, function* () {
194
- const { endpoint, indexName, docType, idName } = this.options;
195
- const { client } = instance(endpoint);
300
+ const { indexName, docType, idName } = this.options;
196
301
  engine_1._log(NS, `- saveItem(${id})`);
302
+ // const { client } = instance(endpoint);
303
+ const client = this.client;
197
304
  // prepare item body and autocomplete fields
198
305
  const body = Object.assign(Object.assign({}, item), { [idName]: id });
199
- this.prepareAutocompleteFields(body);
306
+ const body2 = this.popullateAutocompleteFields(body);
200
307
  type = `${type || docType}`;
201
- const params = {
202
- index: indexName,
203
- type,
204
- id,
205
- body,
206
- };
207
- if (idName == '_id')
208
- delete params.body[idName]; // `_id` is reserved in ES6.
308
+ const params = { index: indexName, type, id, body: body2 };
309
+ if (idName === '_id')
310
+ delete params.body[idName]; //WARN! `_id` is reserved in ES6.
209
311
  engine_1._log(NS, `> params[${id}] =`, engine_1.$U.json(params));
210
312
  //NOTE - use npm `elasticsearch#13.2.0` for avoiding error.
211
- const res = yield client.create(params).catch(exports.$ERROR.handler('save', e => {
212
- engine_1._log(NS, `> save[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
213
- if (`${e.message}`.startsWith('409 version_conflict_engine_exception')) {
214
- //! try to update document...
215
- const params = { index: indexName, type, id, body: { doc: item } };
216
- return client.update(params);
313
+ const res = yield client.create(params).catch(
314
+ // $ERROR.throwAsJson,
315
+ exports.$ERROR.handler('save', e => {
316
+ const msg = 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);
217
323
  }
218
324
  throw e;
219
325
  }));
220
- // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
221
- // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":1,"result":"noop","_shards":{"total":0,"successful":0,"failed":0}}
222
- engine_1._log(NS, `> create[${id}].res =`, engine_1.$U.json(res));
223
- engine_1._log(NS, `> create[${id}].result =`, res.result); // 'created','noop','updated'
224
- engine_1._log(NS, `> create[${id}]._version =`, res._version); // 1
225
- // return res;
226
- const _version = engine_1.$U.N(res._version, 0);
227
- const _id = res._id;
228
- const res2 = Object.assign(Object.assign({}, item), { _id, _version });
326
+ 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 });
229
330
  return res2;
230
331
  });
231
332
  }
@@ -235,28 +336,30 @@ class Elastic6Service {
235
336
  * @param item item to push
236
337
  */
237
338
  pushItem(item, type) {
339
+ var _a, _b;
238
340
  return __awaiter(this, void 0, void 0, function* () {
239
- const { endpoint, indexName, docType } = this.options;
240
- const { client } = instance(endpoint);
341
+ const { indexName, docType } = this.options;
241
342
  const id = '';
242
343
  type = `${type || docType}`;
243
344
  const body = Object.assign({}, item);
244
- this.prepareAutocompleteFields(body);
345
+ const body2 = this.popullateAutocompleteFields(body);
245
346
  engine_1._log(NS, `- pushItem(${id})`);
246
- const params = { index: indexName, type, body };
347
+ const params = { index: indexName, type, body: body2 };
247
348
  engine_1._log(NS, `> params[${id}] =`, engine_1.$U.json(params));
248
349
  //NOTE - use npm `elasticsearch#13.2.0` for avoiding error.
249
- const res = yield client.index(params).catch(exports.$ERROR.handler('index', e => {
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 => {
250
355
  engine_1._err(NS, `> index[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
251
356
  throw e;
252
357
  }));
253
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}
254
- engine_1._log(NS, `> create[${id}].res =`, engine_1.$U.json(res));
255
- engine_1._log(NS, `> create[${id}].result =`, res.result); // 'created','noop','updated'
256
- engine_1._log(NS, `> create[${id}]._version =`, res._version); // 1
257
- const _id = res._id;
258
- const _version = res._version;
259
- const res2 = Object.assign(Object.assign({}, item), { _id, _version });
359
+ 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 });
260
363
  return res2;
261
364
  });
262
365
  }
@@ -267,34 +370,35 @@ class Elastic6Service {
267
370
  * @param views projections
268
371
  */
269
372
  readItem(id, views) {
373
+ var _a, _b, _c;
270
374
  return __awaiter(this, void 0, void 0, function* () {
271
- const { endpoint, indexName, docType } = this.options;
272
- const { client } = instance(endpoint);
375
+ const { indexName, docType } = this.options;
273
376
  const type = `${docType}`;
274
377
  engine_1._log(NS, `- readItem(${id})`);
275
378
  const params = { index: indexName, type, id };
276
379
  if (views) {
277
380
  const fields = [];
278
- const is_array = Array.isArray(views);
279
- engine_1.$_.each(views, (v, k) => {
280
- fields.push(is_array ? v : k);
381
+ const keys = Array.isArray(views) ? views : Object.keys(views);
382
+ keys.forEach((k) => {
383
+ fields.push(k);
281
384
  });
282
385
  params._source = fields;
283
386
  }
284
387
  engine_1._log(NS, `> params[${id}] =`, engine_1.$U.json(params));
285
- const res = yield client.get(params).catch(exports.$ERROR.handler('read', e => {
286
- engine_1._err(NS, `> read[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
287
- if (`${e.message}`.startsWith('404 Not Found'))
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 = test_helper_1.GETERR(e);
394
+ if (msg.startsWith('404 NOT FOUND'))
288
395
  throw new Error(`404 NOT FOUND - id:${id}`);
289
396
  throw e;
290
397
  }));
291
- // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":2,"found":true,"_source":{"name":"haha"}}
292
- engine_1._log(NS, `> read[${id}].res =`, engine_1.$U.json(res));
293
- engine_1._log(NS, `> create[${id}].found =`, res.found); // true
294
- engine_1._log(NS, `> create[${id}]._version =`, res._version); // 2
295
- const _id = res._id;
296
- const _version = res._version;
297
- const data = (res && res._source) || {};
398
+ 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 = ((_c = res) === null || _c === void 0 ? void 0 : _c._source) || {};
298
402
  // delete internal (analyzed) field
299
403
  delete data[Elastic6Service.DECOMPOSED_FIELD];
300
404
  delete data[Elastic6Service.QWERTY_FIELD];
@@ -308,26 +412,26 @@ class Elastic6Service {
308
412
  * @param id item-id
309
413
  */
310
414
  deleteItem(id) {
415
+ var _a, _b, _c;
311
416
  return __awaiter(this, void 0, void 0, function* () {
312
- const { endpoint, indexName, docType } = this.options;
313
- const { client } = instance(endpoint);
417
+ const { indexName, docType } = this.options;
314
418
  const type = `${docType}`;
315
419
  engine_1._log(NS, `- readItem(${id})`);
316
420
  const params = { index: indexName, type, id };
317
421
  engine_1._log(NS, `> params[${id}] =`, engine_1.$U.json(params));
318
- const res = yield client.delete(params).catch(exports.$ERROR.handler('delete', e => {
319
- engine_1._err(NS, `> delete[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
320
- if (`${e.message}`.startsWith('404 Not Found'))
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 = test_helper_1.GETERR(e);
426
+ if (msg.startsWith('404 NOT FOUND'))
321
427
  throw new Error(`404 NOT FOUND - id:${id}`);
322
428
  throw e;
323
429
  }));
324
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}
325
- engine_1._log(NS, `> delete[${id}].res =`, engine_1.$U.json(res));
326
- engine_1._log(NS, `> delete[${id}].result =`, res.result); // true
327
- engine_1._log(NS, `> delete[${id}]._version =`, res._version); // 2
328
- const _id = res._id;
329
- const _version = res._version;
330
- const data = (res && res._source) || {};
431
+ 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) || {};
331
435
  const res2 = Object.assign(Object.assign({}, data), { _id, _version });
332
436
  return res2;
333
437
  });
@@ -340,47 +444,105 @@ class Elastic6Service {
340
444
  */
341
445
  updateItem(id, item, increments) {
342
446
  return __awaiter(this, void 0, void 0, function* () {
343
- const { endpoint, indexName, docType } = this.options;
344
- const { client } = instance(endpoint);
447
+ const { indexName, docType, idName } = this.options;
345
448
  const type = `${docType}`;
346
449
  engine_1._log(NS, `- updateItem(${id})`);
347
450
  item = !item && increments ? undefined : item;
348
451
  //! prepare params.
349
452
  const params = { index: indexName, type, id, body: { doc: item } };
453
+ const version = this.version;
350
454
  if (increments) {
351
455
  //! it will create if not exists.
352
- params.body.upsert = Object.assign(Object.assign({}, increments), { [indexName]: id });
353
- const scripts = engine_1.$_.reduce(increments, (L, val, key) => {
456
+ params.body.upsert = Object.assign(Object.assign({}, increments), { [idName]: id });
457
+ const scripts = Object.entries(increments).reduce((L, [key, val]) => {
354
458
  L.push(`ctx._source.${key} += ${val}`);
355
459
  return L;
356
460
  }, []);
357
- params.body.lang = 'painless';
461
+ if (version < 7.0)
462
+ params.body.lang = 'painless';
358
463
  params.body.script = scripts.join('; ');
359
464
  }
360
465
  engine_1._log(NS, `> params[${id}] =`, engine_1.$U.json(params));
361
- const res = yield client.update(params).catch(exports.$ERROR.handler('update', e => {
362
- engine_1._err(NS, `> update[${indexName}].err =`, e instanceof Error ? e : engine_1.$U.json(e));
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 = test_helper_1.GETERR(e);
363
470
  //! id 아이템이 없을 경우 발생함.
364
- if (`${e.message}`.startsWith('404 document_missing_exception'))
471
+ if (msg.startsWith('404 DOCUMENT MISSING'))
365
472
  throw new Error(`404 NOT FOUND - id:${id}`);
366
473
  //! 해당 속성이 없을때 업데이트 하려면 생길 수 있음.
367
- if (`${e.message}`.startsWith('400 remote_transport_exception'))
474
+ if (msg.startsWith('400 REMOTE TRANSPORT'))
368
475
  throw new Error(`400 INVALID FIELD - id:${id}`);
369
- if (`${e.message}`.startsWith('404 Not Found'))
476
+ if (msg.startsWith('404 NOT FOUND'))
370
477
  throw new Error(`404 NOT FOUND - id:${id}`);
371
- throw e;
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;
372
485
  }));
373
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}
374
487
  // {"_index":"test-v3","_type":"_doc","_id":"aaa","_version":2,"result":"noop","_shards":{"total":0,"successful":0,"failed":0}}
375
- engine_1._log(NS, `> update[${id}].res =`, engine_1.$U.json(res));
376
- engine_1._log(NS, `> update[${id}].result =`, res.result); // true
377
- engine_1._log(NS, `> update[${id}]._version =`, res._version); // 2
378
- const _id = res._id;
379
- const _version = res._version;
488
+ 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;
380
491
  const res2 = Object.assign(Object.assign({}, item), { _id, _version });
381
492
  return res2;
382
493
  });
383
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
+ engine_1._log(NS, `- search(${indexName}, ${searchType || ''})....`);
504
+ 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
+ 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
+ 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
+ }
384
546
  /**
385
547
  * prepare default setting
386
548
  * - migrated from engine-v2.
@@ -391,14 +553,94 @@ class Elastic6Service {
391
553
  * @param replicas number of replicas (default 1)
392
554
  * @param timeSeries flag of TIMESERIES (default false)
393
555
  */
394
- static prepareSettings(docType, idName, timeSeries, shards, replicas) {
395
- shards = shards === undefined ? 4 : shards;
396
- replicas = replicas === undefined ? 1 : replicas;
397
- timeSeries = timeSeries === undefined ? false : timeSeries;
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;
398
563
  //! core config.
399
564
  const CONF_ES_DOCTYPE = docType;
400
565
  const CONF_ID_NAME = idName;
401
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.
402
644
  const ES_SETTINGS = {
403
645
  settings: {
404
646
  number_of_shards: shards,
@@ -433,98 +675,31 @@ class Elastic6Service {
433
675
  autocomplete_case_sensitive: {
434
676
  type: 'custom',
435
677
  tokenizer: 'edge_30grams',
436
- filter: ['standard'],
437
- },
438
- },
439
- },
440
- },
441
- mappings: {
442
- [CONF_ES_DOCTYPE]: {
443
- // NOTE: the order of dynamic templates are important.
444
- dynamic_templates: [
445
- // 1. Search-as-You-Type (autocomplete search) - apply to '_decomposed.*' fields
446
- {
447
- autocomplete: {
448
- path_match: `${Elastic6Service.DECOMPOSED_FIELD}.*`,
449
- mapping: {
450
- type: 'text',
451
- analyzer: 'autocomplete_case_insensitive',
452
- search_analyzer: 'standard',
453
- },
454
- },
455
- },
456
- // 2. Search-as-You-Type (Korean to Alphabet sequence in QWERTY/2벌식 keyboard) - apply to '_qwerty.*' fields
457
- {
458
- autocomplete_qwerty: {
459
- path_match: `${Elastic6Service.QWERTY_FIELD}.*`,
460
- mapping: {
461
- type: 'text',
462
- analyzer: 'autocomplete_case_sensitive',
463
- search_analyzer: 'whitespace',
464
- },
465
- },
466
- },
467
- // 3. string type ID field
468
- {
469
- string_id: {
470
- match_mapping_type: 'string',
471
- match: CONF_ID_NAME,
472
- mapping: {
473
- type: 'keyword',
474
- ignore_above: 256,
475
- },
476
- },
477
- },
478
- // 4. any other string fields - use Hangul analyzer and create 'keyword' sub-field
479
- {
480
- strings: {
481
- match_mapping_type: 'string',
482
- mapping: {
483
- type: 'text',
484
- analyzer: 'hangul',
485
- search_analyzer: 'hangul',
486
- fields: {
487
- // keyword sub-field
488
- // 문자열 타입에 대한 템플릿을 지정하지 않으면 기본으로 ES가 '.keyword' 서브필드를 생성하나
489
- // 문자열 타입 템플릿 재정의 시 기본으로 생성되지 않으므로 명시적으로 선언함.
490
- keyword: {
491
- type: 'keyword',
492
- ignore_above: 256,
493
- },
494
- },
495
- },
496
- },
497
- },
498
- ],
499
- properties: {
500
- '@version': {
501
- type: 'keyword',
502
- index: false,
503
- },
504
- created_at: {
505
- type: 'date',
506
- format: 'strict_date_optional_time||epoch_millis',
507
- },
508
- updated_at: {
509
- type: 'date',
510
- format: 'strict_date_optional_time||epoch_millis',
511
- },
512
- deleted_at: {
513
- type: 'date',
514
- format: 'strict_date_optional_time||epoch_millis',
678
+ filter: version < 7.0 ? ['standard'] : [],
515
679
  },
516
680
  },
517
681
  },
518
682
  },
683
+ //! since 7.x. no mapping for types.
684
+ mappings: version < 7.0 ? { [CONF_ES_DOCTYPE]: ES_MAPPINGS } : ES_MAPPINGS,
519
685
  };
520
686
  //! timeseries 데이터로, 기본 timestamp 값을 넣어준다. (주의! save시 current-time 값 자동 저장)
521
687
  if (!!CONF_ES_TIMESERIES) {
522
688
  ES_SETTINGS.settings.refresh_interval = '5s';
523
- ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties['@timestamp'] = { type: 'date', doc_values: true };
524
- ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties['ip'] = { type: 'ip' };
525
- //! clear mappings.
526
- const CLEANS = '@version,created_at,updated_at,deleted_at'.split(',');
527
- CLEANS.map(key => delete ES_SETTINGS.mappings[CONF_ES_DOCTYPE].properties[key]);
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
+ }
528
703
  }
529
704
  //! returns settings.
530
705
  return ES_SETTINGS;
@@ -534,31 +709,31 @@ class Elastic6Service {
534
709
  * @param body item body to be saved into ES6 index
535
710
  * @private
536
711
  */
537
- prepareAutocompleteFields(body) {
712
+ popullateAutocompleteFields(body) {
538
713
  const { autocompleteFields } = this.options;
539
- if (body && Array.isArray(autocompleteFields) && autocompleteFields.length > 0) {
540
- body[Elastic6Service.DECOMPOSED_FIELD] = {};
541
- body[Elastic6Service.QWERTY_FIELD] = {};
542
- autocompleteFields.forEach(field => {
543
- const value = body[field];
544
- if (typeof value == 'string' || value) {
545
- // 한글의 경우 자모 분해 형태와 영자판 변형 형태를 제공하고, 영문의 경우 원본 텍스트만 제공한다.
546
- // 다만 사용자가 공백/하이픈을 생략하고 입력하는 경우에 대응하기 위해 공백/하이픈을 제거한 형태를 공통으로 제공한다.
547
- if (hangul_service_1.default.isHangul(value, true)) {
548
- // 자모 분해 (e.g. '레몬' -> 'ㄹㅔㅁㅗㄴ')
549
- const decomposed = hangul_service_1.default.asJamoSequence(value);
550
- const recomposed = decomposed.replace(/[ -]/g, '');
551
- body[Elastic6Service.DECOMPOSED_FIELD][field] = [decomposed, recomposed];
552
- // 영자판 (e.g. '레몬' -> 'fpahs')
553
- body[Elastic6Service.QWERTY_FIELD][field] = hangul_service_1.default.asAlphabetKeyStokes(value);
554
- }
555
- else {
556
- const recomposed = value.replace(/[ -]/g, '');
557
- body[Elastic6Service.DECOMPOSED_FIELD][field] = [value, recomposed];
558
- }
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);
559
729
  }
560
- });
561
- }
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]: {} }));
562
737
  }
563
738
  }
564
739
  exports.Elastic6Service = Elastic6Service;
@@ -569,94 +744,104 @@ Elastic6Service.QWERTY_FIELD = '_qwerty';
569
744
  * error samples
570
745
  */
571
746
  exports.$ERROR = {
572
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
573
- handler: (name, cb) => (e) => {
574
- engine_1._err(NS, `! err[${name}]@a =`, e instanceof Error, engine_1.$U.json(e));
575
- const status = `${e.statusCode || ''}`;
576
- const message = `${e.message || e.msg || ''}`;
577
- const error = ((e) => {
578
- if (!e)
579
- return {};
580
- if (e.body && e.body.error) {
581
- const error = e.body.error;
582
- if (error.root_cause && Array.isArray(error.root_cause))
583
- return error.root_cause[0];
584
- else if (error.root_cause)
585
- return error.root_cause;
586
- return 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
+ }
587
775
  }
588
- else if (e.response) {
589
- const error = typeof e.response == 'string' && e.response.startsWith('{') ? JSON.parse(e.response) : e.response;
590
- if (error.root_cause && Array.isArray(error.root_cause))
591
- return error.root_cause[0];
592
- else if (error.root_cause)
593
- return error.root_cause;
594
- return error;
776
+ catch (e) {
777
+ const $ret = { type: 'string', value: meta, error: test_helper_1.GETERR(e) };
778
+ return $ret;
595
779
  }
596
- else {
597
- const type = e.statusCode || e.status || 0;
598
- const reason = e.displayName || e.msg;
599
- const path = e.path || '';
600
- return { type, reason, path, message };
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)
802
+ .toUpperCase()
803
+ .split('_')
804
+ .slice(0, -1)
805
+ .join(' ');
806
+ const status = engine_1.$U.N((_a = E.meta) === null || _a === void 0 ? void 0 : _a.statusCode, type.includes('NOT FOUND') ? 404 : 400);
807
+ return { status, type: type || (status === 404 ? 'NOT FOUND' : 'UNKNOWN') };
601
808
  }
602
- })(e);
603
- error.status = error.status || status;
604
- error.message = error.message || message;
605
- //! print the unknown type exception
606
- if (!error || error.status) {
607
- // _err(NS, `! err[${name}]@b =`, e instanceof Error, $U.json(e));
608
- // _err(NS, `> err[${name}]@c =`, $U.json(error));
609
- // _err(NS, `> error[${name}].type =`, error.type);
610
- // _err(NS, `> error[${name}].reason =`, error.reason);
611
- // _err(NS, `> error[${name}].message =`, error.message);
809
+ //! from ES6.2
810
+ if (!E.response)
811
+ return null;
812
+ const $res = exports.$ERROR.parseMeta(E.response);
813
+ //! find the root-cause.
814
+ const pic1 = (N, i = 0) => (N && Array.isArray(N) ? N[i] : N);
815
+ const cause = pic1((_b = $res === null || $res === void 0 ? void 0 : $res.error) === null || _b === void 0 ? void 0 : _b.root_cause);
816
+ const status = engine_1.$U.N(((_c = $res.error) === null || _c === void 0 ? void 0 : _c.status) || $res.status);
817
+ const reason = _S((_d = $res.error) === null || _d === void 0 ? void 0 : _d.reason, $res.found === false || $res.result === 'not_found' ? 'NOT FOUND' : '');
818
+ const type = _S(cause === null || cause === void 0 ? void 0 : cause.type)
819
+ .toUpperCase()
820
+ .split('_')
821
+ .slice(0, -1)
822
+ .join(' ');
823
+ return { status, reason, cause, type: type || reason };
824
+ })(E);
825
+ //! FINAL. convert to error-object.
826
+ return {
827
+ status: engine_1.$U.N(status, (reason === null || reason === void 0 ? void 0 : reason.status) || 0),
828
+ message: message || (reason === null || reason === void 0 ? void 0 : reason.reason),
829
+ reason,
830
+ };
831
+ },
832
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
833
+ handler: (name, cb) => (e) => {
834
+ const E = exports.$ERROR.asError(e);
835
+ //! unknown error found..
836
+ if (!(E === null || E === void 0 ? void 0 : E.status)) {
837
+ engine_1._err(NS, `! err[${name}]@handler =`, e instanceof Error, engine_1.$U.json(e));
838
+ throw e;
612
839
  }
613
- //! build Error instance.
614
- const $e = new Error(`${error.status} ${error.type || error.reason || error.message} - ${error.reason || error.message}`);
840
+ const $e = new Error(`${E.status} ${E.reason.type} - ${E.message}`);
615
841
  if (cb)
616
- return cb($e);
842
+ return cb($e, E);
617
843
  throw $e;
618
844
  },
619
- index_not_found_exception: {
620
- msg: '[index_not_found_exception] no such index, with { resource.type="index_or_alias" & resource.id="test-v2" & index_uuid="_na_" & index="test-v2" }',
621
- path: '/test-v2',
622
- query: {},
623
- statusCode: 404,
624
- response: '{"error":{"root_cause":[{"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"test-v2","index_uuid":"_na_","index":"test-v2"}],"type":"index_not_found_exception","reason":"no such index","resource.type":"index_or_alias","resource.id":"test-v2","index_uuid":"_na_","index":"test-v2"},"status":404}',
625
- },
626
- resource_already_exists_exception: {
627
- msg: '[resource_already_exists_exception] index [test-v2/R_X1Daw7S0e8qIh_W3M-Fg] already exists, with { index_uuid="R_X1Daw7S0e8qIh_W3M-Fg" & index="test-v2" }',
628
- path: '/test-v2',
629
- query: {},
630
- body: '{"settings":{"index":{"number_of_shards":4,"number_of_replicas":1}},"template":"test-v2","mappings":{"_default_":{"dynamic_templates":[{"string_fields":{"match":"*_multi","match_mapping_type":"string","mapping":{"type":"multi_field","fields":{"{name}":{"type":"text","index":"analyzed","omit_norms":true,"index_options":"docs"},"{name}.raw":{"type":"text","index":"not_analyzed","ignore_above":256}}}}}],"_source":{"enabled":true},"properties":{"@version":{"type":"text","index":false},"title":{"type":"text"},"name":{"type":"text"},"created_at":{"type":"date","format":"strict_date_optional_time||epoch_millis"},"updated_at":{"type":"date","format":"strict_date_optional_time||epoch_millis"},"deleted_at":{"type":"date","format":"strict_date_optional_time||epoch_millis"},"@id":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}',
631
- statusCode: 400,
632
- response: '{"error":{"root_cause":[{"type":"resource_already_exists_exception","reason":"index [test-v2/R_X1Daw7S0e8qIh_W3M-Fg] already exists","index_uuid":"R_X1Daw7S0e8qIh_W3M-Fg","index":"test-v2"}],"type":"resource_already_exists_exception","reason":"index [test-v2/R_X1Daw7S0e8qIh_W3M-Fg] already exists","index_uuid":"R_X1Daw7S0e8qIh_W3M-Fg","index":"test-v2"},"status":400}',
633
- },
634
- not_found: {
635
- msg: 'Not Found',
636
- path: '/test-v3/_doc/bbb',
637
- query: {},
638
- statusCode: 404,
639
- response: '{"_index":"test-v3","_type":"_doc","_id":"bbb","found":false}',
640
- },
641
- action_request_validation_exception: {
642
- msg: '[action_request_validation_exception] Validation Failed: 1: script or doc is missing;',
643
- path: '/test-v3/_doc/aaa/_update',
644
- query: {},
645
- statusCode: 400,
646
- response: '{"error":{"root_cause":[{"type":"action_request_validation_exception","reason":"Validation Failed: 1: script or doc is missing;"}],"type":"action_request_validation_exception","reason":"Validation Failed: 1: script or doc is missing;"},"status":400}',
647
- },
648
- remote_transport_exception: {
649
- msg: '[remote_transport_exception] [rt8LrQT][x.x.x.x:9300][indices:data/write/update[s]]',
650
- path: '/test-v3/_doc/aaa/_update',
651
- query: {},
652
- body: '{"upsert":{"count":2,"a":5},"script":"ctx._source.count += 2,ctx._source.a += 5"}',
653
- statusCode: 400,
654
- response: '{"error":{"root_cause":[{"type":"remote_transport_exception","reason":"[rt8LrQT][x.x.x.x:9300][indices:data/write/update[s]]"}],"type":"illegal_argument_exception","reason":"failed to execute script","caused_by":{"type":"script_exception","reason":"compile error","script_stack":["ctx._source.count += 2,ctx._source.a += 5"," ^---- HERE"],"script":"ctx._source.count += 2,ctx._source.a += 5","lang":"painless","caused_by":{"type":"illegal_argument_exception","reason":"unexpected token [\',\'] was expecting one of [{<EOF>, \';\'}]."}}},"status":400}',
655
- },
656
- version_conflict_engine_exception: {
657
- '!': '가끔씩 update할때 나는것 같음! 개선 필요 @191121',
658
- msg: '[version_conflict_engine_exception] [item][TTDfu-tfwfoE0CFuQ=]: version conflict, current version [3] is different than the one provided [2], with { index_uuid="GxCGaNZoSZuoDFTmWfjqtg" & shard="4" & index="clusters-v1" }',
659
- },
660
845
  };
661
846
  /** ****************************************************************************************************************
662
847
  * Dummy Elastic6 Service
@@ -713,7 +898,7 @@ class DummyElastic6Service extends Elastic6Service {
713
898
  updateItem(id, updates, increments) {
714
899
  return __awaiter(this, void 0, void 0, function* () {
715
900
  const org = yield this.readItem(id);
716
- const item = Object.assign(Object.assign(Object.assign({}, org), updates), { _version: Number(org._version) + 1 });
901
+ const item = Object.assign(Object.assign(Object.assign({}, org), updates), { _version: Number(org._version || 0) + 1 });
717
902
  if (increments) {
718
903
  //TODO - support increments in dummy.
719
904
  }