lemon-core 4.3.0 → 5.0.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.
- package/README.md +127 -2
- package/dist/common/lemon-error.d.ts +34 -0
- package/dist/common/lemon-error.js +52 -0
- package/dist/common/lemon-error.js.map +1 -0
- package/dist/controllers/general-api-controller.d.ts +7 -0
- package/dist/controllers/general-api-controller.js +7 -0
- package/dist/controllers/general-api-controller.js.map +1 -1
- package/dist/cores/api/api-service.js +10 -43
- package/dist/cores/api/api-service.js.map +1 -1
- package/dist/cores/aws/aws-kms-service.d.ts +13 -5
- package/dist/cores/aws/aws-kms-service.js +23 -9
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/aws/aws-s3-service.d.ts +30 -4
- package/dist/cores/aws/aws-s3-service.js +35 -15
- package/dist/cores/aws/aws-s3-service.js.map +1 -1
- package/dist/cores/aws/aws-sns-service.js +59 -9
- package/dist/cores/aws/aws-sns-service.js.map +1 -1
- package/dist/cores/aws/aws-sqs-service.d.ts +1 -1
- package/dist/cores/aws/aws-sqs-service.js +54 -12
- package/dist/cores/aws/aws-sqs-service.js.map +1 -1
- package/dist/cores/cache/cache-service.d.ts +10 -9
- package/dist/cores/cache/cache-service.js +9 -346
- package/dist/cores/cache/cache-service.js.map +1 -1
- package/dist/cores/config/config-service.d.ts +3 -15
- package/dist/cores/config/config-service.js +5 -34
- package/dist/cores/config/config-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-query-service.js +42 -2
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-scan-service.js +42 -2
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-service.d.ts +45 -14
- package/dist/cores/dynamo/dynamo-service.js +48 -21
- package/dist/cores/dynamo/dynamo-service.js.map +1 -1
- package/dist/cores/dynamo/tools/expressions.js +32 -22
- package/dist/cores/dynamo/tools/expressions.js.map +1 -1
- package/dist/cores/dynamo/tools/lang.d.ts +30 -0
- package/dist/cores/dynamo/tools/lang.js +75 -0
- package/dist/cores/dynamo/tools/lang.js.map +1 -0
- package/dist/cores/dynamo/tools/query.js +20 -21
- package/dist/cores/dynamo/tools/query.js.map +1 -1
- package/dist/cores/dynamo/tools/scan.js +15 -16
- package/dist/cores/dynamo/tools/scan.js.map +1 -1
- package/dist/cores/dynamo/tools/serializer.js +40 -38
- package/dist/cores/dynamo/tools/serializer.js.map +1 -1
- package/dist/cores/dynamo/tools/utils.d.ts +6 -2
- package/dist/cores/dynamo/tools/utils.js +11 -8
- package/dist/cores/dynamo/tools/utils.js.map +1 -1
- package/dist/cores/elastic/elastic6-query-service.d.ts +1 -104
- package/dist/cores/elastic/elastic6-query-service.js +15 -489
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
- package/dist/cores/elastic/elastic6-service.d.ts +1 -482
- package/dist/cores/elastic/elastic6-service.js +15 -1153
- package/dist/cores/elastic/elastic6-service.js.map +1 -1
- package/dist/cores/elastic/index.d.ts +2 -2
- package/dist/cores/elastic/index.js +3 -2
- package/dist/cores/elastic/index.js.map +1 -1
- package/dist/cores/elastic/os2-query-service.d.ts +104 -0
- package/dist/cores/elastic/os2-query-service.js +495 -0
- package/dist/cores/elastic/os2-query-service.js.map +1 -0
- package/dist/cores/elastic/os2-service.d.ts +372 -0
- package/dist/cores/elastic/os2-service.js +943 -0
- package/dist/cores/elastic/os2-service.js.map +1 -0
- package/dist/cores/index.d.ts +6 -1
- package/dist/cores/index.js +9 -2
- package/dist/cores/index.js.map +1 -1
- package/dist/cores/lambda/index.js +2 -1
- package/dist/cores/lambda/index.js.map +1 -1
- package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -0
- package/dist/cores/lambda/lambda-cron-handler.js +5 -1
- package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +5 -4
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js +18 -5
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-handler.d.ts +22 -2
- package/dist/cores/lambda/lambda-handler.js +85 -23
- package/dist/cores/lambda/lambda-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sns-handler.d.ts +1 -0
- package/dist/cores/lambda/lambda-sns-handler.js +5 -0
- package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.d.ts +1 -0
- package/dist/cores/lambda/lambda-sqs-handler.js +20 -5
- package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-web-handler.d.ts +10 -0
- package/dist/cores/lambda/lambda-web-handler.js +107 -41
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/protocol/aws-lambda-helper.js +58 -11
- package/dist/cores/protocol/aws-lambda-helper.js.map +1 -1
- package/dist/cores/protocol/index.js +3 -0
- package/dist/cores/protocol/index.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +26 -5
- package/dist/cores/protocol/protocol-service.js +42 -12
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/protocol/protocol-sign.d.ts +72 -0
- package/dist/cores/protocol/protocol-sign.js +194 -0
- package/dist/cores/protocol/protocol-sign.js.map +1 -0
- package/dist/cores/storage/index.d.ts +0 -1
- package/dist/cores/storage/index.js +0 -1
- package/dist/cores/storage/index.js.map +1 -1
- package/dist/cores/storage/model-fields.d.ts +7 -0
- package/dist/cores/storage/model-fields.js +21 -0
- package/dist/cores/storage/model-fields.js.map +1 -0
- package/dist/cores/storage/model-manager.d.ts +5 -2
- package/dist/cores/storage/model-manager.js +11 -3
- package/dist/cores/storage/model-manager.js.map +1 -1
- package/dist/engine/builder.js +20 -2
- package/dist/engine/builder.js.map +1 -1
- package/dist/engine/engine.d.ts +2 -2
- package/dist/engine/engine.js +5 -5
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/utilities.d.ts +20 -12
- package/dist/engine/utilities.js +57 -86
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.d.ts +0 -6
- package/dist/environ.js +1 -12
- package/dist/environ.js.map +1 -1
- package/dist/esm/index.mjs +141 -0
- package/dist/esm/testing.mjs +12 -0
- package/dist/extended/abstract-service.d.ts +48 -139
- package/dist/extended/abstract-service.js +46 -382
- package/dist/extended/abstract-service.js.map +1 -1
- package/dist/extended/cores/abstract-controllers.d.ts +25 -0
- package/dist/extended/cores/abstract-controllers.js +77 -7
- package/dist/extended/cores/abstract-controllers.js.map +1 -1
- package/dist/extended/cores/abstract-rest-apis.d.ts +2 -1
- package/dist/extended/cores/abstract-rest-apis.js +2 -1
- package/dist/extended/cores/abstract-rest-apis.js.map +1 -1
- package/dist/extended/cores/abstract-services.d.ts +48 -87
- package/dist/extended/cores/abstract-services.js +121 -248
- package/dist/extended/cores/abstract-services.js.map +1 -1
- package/dist/extended/cores/commons.d.ts +4 -113
- package/dist/extended/cores/commons.js +26 -180
- package/dist/extended/cores/commons.js.map +1 -1
- package/dist/extended/cores/fields-admin.d.ts +91 -0
- package/dist/extended/cores/fields-admin.js +142 -0
- package/dist/extended/cores/fields-admin.js.map +1 -0
- package/dist/extended/cores/index.d.ts +2 -0
- package/dist/extended/cores/index.js +2 -0
- package/dist/extended/cores/index.js.map +1 -1
- package/dist/extended/cores/types.d.ts +3 -225
- package/dist/extended/cores/types.js +28 -0
- package/dist/extended/cores/types.js.map +1 -1
- package/dist/helpers/helpers.d.ts +10 -5
- package/dist/helpers/helpers.js +46 -58
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/helpers/types.d.ts +22 -10
- package/dist/index.d.ts +1 -5
- package/dist/index.js +8 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/http-fetch.d.ts +54 -0
- package/dist/lib/http-fetch.js +133 -0
- package/dist/lib/http-fetch.js.map +1 -0
- package/dist/lib/lazy.d.ts +22 -0
- package/dist/lib/lazy.js +54 -0
- package/dist/lib/lazy.js.map +1 -0
- package/dist/lib/perf.d.ts +35 -0
- package/dist/lib/perf.js +52 -0
- package/dist/lib/perf.js.map +1 -0
- package/dist/tools/tools.d.ts +15 -3
- package/dist/tools/tools.js +21 -4
- package/dist/tools/tools.js.map +1 -1
- package/package.json +96 -39
- package/dist/cores/storage/redis-storage-service.d.ts +0 -183
- package/dist/cores/storage/redis-storage-service.js +0 -377
- package/dist/cores/storage/redis-storage-service.js.map +0 -1
- package/dist/generated/field-registry.d.ts +0 -12
- package/dist/generated/field-registry.js +0 -21
- package/dist/generated/field-registry.js.map +0 -1
|
@@ -33,8 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.$ES6Routed = exports.$
|
|
37
|
-
exports.sourceToItem = sourceToItem;
|
|
36
|
+
exports.$ES6Routed = exports.$OS2 = exports._OS2 = exports.OS2Instance = exports.OS2FGACManager = exports.OS2Service = exports.MyManagerProxy = exports.MyCoreProxy = exports.MyCoreManager = exports.MyCoreService = exports.sourceToItem = void 0;
|
|
38
37
|
/**
|
|
39
38
|
* `abstract-services.ts`
|
|
40
39
|
* - common services used in `/cores`
|
|
@@ -74,6 +73,8 @@ exports.sourceToItem = sourceToItem;
|
|
|
74
73
|
* @date 2026-01-05 optimized `hasAdminRole()` and `getCurrentSession()`.
|
|
75
74
|
* @date 2026-02-11 optimized `proxy.mget()` with `throwable` options.
|
|
76
75
|
* @date 2026-04-09 optimized `types` to fix `ModelType` cast error.
|
|
76
|
+
* @date 2026-10-27 v5 B2-b: OpenSearch client, lazy `$OS2` (= `$ES6Routed`), one service set per instance.
|
|
77
|
+
* @date 2026-10-28 v5 B4: `CORE_FIELDS = fieldsOf(CoreModel)`; manager `fields` may be a model class.
|
|
77
78
|
*
|
|
78
79
|
* @copyright (C) 2022 LemonCloud Co Ltd. - All Rights Reserved.
|
|
79
80
|
* @origin `@lemoncloud/lemon-templates-api/cores`
|
|
@@ -82,19 +83,24 @@ exports.sourceToItem = sourceToItem;
|
|
|
82
83
|
const engine_1 = require("../../engine/");
|
|
83
84
|
const cores_1 = __importStar(require("../../cores/"));
|
|
84
85
|
const cores_2 = require("../../cores/");
|
|
85
|
-
const cores_3 = require("../../cores/");
|
|
86
86
|
const test_helper_1 = require("../../common/test-helper");
|
|
87
87
|
const tools_1 = require("../../tools/");
|
|
88
88
|
const helpers_1 = require("../../helpers/");
|
|
89
89
|
const abstract_service_1 = require("../abstract-service");
|
|
90
|
+
//* v5 B3: the local copy was identical to the L1 one (the root already used that); re-exported to keep this deep path.
|
|
91
|
+
var abstract_service_2 = require("../abstract-service");
|
|
92
|
+
Object.defineProperty(exports, "sourceToItem", { enumerable: true, get: function () { return abstract_service_2.sourceToItem; } });
|
|
93
|
+
const lazy_1 = require("../../lib/lazy");
|
|
94
|
+
const perf_1 = require("../../lib/perf");
|
|
95
|
+
const lemon_model_1 = require("lemon-model");
|
|
90
96
|
const commons_1 = require("./commons");
|
|
91
|
-
const field_registry_1 = require("../../generated/field-registry");
|
|
92
97
|
const NAME = engine_1.$U.env('NAME', 'lemon');
|
|
93
98
|
const NS = engine_1.$U.NS('HDBS', 'green');
|
|
94
99
|
/**
|
|
95
|
-
* fields in core model.
|
|
100
|
+
* fields in core model (L2: the 14 L1 `CORE_FIELDS` + `id`, `_id`).
|
|
101
|
+
* - v5 B4: read from the `@field()` annotations of the `CoreModel` class (was the generated registry).
|
|
96
102
|
*/
|
|
97
|
-
const CORE_FIELDS =
|
|
103
|
+
const CORE_FIELDS = (0, lemon_model_1.fieldsOf)(lemon_model_1.CoreModel);
|
|
98
104
|
/**
|
|
99
105
|
* lookup table for common types.
|
|
100
106
|
*/
|
|
@@ -120,9 +126,10 @@ class MyCoreService extends abstract_service_1.CoreService {
|
|
|
120
126
|
}
|
|
121
127
|
/**
|
|
122
128
|
* make proxy, and use callback to handle.
|
|
123
|
-
* - it will save automatically.
|
|
129
|
+
* - it will save automatically on success.
|
|
130
|
+
* - v5: on exception it saves only when `options.saveOnError` is true (default false, B5 § 6.7).
|
|
124
131
|
*/
|
|
125
|
-
guardProxy = async (context, callback) => {
|
|
132
|
+
guardProxy = async (context, callback, options) => {
|
|
126
133
|
const proxy = this.createProxy(context);
|
|
127
134
|
try {
|
|
128
135
|
const result = await callback(proxy);
|
|
@@ -131,20 +138,22 @@ class MyCoreService extends abstract_service_1.CoreService {
|
|
|
131
138
|
return result;
|
|
132
139
|
}
|
|
133
140
|
catch (e) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
//* v5: save pending updates on exception only by opt-in (v4 always saved @240613).
|
|
142
|
+
if (options?.saveOnError) {
|
|
143
|
+
const saved = await proxy.saveAllUpdates().catch(e => (0, test_helper_1.GETERR$)(e));
|
|
144
|
+
(0, engine_1._log)(`> saved =`, engine_1.$U.json(saved));
|
|
145
|
+
}
|
|
137
146
|
throw e;
|
|
138
147
|
}
|
|
139
148
|
};
|
|
140
149
|
/**
|
|
141
|
-
* run search
|
|
142
|
-
* - override this to hide `$
|
|
150
|
+
* run search (via `$OS2`)
|
|
151
|
+
* - override this to hide `$OS2`
|
|
143
152
|
*/
|
|
144
153
|
async doSearch(body) {
|
|
145
154
|
(0, engine_1._log)(`doSearch()`);
|
|
146
155
|
(0, engine_1._log)(`> list.query =`, engine_1.$U.json(body));
|
|
147
|
-
const result = await exports.$
|
|
156
|
+
const result = await exports.$OS2.search(body);
|
|
148
157
|
(0, engine_1._log)(`> list.res =`, engine_1.$U.json({ ...result, list: [result?.list?.[0]] }));
|
|
149
158
|
return result;
|
|
150
159
|
}
|
|
@@ -155,18 +164,12 @@ class MyCoreService extends abstract_service_1.CoreService {
|
|
|
155
164
|
const USE_SESSION = commons_1.$T.S(engine_1.$U.env('USE_SESSION', '')).toLowerCase();
|
|
156
165
|
return USE_SESSION && USE_SESSION != '0' && USE_SESSION != 'false' ? true : false;
|
|
157
166
|
}
|
|
158
|
-
/**
|
|
159
|
-
* @deprecated typo kept for 1 minor as a non-breaking alias — use `isUseSession()` instead. (cores-migration P1, decision #2)
|
|
160
|
-
*/
|
|
161
|
-
isUseSssion() {
|
|
162
|
-
return this.isUseSession();
|
|
163
|
-
}
|
|
164
167
|
/**
|
|
165
168
|
* check if search-engine is supportable
|
|
166
169
|
* @returns
|
|
167
170
|
*/
|
|
168
171
|
hasSearchEngine() {
|
|
169
|
-
const useSearch = !!exports.$
|
|
172
|
+
const useSearch = !!exports.$OS2.options?.indexName;
|
|
170
173
|
return useSearch;
|
|
171
174
|
}
|
|
172
175
|
}
|
|
@@ -187,12 +190,16 @@ class MyCoreManager extends abstract_service_1.CoreManager {
|
|
|
187
190
|
* constructor
|
|
188
191
|
* @protected
|
|
189
192
|
*/
|
|
190
|
-
constructor(type, parent,
|
|
193
|
+
constructor(type, parent,
|
|
194
|
+
//* v5 B4: a `string[]` or a model class (resolved in `AbstractManager`).
|
|
195
|
+
fields, options) {
|
|
191
196
|
super(type, parent, fields, options?.uniqueField);
|
|
192
197
|
this.options = options;
|
|
193
|
-
|
|
198
|
+
//* v5: sync is opt-in (default false), so `$OS2` is built only when a manager asks (B5 § 6.7).
|
|
199
|
+
const enableSync = options?.enableSync ?? false;
|
|
200
|
+
//* the first manager with `enableSync: true` builds the lazy `$OS2` (1 listener when `OS2_ENDPOINT` is set).
|
|
194
201
|
if (enableSync)
|
|
195
|
-
exports.$
|
|
202
|
+
exports.$OS2.synchronizer?.enableSynchronization(this.type);
|
|
196
203
|
this.logNS = engine_1.$U.NS(type, 'yellow');
|
|
197
204
|
}
|
|
198
205
|
/**
|
|
@@ -690,11 +697,12 @@ class MyCoreManager extends abstract_service_1.CoreManager {
|
|
|
690
697
|
return result;
|
|
691
698
|
};
|
|
692
699
|
const _saveBulk = async (operations) => {
|
|
693
|
-
const elastic = exports.$
|
|
700
|
+
const elastic = exports.$OS2.client;
|
|
694
701
|
const $res = await elastic.bulk({ body: operations }).catch(e => {
|
|
695
702
|
(0, engine_1._err)(this.NS, `>> err=`, e);
|
|
696
703
|
throw e;
|
|
697
704
|
});
|
|
705
|
+
//* the OS client types `items[].index.error` as an object; read it in the v4 shape.
|
|
698
706
|
const list = $res.body?.items?.map(item => ({
|
|
699
707
|
_id: item.index._id,
|
|
700
708
|
_version: item.index._version,
|
|
@@ -714,7 +722,7 @@ class MyCoreManager extends abstract_service_1.CoreManager {
|
|
|
714
722
|
const _transformBulkOperations = (dataChunk) => {
|
|
715
723
|
return dataChunk.flatMap(doc => {
|
|
716
724
|
const { _id, ...items } = doc;
|
|
717
|
-
return [{ index: { _index: exports.$
|
|
725
|
+
return [{ index: { _index: exports.$OS2.options?.indexName, _id: doc._id } }, items];
|
|
718
726
|
});
|
|
719
727
|
};
|
|
720
728
|
const results = await (0, helpers_1.my_sequence)(chunkList, async (N) => {
|
|
@@ -821,7 +829,8 @@ class MyCoreProxy extends abstract_service_1.AbstractProxy {
|
|
|
821
829
|
USE_SESSION && (0, engine_1._inf)(this.service.NS, `> use-session =`, useSession, USE_SESSION);
|
|
822
830
|
const context = (options?.context ?? this.context);
|
|
823
831
|
//* WARN - in case of local, no need to throw error.
|
|
824
|
-
|
|
832
|
+
//* v5: local mode is a runtime setting (`LOCAL_MODE=1` off Lambda), never from `context.domain` (B5 § 6.3).
|
|
833
|
+
const isLocal = engine_1.$U.isLocalMode();
|
|
825
834
|
// load the `identity-token` from json file.
|
|
826
835
|
const _load = (file) => {
|
|
827
836
|
const data = (0, tools_1.loadJsonSync)(file);
|
|
@@ -856,12 +865,14 @@ class MyCoreProxy extends abstract_service_1.AbstractProxy {
|
|
|
856
865
|
}
|
|
857
866
|
}
|
|
858
867
|
//TODO - 아래 코드는 개선의 여지가 있음(문제점???) @241210
|
|
859
|
-
|
|
868
|
+
//* v5: `LOCAL_ACCOUNT` is honoured only in local mode (B5 § 6.3).
|
|
869
|
+
if (LOCAL_ACCOUNT && isLocal)
|
|
860
870
|
return _default();
|
|
861
871
|
if (useSession) {
|
|
862
872
|
// _inf(this.service.NS, `> use-session =`, useSession, USE_SESSION);
|
|
863
873
|
if (useSession === true || useSession === 'true' || useSession === '1') {
|
|
864
|
-
|
|
874
|
+
//* v5: a session file (`USE_SESSION=*.json`) is honoured only in local mode (B5 § 6.3).
|
|
875
|
+
if (isLocal && USE_SESSION?.endsWith('.json')) {
|
|
865
876
|
const $sess = _load(USE_SESSION);
|
|
866
877
|
(0, engine_1._inf)(this.service.NS, `> use-session-json =`, engine_1.$U.json($sess));
|
|
867
878
|
return $sess;
|
|
@@ -906,7 +917,8 @@ class MyCoreProxy extends abstract_service_1.AbstractProxy {
|
|
|
906
917
|
*/
|
|
907
918
|
asCurrentIdentityId = (context) => {
|
|
908
919
|
context = context ?? this.context;
|
|
909
|
-
|
|
920
|
+
//* v5: `LOCAL_ACCOUNT` fallback only in local mode, not from `context.domain` (B5 § 6.3).
|
|
921
|
+
if (engine_1.$U.isLocalMode() && !context?.identity?.identityId) {
|
|
910
922
|
const LOCAL_ACCOUNT = engine_1.$U.env('LOCAL_ACCOUNT', '');
|
|
911
923
|
return LOCAL_ACCOUNT ? LOCAL_ACCOUNT : null;
|
|
912
924
|
}
|
|
@@ -923,8 +935,8 @@ class MyCoreProxy extends abstract_service_1.AbstractProxy {
|
|
|
923
935
|
const errScope = options?.errScope ?? `assertContext()`;
|
|
924
936
|
const $idt = context?.identity;
|
|
925
937
|
const isS = (s) => typeof s === 'string' && s?.length > 0;
|
|
926
|
-
//* call in local
|
|
927
|
-
const isLocal =
|
|
938
|
+
//* call in local (v5: runtime local mode only, never from `context.domain` — B5 § 6.3)
|
|
939
|
+
const isLocal = engine_1.$U.isLocalMode();
|
|
928
940
|
//* signed call with access-key
|
|
929
941
|
const isSigned = isS($idt?.accessKey);
|
|
930
942
|
//* authed by cognito provider.
|
|
@@ -959,7 +971,7 @@ class MyCoreProxy extends abstract_service_1.AbstractProxy {
|
|
|
959
971
|
}
|
|
960
972
|
/**
|
|
961
973
|
* check if current context has `admin` access
|
|
962
|
-
* 1. run in local
|
|
974
|
+
* 1. run in local mode (`$U.isLocalMode()`, v5 — no longer `domain='localhost'`)
|
|
963
975
|
* 2. access via signed access-key
|
|
964
976
|
* 3. authorized cognito and has `admin` role in identity-token.
|
|
965
977
|
*
|
|
@@ -1086,12 +1098,11 @@ class MyManagerProxy extends abstract_service_1.ManagerProxy {
|
|
|
1086
1098
|
* @returns
|
|
1087
1099
|
*/
|
|
1088
1100
|
packSearchParam(param, model, options) {
|
|
1089
|
-
const $ctx = this.proxy.context;
|
|
1090
1101
|
const type = this.$mgr.type;
|
|
1091
1102
|
const useSession = options?.useSession ?? false;
|
|
1092
1103
|
const throwable = options?.throwable ?? true;
|
|
1093
1104
|
const errScope = options?.errScope ?? `packSearchParam(${type})`;
|
|
1094
|
-
const isLocal =
|
|
1105
|
+
const isLocal = engine_1.$U.isLocalMode(); //* v5: drop the `sid` pin only in local mode (B5 § 6.3).
|
|
1095
1106
|
const session = useSession ? this.proxy.getCurrentSession({ throwable }) : null;
|
|
1096
1107
|
const _has = (name) => param && (typeof param[name] === 'string' || typeof param[name] === 'number');
|
|
1097
1108
|
const _val = (name) => (param ? commons_1.$T.S2(param[name]) : undefined);
|
|
@@ -1221,14 +1232,23 @@ class MyManagerProxy extends abstract_service_1.ManagerProxy {
|
|
|
1221
1232
|
const $sess = this.proxy.getCurrentSession({ throwable, useSession, context });
|
|
1222
1233
|
if (useSession && !$sess)
|
|
1223
1234
|
return false;
|
|
1235
|
+
// session & model information.
|
|
1236
|
+
const S = { sid: commons_1.$T.S2($sess?.sid), uid: commons_1.$T.S2($sess?.uid) };
|
|
1237
|
+
const M = { sid: commons_1.$T.S2(model?.sid), uid: commons_1.$T.S2(model?.uid) };
|
|
1238
|
+
//* v5: access mode for update/delete of a `sid`-less record, env `SID_LEGACY_ACCESS` (B5 § 6.4).
|
|
1239
|
+
const legacy = engine_1.$U.sidLegacyAccess();
|
|
1240
|
+
const isLegacyWrite = !M.sid && (_act === 'update' || _act === 'delete');
|
|
1241
|
+
//* v5: `deny` refuses update/delete of a `sid`-less record before the admin pass (B5 § 6.4).
|
|
1242
|
+
if (isLegacyWrite && legacy === 'deny') {
|
|
1243
|
+
if (throwable)
|
|
1244
|
+
throw new Error(`403 NOT ALLOWED - action[${_act}] is invalid @${errScope}`);
|
|
1245
|
+
return false;
|
|
1246
|
+
}
|
|
1224
1247
|
// admin can do anything.
|
|
1225
1248
|
const isAdmin = this.proxy.hasAdminRole(null, { errScope, context });
|
|
1226
1249
|
const hasRole = $sess?.roles?.length > 0 ? true : false; // guest if empty.
|
|
1227
1250
|
if (isAdmin)
|
|
1228
1251
|
return true;
|
|
1229
|
-
// session & model information.
|
|
1230
|
-
const S = { sid: commons_1.$T.S2($sess?.sid), uid: commons_1.$T.S2($sess?.uid) };
|
|
1231
|
-
const M = { sid: commons_1.$T.S2(model?.sid), uid: commons_1.$T.S2(model?.uid) };
|
|
1232
1252
|
// check action.
|
|
1233
1253
|
if (hasRole) {
|
|
1234
1254
|
switch (_act) {
|
|
@@ -1243,9 +1263,13 @@ class MyManagerProxy extends abstract_service_1.ManagerProxy {
|
|
|
1243
1263
|
break;
|
|
1244
1264
|
case 'update':
|
|
1245
1265
|
case 'delete':
|
|
1246
|
-
// (default) action is allowed if sid&uid matches
|
|
1247
|
-
|
|
1248
|
-
|
|
1266
|
+
// (default) action is allowed if sid&uid matches.
|
|
1267
|
+
//* v5: a `sid`-less record is admin-only for update/delete (B5 § 6.4); `open` keeps the v4 rule.
|
|
1268
|
+
if (!M.sid) {
|
|
1269
|
+
if (legacy === 'open')
|
|
1270
|
+
return true;
|
|
1271
|
+
break;
|
|
1272
|
+
}
|
|
1249
1273
|
if (S.sid === M.sid && S.uid === M.uid)
|
|
1250
1274
|
return true;
|
|
1251
1275
|
break;
|
|
@@ -1351,112 +1375,29 @@ exports.MyManagerProxy = MyManagerProxy;
|
|
|
1351
1375
|
/**
|
|
1352
1376
|
* class: `OS2Service`
|
|
1353
1377
|
* - Master 권한 전용 Elasticsearch 관리 서비스
|
|
1354
|
-
* -
|
|
1378
|
+
* - service for OS2: data path via FGAC (`$fgac`), index management via the master client.
|
|
1355
1379
|
*/
|
|
1356
|
-
class OS2Service extends cores_1.
|
|
1380
|
+
class OS2Service extends cores_1.OS2CoreService {
|
|
1357
1381
|
$fgac;
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
const masterPass = _config('OS2_MASTER_PWD');
|
|
1362
|
-
// if (!masterUser || !masterPass) throw new Error('400 NO MASTER - OS2_MASTER_UID/OS2_MASTER_PWD is required!');
|
|
1363
|
-
const client = new cores_3.elasticsearch.Client({
|
|
1364
|
-
node: endpoint,
|
|
1365
|
-
ssl: {
|
|
1366
|
-
ca: process.env.elasticsearch_certificate,
|
|
1367
|
-
rejectUnauthorized: false,
|
|
1368
|
-
},
|
|
1369
|
-
auth: {
|
|
1370
|
-
username: masterUser,
|
|
1371
|
-
password: masterPass,
|
|
1372
|
-
},
|
|
1373
|
-
});
|
|
1374
|
-
return { client };
|
|
1375
|
-
}
|
|
1382
|
+
/**
|
|
1383
|
+
* constructor (no client here; the master client is created on first `client` access)
|
|
1384
|
+
*/
|
|
1376
1385
|
constructor(options, fgac) {
|
|
1377
1386
|
super(options);
|
|
1378
|
-
if (!options.endpoint)
|
|
1379
|
-
throw new Error('.endpoint (URL) is required');
|
|
1380
|
-
if (!options.indexName)
|
|
1381
|
-
throw new Error('.indexName (string) is required');
|
|
1382
|
-
const { client } = OS2Service.instance(options.endpoint);
|
|
1383
|
-
this._options = { docType: '_doc', idName: '$id', version: '6.8', ...options };
|
|
1384
|
-
this._client = client;
|
|
1385
1387
|
this.$fgac = fgac;
|
|
1386
1388
|
}
|
|
1387
|
-
get client() {
|
|
1388
|
-
return this._client;
|
|
1389
|
-
}
|
|
1390
|
-
get options() {
|
|
1391
|
-
return this._options;
|
|
1392
|
-
}
|
|
1393
|
-
/**
|
|
1394
|
-
* describe `settings` and `mappings` of index.
|
|
1395
|
-
*/
|
|
1396
|
-
async describe() {
|
|
1397
|
-
const { indexName } = this.options;
|
|
1398
|
-
//* call create index..
|
|
1399
|
-
(0, engine_1._log)(NS, `- describe(${indexName})`);
|
|
1400
|
-
//* read settings.
|
|
1401
|
-
// const { client } = instance(endpoint);
|
|
1402
|
-
const client = this.client;
|
|
1403
|
-
const res = await client.indices.getSettings({ index: indexName }).catch(
|
|
1404
|
-
// $ERROR.throwAsJson,
|
|
1405
|
-
cores_1.$ERROR.handler('describe', e => {
|
|
1406
|
-
const msg = (0, test_helper_1.GETERR)(e);
|
|
1407
|
-
if (msg.startsWith('404 INDEX NOT FOUND'))
|
|
1408
|
-
throw new Error(`404 NOT FOUND - index:${indexName}`);
|
|
1409
|
-
throw e;
|
|
1410
|
-
}));
|
|
1411
|
-
(0, engine_1._log)(NS, `> settings[${indexName}] =`, engine_1.$U.json({ ...res, meta: undefined }));
|
|
1412
|
-
const settings = (res.body && res.body[indexName] && res.body[indexName].settings) || {};
|
|
1413
|
-
(0, engine_1._log)(NS, `> number_of_shards =`, settings.index && settings.index.number_of_shards); // 5
|
|
1414
|
-
(0, engine_1._log)(NS, `> number_of_replicas =`, settings.index && settings.index.number_of_replicas); // 1
|
|
1415
|
-
//* read mappings.
|
|
1416
|
-
const res2 = await client.indices.getMapping({ index: indexName });
|
|
1417
|
-
(0, engine_1._log)(NS, `> mappings[${indexName}] =`, engine_1.$U.json(res2));
|
|
1418
|
-
const mappings = (res2.body && res2.body[indexName] && res2.body[indexName].mappings) || {};
|
|
1419
|
-
//* returns
|
|
1420
|
-
return { settings, mappings };
|
|
1421
|
-
}
|
|
1422
1389
|
/**
|
|
1423
|
-
*
|
|
1424
|
-
* @param settings - creating settings
|
|
1390
|
+
* build the master client: `auth` is read from config now (after engine init), and set only when both exist.
|
|
1425
1391
|
*/
|
|
1426
|
-
|
|
1427
|
-
const
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
const payload = {
|
|
1434
|
-
settings: {
|
|
1435
|
-
number_of_shards: 5,
|
|
1436
|
-
number_of_replicas: 1,
|
|
1437
|
-
},
|
|
1438
|
-
...settings,
|
|
1439
|
-
};
|
|
1440
|
-
(0, engine_1._log)(NS, `> settings[${indexName}] = `, engine_1.$U.json(payload));
|
|
1441
|
-
//* call create index..
|
|
1442
|
-
const client = this.client;
|
|
1443
|
-
const res = await client.indices.create({ index: indexName, body: payload }).catch(
|
|
1444
|
-
// $ERROR.throwAsJson,
|
|
1445
|
-
cores_1.$ERROR.handler('create', e => {
|
|
1446
|
-
const msg = (0, test_helper_1.GETERR)(e);
|
|
1447
|
-
if (msg.startsWith('400 RESOURCE ALREADY EXISTS'))
|
|
1448
|
-
throw new Error(`400 IN USE - index:${indexName}`);
|
|
1449
|
-
throw e;
|
|
1450
|
-
}));
|
|
1451
|
-
// if (res) throw res;
|
|
1452
|
-
(0, engine_1._log)(NS, `> create[${indexName}] =`, engine_1.$U.json({ ...res, meta: undefined }));
|
|
1453
|
-
//* build result.
|
|
1454
|
-
return {
|
|
1455
|
-
status: res.statusCode,
|
|
1456
|
-
index: indexName,
|
|
1457
|
-
acknowledged: res.body.shards_acknowledged,
|
|
1458
|
-
};
|
|
1392
|
+
createClient() {
|
|
1393
|
+
const _config = (n) => cores_1.default.config.config.get(n);
|
|
1394
|
+
const username = _config('OS2_MASTER_UID');
|
|
1395
|
+
const password = _config('OS2_MASTER_PWD');
|
|
1396
|
+
const auth = username && password ? { auth: { username, password } } : {};
|
|
1397
|
+
//* same node/ssl as the base; the package is loaded here, on first use.
|
|
1398
|
+
return this.newClient(auth);
|
|
1459
1399
|
}
|
|
1400
|
+
//* v5 B3: `describe`/`createIndex`/`search` are inherited from `OS2CoreService` (identical-body overrides removed).
|
|
1460
1401
|
/**
|
|
1461
1402
|
* delete index by name
|
|
1462
1403
|
*/
|
|
@@ -1512,7 +1453,7 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1512
1453
|
async bulkItems(items, options) {
|
|
1513
1454
|
const errScope = `bulkItems(${this.options.indexName})`;
|
|
1514
1455
|
const { indexName } = this.options;
|
|
1515
|
-
|
|
1456
|
+
//* FGAC only: do not touch `this.client` here (it would create the master client).
|
|
1516
1457
|
const idName = options?.idName ?? '_id';
|
|
1517
1458
|
if (!Array.isArray(items) || items.length === 0)
|
|
1518
1459
|
throw new Error(`@items (array) is required - length=${items?.length ?? 'null'} - ${errScope}`);
|
|
@@ -1562,19 +1503,17 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1562
1503
|
return { success, failed, failedItems };
|
|
1563
1504
|
}
|
|
1564
1505
|
/**
|
|
1565
|
-
* push item for time-series data.
|
|
1506
|
+
* push item for time-series data (via FGAC; the result is the response body itself).
|
|
1566
1507
|
*
|
|
1567
1508
|
* @param item - item to push
|
|
1568
|
-
* @param type - document type (default: doc-type given at construction time)
|
|
1569
1509
|
*/
|
|
1570
|
-
async pushItem(item
|
|
1571
|
-
const { indexName
|
|
1510
|
+
async pushItem(item) {
|
|
1511
|
+
const { indexName } = this.options;
|
|
1572
1512
|
const id = item.id ?? '';
|
|
1573
|
-
type = `${type || docType}`;
|
|
1574
1513
|
const body = { ...item };
|
|
1575
1514
|
const body2 = this.popullateAutocompleteFields(body);
|
|
1576
1515
|
(0, engine_1._log)(NS, `- pushItem(${id})`);
|
|
1577
|
-
const params = { index: indexName,
|
|
1516
|
+
const params = { index: indexName, body: body2, id };
|
|
1578
1517
|
(0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
|
|
1579
1518
|
//NOTE - use npm `elasticsearch#13.2.0` for avoiding error.
|
|
1580
1519
|
// const { client } = instance(endpoint);
|
|
@@ -1586,8 +1525,9 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1586
1525
|
}));
|
|
1587
1526
|
// {"_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}
|
|
1588
1527
|
(0, engine_1._log)(NS, `> create[${id}].res =`, engine_1.$U.json({ ...res, meta: undefined }));
|
|
1589
|
-
|
|
1590
|
-
const
|
|
1528
|
+
//* fixed: the FGAC result is the body itself (v4 read `res.body?._id`, always undefined)
|
|
1529
|
+
const _id = res?._id;
|
|
1530
|
+
const _version = res?._version;
|
|
1591
1531
|
const res2 = { ...body, _id, _version };
|
|
1592
1532
|
return res2;
|
|
1593
1533
|
}
|
|
@@ -1598,10 +1538,9 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1598
1538
|
* @param views - projections
|
|
1599
1539
|
*/
|
|
1600
1540
|
async readItem(id, views) {
|
|
1601
|
-
const { indexName
|
|
1602
|
-
const type = `${docType}`;
|
|
1541
|
+
const { indexName } = this.options;
|
|
1603
1542
|
(0, engine_1._log)(NS, `- readItem(${id})`);
|
|
1604
|
-
const params = { index: indexName,
|
|
1543
|
+
const params = { index: indexName, id };
|
|
1605
1544
|
if (views) {
|
|
1606
1545
|
const fields = [];
|
|
1607
1546
|
const keys = Array.isArray(views) ? views : Object.keys(views);
|
|
@@ -1627,8 +1566,8 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1627
1566
|
const _version = res._version;
|
|
1628
1567
|
const data = res?._source || res._source || {};
|
|
1629
1568
|
// delete internal (analyzed) field
|
|
1630
|
-
delete data[cores_1.
|
|
1631
|
-
delete data[cores_1.
|
|
1569
|
+
delete data[cores_1.OS2CoreService.DECOMPOSED_FIELD];
|
|
1570
|
+
delete data[cores_1.OS2CoreService.QWERTY_FIELD];
|
|
1632
1571
|
const res2 = { ...data, _id, _version };
|
|
1633
1572
|
return res2;
|
|
1634
1573
|
}
|
|
@@ -1638,10 +1577,9 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1638
1577
|
* @param id - item-id
|
|
1639
1578
|
*/
|
|
1640
1579
|
async deleteItem(id) {
|
|
1641
|
-
const { indexName
|
|
1642
|
-
const type = `${docType}`;
|
|
1580
|
+
const { indexName } = this.options;
|
|
1643
1581
|
(0, engine_1._log)(NS, `- deleteItem(${id})`);
|
|
1644
|
-
const params = { index: indexName,
|
|
1582
|
+
const params = { index: indexName, id, body: {} };
|
|
1645
1583
|
(0, engine_1._log)(NS, `> params[${id}] =`, engine_1.$U.json(params));
|
|
1646
1584
|
// const { client } = instance(endpoint);
|
|
1647
1585
|
const res = await this.$fgac.doFgacDelete(params).catch(cores_1.$ERROR.handler('delete', e => {
|
|
@@ -1688,13 +1626,13 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1688
1626
|
async searchRaw(body, searchType) {
|
|
1689
1627
|
if (!body)
|
|
1690
1628
|
throw new Error('@body (SearchBody) is required');
|
|
1691
|
-
const { indexName
|
|
1629
|
+
const { indexName } = this.options;
|
|
1692
1630
|
(0, engine_1._log)(NS, `- search(${indexName}, ${searchType || ''})....`);
|
|
1693
1631
|
(0, engine_1._log)(NS, `> body =`, engine_1.$U.json(body));
|
|
1694
|
-
const
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
(0, engine_1._log)(NS, `> params
|
|
1632
|
+
const params = { index: indexName, body };
|
|
1633
|
+
if (searchType)
|
|
1634
|
+
params.search_type = searchType;
|
|
1635
|
+
(0, engine_1._log)(NS, `> params =`, engine_1.$U.json({ ...params, body: undefined }));
|
|
1698
1636
|
const $res = await this.$fgac.doFgacSearch(params).catch(cores_1.$ERROR.handler('search', e => {
|
|
1699
1637
|
(0, engine_1._err)(NS, `> search[${indexName}].err =`, e);
|
|
1700
1638
|
throw e;
|
|
@@ -1702,31 +1640,6 @@ class OS2Service extends cores_1.Elastic6Service {
|
|
|
1702
1640
|
//* return raw results.
|
|
1703
1641
|
return $res;
|
|
1704
1642
|
}
|
|
1705
|
-
/**
|
|
1706
|
-
* run search, and get the formatmted response.
|
|
1707
|
-
* @param body - Elasticsearch Query DSL that defines the search request (e.g., size, query, filters).
|
|
1708
|
-
* @param searchType - type of search (e.g., 'query_then_fetch', 'dfs_query_then_fetch').
|
|
1709
|
-
*
|
|
1710
|
-
*/
|
|
1711
|
-
async search(body, searchType) {
|
|
1712
|
-
const size = engine_1.$U.N(body.size, 0);
|
|
1713
|
-
const response = await this.searchRaw(body, searchType);
|
|
1714
|
-
// return w/ transformed id
|
|
1715
|
-
const hits = response.hits;
|
|
1716
|
-
if (typeof hits !== 'object')
|
|
1717
|
-
throw new Error(`.hits (object) is required - hits:${engine_1.$U.json(hits)}`);
|
|
1718
|
-
//NOTE - ES6.8 w/ OS1.1
|
|
1719
|
-
return {
|
|
1720
|
-
total: typeof hits.total?.value === 'number' ? hits.total?.value : hits.total,
|
|
1721
|
-
list: hits.hits.map((hit) => ({
|
|
1722
|
-
...hit._source,
|
|
1723
|
-
_id: hit._id,
|
|
1724
|
-
_score: hit._score,
|
|
1725
|
-
})),
|
|
1726
|
-
last: hits.hits.length === size && size > 0 ? hits.hits[size - 1]?.sort : undefined,
|
|
1727
|
-
aggregations: response.aggregations,
|
|
1728
|
-
};
|
|
1729
|
-
}
|
|
1730
1643
|
}
|
|
1731
1644
|
exports.OS2Service = OS2Service;
|
|
1732
1645
|
/**
|
|
@@ -1770,7 +1683,7 @@ class OS2FGACManager {
|
|
|
1770
1683
|
async doFgacSearch(params) {
|
|
1771
1684
|
const index = params?.index ?? '';
|
|
1772
1685
|
const body = (0, commons_1.onlyDefined)(params?.body ?? undefined);
|
|
1773
|
-
const queryParams = params?.
|
|
1686
|
+
const queryParams = params?.search_type ? { search_type: params?.search_type } : undefined;
|
|
1774
1687
|
return this.proxy.doProxy('POST', index, `_search`, queryParams, body);
|
|
1775
1688
|
}
|
|
1776
1689
|
/** FGAC 기반 읽기: client.get() 대응 */
|
|
@@ -1901,31 +1814,33 @@ exports.OS2FGACManager = OS2FGACManager;
|
|
|
1901
1814
|
/**
|
|
1902
1815
|
* OS2 인스턴스
|
|
1903
1816
|
* - describeIndex(), destroyIndex(), search() with elastic initialized by master-key
|
|
1817
|
+
* - one service set (fgac, elastic, query, synchronizer) only when `endpoint && indexName`.
|
|
1904
1818
|
*/
|
|
1905
|
-
class OS2Instance extends abstract_service_1.
|
|
1819
|
+
class OS2Instance extends abstract_service_1.AbstractOS2Instance {
|
|
1906
1820
|
fgac;
|
|
1907
|
-
|
|
1908
|
-
|
|
1821
|
+
/**
|
|
1822
|
+
* build one service set when `endpoint && indexName` (no client: it is created on first use).
|
|
1823
|
+
*/
|
|
1824
|
+
constructor({ endpoint, indexName, idName, tableName, autocompleteFields, roleName, userName, }) {
|
|
1825
|
+
super();
|
|
1909
1826
|
const options = (0, commons_1.onlyDefined)({
|
|
1910
1827
|
endpoint,
|
|
1911
1828
|
indexName,
|
|
1912
|
-
version: esVersion,
|
|
1913
1829
|
autocompleteFields,
|
|
1914
1830
|
roleName,
|
|
1915
1831
|
userName,
|
|
1916
1832
|
idName: idName === null ? undefined : idName ?? '$id',
|
|
1917
1833
|
});
|
|
1918
1834
|
if (endpoint && indexName) {
|
|
1919
|
-
if (esDocType)
|
|
1920
|
-
options.docType = esDocType;
|
|
1921
1835
|
this.fgac = new OS2FGACManager(options);
|
|
1922
1836
|
this.elastic = new OS2Service(options, this.fgac);
|
|
1923
|
-
this.
|
|
1924
|
-
this.
|
|
1925
|
-
this.synchronizer = new abstract_service_1.Elastic6Synchronizer(this.elastic, { tableName });
|
|
1837
|
+
this.query = new cores_1.OS2QueryService(this.elastic);
|
|
1838
|
+
this.synchronizer = new abstract_service_1.OS2Synchronizer(this.elastic, { tableName });
|
|
1926
1839
|
}
|
|
1927
1840
|
}
|
|
1928
1841
|
hello = () => `OS2Instance`;
|
|
1842
|
+
//* v5 B3: `describeIndex` is inherited from `AbstractOS2Instance` (identical-body override removed).
|
|
1843
|
+
//* kept (unlike the removed identical overrides): it narrows the return type to `OS2Option`.
|
|
1929
1844
|
get options() {
|
|
1930
1845
|
if (!this.elastic)
|
|
1931
1846
|
return null;
|
|
@@ -1934,35 +1849,6 @@ class OS2Instance extends abstract_service_1.Elastic6Instance {
|
|
|
1934
1849
|
get $X2() {
|
|
1935
1850
|
return $X2;
|
|
1936
1851
|
}
|
|
1937
|
-
/**
|
|
1938
|
-
* display index settings and mappings
|
|
1939
|
-
*/
|
|
1940
|
-
async describeIndex() {
|
|
1941
|
-
return this.elastic && (await this.elastic.describe());
|
|
1942
|
-
}
|
|
1943
|
-
/**
|
|
1944
|
-
* create Elasticsearch index with ES7+ mapping structure
|
|
1945
|
-
*/
|
|
1946
|
-
async createIndex() {
|
|
1947
|
-
if (!this.elastic)
|
|
1948
|
-
return null;
|
|
1949
|
-
const { docType, idName, version = '2.10' } = this.options;
|
|
1950
|
-
const settings = cores_1.Elastic6Service.prepareSettings({ docType, idName, version });
|
|
1951
|
-
// _doc 제거 및 properties 병합
|
|
1952
|
-
if (settings.mappings?._doc) {
|
|
1953
|
-
const { dynamic_templates, properties: docProperties } = settings.mappings._doc;
|
|
1954
|
-
settings.mappings = {
|
|
1955
|
-
...settings.mappings,
|
|
1956
|
-
...(dynamic_templates ? { dynamic_templates } : {}),
|
|
1957
|
-
properties: {
|
|
1958
|
-
...(docProperties || {}),
|
|
1959
|
-
...(settings.mappings.properties || {}),
|
|
1960
|
-
},
|
|
1961
|
-
};
|
|
1962
|
-
delete settings.mappings._doc;
|
|
1963
|
-
}
|
|
1964
|
-
return this.elastic.createIndex(settings);
|
|
1965
|
-
}
|
|
1966
1852
|
/**
|
|
1967
1853
|
* search
|
|
1968
1854
|
*/
|
|
@@ -2074,14 +1960,6 @@ class OS2Instance extends abstract_service_1.Elastic6Instance {
|
|
|
2074
1960
|
}
|
|
2075
1961
|
}
|
|
2076
1962
|
exports.OS2Instance = OS2Instance;
|
|
2077
|
-
function sourceToItem(_source, idName = '$id') {
|
|
2078
|
-
const item = { ..._source };
|
|
2079
|
-
if (idName in item) {
|
|
2080
|
-
item._id = item[idName];
|
|
2081
|
-
delete item[idName];
|
|
2082
|
-
}
|
|
2083
|
-
return item;
|
|
2084
|
-
}
|
|
2085
1963
|
/**
|
|
2086
1964
|
* internal tools
|
|
2087
1965
|
*/
|
|
@@ -2132,25 +2010,21 @@ const $X2 = {
|
|
|
2132
2010
|
};
|
|
2133
2011
|
/**
|
|
2134
2012
|
* factory of `OS2Instance`
|
|
2013
|
+
* - reads `OS2_ENDPOINT`, `OS2_INDEX`, `MY_DYNAMO_TABLE`, `OS2_AUTOCOMPLETE_FIELDS` (no version, no doc-type).
|
|
2135
2014
|
*/
|
|
2136
2015
|
const _OS2 = (options) => {
|
|
2137
2016
|
return new (class extends OS2Instance {
|
|
2017
|
+
// 0. load from env configuration, then 1. build the instance.
|
|
2138
2018
|
constructor() {
|
|
2139
|
-
// 0. load from env configuration.
|
|
2140
2019
|
const endpoint = options?.endpoint ?? engine_1.$U.env('OS2_ENDPOINT', '');
|
|
2141
2020
|
const indexName = options?.indexName ?? engine_1.$U.env('OS2_INDEX', 'test-x1');
|
|
2142
|
-
const esVersion = options?.version ?? engine_1.$U.env('OS2_VERSION', '2.10');
|
|
2143
|
-
const esDocType = options?.docType ?? engine_1.$U.env('OS2_DOCTYPE', '');
|
|
2144
2021
|
const tableName = engine_1.$U.env('MY_DYNAMO_TABLE', '');
|
|
2145
2022
|
const autocompleteFields = options?.autocompleteFields ?? commons_1.$T.SS(engine_1.$U.env('OS2_AUTOCOMPLETE_FIELDS', ''));
|
|
2146
2023
|
const roleName = options?.roleName;
|
|
2147
2024
|
const userName = options?.userName;
|
|
2148
|
-
// 1. initialize instance.
|
|
2149
2025
|
super({
|
|
2150
2026
|
endpoint,
|
|
2151
2027
|
indexName,
|
|
2152
|
-
esVersion,
|
|
2153
|
-
esDocType,
|
|
2154
2028
|
tableName,
|
|
2155
2029
|
autocompleteFields,
|
|
2156
2030
|
roleName,
|
|
@@ -2166,16 +2040,15 @@ const _OS2 = (options) => {
|
|
|
2166
2040
|
})();
|
|
2167
2041
|
};
|
|
2168
2042
|
exports._OS2 = _OS2;
|
|
2169
|
-
/** dynamically load the OS2 instance if `OS2_ENDPOINT` is set */
|
|
2170
|
-
const hasOS2 = engine_1.$U.env('OS2_ENDPOINT', '').startsWith('https://');
|
|
2171
|
-
exports.$OS2 = (0, exports._OS2)();
|
|
2172
|
-
exports.$ES6 = hasOS2 ? (0, exports._OS2)() : (0, abstract_service_1._ES6)();
|
|
2173
2043
|
/**
|
|
2174
|
-
*
|
|
2175
|
-
* -
|
|
2176
|
-
* -
|
|
2177
|
-
|
|
2178
|
-
|
|
2044
|
+
* the default `OS2Instance`, built lazily by `_OS2()` on first access (S-25).
|
|
2045
|
+
* - nothing is built at import: no client, no dynamo-stream listener.
|
|
2046
|
+
* - without `OS2_ENDPOINT` it is an `OS2Instance` with `options === null`.
|
|
2047
|
+
*/
|
|
2048
|
+
//* the factory prints one `PERF > instance $OS2` line (D40; the namespace is built at call time).
|
|
2049
|
+
exports.$OS2 = (0, lazy_1.lazyInstance)(() => (0, perf_1.measure)(engine_1._inf, engine_1.$U.NS('PERF', 'cyan'), 'instance $OS2', () => (0, exports._OS2)()));
|
|
2050
|
+
/**
|
|
2051
|
+
* explicit alias of `$OS2` (the same object). The name is kept; the meaning is OS2.
|
|
2179
2052
|
*/
|
|
2180
|
-
exports.$ES6Routed = exports.$
|
|
2053
|
+
exports.$ES6Routed = exports.$OS2;
|
|
2181
2054
|
//# sourceMappingURL=abstract-services.js.map
|