lemon-core 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/controllers/dummy-controller.d.ts +1 -1
- package/dist/controllers/dummy-controller.js +2 -2
- package/dist/controllers/dummy-controller.js.map +1 -1
- package/dist/controllers/general-api-controller.d.ts +1 -1
- package/dist/cores/api/api-service.d.ts +239 -0
- package/dist/cores/api/api-service.js +674 -0
- package/dist/cores/api/api-service.js.map +1 -0
- package/dist/cores/api/index.d.ts +10 -0
- package/dist/cores/api/index.js +27 -0
- package/dist/cores/api/index.js.map +1 -0
- package/dist/cores/aws/aws-kms-service.d.ts +53 -2
- package/dist/cores/aws/aws-kms-service.js +104 -17
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/cache/cache-service.d.ts +440 -0
- package/dist/cores/cache/cache-service.js +967 -0
- package/dist/cores/cache/cache-service.js.map +1 -0
- package/dist/cores/cache/index.d.ts +10 -0
- package/dist/cores/cache/index.js +27 -0
- package/dist/cores/cache/index.js.map +1 -0
- package/dist/cores/cache-service.d.ts +54 -18
- package/dist/cores/cache-service.js +37 -26
- package/dist/cores/cache-service.js.map +1 -1
- package/dist/cores/core-types.d.ts +42 -12
- package/dist/cores/dynamo/dynamo-query-service.d.ts +52 -0
- package/dist/cores/dynamo/dynamo-query-service.js +127 -0
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -0
- package/dist/cores/dynamo/dynamo-scan-service.d.ts +70 -0
- package/dist/cores/dynamo/dynamo-scan-service.js +164 -0
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -0
- package/dist/cores/dynamo/dynamo-service.d.ts +192 -0
- package/dist/cores/dynamo/dynamo-service.js +525 -0
- package/dist/cores/dynamo/dynamo-service.js.map +1 -0
- package/dist/cores/dynamo/index.d.ts +12 -0
- package/dist/cores/dynamo/index.js +29 -0
- package/dist/cores/dynamo/index.js.map +1 -0
- package/dist/cores/elastic/elastic6-query-service.d.ts +104 -0
- package/dist/cores/elastic/elastic6-query-service.js +510 -0
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -0
- package/dist/cores/elastic/elastic6-service.d.ts +273 -0
- package/dist/cores/elastic/elastic6-service.js +903 -0
- package/dist/cores/elastic/elastic6-service.js.map +1 -0
- package/dist/cores/elastic/hangul-service.d.ts +102 -0
- package/dist/cores/elastic/hangul-service.js +205 -0
- package/dist/cores/elastic/hangul-service.js.map +1 -0
- package/dist/cores/elastic/index.d.ts +12 -0
- package/dist/cores/elastic/index.js +29 -0
- package/dist/cores/elastic/index.js.map +1 -0
- package/dist/cores/hangul-service.d.ts +17 -3
- package/dist/cores/hangul-service.js +17 -8
- package/dist/cores/hangul-service.js.map +1 -1
- package/dist/cores/index.d.ts +5 -11
- package/dist/cores/index.js +8 -13
- package/dist/cores/index.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-web-handler.d.ts +158 -8
- package/dist/cores/lambda/lambda-web-handler.js +283 -77
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +4 -0
- package/dist/cores/protocol/protocol-service.js +12 -7
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/storage/http-storage-service.d.ts +22 -0
- package/dist/cores/storage/http-storage-service.js +129 -0
- package/dist/cores/storage/http-storage-service.js.map +1 -0
- package/dist/cores/storage/index.d.ts +14 -0
- package/dist/cores/storage/index.js +31 -0
- package/dist/cores/storage/index.js.map +1 -0
- package/dist/cores/storage/model-manager.d.ts +93 -0
- package/dist/cores/storage/model-manager.js +192 -0
- package/dist/cores/storage/model-manager.js.map +1 -0
- package/dist/cores/storage/proxy-storage-service.d.ts +573 -0
- package/dist/cores/storage/proxy-storage-service.js +913 -0
- package/dist/cores/storage/proxy-storage-service.js.map +1 -0
- package/dist/cores/storage/redis-storage-service.d.ts +183 -0
- package/dist/cores/storage/redis-storage-service.js +391 -0
- package/dist/cores/storage/redis-storage-service.js.map +1 -0
- package/dist/cores/storage/storage-service.d.ts +169 -0
- package/dist/cores/storage/storage-service.js +374 -0
- package/dist/cores/storage/storage-service.js.map +1 -0
- package/dist/cores/storage-service.d.ts +1 -1
- package/dist/cores/storage-service.js +2 -2
- package/dist/cores/storage-service.js.map +1 -1
- package/dist/engine/utilities.d.ts +4 -3
- package/dist/engine/utilities.js +6 -6
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.d.ts +2 -2
- package/dist/environ.js +7 -4
- package/dist/environ.js.map +1 -1
- package/dist/extended/abstract-service.d.ts +533 -0
- package/dist/extended/abstract-service.js +915 -0
- package/dist/extended/abstract-service.js.map +1 -0
- package/dist/extended/index.d.ts +10 -0
- package/dist/extended/index.js +27 -0
- package/dist/extended/index.js.map +1 -0
- package/dist/helpers/helpers.d.ts +7 -0
- package/dist/helpers/helpers.js +7 -0
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
|
@@ -42,23 +42,23 @@ export declare type NextMode = 'LIST' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PAT
|
|
|
42
42
|
* - the context parameter for each next-handler `fx(id, param, body, context)`
|
|
43
43
|
* - possible to query user's detail via OAuth Resource Server.
|
|
44
44
|
*/
|
|
45
|
-
export interface NextIdentity {
|
|
45
|
+
export interface NextIdentity<T = any> {
|
|
46
46
|
/**
|
|
47
47
|
* site-id (like domain group)
|
|
48
48
|
*/
|
|
49
|
-
sid
|
|
49
|
+
sid?: string;
|
|
50
50
|
/**
|
|
51
|
-
* user-id (user
|
|
51
|
+
* user-id (user id)
|
|
52
52
|
*/
|
|
53
|
-
uid
|
|
53
|
+
uid?: string;
|
|
54
54
|
/**
|
|
55
55
|
* group-id (group id)
|
|
56
56
|
*/
|
|
57
|
-
gid
|
|
57
|
+
gid?: string;
|
|
58
58
|
/**
|
|
59
59
|
* roles (like `user`, `admin`, `super`)
|
|
60
60
|
*/
|
|
61
|
-
roles
|
|
61
|
+
roles?: string[];
|
|
62
62
|
/**
|
|
63
63
|
* prefered language (like 'ko')
|
|
64
64
|
* - use `x-lemon-language` header, or in `x-lemon-identity`
|
|
@@ -66,15 +66,40 @@ export interface NextIdentity {
|
|
|
66
66
|
*/
|
|
67
67
|
lang?: string;
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* (optional) internal last-error message
|
|
70
|
+
* - if this is not empty, then DO NOT use this object.
|
|
71
|
+
* @since ver3.1.2 2022/MAY/15
|
|
70
72
|
*/
|
|
71
|
-
|
|
73
|
+
error?: string;
|
|
74
|
+
/**
|
|
75
|
+
* something unknown having the original data.
|
|
76
|
+
*/
|
|
77
|
+
meta?: T;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* class: `NextIdentityJwt`
|
|
81
|
+
* - JWT-Token based identity
|
|
82
|
+
*/
|
|
83
|
+
export interface NextIdentityJwt<T = any> extends NextIdentity<T> {
|
|
84
|
+
/**
|
|
85
|
+
* issuer of jwt
|
|
86
|
+
* - must be in format of `kms/<alias>`
|
|
87
|
+
*/
|
|
88
|
+
iss: string;
|
|
89
|
+
/**
|
|
90
|
+
* expired timestamp (sec)
|
|
91
|
+
*/
|
|
92
|
+
exp: number;
|
|
93
|
+
/**
|
|
94
|
+
* issued timestamp (sec)
|
|
95
|
+
*/
|
|
96
|
+
iat: number;
|
|
72
97
|
}
|
|
73
98
|
/**
|
|
74
99
|
* class: `NextIdentityCognito`
|
|
75
100
|
* - extended information w/ cognito identity.
|
|
76
101
|
*/
|
|
77
|
-
export interface NextIdentityCognito extends NextIdentity {
|
|
102
|
+
export interface NextIdentityCognito<T = any> extends NextIdentity<T> {
|
|
78
103
|
/**
|
|
79
104
|
* account-id of AWS Credential
|
|
80
105
|
*/
|
|
@@ -95,12 +120,17 @@ export interface NextIdentityCognito extends NextIdentity {
|
|
|
95
120
|
* user-agent string like 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4)'
|
|
96
121
|
*/
|
|
97
122
|
userAgent?: string;
|
|
123
|
+
/**
|
|
124
|
+
* (optional) caller string like `AROXXXXXX:CognitoIdentityCredentials` from `APIGatewayEventIdentity`
|
|
125
|
+
* - available since `3.1.1`
|
|
126
|
+
*/
|
|
127
|
+
caller?: string;
|
|
98
128
|
}
|
|
99
129
|
/**
|
|
100
130
|
* class: `NextIdentityAcess`
|
|
101
131
|
* - extended information w/ site + account access information.
|
|
102
132
|
*/
|
|
103
|
-
export interface NextIdentityAccess extends NextIdentity {
|
|
133
|
+
export interface NextIdentityAccess<T = any> extends NextIdentity<T> {
|
|
104
134
|
/**
|
|
105
135
|
* site-information for domain
|
|
106
136
|
*/
|
|
@@ -145,7 +175,7 @@ export interface NextIdentityAccess extends NextIdentity {
|
|
|
145
175
|
}
|
|
146
176
|
/**
|
|
147
177
|
* class: `NextContext`
|
|
148
|
-
* - information of caller's context
|
|
178
|
+
* - information of caller's context w/ `next-identity`.
|
|
149
179
|
*/
|
|
150
180
|
export interface NextContext<T extends NextIdentity = NextIdentity> {
|
|
151
181
|
/**
|
|
@@ -169,7 +199,7 @@ export interface NextContext<T extends NextIdentity = NextIdentity> {
|
|
|
169
199
|
*/
|
|
170
200
|
requestId?: string;
|
|
171
201
|
/**
|
|
172
|
-
* id of account
|
|
202
|
+
* id of aws account number from initial request. (ex: `085403634746` for lemon profile)
|
|
173
203
|
*/
|
|
174
204
|
accountId?: string;
|
|
175
205
|
/**
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { GeneralItem } from '../core-types';
|
|
2
|
+
import { DynamoOption } from './dynamo-service';
|
|
3
|
+
/**
|
|
4
|
+
* class: QueryResult
|
|
5
|
+
* - result information of query.
|
|
6
|
+
*/
|
|
7
|
+
export interface DynamoQueryResult<T> {
|
|
8
|
+
list: T[];
|
|
9
|
+
count?: number;
|
|
10
|
+
last?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* feature: `DynamoSimpleQueriable`
|
|
14
|
+
* - simple query capable class.
|
|
15
|
+
*/
|
|
16
|
+
export interface DynamoSimpleQueriable<T extends GeneralItem> {
|
|
17
|
+
/**
|
|
18
|
+
* simple range query by `partition-key` w/ limit.
|
|
19
|
+
*
|
|
20
|
+
* @param pkey value of partition-key
|
|
21
|
+
*/
|
|
22
|
+
queryAll(pkey: string, limit?: number, isDesc?: boolean): Promise<DynamoQueryResult<T>>;
|
|
23
|
+
/**
|
|
24
|
+
* simple range query by `partition-key` and `range: sort-key` w/ limit.
|
|
25
|
+
*
|
|
26
|
+
* @param pkey value of partition-key
|
|
27
|
+
* @param from range start (included)
|
|
28
|
+
* @param to range end (included)
|
|
29
|
+
* @param limit limit of page
|
|
30
|
+
* @param last the last evaluated key (as sort-key)
|
|
31
|
+
*/
|
|
32
|
+
queryRange(pkey: string, from: number, to: number, limit?: number, last?: number): Promise<DynamoQueryResult<T>>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* class: `DynamoQueryService`
|
|
36
|
+
* - support simple query like range search.
|
|
37
|
+
*/
|
|
38
|
+
export declare class DynamoQueryService<T extends GeneralItem> implements DynamoSimpleQueriable<T> {
|
|
39
|
+
protected options: DynamoOption;
|
|
40
|
+
constructor(options: DynamoOption);
|
|
41
|
+
/**
|
|
42
|
+
* say hello of identity.
|
|
43
|
+
*/
|
|
44
|
+
hello: () => string;
|
|
45
|
+
queryAll(pkey: string, limit?: number, isDesc?: boolean): Promise<DynamoQueryResult<T>>;
|
|
46
|
+
queryRange(pkey: string, from: number, to: number, limit?: number, last?: number): Promise<DynamoQueryResult<T>>;
|
|
47
|
+
/**
|
|
48
|
+
* query by range of sort-key.
|
|
49
|
+
* NOTE - `dynamodb`의 일부 코드를 이용하여, 간단버전으로 지원함.
|
|
50
|
+
*/
|
|
51
|
+
queryRangeBy(pkey: string, from: number, to: number, limit?: number, last?: number, isDesc?: boolean): Promise<DynamoQueryResult<T>>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DynamoQueryService = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* `dynamo-query-service.ts`
|
|
18
|
+
* - common service to query with pkey+sort via dynamo
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* @author Steve Jung <steve@lemoncloud.io>
|
|
22
|
+
* @date 2019-11-6 initial version with `dynamodb` package.
|
|
23
|
+
*
|
|
24
|
+
* @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
|
|
25
|
+
*/
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
27
|
+
const engine_1 = require("../../engine/");
|
|
28
|
+
const dynamo_service_1 = require("./dynamo-service");
|
|
29
|
+
const NS = engine_1.$U.NS('DYQR', 'green'); // NAMESPACE TO BE PRINTED.
|
|
30
|
+
/** ****************************************************************************************************************
|
|
31
|
+
* Service Main
|
|
32
|
+
** ****************************************************************************************************************/
|
|
33
|
+
const query_1 = __importDefault(require("../../lib/dynamo/query"));
|
|
34
|
+
const serializer_1 = __importDefault(require("../../lib/dynamo/serializer"));
|
|
35
|
+
/**
|
|
36
|
+
* class: `DynamoQueryService`
|
|
37
|
+
* - support simple query like range search.
|
|
38
|
+
*/
|
|
39
|
+
class DynamoQueryService {
|
|
40
|
+
constructor(options) {
|
|
41
|
+
/**
|
|
42
|
+
* say hello of identity.
|
|
43
|
+
*/
|
|
44
|
+
this.hello = () => `dynamo-query-service:${this.options.tableName}`;
|
|
45
|
+
// eslint-disable-next-line prettier/prettier
|
|
46
|
+
(0, engine_1._inf)(NS, `DynamoQueryService(${options.tableName}/${options.idName}${options.sortName ? '/' : ''}${options.sortName || ''})...`);
|
|
47
|
+
if (!options.tableName)
|
|
48
|
+
throw new Error('.tableName is required');
|
|
49
|
+
if (!options.idName)
|
|
50
|
+
throw new Error('.idName is required');
|
|
51
|
+
this.options = options;
|
|
52
|
+
}
|
|
53
|
+
queryAll(pkey, limit, isDesc) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
return this.queryRangeBy(pkey, -1, -1, limit, null, isDesc);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
queryRange(pkey, from, to, limit, last) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
return this.queryRangeBy(pkey, from, to, limit, last, false);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* query by range of sort-key.
|
|
65
|
+
* NOTE - `dynamodb`의 일부 코드를 이용하여, 간단버전으로 지원함.
|
|
66
|
+
*/
|
|
67
|
+
queryRangeBy(pkey, from, to, limit, last, isDesc) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
(0, engine_1._log)(NS, `queryRangeBy(${pkey}, ${from}, ${to})...`);
|
|
70
|
+
//! load table information..
|
|
71
|
+
const { tableName, idName, sortName, idType, sortType } = this.options;
|
|
72
|
+
const query = new query_1.default(pkey, { schema: { hashKey: idName, rangeKey: sortName }, tableName: () => tableName }, serializer_1.default);
|
|
73
|
+
// _log(NS, '> query =', query);
|
|
74
|
+
//! build query with builder.
|
|
75
|
+
if (sortName) {
|
|
76
|
+
const keyCondition = query.where(sortName);
|
|
77
|
+
from !== -1 && to !== -1 ? keyCondition.between(from, to) : keyCondition.gte(0);
|
|
78
|
+
}
|
|
79
|
+
isDesc ? query.descending() : query.ascending();
|
|
80
|
+
if (limit !== undefined)
|
|
81
|
+
query.limit(limit);
|
|
82
|
+
query.addKeyCondition(query.buildKey());
|
|
83
|
+
if (last) {
|
|
84
|
+
query.startKey(pkey, last);
|
|
85
|
+
}
|
|
86
|
+
//TODO - replace '@' prefix of properties.
|
|
87
|
+
const payload = query.buildRequest();
|
|
88
|
+
const filter = (N) => Object.keys(N).reduce((O, key) => {
|
|
89
|
+
const val = N[key];
|
|
90
|
+
key = key.startsWith('#@') ? '#_' + key.substring(2) : key;
|
|
91
|
+
key = key.startsWith(':@') ? ':_' + key.substring(2) : key;
|
|
92
|
+
O[key] = val;
|
|
93
|
+
return O;
|
|
94
|
+
}, {});
|
|
95
|
+
payload.ExpressionAttributeNames = filter(payload.ExpressionAttributeNames);
|
|
96
|
+
payload.ExpressionAttributeValues = filter(payload.ExpressionAttributeValues);
|
|
97
|
+
payload.KeyConditionExpression = payload.KeyConditionExpression.replace(/([\#\:])@/g, '$1_');
|
|
98
|
+
(0, engine_1._log)(NS, `> payload[${pkey}] =`, engine_1.$U.json(payload));
|
|
99
|
+
//! get instance of dynamodoc, and execute query().
|
|
100
|
+
const { dynamodoc } = dynamo_service_1.DynamoService.instance();
|
|
101
|
+
const res = yield dynamodoc.query(payload).promise();
|
|
102
|
+
if (res) {
|
|
103
|
+
// _log(NS, `> query[${pkey}].res =`, $U.json(res)); // `startKey`
|
|
104
|
+
const items = res.Items || [];
|
|
105
|
+
const count = res.Count;
|
|
106
|
+
const scannedCount = res.ScannedCount;
|
|
107
|
+
const $lek = res.LastEvaluatedKey || {};
|
|
108
|
+
const last = engine_1.$U.N($lek[sortName], 0);
|
|
109
|
+
(0, engine_1._log)(NS, `> query[${pkey}].items.len =`, items.length);
|
|
110
|
+
(0, engine_1._log)(NS, `> query[${pkey}].count =`, count);
|
|
111
|
+
(0, engine_1._log)(NS, `> query[${pkey}].scannedCount =`, scannedCount);
|
|
112
|
+
(0, engine_1._log)(NS, `> query[${pkey}].lastKey =`, last);
|
|
113
|
+
//! prepare result-set
|
|
114
|
+
const result = {
|
|
115
|
+
list: items,
|
|
116
|
+
count,
|
|
117
|
+
last,
|
|
118
|
+
};
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
//! avoid null exception
|
|
122
|
+
return { list: [] };
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.DynamoQueryService = DynamoQueryService;
|
|
127
|
+
//# sourceMappingURL=dynamo-query-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamo-query-service.js","sourceRoot":"","sources":["../../../src/cores/dynamo/dynamo-query-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,6DAA6D;AAC7D,0CAAqD;AAErD,qDAA+D;AAC/D,MAAM,EAAE,GAAG,WAAE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,2BAA2B;AAuC9D;;qHAEqH;AACrH,mEAA2C;AAC3C,6EAAqD;AAErD;;;GAGG;AACH,MAAa,kBAAkB;IAE3B,YAAmB,OAAqB;QAQxC;;WAEG;QACI,UAAK,GAAG,GAAG,EAAE,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAVlE,6CAA6C;QAC7C,IAAA,aAAI,EAAC,EAAE,EAAE,sBAAsB,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,MAAM,CAAC,CAAC;QACjI,IAAI,CAAC,OAAO,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAOY,QAAQ,CAAC,IAAY,EAAE,KAAc,EAAE,MAAgB;;YAChE,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAChE,CAAC;KAAA;IAEY,UAAU,CACnB,IAAY,EACZ,IAAY,EACZ,EAAU,EACV,KAAc,EACd,IAAa;;YAEb,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;KAAA;IAED;;;OAGG;IACU,YAAY,CACrB,IAAY,EACZ,IAAY,EACZ,EAAU,EACV,KAAc,EACd,IAAa,EACb,MAAgB;;YAEhB,IAAA,aAAI,EAAC,EAAE,EAAE,gBAAgB,IAAI,KAAK,IAAI,KAAK,EAAE,MAAM,CAAC,CAAC;YAErD,4BAA4B;YAC5B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACvE,MAAM,KAAK,GAAG,IAAI,eAAK,CACnB,IAAI,EACJ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,EAC/E,oBAAU,CACb,CAAC;YACF,gCAAgC;YAEhC,6BAA6B;YAC7B,IAAI,QAAQ,EAAE;gBACV,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC3C,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACnF;YACD,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YAChD,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5C,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxC,IAAI,IAAI,EAAE;gBACN,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;aAC9B;YAED,0CAA0C;YAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,CAAC,CAAM,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,GAAW,EAAE,EAAE;gBAC1C,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC3D,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC3D,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;gBACb,OAAO,CAAC,CAAC;YACb,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,OAAO,CAAC,wBAAwB,GAAG,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;YAC5E,OAAO,CAAC,yBAAyB,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;YAC9E,OAAO,CAAC,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YAC7F,IAAA,aAAI,EAAC,EAAE,EAAE,aAAa,IAAI,KAAK,EAAE,WAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAEnD,mDAAmD;YACnD,MAAM,EAAE,SAAS,EAAE,GAAG,8BAAa,CAAC,QAAQ,EAAE,CAAC;YAC/C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YACrD,IAAI,GAAG,EAAE;gBACL,kEAAkE;gBAClE,MAAM,KAAK,GAAc,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;gBACxB,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;gBACtC,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;gBACxC,MAAM,IAAI,GAAG,WAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrC,IAAA,aAAI,EAAC,EAAE,EAAE,WAAW,IAAI,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBACvD,IAAA,aAAI,EAAC,EAAE,EAAE,WAAW,IAAI,WAAW,EAAE,KAAK,CAAC,CAAC;gBAC5C,IAAA,aAAI,EAAC,EAAE,EAAE,WAAW,IAAI,kBAAkB,EAAE,YAAY,CAAC,CAAC;gBAC1D,IAAA,aAAI,EAAC,EAAE,EAAE,WAAW,IAAI,aAAa,EAAE,IAAI,CAAC,CAAC;gBAC7C,sBAAsB;gBACtB,MAAM,MAAM,GAAyB;oBACjC,IAAI,EAAE,KAAY;oBAClB,KAAK;oBACL,IAAI;iBACP,CAAC;gBACF,OAAO,MAAM,CAAC;aACjB;YAED,wBAAwB;YACxB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACxB,CAAC;KAAA;CACJ;AAzGD,gDAyGC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GeneralItem } from '../core-types';
|
|
2
|
+
import { DynamoOption } from './dynamo-service';
|
|
3
|
+
interface ComparisonCondition {
|
|
4
|
+
key: string;
|
|
5
|
+
comparator: '=' | '!=' | '<=' | '<' | '>=' | '>';
|
|
6
|
+
value: number | string;
|
|
7
|
+
}
|
|
8
|
+
interface BetweenCondition {
|
|
9
|
+
key: string;
|
|
10
|
+
from: number | string;
|
|
11
|
+
to: number | string;
|
|
12
|
+
}
|
|
13
|
+
interface ExistenceCondition {
|
|
14
|
+
key: string;
|
|
15
|
+
exists: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface StringCondition {
|
|
18
|
+
key: string;
|
|
19
|
+
operator: 'begins_with' | 'contains';
|
|
20
|
+
value: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* interface: DynamoScanFilter
|
|
24
|
+
* - for joining multiple conditions with logical AND -> Array
|
|
25
|
+
* - for joining multiple conditions with logical OR -> { or: Array }
|
|
26
|
+
*/
|
|
27
|
+
declare type Condition = ComparisonCondition | BetweenCondition | ExistenceCondition | StringCondition;
|
|
28
|
+
export declare type DynamoScanFilter = (Condition | {
|
|
29
|
+
not: Condition;
|
|
30
|
+
}) | DynamoScanFilter[] | {
|
|
31
|
+
or: DynamoScanFilter[];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* class: DynamoScanResult
|
|
35
|
+
* - result information of scan.
|
|
36
|
+
*/
|
|
37
|
+
export interface DynamoScanResult<T> {
|
|
38
|
+
list: T[];
|
|
39
|
+
count?: number;
|
|
40
|
+
last?: any;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* feature: `DynamoSimpleScannable`
|
|
44
|
+
* - simple scan capable class.
|
|
45
|
+
*/
|
|
46
|
+
export interface DynamoSimpleScannable<T extends GeneralItem> {
|
|
47
|
+
/**
|
|
48
|
+
* simple filtered scan w/ limit.
|
|
49
|
+
*
|
|
50
|
+
* @param limit limit of page
|
|
51
|
+
* @param last the last evaluated key
|
|
52
|
+
* @param filter scan filter
|
|
53
|
+
*/
|
|
54
|
+
scan(limit?: number, last?: any, filter?: DynamoScanFilter): Promise<DynamoScanResult<T>>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* class: `DynamoScanService`
|
|
58
|
+
* - support simple scan like range scan.
|
|
59
|
+
*/
|
|
60
|
+
export declare class DynamoScanService<T extends GeneralItem> implements DynamoSimpleScannable<T> {
|
|
61
|
+
protected options: DynamoOption;
|
|
62
|
+
constructor(options: DynamoOption);
|
|
63
|
+
/**
|
|
64
|
+
* say hello of identity.
|
|
65
|
+
*/
|
|
66
|
+
hello: () => string;
|
|
67
|
+
scan(limit?: number, last?: any, filter?: DynamoScanFilter): Promise<DynamoScanResult<T>>;
|
|
68
|
+
private buildPayload;
|
|
69
|
+
}
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DynamoScanService = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* `dynamo-scan-service.ts`
|
|
18
|
+
* - common service to scan with filters+sort via dynamo
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* @author Tim Hong <tim@lemoncloud.io>
|
|
22
|
+
* @date 2020-01-20 initial version
|
|
23
|
+
*
|
|
24
|
+
* @copyright (C) 2020 LemonCloud Co Ltd. - All Rights Reserved.
|
|
25
|
+
*/
|
|
26
|
+
const engine_1 = require("../../engine/");
|
|
27
|
+
const dynamo_service_1 = require("./dynamo-service");
|
|
28
|
+
const NS = engine_1.$U.NS('DSCN', 'green'); // NAMESPACE TO BE PRINTED.
|
|
29
|
+
function isComparisonCondition(c) {
|
|
30
|
+
return 'comparator' in c;
|
|
31
|
+
}
|
|
32
|
+
function isBetweenCondition(c) {
|
|
33
|
+
return 'from' in c && 'to' in c;
|
|
34
|
+
}
|
|
35
|
+
function isExistenceCondition(c) {
|
|
36
|
+
return 'exists' in c;
|
|
37
|
+
}
|
|
38
|
+
function isStringCondition(c) {
|
|
39
|
+
return 'operator' in c;
|
|
40
|
+
}
|
|
41
|
+
/** ****************************************************************************************************************
|
|
42
|
+
* Service Main
|
|
43
|
+
** ****************************************************************************************************************/
|
|
44
|
+
const scan_1 = __importDefault(require("../../lib/dynamo/scan"));
|
|
45
|
+
const serializer_1 = __importDefault(require("../../lib/dynamo/serializer"));
|
|
46
|
+
/**
|
|
47
|
+
* class: `DynamoScanService`
|
|
48
|
+
* - support simple scan like range scan.
|
|
49
|
+
*/
|
|
50
|
+
class DynamoScanService {
|
|
51
|
+
constructor(options) {
|
|
52
|
+
/**
|
|
53
|
+
* say hello of identity.
|
|
54
|
+
*/
|
|
55
|
+
this.hello = () => `dynamo-scan-service:${this.options.tableName}`;
|
|
56
|
+
// eslint-disable-next-line prettier/prettier
|
|
57
|
+
(0, engine_1._inf)(NS, `DynamoScanService(${options.tableName}/${options.idName}${options.sortName ? '/' : ''}${options.sortName || ''})...`);
|
|
58
|
+
if (!options.tableName)
|
|
59
|
+
throw new Error('.tableName is required');
|
|
60
|
+
if (!options.idName)
|
|
61
|
+
throw new Error('.idName is required');
|
|
62
|
+
this.options = options;
|
|
63
|
+
}
|
|
64
|
+
scan(limit, last, filter) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
(0, engine_1._log)(NS, `scan()...`);
|
|
67
|
+
//! build scan input payload
|
|
68
|
+
const payload = this.buildPayload(limit, last, filter);
|
|
69
|
+
(0, engine_1._log)(NS, `> payload =`, engine_1.$U.json(payload));
|
|
70
|
+
//! get instance of dynamodoc, and execute query().
|
|
71
|
+
const { dynamodoc } = dynamo_service_1.DynamoService.instance();
|
|
72
|
+
const res = yield dynamodoc.scan(payload).promise();
|
|
73
|
+
(0, engine_1._log)(NS, `> scan.res =`, engine_1.$U.json(res));
|
|
74
|
+
const items = res.Items || [];
|
|
75
|
+
const count = res.Count;
|
|
76
|
+
const scannedCount = res.ScannedCount;
|
|
77
|
+
const $lek = res.LastEvaluatedKey || {};
|
|
78
|
+
(0, engine_1._log)(NS, `> scan.items.len =`, items.length);
|
|
79
|
+
(0, engine_1._log)(NS, `> scan.count =`, count);
|
|
80
|
+
(0, engine_1._log)(NS, `> scan.scannedCount =`, scannedCount);
|
|
81
|
+
(0, engine_1._log)(NS, `> scan.last =`, $lek);
|
|
82
|
+
//! return result-set
|
|
83
|
+
return {
|
|
84
|
+
list: items,
|
|
85
|
+
count,
|
|
86
|
+
last: $lek,
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
buildPayload(limit, last, filter) {
|
|
91
|
+
const { tableName, idName, sortName } = this.options;
|
|
92
|
+
const scan = new scan_1.default({ schema: { hashKey: idName, rangeKey: sortName }, tableName: () => tableName }, serializer_1.default);
|
|
93
|
+
// Limit & Last
|
|
94
|
+
if (limit > 0)
|
|
95
|
+
scan.limit(limit);
|
|
96
|
+
if (last)
|
|
97
|
+
scan.startKey(last[this.options.idName], last[this.options.sortName]);
|
|
98
|
+
// Filter
|
|
99
|
+
if (filter) {
|
|
100
|
+
const expAttrNames = {};
|
|
101
|
+
const expAttrValues = {};
|
|
102
|
+
const asFilterExpression = (filter) => {
|
|
103
|
+
const asAttrName = (key) => {
|
|
104
|
+
const attrNameVar = `#${key}`;
|
|
105
|
+
expAttrNames[attrNameVar] = key;
|
|
106
|
+
return attrNameVar;
|
|
107
|
+
};
|
|
108
|
+
const asAttrValue = (key, value) => {
|
|
109
|
+
const attrValueVar = (function () {
|
|
110
|
+
for (let i = 0;; i++) {
|
|
111
|
+
const valueVar = `:${key}${i}`;
|
|
112
|
+
if (!(valueVar in expAttrValues))
|
|
113
|
+
return valueVar;
|
|
114
|
+
}
|
|
115
|
+
})();
|
|
116
|
+
expAttrValues[attrValueVar] = value;
|
|
117
|
+
return attrValueVar;
|
|
118
|
+
};
|
|
119
|
+
if (Array.isArray(filter)) {
|
|
120
|
+
return `(${filter.map(asFilterExpression).join(' AND ')})`;
|
|
121
|
+
}
|
|
122
|
+
else if ('or' in filter && Array.isArray(filter.or)) {
|
|
123
|
+
return `(${filter.or.map(asFilterExpression).join(' OR ')})`;
|
|
124
|
+
}
|
|
125
|
+
else if ('not' in filter) {
|
|
126
|
+
return `NOT ${asFilterExpression(filter.not)}`;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const cond = filter;
|
|
130
|
+
if (isComparisonCondition(cond)) {
|
|
131
|
+
const [name, value] = [asAttrName(cond.key), asAttrValue(cond.key, cond.value)];
|
|
132
|
+
return cond.comparator === '!='
|
|
133
|
+
? `NOT ${name} = ${value}`
|
|
134
|
+
: `${name} ${cond.comparator} ${value}`;
|
|
135
|
+
}
|
|
136
|
+
else if (isBetweenCondition(cond)) {
|
|
137
|
+
const [name, from, to] = [
|
|
138
|
+
asAttrName(cond.key),
|
|
139
|
+
asAttrValue(cond.key, cond.from),
|
|
140
|
+
asAttrValue(cond.key, cond.to),
|
|
141
|
+
];
|
|
142
|
+
return `${name} BETWEEN ${from} AND ${to}`;
|
|
143
|
+
}
|
|
144
|
+
else if (isExistenceCondition(cond)) {
|
|
145
|
+
const name = asAttrName(cond.key);
|
|
146
|
+
return cond.exists ? `attribute_exists(${name})` : `attribute_not_exists(${name})`;
|
|
147
|
+
}
|
|
148
|
+
else if (isStringCondition(cond)) {
|
|
149
|
+
const [name, value] = [asAttrName(cond.key), asAttrValue(cond.key, cond.value)];
|
|
150
|
+
return `${cond.operator}(${name}, ${value})`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
scan.filterExpression(asFilterExpression(filter));
|
|
155
|
+
if (Object.keys(expAttrNames).length)
|
|
156
|
+
scan.expressionAttributeNames(expAttrNames);
|
|
157
|
+
if (Object.keys(expAttrValues).length)
|
|
158
|
+
scan.expressionAttributeValues(expAttrValues);
|
|
159
|
+
}
|
|
160
|
+
return scan.buildRequest();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.DynamoScanService = DynamoScanService;
|
|
164
|
+
//# sourceMappingURL=dynamo-scan-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamo-scan-service.js","sourceRoot":"","sources":["../../../src/cores/dynamo/dynamo-scan-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,0CAA+C;AAE/C,qDAA+D;AAC/D,MAAM,EAAE,GAAG,WAAE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,2BAA2B;AAS9D,SAAS,qBAAqB,CAAC,CAAY;IACvC,OAAO,YAAY,IAAI,CAAC,CAAC;AAC7B,CAAC;AAQD,SAAS,kBAAkB,CAAC,CAAY;IACpC,OAAO,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AACpC,CAAC;AAOD,SAAS,oBAAoB,CAAC,CAAY;IACtC,OAAO,QAAQ,IAAI,CAAC,CAAC;AACzB,CAAC;AAQD,SAAS,iBAAiB,CAAC,CAAY;IACnC,OAAO,UAAU,IAAI,CAAC,CAAC;AAC3B,CAAC;AAsCD;;qHAEqH;AACrH,iEAAyC;AACzC,6EAAqD;AAErD;;;GAGG;AACH,MAAa,iBAAiB;IAG1B,YAAmB,OAAqB;QAQxC;;WAEG;QACI,UAAK,GAAG,GAAG,EAAE,CAAC,uBAAuB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAVjE,6CAA6C;QAC7C,IAAA,aAAI,EAAC,EAAE,EAAE,qBAAqB,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,MAAM,CAAC,CAAC;QAChI,IAAI,CAAC,OAAO,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAOY,IAAI,CAAC,KAAc,EAAE,IAAU,EAAE,MAAyB;;YACnE,IAAA,aAAI,EAAC,EAAE,EAAE,WAAW,CAAC,CAAC;YAEtB,4BAA4B;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACvD,IAAA,aAAI,EAAC,EAAE,EAAE,aAAa,EAAE,WAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAE1C,mDAAmD;YACnD,MAAM,EAAE,SAAS,EAAE,GAAG,8BAAa,CAAC,QAAQ,EAAE,CAAC;YAC/C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YACpD,IAAA,aAAI,EAAC,EAAE,EAAE,cAAc,EAAE,WAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAEvC,MAAM,KAAK,GAAc,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACxB,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;YACtC,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;YACxC,IAAA,aAAI,EAAC,EAAE,EAAE,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAA,aAAI,EAAC,EAAE,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;YAClC,IAAA,aAAI,EAAC,EAAE,EAAE,uBAAuB,EAAE,YAAY,CAAC,CAAC;YAChD,IAAA,aAAI,EAAC,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;YAEhC,qBAAqB;YACrB,OAAO;gBACH,IAAI,EAAE,KAAY;gBAClB,KAAK;gBACL,IAAI,EAAE,IAAI;aACb,CAAC;QACN,CAAC;KAAA;IAEO,YAAY,CAAC,KAAc,EAAE,IAAU,EAAE,MAAyB;QACtE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,cAAI,CACjB,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,EAC/E,oBAAU,CACb,CAAC;QAEF,eAAe;QACf,IAAI,KAAK,GAAG,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,IAAI;YAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhF,SAAS;QACT,IAAI,MAAM,EAAE;YACR,MAAM,YAAY,GAA2B,EAAE,CAAC;YAChD,MAAM,aAAa,GAA2B,EAAE,CAAC;YACjD,MAAM,kBAAkB,GAAG,CAAC,MAAwB,EAAU,EAAE;gBAC5D,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE;oBACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;oBAC9B,YAAY,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;oBAChC,OAAO,WAAW,CAAC;gBACvB,CAAC,CAAC;gBACF,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,KAAU,EAAU,EAAE;oBACpD,MAAM,YAAY,GAAG,CAAC;wBAClB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,EAAE,EAAE;4BACnB,MAAM,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;4BAC/B,IAAI,CAAC,CAAC,QAAQ,IAAI,aAAa,CAAC;gCAAE,OAAO,QAAQ,CAAC;yBACrD;oBACL,CAAC,CAAC,EAAE,CAAC;oBACL,aAAa,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC;oBACpC,OAAO,YAAY,CAAC;gBACxB,CAAC,CAAC;gBAEF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBACvB,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;iBAC9D;qBAAM,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;oBACnD,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;iBAChE;qBAAM,IAAI,KAAK,IAAI,MAAM,EAAE;oBACxB,OAAO,OAAO,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;iBAClD;qBAAM;oBACH,MAAM,IAAI,GAAG,MAAmB,CAAC;oBAEjC,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE;wBAC7B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;wBAChF,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI;4BAC3B,CAAC,CAAC,OAAO,IAAI,MAAM,KAAK,EAAE;4BAC1B,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,KAAK,EAAE,CAAC;qBAC/C;yBAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE;wBACjC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG;4BACrB,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;4BACpB,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;4BAChC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;yBACjC,CAAC;wBACF,OAAO,GAAG,IAAI,YAAY,IAAI,QAAQ,EAAE,EAAE,CAAC;qBAC9C;yBAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE;wBACnC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAClC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC,CAAC,wBAAwB,IAAI,GAAG,CAAC;qBACtF;yBAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE;wBAChC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;wBAChF,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC;qBAChD;iBACJ;YACL,CAAC,CAAC;YAEF,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM;gBAAE,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC;YAClF,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM;gBAAE,IAAI,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;SACxF;QAED,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;IAC/B,CAAC;CACJ;AAnHD,8CAmHC"}
|