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.
Files changed (167) hide show
  1. package/README.md +127 -2
  2. package/dist/common/lemon-error.d.ts +34 -0
  3. package/dist/common/lemon-error.js +52 -0
  4. package/dist/common/lemon-error.js.map +1 -0
  5. package/dist/controllers/general-api-controller.d.ts +7 -0
  6. package/dist/controllers/general-api-controller.js +7 -0
  7. package/dist/controllers/general-api-controller.js.map +1 -1
  8. package/dist/cores/api/api-service.js +10 -43
  9. package/dist/cores/api/api-service.js.map +1 -1
  10. package/dist/cores/aws/aws-kms-service.d.ts +13 -5
  11. package/dist/cores/aws/aws-kms-service.js +23 -9
  12. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  13. package/dist/cores/aws/aws-s3-service.d.ts +30 -4
  14. package/dist/cores/aws/aws-s3-service.js +35 -15
  15. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  16. package/dist/cores/aws/aws-sns-service.js +59 -9
  17. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  18. package/dist/cores/aws/aws-sqs-service.d.ts +1 -1
  19. package/dist/cores/aws/aws-sqs-service.js +54 -12
  20. package/dist/cores/aws/aws-sqs-service.js.map +1 -1
  21. package/dist/cores/cache/cache-service.d.ts +10 -9
  22. package/dist/cores/cache/cache-service.js +9 -346
  23. package/dist/cores/cache/cache-service.js.map +1 -1
  24. package/dist/cores/config/config-service.d.ts +3 -15
  25. package/dist/cores/config/config-service.js +5 -34
  26. package/dist/cores/config/config-service.js.map +1 -1
  27. package/dist/cores/dynamo/dynamo-query-service.js +42 -2
  28. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
  29. package/dist/cores/dynamo/dynamo-scan-service.js +42 -2
  30. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
  31. package/dist/cores/dynamo/dynamo-service.d.ts +45 -14
  32. package/dist/cores/dynamo/dynamo-service.js +48 -21
  33. package/dist/cores/dynamo/dynamo-service.js.map +1 -1
  34. package/dist/cores/dynamo/tools/expressions.js +32 -22
  35. package/dist/cores/dynamo/tools/expressions.js.map +1 -1
  36. package/dist/cores/dynamo/tools/lang.d.ts +30 -0
  37. package/dist/cores/dynamo/tools/lang.js +75 -0
  38. package/dist/cores/dynamo/tools/lang.js.map +1 -0
  39. package/dist/cores/dynamo/tools/query.js +20 -21
  40. package/dist/cores/dynamo/tools/query.js.map +1 -1
  41. package/dist/cores/dynamo/tools/scan.js +15 -16
  42. package/dist/cores/dynamo/tools/scan.js.map +1 -1
  43. package/dist/cores/dynamo/tools/serializer.js +40 -38
  44. package/dist/cores/dynamo/tools/serializer.js.map +1 -1
  45. package/dist/cores/dynamo/tools/utils.d.ts +6 -2
  46. package/dist/cores/dynamo/tools/utils.js +11 -8
  47. package/dist/cores/dynamo/tools/utils.js.map +1 -1
  48. package/dist/cores/elastic/elastic6-query-service.d.ts +1 -104
  49. package/dist/cores/elastic/elastic6-query-service.js +15 -489
  50. package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
  51. package/dist/cores/elastic/elastic6-service.d.ts +1 -482
  52. package/dist/cores/elastic/elastic6-service.js +15 -1153
  53. package/dist/cores/elastic/elastic6-service.js.map +1 -1
  54. package/dist/cores/elastic/index.d.ts +2 -2
  55. package/dist/cores/elastic/index.js +3 -2
  56. package/dist/cores/elastic/index.js.map +1 -1
  57. package/dist/cores/elastic/os2-query-service.d.ts +104 -0
  58. package/dist/cores/elastic/os2-query-service.js +495 -0
  59. package/dist/cores/elastic/os2-query-service.js.map +1 -0
  60. package/dist/cores/elastic/os2-service.d.ts +372 -0
  61. package/dist/cores/elastic/os2-service.js +943 -0
  62. package/dist/cores/elastic/os2-service.js.map +1 -0
  63. package/dist/cores/index.d.ts +6 -1
  64. package/dist/cores/index.js +9 -2
  65. package/dist/cores/index.js.map +1 -1
  66. package/dist/cores/lambda/index.js +2 -1
  67. package/dist/cores/lambda/index.js.map +1 -1
  68. package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -0
  69. package/dist/cores/lambda/lambda-cron-handler.js +5 -1
  70. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  71. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +5 -4
  72. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +18 -5
  73. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  74. package/dist/cores/lambda/lambda-handler.d.ts +22 -2
  75. package/dist/cores/lambda/lambda-handler.js +85 -23
  76. package/dist/cores/lambda/lambda-handler.js.map +1 -1
  77. package/dist/cores/lambda/lambda-sns-handler.d.ts +1 -0
  78. package/dist/cores/lambda/lambda-sns-handler.js +5 -0
  79. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  80. package/dist/cores/lambda/lambda-sqs-handler.d.ts +1 -0
  81. package/dist/cores/lambda/lambda-sqs-handler.js +20 -5
  82. package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
  83. package/dist/cores/lambda/lambda-web-handler.d.ts +10 -0
  84. package/dist/cores/lambda/lambda-web-handler.js +107 -41
  85. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  86. package/dist/cores/protocol/aws-lambda-helper.js +58 -11
  87. package/dist/cores/protocol/aws-lambda-helper.js.map +1 -1
  88. package/dist/cores/protocol/index.js +3 -0
  89. package/dist/cores/protocol/index.js.map +1 -1
  90. package/dist/cores/protocol/protocol-service.d.ts +26 -5
  91. package/dist/cores/protocol/protocol-service.js +42 -12
  92. package/dist/cores/protocol/protocol-service.js.map +1 -1
  93. package/dist/cores/protocol/protocol-sign.d.ts +72 -0
  94. package/dist/cores/protocol/protocol-sign.js +194 -0
  95. package/dist/cores/protocol/protocol-sign.js.map +1 -0
  96. package/dist/cores/storage/index.d.ts +0 -1
  97. package/dist/cores/storage/index.js +0 -1
  98. package/dist/cores/storage/index.js.map +1 -1
  99. package/dist/cores/storage/model-fields.d.ts +7 -0
  100. package/dist/cores/storage/model-fields.js +21 -0
  101. package/dist/cores/storage/model-fields.js.map +1 -0
  102. package/dist/cores/storage/model-manager.d.ts +5 -2
  103. package/dist/cores/storage/model-manager.js +11 -3
  104. package/dist/cores/storage/model-manager.js.map +1 -1
  105. package/dist/engine/builder.js +20 -2
  106. package/dist/engine/builder.js.map +1 -1
  107. package/dist/engine/engine.d.ts +2 -2
  108. package/dist/engine/engine.js +5 -5
  109. package/dist/engine/engine.js.map +1 -1
  110. package/dist/engine/utilities.d.ts +20 -12
  111. package/dist/engine/utilities.js +57 -86
  112. package/dist/engine/utilities.js.map +1 -1
  113. package/dist/environ.d.ts +0 -6
  114. package/dist/environ.js +1 -12
  115. package/dist/environ.js.map +1 -1
  116. package/dist/esm/index.mjs +141 -0
  117. package/dist/esm/testing.mjs +12 -0
  118. package/dist/extended/abstract-service.d.ts +48 -139
  119. package/dist/extended/abstract-service.js +46 -382
  120. package/dist/extended/abstract-service.js.map +1 -1
  121. package/dist/extended/cores/abstract-controllers.d.ts +25 -0
  122. package/dist/extended/cores/abstract-controllers.js +77 -7
  123. package/dist/extended/cores/abstract-controllers.js.map +1 -1
  124. package/dist/extended/cores/abstract-rest-apis.d.ts +2 -1
  125. package/dist/extended/cores/abstract-rest-apis.js +2 -1
  126. package/dist/extended/cores/abstract-rest-apis.js.map +1 -1
  127. package/dist/extended/cores/abstract-services.d.ts +48 -87
  128. package/dist/extended/cores/abstract-services.js +121 -248
  129. package/dist/extended/cores/abstract-services.js.map +1 -1
  130. package/dist/extended/cores/commons.d.ts +4 -113
  131. package/dist/extended/cores/commons.js +26 -180
  132. package/dist/extended/cores/commons.js.map +1 -1
  133. package/dist/extended/cores/fields-admin.d.ts +91 -0
  134. package/dist/extended/cores/fields-admin.js +142 -0
  135. package/dist/extended/cores/fields-admin.js.map +1 -0
  136. package/dist/extended/cores/index.d.ts +2 -0
  137. package/dist/extended/cores/index.js +2 -0
  138. package/dist/extended/cores/index.js.map +1 -1
  139. package/dist/extended/cores/types.d.ts +3 -225
  140. package/dist/extended/cores/types.js +28 -0
  141. package/dist/extended/cores/types.js.map +1 -1
  142. package/dist/helpers/helpers.d.ts +10 -5
  143. package/dist/helpers/helpers.js +46 -58
  144. package/dist/helpers/helpers.js.map +1 -1
  145. package/dist/helpers/types.d.ts +22 -10
  146. package/dist/index.d.ts +1 -5
  147. package/dist/index.js +8 -14
  148. package/dist/index.js.map +1 -1
  149. package/dist/lib/http-fetch.d.ts +54 -0
  150. package/dist/lib/http-fetch.js +133 -0
  151. package/dist/lib/http-fetch.js.map +1 -0
  152. package/dist/lib/lazy.d.ts +22 -0
  153. package/dist/lib/lazy.js +54 -0
  154. package/dist/lib/lazy.js.map +1 -0
  155. package/dist/lib/perf.d.ts +35 -0
  156. package/dist/lib/perf.js +52 -0
  157. package/dist/lib/perf.js.map +1 -0
  158. package/dist/tools/tools.d.ts +15 -3
  159. package/dist/tools/tools.js +21 -4
  160. package/dist/tools/tools.js.map +1 -1
  161. package/package.json +96 -39
  162. package/dist/cores/storage/redis-storage-service.d.ts +0 -183
  163. package/dist/cores/storage/redis-storage-service.js +0 -377
  164. package/dist/cores/storage/redis-storage-service.js.map +0 -1
  165. package/dist/generated/field-registry.d.ts +0 -12
  166. package/dist/generated/field-registry.js +0 -21
  167. 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.$ES6 = exports.$OS2 = exports._OS2 = exports.OS2Instance = exports.OS2FGACManager = exports.OS2Service = exports.MyManagerProxy = exports.MyCoreProxy = exports.MyCoreManager = exports.MyCoreService = void 0;
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 = field_registry_1.fieldKeys.coreModel();
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
- //WARN! force to save models even for exception @240613
135
- const saved = await proxy.saveAllUpdates().catch(e => (0, test_helper_1.GETERR$)(e));
136
- (0, engine_1._log)(`> saved =`, engine_1.$U.json(saved));
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 `$ES6`
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.$ES6.search(body);
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.$ES6.options?.indexName;
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, fields, options) {
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
- const enableSync = options?.enableSync ?? true;
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.$ES6.synchronizer?.enableSynchronization(this.type);
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.$ES6.client;
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.$ES6.options?.indexName, _id: doc._id } }, items];
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
- const isLocal = context?.domain === 'localhost';
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
- if (LOCAL_ACCOUNT)
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
- if (USE_SESSION?.endsWith('.json')) {
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
- if (context?.domain === 'localhost' && !context?.identity?.identityId) {
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 = context?.domain === 'localhost';
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 environ (or internal protocol with domin='localhost')
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 = $ctx?.domain === 'localhost';
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 or no sid.
1247
- if (!M.sid)
1248
- return true;
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
- * - elasticsearch service for OS2.
1378
+ * - service for OS2: data path via FGAC (`$fgac`), index management via the master client.
1355
1379
  */
1356
- class OS2Service extends cores_1.Elastic6Service {
1380
+ class OS2Service extends cores_1.OS2CoreService {
1357
1381
  $fgac;
1358
- static instance(endpoint) {
1359
- const _config = (n) => cores_1.default.config.config.get(n);
1360
- const masterUser = _config('OS2_MASTER_UID');
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
- * create index by name
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
- async createIndex(settings) {
1427
- const { indexName, docType, idName, timeSeries, version } = this.options;
1428
- settings = settings || cores_1.Elastic6Service.prepareSettings({ docType, idName, timeSeries, version });
1429
- if (!indexName)
1430
- new Error('@index is required!');
1431
- (0, engine_1._log)(NS, `- createIndex(${indexName})`);
1432
- //* prepare payload
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
- const client = this.client;
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, type) {
1571
- const { indexName, docType } = this.options;
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, type, body: body2, id };
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
- const _id = res.body?._id;
1590
- const _version = res.body?._version;
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, docType } = this.options;
1602
- const type = `${docType}`;
1541
+ const { indexName } = this.options;
1603
1542
  (0, engine_1._log)(NS, `- readItem(${id})`);
1604
- const params = { index: indexName, type, id };
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.Elastic6Service.DECOMPOSED_FIELD];
1631
- delete data[cores_1.Elastic6Service.QWERTY_FIELD];
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, docType } = this.options;
1642
- const type = `${docType}`;
1580
+ const { indexName } = this.options;
1643
1581
  (0, engine_1._log)(NS, `- deleteItem(${id})`);
1644
- const params = { index: indexName, type, id, body: {} };
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, docType } = this.options;
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 tmp = docType ? docType : '';
1695
- const params = { index: indexName, body, searchType };
1696
- // check version to include 'type' in params
1697
- (0, engine_1._log)(NS, `> params[${tmp}] =`, engine_1.$U.json({ ...params, body: undefined }));
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?.searchType ? { search_type: params?.searchType } : undefined;
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.Elastic6Instance {
1819
+ class OS2Instance extends abstract_service_1.AbstractOS2Instance {
1906
1820
  fgac;
1907
- constructor({ endpoint, indexName, idName, esVersion, esDocType, tableName, autocompleteFields, roleName, userName, }) {
1908
- super({ endpoint, indexName, esVersion, esDocType, tableName, autocompleteFields });
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.client = this.elastic.client;
1924
- this.query = new cores_1.Elastic6QueryService(this.elastic);
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
- * explicit alias for the OS2-routing `$ES6` above (decision #3, cores-migration P1).
2175
- * - kept as `$ES6` here for deep-import compatibility (`lemon-core/dist/extended/cores`).
2176
- * - exported at root ONLY under this name: root `$ES6` stays pinned to the L1
2177
- * (non-OS2) `extended/abstract-service` version, so consumers must opt in by
2178
- * name instead of silently getting OS2-routing behavior via the root barrel.
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.$ES6;
2053
+ exports.$ES6Routed = exports.$OS2;
2181
2054
  //# sourceMappingURL=abstract-services.js.map