aws-service-stack 0.18.447 → 0.18.449
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 +79 -7
- package/dist/controller/base-controller.d.ts +2 -1
- package/dist/controller/base-controller.d.ts.map +1 -1
- package/dist/controller/base-controller.js +64 -15
- package/dist/controller/base-controller.js.map +1 -1
- package/dist/controller/controller-api.d.ts +13 -2
- package/dist/controller/controller-api.d.ts.map +1 -1
- package/dist/controller/controller-api.js +77 -10
- package/dist/controller/controller-api.js.map +1 -1
- package/dist/controller/controller-request.d.ts +3 -0
- package/dist/controller/controller-request.d.ts.map +1 -1
- package/dist/controller/controller-request.js +5 -0
- package/dist/controller/controller-request.js.map +1 -1
- package/dist/controller/controller-role.d.ts +2 -1
- package/dist/controller/controller-role.d.ts.map +1 -1
- package/dist/controller/controller-role.js +12 -3
- package/dist/controller/controller-role.js.map +1 -1
- package/dist/model/base.config.d.ts +4 -1
- package/dist/model/base.config.d.ts.map +1 -1
- package/dist/model/base.config.js +1 -0
- package/dist/model/base.config.js.map +1 -1
- package/dist/model/base.model.d.ts +3 -0
- package/dist/model/base.model.d.ts.map +1 -1
- package/dist/model/base.model.js.map +1 -1
- package/dist/model/caller.model.d.ts +22 -0
- package/dist/model/caller.model.d.ts.map +1 -0
- package/dist/model/caller.model.js +12 -0
- package/dist/model/caller.model.js.map +1 -0
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +1 -0
- package/dist/model/index.js.map +1 -1
- package/dist/model/validation.model.d.ts +15 -1
- package/dist/model/validation.model.d.ts.map +1 -1
- package/dist/model/validation.model.js +3 -1
- package/dist/model/validation.model.js.map +1 -1
- package/dist/utils/auth/caller.d.ts +9 -0
- package/dist/utils/auth/caller.d.ts.map +1 -0
- package/dist/utils/auth/caller.js +108 -0
- package/dist/utils/auth/caller.js.map +1 -0
- package/dist/utils/auth/policy-view.d.ts +42 -0
- package/dist/utils/auth/policy-view.d.ts.map +1 -0
- package/dist/utils/auth/policy-view.js +170 -0
- package/dist/utils/auth/policy-view.js.map +1 -0
- package/dist/utils/http/api-event.d.ts +23 -0
- package/dist/utils/http/api-event.d.ts.map +1 -0
- package/dist/utils/http/api-event.js +84 -0
- package/dist/utils/http/api-event.js.map +1 -0
- package/dist/utils/http/http.util.d.ts +12 -2
- package/dist/utils/http/http.util.d.ts.map +1 -1
- package/dist/utils/http/http.util.js +50 -24
- package/dist/utils/http/http.util.js.map +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/opensearch/opensearch.parser.aggs.d.ts +2 -1
- package/dist/utils/opensearch/opensearch.parser.aggs.d.ts.map +1 -1
- package/dist/utils/opensearch/opensearch.parser.aggs.js +38 -4
- package/dist/utils/opensearch/opensearch.parser.aggs.js.map +1 -1
- package/dist/utils/opensearch/opensearch.parser.d.ts +1 -1
- package/dist/utils/reflection.util.d.ts +4 -0
- package/dist/utils/reflection.util.d.ts.map +1 -1
- package/dist/utils/reflection.util.js +17 -0
- package/dist/utils/reflection.util.js.map +1 -1
- package/package.json +60 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-event.js","sourceRoot":"","sources":["../../../src/utils/http/api-event.ts"],"names":[],"mappings":"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","sourcesContent":["import type { HttpMethod } from \"@chinggis/types\";\nimport type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from \"aws-lambda\";\n\nexport type ApiEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\n\nexport interface NormalizedApiEvent {\n version: \"1.0\" | \"2.0\";\n method: HttpMethod;\n /** Route template with leading slash, e.g. \"/entities/{id}\" */\n routePath: string;\n rawPath: string;\n /** Header names are lower-cased */\n headers: Record<string, string>;\n query: Record<string, string>;\n multiQuery: Record<string, string[]>;\n pathParameters: Record<string, string>;\n /** base64 already decoded */\n body?: string;\n /** REST API (v1) requestContext.authorizer.claims only */\n // biome-ignore lint/suspicious/noExplicitAny: claims are arbitrary JWT payload\n restClaims?: Record<string, any>;\n raw: ApiEvent;\n}\n\nexport function isHttpApiEvent(event: ApiEvent): event is APIGatewayProxyEventV2 {\n return (event as APIGatewayProxyEventV2).version === \"2.0\";\n}\n\nfunction lowerCaseKeys(headers: Record<string, string | undefined> | null | undefined): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers ?? {})) {\n if (value !== undefined) result[key.toLowerCase()] = value;\n }\n return result;\n}\n\nfunction definedEntries(record: Record<string, string | undefined> | null | undefined): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(record ?? {})) {\n if (value !== undefined) result[key] = value;\n }\n return result;\n}\n\nfunction decodeBody(body: string | null | undefined, isBase64Encoded: boolean | undefined): string | undefined {\n if (body === null || body === undefined) return undefined;\n return isBase64Encoded ? Buffer.from(body, \"base64\").toString(\"utf-8\") : body;\n}\n\nexport function normalizeApiEvent(event: ApiEvent): NormalizedApiEvent {\n if (isHttpApiEvent(event)) {\n const query = definedEntries(event.queryStringParameters);\n const multiQuery: Record<string, string[]> = {};\n if (event.rawQueryString) {\n const params = new URLSearchParams(event.rawQueryString);\n for (const key of new Set(params.keys())) multiQuery[key] = params.getAll(key);\n } else {\n for (const [key, value] of Object.entries(query)) multiQuery[key] = value.split(\",\");\n }\n\n const routeKey = event.routeKey ?? \"\";\n const spaceIdx = routeKey.indexOf(\" \");\n const routePath = routeKey === \"$default\" || spaceIdx < 0 ? event.rawPath : routeKey.slice(spaceIdx + 1);\n\n return {\n version: \"2.0\",\n method: event.requestContext.http.method as HttpMethod,\n routePath,\n rawPath: event.rawPath,\n headers: lowerCaseKeys(event.headers),\n query,\n multiQuery,\n pathParameters: definedEntries(event.pathParameters),\n body: decodeBody(event.body, event.isBase64Encoded),\n raw: event,\n };\n }\n\n const multiQuery: Record<string, string[]> = {};\n for (const [key, values] of Object.entries(event.multiValueQueryStringParameters ?? {})) {\n if (values) multiQuery[key] = values;\n }\n const query = definedEntries(event.queryStringParameters);\n for (const [key, value] of Object.entries(query)) {\n if (!(key in multiQuery)) multiQuery[key] = [value];\n }\n\n const resourcePath = event.requestContext?.resourcePath ?? event.resource ?? \"\";\n const claims = event.requestContext?.authorizer?.claims;\n\n return {\n version: \"1.0\",\n method: event.httpMethod as HttpMethod,\n routePath: resourcePath.startsWith(\"/\") ? resourcePath : `/${resourcePath}`,\n rawPath: event.path,\n headers: lowerCaseKeys(event.headers),\n query,\n multiQuery,\n pathParameters: definedEntries(event.pathParameters),\n body: decodeBody(event.body, event.isBase64Encoded),\n restClaims: claims ?? undefined,\n raw: event,\n };\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CognitoUser, EndpointPolicy, EntityConfig, Filter, HttpMethod, RequestType, ResponseFields } from "../../index";
|
|
2
|
-
import {
|
|
2
|
+
import { type Caller } from "../../model/caller.model";
|
|
3
|
+
import { type ApiEvent } from "./api-event";
|
|
3
4
|
export type APIResponse = {
|
|
4
5
|
statusCode: number;
|
|
5
6
|
headers?: Record<string, string>;
|
|
@@ -15,7 +16,10 @@ export declare const createApiResponse: (statusCode: number, body: any, options?
|
|
|
15
16
|
export interface HttpRequest<B = any, Q = any, P = any> {
|
|
16
17
|
event: any;
|
|
17
18
|
methode: HttpMethod;
|
|
19
|
+
/** "<METHOD> <routePath>" (same value as before on REST) */
|
|
18
20
|
resourcePath: string;
|
|
21
|
+
/** Route template with leading slash, e.g. "/entities/{id}" (REST resourcePath, HTTP API routeKey path) */
|
|
22
|
+
routePath: string;
|
|
19
23
|
body?: B;
|
|
20
24
|
queryStringParameters?: Q;
|
|
21
25
|
filter?: Filter;
|
|
@@ -29,8 +33,14 @@ export interface HttpRequest<B = any, Q = any, P = any> {
|
|
|
29
33
|
entityId: string;
|
|
30
34
|
profileId?: string;
|
|
31
35
|
parentId?: string;
|
|
36
|
+
/** Verified caller; only set when CALLER_POOLS are configured */
|
|
37
|
+
caller?: Caller;
|
|
38
|
+
/** Response fields of the caller's policy view; overrides policy.response */
|
|
39
|
+
responseFields?: ResponseFields;
|
|
40
|
+
/** Resolved forced filter of the caller's policy view (only set when the view forces keys) */
|
|
41
|
+
forcedFilter?: Record<string, any>;
|
|
32
42
|
}
|
|
33
|
-
export declare const parseHttpRequest: (event:
|
|
43
|
+
export declare const parseHttpRequest: (event: ApiEvent, config: EntityConfig, caller?: Caller) => HttpRequest;
|
|
34
44
|
export declare function parseFilter(params: Record<string, any> | string, searchBy?: string[]): Filter;
|
|
35
45
|
export declare function toRecord(queryString: string, options?: {
|
|
36
46
|
parseDates?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.util.d.ts","sourceRoot":"","sources":["../../../src/utils/http/http.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAM,EACN,UAAU,EACV,WAAW,EACX,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"http.util.d.ts","sourceRoot":"","sources":["../../../src/utils/http/http.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAM,EACN,UAAU,EACV,WAAW,EACX,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,KAAK,QAAQ,EAAqB,MAAM,aAAa,CAAC;AAG/D,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,kBAG1C,CAAC;AAEF,eAAO,MAAM,iBAAiB,eAChB,MAAM,QACZ,GAAG,YACC,kBAAkB,oBACV,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACvC,WAaF,CAAC;AAEF,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;IACpD,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,2GAA2G;IAC3G,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,+BAA+B,CAAC,EAAE,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC;AAED,eAAO,MAAM,gBAAgB,UAAW,QAAQ,UAAU,YAAY,WAAW,MAAM,KAAG,WAmGzF,CAAC;AAEF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAwG7F;AAyCD,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiBrG;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,cAAc,CAM/G"}
|
|
@@ -5,6 +5,8 @@ exports.parseFilter = parseFilter;
|
|
|
5
5
|
exports.toRecord = toRecord;
|
|
6
6
|
exports.findMatchedPolicy = findMatchedPolicy;
|
|
7
7
|
const index_1 = require("../../index");
|
|
8
|
+
const caller_model_1 = require("../../model/caller.model");
|
|
9
|
+
const api_event_1 = require("./api-event");
|
|
8
10
|
const string_util_1 = require("../string.util");
|
|
9
11
|
exports.DEFAULT_API_RESPONSE_OPTIONS = {
|
|
10
12
|
origin: "*",
|
|
@@ -24,8 +26,12 @@ const createApiResponse = (statusCode, body, options, responseHeaders) => {
|
|
|
24
26
|
};
|
|
25
27
|
};
|
|
26
28
|
exports.createApiResponse = createApiResponse;
|
|
27
|
-
const parseHttpRequest = (event, config) => {
|
|
28
|
-
const
|
|
29
|
+
const parseHttpRequest = (event, config, caller) => {
|
|
30
|
+
const normalized = (0, api_event_1.normalizeApiEvent)(event);
|
|
31
|
+
const isRest = normalized.version === "1.0";
|
|
32
|
+
const rawEvent = event;
|
|
33
|
+
// claims are an arbitrary JWT payload (typed any as before)
|
|
34
|
+
const identity = caller ? caller.claims : normalized.restClaims;
|
|
29
35
|
// request user data
|
|
30
36
|
const groupsCognito = (0, string_util_1.toArray)(identity?.["cognito:groups"]);
|
|
31
37
|
const username = identity?.["cognito:username"] || "";
|
|
@@ -34,30 +40,49 @@ const parseHttpRequest = (event, config) => {
|
|
|
34
40
|
const parentId = identity?.["custom:parentId"];
|
|
35
41
|
const adminGroups = new Set((0, string_util_1.normalizeLower)((0, string_util_1.toArray)(config.ADMIN_GROUP_NAME)));
|
|
36
42
|
const groups = (0, string_util_1.normalizeLower)((0, string_util_1.toArray)(groupsCognito));
|
|
37
|
-
|
|
43
|
+
// With verified callers only the admin pool + admin group (kind ADMIN) is admin; legacy: group check
|
|
44
|
+
const isAdmin = caller ? caller.kind === caller_model_1.CallerKind.ADMIN : groups.some((g) => adminGroups.has(g));
|
|
38
45
|
let requestType = index_1.RequestType.GUEST;
|
|
39
46
|
let isParent = false;
|
|
40
47
|
if (identity?.["custom:isParent"] != null) {
|
|
41
48
|
isParent = identity["custom:isParent"] === "1";
|
|
42
49
|
}
|
|
43
|
-
if (
|
|
50
|
+
if (caller) {
|
|
51
|
+
if (caller.kind === caller_model_1.CallerKind.ADMIN)
|
|
52
|
+
requestType = index_1.RequestType.ADMIN;
|
|
53
|
+
else if (caller.kind !== caller_model_1.CallerKind.GUEST)
|
|
54
|
+
requestType = index_1.RequestType.USER;
|
|
55
|
+
}
|
|
56
|
+
else if (isAdmin) {
|
|
44
57
|
requestType = index_1.RequestType.ADMIN;
|
|
45
58
|
}
|
|
46
59
|
else if (profileId || userId)
|
|
47
60
|
requestType = index_1.RequestType.USER;
|
|
48
|
-
const entityId = decodeURIComponent(
|
|
49
|
-
const
|
|
50
|
-
|
|
61
|
+
const entityId = decodeURIComponent(normalized.pathParameters?.id || "");
|
|
62
|
+
const routePath = normalized.routePath;
|
|
63
|
+
// REST keeps the exact former value of requestContext.resourcePath
|
|
64
|
+
const eventResourcePath = isRest ? rawEvent?.requestContext?.resourcePath : routePath;
|
|
65
|
+
const resourcePath = normalized.method + " " + eventResourcePath;
|
|
51
66
|
const customEntries = Object.entries(identity ?? {}).filter(([key]) => key.startsWith("custom:"));
|
|
67
|
+
const queryStringParameters = isRest
|
|
68
|
+
? rawEvent?.queryStringParameters || undefined
|
|
69
|
+
: Object.keys(normalized.query).length
|
|
70
|
+
? normalized.query
|
|
71
|
+
: undefined;
|
|
72
|
+
const multiValueQueryStringParameters = isRest
|
|
73
|
+
? rawEvent?.multiValueQueryStringParameters || undefined
|
|
74
|
+
: Object.keys(normalized.multiQuery).length
|
|
75
|
+
? normalized.multiQuery
|
|
76
|
+
: undefined;
|
|
52
77
|
const parsedParams = {
|
|
53
78
|
event: event,
|
|
54
|
-
methode:
|
|
55
|
-
queryStringParameters
|
|
56
|
-
filter:
|
|
57
|
-
? parseFilter(
|
|
79
|
+
methode: normalized.method,
|
|
80
|
+
queryStringParameters,
|
|
81
|
+
filter: queryStringParameters
|
|
82
|
+
? parseFilter(queryStringParameters, normalized.multiQuery.searchBy)
|
|
58
83
|
: {},
|
|
59
|
-
multiValueQueryStringParameters
|
|
60
|
-
pathParameters:
|
|
84
|
+
multiValueQueryStringParameters,
|
|
85
|
+
pathParameters: rawEvent?.pathParameters || undefined,
|
|
61
86
|
body: undefined,
|
|
62
87
|
identity: identity
|
|
63
88
|
? {
|
|
@@ -67,24 +92,24 @@ const parseHttpRequest = (event, config) => {
|
|
|
67
92
|
parentId,
|
|
68
93
|
groups,
|
|
69
94
|
username,
|
|
70
|
-
Authorization:
|
|
71
|
-
identityId:
|
|
95
|
+
Authorization: normalized.headers.authorization,
|
|
96
|
+
identityId: normalized.headers["x-cognito-identity-id"],
|
|
72
97
|
attributes: Object.fromEntries(customEntries.map(([key, value]) => [key.replace("custom:", ""), value])),
|
|
73
98
|
}
|
|
74
99
|
: undefined,
|
|
75
|
-
// username,
|
|
76
|
-
// userId,
|
|
77
|
-
// isAdmin,
|
|
78
100
|
profileId,
|
|
79
101
|
parentId,
|
|
80
102
|
requestType,
|
|
81
103
|
resourcePath,
|
|
104
|
+
routePath,
|
|
82
105
|
entityId: entityId === "null" || entityId === "undefined" ? profileId : entityId,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
106
|
+
headers: { ...rawEvent?.headers },
|
|
107
|
+
policy: findMatchedPolicy(normalized.method, eventResourcePath, config.ENDPOINT_POLICY),
|
|
108
|
+
caller,
|
|
86
109
|
};
|
|
87
|
-
|
|
110
|
+
// Legacy keeps the former TypeError on an unmatched policy; caller mode lets the controller answer 404
|
|
111
|
+
const policyAccess = caller ? parsedParams.policy?.access : parsedParams.policy.access;
|
|
112
|
+
if (!isAdmin && policyAccess && policyAccess.includes(index_1.Access.OWNER)) {
|
|
88
113
|
if (isParent)
|
|
89
114
|
parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? "ownerParentId"] = profileId;
|
|
90
115
|
else
|
|
@@ -92,8 +117,9 @@ const parseHttpRequest = (event, config) => {
|
|
|
92
117
|
if (parentId)
|
|
93
118
|
parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? "ownerParentId"] = parentId;
|
|
94
119
|
}
|
|
95
|
-
|
|
96
|
-
|
|
120
|
+
const body = normalized.body;
|
|
121
|
+
if (body)
|
|
122
|
+
parsedParams.body = typeof body === "string" ? JSON.parse(body) : body;
|
|
97
123
|
return parsedParams;
|
|
98
124
|
};
|
|
99
125
|
exports.parseHttpRequest = parseHttpRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.util.js","sourceRoot":"","sources":["../../../src/utils/http/http.util.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Access,\n CognitoUser,\n EndpointPolicy,\n EntityConfig,\n Filter,\n HttpMethod,\n RequestType,\n ResponseFields,\n SortOrder,\n toCaseInsensitive,\n} from \"../../index\";\nimport { APIGatewayProxyEvent } from \"aws-lambda\";\nimport { getFirst, normalizeLower, toArray, trimSpecialChar } from \"../string.util\";\n\nexport type APIResponse = {\n statusCode: number;\n headers?: Record<string, string>;\n body: string;\n};\n\nexport type APIResponseOptions = {\n origin?: string;\n contentType: string;\n fields?: ResponseFields;\n};\n\nexport const DEFAULT_API_RESPONSE_OPTIONS: APIResponseOptions = {\n origin: \"*\",\n contentType: \"application/json\",\n};\n\nexport const createApiResponse = (\n statusCode: number,\n body: any,\n options?: APIResponseOptions,\n responseHeaders?: Record<string, string>,\n): APIResponse => {\n const origin = options?.origin ?? DEFAULT_API_RESPONSE_OPTIONS.origin;\n const contentType = options?.contentType ?? DEFAULT_API_RESPONSE_OPTIONS.contentType;\n\n return {\n statusCode,\n body: JSON.stringify(body),\n headers: {\n \"Access-Control-Allow-Origin\": origin,\n \"Content-Type\": contentType,\n ...(responseHeaders ?? {}),\n },\n };\n};\n\nexport interface HttpRequest<B = any, Q = any, P = any> {\n event: any;\n methode: HttpMethod;\n resourcePath: string;\n body?: B;\n queryStringParameters?: Q;\n filter?: Filter;\n customQueryParameters?: Record<string, string>;\n multiValueQueryStringParameters?: Q;\n pathParameters?: P;\n identity?: CognitoUser;\n headers?: Record<string, string>;\n requestType: RequestType;\n policy: EndpointPolicy;\n entityId: string;\n profileId?: string;\n parentId?: string;\n}\n\nexport const parseHttpRequest = (event: APIGatewayProxyEvent, config: EntityConfig): HttpRequest => {\n const identity = event?.requestContext?.authorizer?.claims;\n\n // request user data\n const groupsCognito = toArray(identity?.[\"cognito:groups\"]);\n\n const username = identity?.[\"cognito:username\"] || \"\";\n const userId = identity?.sub || \"\";\n const profileId = identity?.profile || username;\n const parentId: string | undefined = identity?.[\"custom:parentId\"];\n\n const adminGroups = new Set(normalizeLower(toArray(config.ADMIN_GROUP_NAME)));\n const groups = normalizeLower(toArray(groupsCognito));\n const isAdmin = groups.some((g) => adminGroups.has(g));\n let requestType: RequestType = RequestType.GUEST;\n let isParent: boolean = false;\n\n if (identity?.[\"custom:isParent\"] != null) {\n isParent = identity[\"custom:isParent\"] === \"1\";\n }\n\n if (isAdmin) {\n requestType = RequestType.ADMIN;\n } else if (profileId || userId) requestType = RequestType.USER;\n\n const entityId = decodeURIComponent(event?.pathParameters?.id || \"\");\n const eventResourcePath = event?.requestContext?.resourcePath;\n const resourcePath = event.httpMethod + \" \" + eventResourcePath;\n const customEntries = Object.entries(identity ?? {}).filter(([key]) => key.startsWith(\"custom:\"));\n\n const parsedParams: HttpRequest = {\n event: event,\n methode: event.httpMethod as HttpMethod,\n queryStringParameters: event?.queryStringParameters || undefined,\n\n filter: event?.queryStringParameters\n ? parseFilter(\n event?.queryStringParameters as Record<string, any>,\n event.multiValueQueryStringParameters[\"searchBy\"],\n )\n : {},\n\n multiValueQueryStringParameters: event?.multiValueQueryStringParameters || undefined,\n pathParameters: event?.pathParameters || undefined,\n body: undefined,\n identity: identity\n ? {\n ...identity,\n isParent,\n isAdmin,\n parentId,\n groups,\n username,\n Authorization: event?.headers?.Authorization,\n identityId:\n event && \"x-cognito-identity-id\" in event.headers ? event.headers[\"x-cognito-identity-id\"] : undefined,\n attributes: Object.fromEntries(customEntries.map(([key, value]) => [key.replace(\"custom:\", \"\"), value])),\n }\n : undefined,\n // username,\n // userId,\n // isAdmin,\n profileId,\n parentId,\n requestType,\n resourcePath,\n entityId: entityId === \"null\" || entityId === \"undefined\" ? profileId : entityId,\n // groups,\n headers: { ...event?.headers },\n policy: findMatchedPolicy(event.httpMethod as HttpMethod, eventResourcePath, config.ENDPOINT_POLICY),\n };\n\n if (!isAdmin && parsedParams.policy.access && parsedParams.policy.access.includes(Access.OWNER)) {\n if (isParent) parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? \"ownerParentId\"] = profileId;\n else parsedParams.filter[config.OWNER_ID_FIELD_NAME ?? \"profileId\"] = profileId;\n if (parentId) parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? \"ownerParentId\"] = parentId;\n }\n\n if (event?.body) parsedParams.body = typeof event.body === \"string\" ? JSON.parse(event.body) : event.body;\n\n return parsedParams;\n};\n\nexport function parseFilter(params: Record<string, any> | string, searchBy?: string[]): Filter {\n const result: Filter = {};\n\n if (searchBy && searchBy.length > 0) {\n result.searchBy = searchBy;\n }\n\n // If the params is a string (URL query string), parse it first\n let parsedParams: Record<string, any>;\n if (typeof params === \"string\") {\n parsedParams = toRecord(params, { parseDates: false });\n } else {\n parsedParams = params;\n }\n\n parsedParams.searchKeyword = getFirst(parsedParams.searchKeyword);\n\n const parseParam = (key: string, parseFunc: (value: string) => any) => {\n const value = parsedParams[key];\n if (value !== undefined && value !== null && String(value).trim() !== \"\") {\n result[key] = parseFunc(value);\n }\n };\n\n parseParam(\"page\", (value) => Number.parseInt(value, 10));\n parseParam(\"size\", (value) => Number.parseInt(value, 10));\n parseParam(\"sortBy\", (value) => value);\n parseParam(\"sort\", (value) => value as SortOrder);\n // parseParam(\"searchBy\", (value) => searchBy);\n parseParam(\"searchKeyword\", (value) => toCaseInsensitive(value));\n parseParam(\"lastKey\", (value) => value);\n parseParam(\"indexName\", (value) => value);\n parseParam(\"indexValue\", (value) => value);\n\n const parseRangeValue = (value: any) => {\n // If value is already a number, return it\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(value)) {\n return value;\n }\n\n // Convert to string for parsing\n const stringValue = String(value);\n\n // Check if it's a valid number (including decimals)\n const numberValue = Number.parseFloat(stringValue);\n if (!Number.isNaN(numberValue)) {\n // Handle zero values (both \"0\" and \"0.0\" should become 0)\n if (numberValue === 0) {\n return 0;\n }\n // Handle integer values\n if (Number.isInteger(numberValue)) {\n return Number.parseInt(stringValue, 10);\n }\n return numberValue;\n }\n\n return value;\n };\n\n // Initialize rangeFilters array\n result.rangeFilters = [];\n\n // Auto-detect range filter patterns with min_ and max_ prefixes\n for (const key in parsedParams) {\n const value = parsedParams[key];\n if (value !== undefined && value !== null && String(value).trim() !== \"\") {\n // Check for min_ and max_ patterns\n const minMatch = key.match(/^min_(.+)$/i);\n const maxMatch = key.match(/^max_(.+)$/i);\n\n if (minMatch) {\n const fieldName = minMatch[1]; // Remove .toLowerCase() to preserve case\n // Find existing range filter or create new one\n let rangeFilter = result.rangeFilters!.find((rf) => rf.fieldName === fieldName);\n if (!rangeFilter) {\n rangeFilter = { fieldName };\n result.rangeFilters!.push(rangeFilter);\n }\n rangeFilter.minValue = parseRangeValue(value);\n } else if (maxMatch) {\n const fieldName = maxMatch[1]; // Remove .toLowerCase() to preserve case\n // Find existing range filter or create new one\n let rangeFilter = result.rangeFilters!.find((rf) => rf.fieldName === fieldName);\n if (!rangeFilter) {\n rangeFilter = { fieldName };\n result.rangeFilters!.push(rangeFilter);\n }\n rangeFilter.maxValue = parseRangeValue(value);\n } else if (!(key in result)) {\n result[key] = value;\n }\n }\n }\n\n // Clean up empty rangeFilters array\n if (result.rangeFilters!.length === 0) {\n delete result.rangeFilters;\n }\n\n return result;\n}\n\nfunction smartParse(value: string): any {\n if (value.includes(\"*\")) return value;\n if (/^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(value)) {\n const parsedDate = new Date(value);\n if (!Number.isNaN(parsedDate.getTime())) {\n return parsedDate;\n }\n }\n\n // Boolean\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n\n // Integer\n if (/^-?\\d+$/.test(value)) {\n if (hasLeadingZeroInteger(value)) return value;\n return parseInt(value, 10);\n }\n\n // Float / Double\n if (/^-?\\d*\\.\\d+$/.test(value)) return parseFloat(value);\n\n if (typeof value === \"string\" && value.includes(\",\")) {\n const valueList = value.split(\",\");\n for (let i = 1; i < valueList.length; i++) {\n valueList[i] = smartParse(valueList[i]);\n }\n return valueList;\n }\n\n // Default: string\n return value;\n}\n\nfunction hasLeadingZeroInteger(value: string): boolean {\n const normalized = value.startsWith(\"-\") ? value.slice(1) : value;\n return normalized.length > 1 && normalized.startsWith(\"0\");\n}\n\nexport function toRecord(queryString: string, options?: { parseDates?: boolean }): Record<string, any> {\n const result: Record<string, any> = {};\n const pairs = queryString.split(\"&\");\n const parseDates = options?.parseDates ?? true;\n\n for (const pair of pairs) {\n const [key, value] = pair.split(\"=\");\n if (key && value !== undefined) {\n const decodedValue = decodeURIComponent(value);\n result[key] =\n !parseDates && /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(decodedValue)\n ? decodedValue\n : smartParse(decodedValue);\n }\n }\n\n return result;\n}\n\nexport function findMatchedPolicy(methode: HttpMethod, path: string, policies: EndpointPolicy[]): EndpointPolicy {\n if (!methode || !path || !policies.length) {\n return null;\n }\n\n return policies.find((policy) => policy.method === methode && trimSpecialChar(policy.path) === trimSpecialChar(path));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http.util.js","sourceRoot":"","sources":["../../../src/utils/http/http.util.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Access,\n CognitoUser,\n EndpointPolicy,\n EntityConfig,\n Filter,\n HttpMethod,\n RequestType,\n ResponseFields,\n SortOrder,\n toCaseInsensitive,\n} from \"../../index\";\nimport { type Caller, CallerKind } from \"../../model/caller.model\";\nimport { type ApiEvent, normalizeApiEvent } from \"./api-event\";\nimport { getFirst, normalizeLower, toArray, trimSpecialChar } from \"../string.util\";\n\nexport type APIResponse = {\n statusCode: number;\n headers?: Record<string, string>;\n body: string;\n};\n\nexport type APIResponseOptions = {\n origin?: string;\n contentType: string;\n fields?: ResponseFields;\n};\n\nexport const DEFAULT_API_RESPONSE_OPTIONS: APIResponseOptions = {\n origin: \"*\",\n contentType: \"application/json\",\n};\n\nexport const createApiResponse = (\n statusCode: number,\n body: any,\n options?: APIResponseOptions,\n responseHeaders?: Record<string, string>,\n): APIResponse => {\n const origin = options?.origin ?? DEFAULT_API_RESPONSE_OPTIONS.origin;\n const contentType = options?.contentType ?? DEFAULT_API_RESPONSE_OPTIONS.contentType;\n\n return {\n statusCode,\n body: JSON.stringify(body),\n headers: {\n \"Access-Control-Allow-Origin\": origin,\n \"Content-Type\": contentType,\n ...(responseHeaders ?? {}),\n },\n };\n};\n\nexport interface HttpRequest<B = any, Q = any, P = any> {\n event: any;\n methode: HttpMethod;\n /** \"<METHOD> <routePath>\" (same value as before on REST) */\n resourcePath: string;\n /** Route template with leading slash, e.g. \"/entities/{id}\" (REST resourcePath, HTTP API routeKey path) */\n routePath: string;\n body?: B;\n queryStringParameters?: Q;\n filter?: Filter;\n customQueryParameters?: Record<string, string>;\n multiValueQueryStringParameters?: Q;\n pathParameters?: P;\n identity?: CognitoUser;\n headers?: Record<string, string>;\n requestType: RequestType;\n policy: EndpointPolicy;\n entityId: string;\n profileId?: string;\n parentId?: string;\n /** Verified caller; only set when CALLER_POOLS are configured */\n caller?: Caller;\n /** Response fields of the caller's policy view; overrides policy.response */\n responseFields?: ResponseFields;\n /** Resolved forced filter of the caller's policy view (only set when the view forces keys) */\n forcedFilter?: Record<string, any>;\n}\n\nexport const parseHttpRequest = (event: ApiEvent, config: EntityConfig, caller?: Caller): HttpRequest => {\n const normalized = normalizeApiEvent(event);\n const isRest = normalized.version === \"1.0\";\n const rawEvent = event as any;\n // claims are an arbitrary JWT payload (typed any as before)\n const identity: any = caller ? caller.claims : normalized.restClaims;\n\n // request user data\n const groupsCognito = toArray(identity?.[\"cognito:groups\"]);\n\n const username = identity?.[\"cognito:username\"] || \"\";\n const userId = identity?.sub || \"\";\n const profileId = identity?.profile || username;\n const parentId: string | undefined = identity?.[\"custom:parentId\"];\n\n const adminGroups = new Set(normalizeLower(toArray(config.ADMIN_GROUP_NAME)));\n const groups = normalizeLower(toArray(groupsCognito));\n // With verified callers only the admin pool + admin group (kind ADMIN) is admin; legacy: group check\n const isAdmin = caller ? caller.kind === CallerKind.ADMIN : groups.some((g) => adminGroups.has(g));\n let requestType: RequestType = RequestType.GUEST;\n let isParent: boolean = false;\n\n if (identity?.[\"custom:isParent\"] != null) {\n isParent = identity[\"custom:isParent\"] === \"1\";\n }\n\n if (caller) {\n if (caller.kind === CallerKind.ADMIN) requestType = RequestType.ADMIN;\n else if (caller.kind !== CallerKind.GUEST) requestType = RequestType.USER;\n } else if (isAdmin) {\n requestType = RequestType.ADMIN;\n } else if (profileId || userId) requestType = RequestType.USER;\n\n const entityId = decodeURIComponent(normalized.pathParameters?.id || \"\");\n const routePath = normalized.routePath;\n // REST keeps the exact former value of requestContext.resourcePath\n const eventResourcePath = isRest ? rawEvent?.requestContext?.resourcePath : routePath;\n const resourcePath = normalized.method + \" \" + eventResourcePath;\n const customEntries = Object.entries(identity ?? {}).filter(([key]) => key.startsWith(\"custom:\"));\n\n const queryStringParameters = isRest\n ? rawEvent?.queryStringParameters || undefined\n : Object.keys(normalized.query).length\n ? normalized.query\n : undefined;\n const multiValueQueryStringParameters = isRest\n ? rawEvent?.multiValueQueryStringParameters || undefined\n : Object.keys(normalized.multiQuery).length\n ? normalized.multiQuery\n : undefined;\n\n const parsedParams: HttpRequest = {\n event: event,\n methode: normalized.method,\n queryStringParameters,\n\n filter: queryStringParameters\n ? parseFilter(queryStringParameters as Record<string, any>, normalized.multiQuery.searchBy)\n : {},\n\n multiValueQueryStringParameters,\n pathParameters: rawEvent?.pathParameters || undefined,\n body: undefined,\n identity: identity\n ? {\n ...identity,\n isParent,\n isAdmin,\n parentId,\n groups,\n username,\n Authorization: normalized.headers.authorization,\n identityId: normalized.headers[\"x-cognito-identity-id\"],\n attributes: Object.fromEntries(customEntries.map(([key, value]) => [key.replace(\"custom:\", \"\"), value])),\n }\n : undefined,\n profileId,\n parentId,\n requestType,\n resourcePath,\n routePath,\n entityId: entityId === \"null\" || entityId === \"undefined\" ? profileId : entityId,\n headers: { ...rawEvent?.headers },\n policy: findMatchedPolicy(normalized.method, eventResourcePath, config.ENDPOINT_POLICY),\n caller,\n };\n\n // Legacy keeps the former TypeError on an unmatched policy; caller mode lets the controller answer 404\n const policyAccess = caller ? parsedParams.policy?.access : parsedParams.policy.access;\n if (!isAdmin && policyAccess && policyAccess.includes(Access.OWNER)) {\n if (isParent) parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? \"ownerParentId\"] = profileId;\n else parsedParams.filter[config.OWNER_ID_FIELD_NAME ?? \"profileId\"] = profileId;\n if (parentId) parsedParams.filter[config.OWNER_PARENT_ID_FIELD_NAME ?? \"ownerParentId\"] = parentId;\n }\n\n const body: any = normalized.body;\n if (body) parsedParams.body = typeof body === \"string\" ? JSON.parse(body) : body;\n\n return parsedParams;\n};\n\nexport function parseFilter(params: Record<string, any> | string, searchBy?: string[]): Filter {\n const result: Filter = {};\n\n if (searchBy && searchBy.length > 0) {\n result.searchBy = searchBy;\n }\n\n // If the params is a string (URL query string), parse it first\n let parsedParams: Record<string, any>;\n if (typeof params === \"string\") {\n parsedParams = toRecord(params, { parseDates: false });\n } else {\n parsedParams = params;\n }\n\n parsedParams.searchKeyword = getFirst(parsedParams.searchKeyword);\n\n const parseParam = (key: string, parseFunc: (value: string) => any) => {\n const value = parsedParams[key];\n if (value !== undefined && value !== null && String(value).trim() !== \"\") {\n result[key] = parseFunc(value);\n }\n };\n\n parseParam(\"page\", (value) => Number.parseInt(value, 10));\n parseParam(\"size\", (value) => Number.parseInt(value, 10));\n parseParam(\"sortBy\", (value) => value);\n parseParam(\"sort\", (value) => value as SortOrder);\n // parseParam(\"searchBy\", (value) => searchBy);\n parseParam(\"searchKeyword\", (value) => toCaseInsensitive(value));\n parseParam(\"lastKey\", (value) => value);\n parseParam(\"indexName\", (value) => value);\n parseParam(\"indexValue\", (value) => value);\n\n const parseRangeValue = (value: any) => {\n // If value is already a number, return it\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(value)) {\n return value;\n }\n\n // Convert to string for parsing\n const stringValue = String(value);\n\n // Check if it's a valid number (including decimals)\n const numberValue = Number.parseFloat(stringValue);\n if (!Number.isNaN(numberValue)) {\n // Handle zero values (both \"0\" and \"0.0\" should become 0)\n if (numberValue === 0) {\n return 0;\n }\n // Handle integer values\n if (Number.isInteger(numberValue)) {\n return Number.parseInt(stringValue, 10);\n }\n return numberValue;\n }\n\n return value;\n };\n\n // Initialize rangeFilters array\n result.rangeFilters = [];\n\n // Auto-detect range filter patterns with min_ and max_ prefixes\n for (const key in parsedParams) {\n const value = parsedParams[key];\n if (value !== undefined && value !== null && String(value).trim() !== \"\") {\n // Check for min_ and max_ patterns\n const minMatch = key.match(/^min_(.+)$/i);\n const maxMatch = key.match(/^max_(.+)$/i);\n\n if (minMatch) {\n const fieldName = minMatch[1]; // Remove .toLowerCase() to preserve case\n // Find existing range filter or create new one\n let rangeFilter = result.rangeFilters!.find((rf) => rf.fieldName === fieldName);\n if (!rangeFilter) {\n rangeFilter = { fieldName };\n result.rangeFilters!.push(rangeFilter);\n }\n rangeFilter.minValue = parseRangeValue(value);\n } else if (maxMatch) {\n const fieldName = maxMatch[1]; // Remove .toLowerCase() to preserve case\n // Find existing range filter or create new one\n let rangeFilter = result.rangeFilters!.find((rf) => rf.fieldName === fieldName);\n if (!rangeFilter) {\n rangeFilter = { fieldName };\n result.rangeFilters!.push(rangeFilter);\n }\n rangeFilter.maxValue = parseRangeValue(value);\n } else if (!(key in result)) {\n result[key] = value;\n }\n }\n }\n\n // Clean up empty rangeFilters array\n if (result.rangeFilters!.length === 0) {\n delete result.rangeFilters;\n }\n\n return result;\n}\n\nfunction smartParse(value: string): any {\n if (value.includes(\"*\")) return value;\n if (/^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(value)) {\n const parsedDate = new Date(value);\n if (!Number.isNaN(parsedDate.getTime())) {\n return parsedDate;\n }\n }\n\n // Boolean\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n\n // Integer\n if (/^-?\\d+$/.test(value)) {\n if (hasLeadingZeroInteger(value)) return value;\n return parseInt(value, 10);\n }\n\n // Float / Double\n if (/^-?\\d*\\.\\d+$/.test(value)) return parseFloat(value);\n\n if (typeof value === \"string\" && value.includes(\",\")) {\n const valueList = value.split(\",\");\n for (let i = 1; i < valueList.length; i++) {\n valueList[i] = smartParse(valueList[i]);\n }\n return valueList;\n }\n\n // Default: string\n return value;\n}\n\nfunction hasLeadingZeroInteger(value: string): boolean {\n const normalized = value.startsWith(\"-\") ? value.slice(1) : value;\n return normalized.length > 1 && normalized.startsWith(\"0\");\n}\n\nexport function toRecord(queryString: string, options?: { parseDates?: boolean }): Record<string, any> {\n const result: Record<string, any> = {};\n const pairs = queryString.split(\"&\");\n const parseDates = options?.parseDates ?? true;\n\n for (const pair of pairs) {\n const [key, value] = pair.split(\"=\");\n if (key && value !== undefined) {\n const decodedValue = decodeURIComponent(value);\n result[key] =\n !parseDates && /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?)?$/.test(decodedValue)\n ? decodedValue\n : smartParse(decodedValue);\n }\n }\n\n return result;\n}\n\nexport function findMatchedPolicy(methode: HttpMethod, path: string, policies: EndpointPolicy[]): EndpointPolicy {\n if (!methode || !path || !policies.length) {\n return null;\n }\n\n return policies.find((policy) => policy.method === methode && trimSpecialChar(policy.path) === trimSpecialChar(path));\n}\n"]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export * from "./http/http.util";
|
|
2
2
|
export * from "./http/http-request";
|
|
3
|
+
export * from "./http/api-event";
|
|
3
4
|
export * from "./array.util";
|
|
4
5
|
export * from "./auth.util";
|
|
6
|
+
export * from "./auth/caller";
|
|
7
|
+
export * from "./auth/policy-view";
|
|
5
8
|
export * from "./date.util";
|
|
6
9
|
export * from "./dynamodb.utils";
|
|
7
10
|
export * from "./env.util";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,aAAa,CAAC;AAE5B,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,aAAa,CAAC;AAE5B,cAAc,oBAAoB,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -16,8 +16,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./http/http.util"), exports);
|
|
18
18
|
__exportStar(require("./http/http-request"), exports);
|
|
19
|
+
__exportStar(require("./http/api-event"), exports);
|
|
19
20
|
__exportStar(require("./array.util"), exports);
|
|
20
21
|
__exportStar(require("./auth.util"), exports);
|
|
22
|
+
__exportStar(require("./auth/caller"), exports);
|
|
23
|
+
__exportStar(require("./auth/policy-view"), exports);
|
|
21
24
|
__exportStar(require("./date.util"), exports);
|
|
22
25
|
__exportStar(require("./dynamodb.utils"), exports);
|
|
23
26
|
__exportStar(require("./env.util"), exports);
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,sDAAoC;AACpC,+CAA6B;AAC7B,8CAA4B;AAC5B,8CAA4B;AAC5B,mDAAiC;AACjC,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,qDAAmC;AACnC,oDAAkC;AAClC,oDAAkC;AAClC,iEAA+C;AAC/C,oEAAkD;AAClD,8CAA4B;AAE5B,qDAAmC","sourcesContent":["export * from \"./http/http.util\";\nexport * from \"./http/http-request\";\nexport * from \"./array.util\";\nexport * from \"./auth.util\";\nexport * from \"./date.util\";\nexport * from \"./dynamodb.utils\";\nexport * from \"./env.util\";\nexport * from \"./error.util\";\nexport * from \"./json.util\";\nexport * from \"./opensearch.utils\";\nexport * from \"./reflection.util\";\nexport * from \"./validation.util\";\nexport * from \"./opensearch/opensearch.parser\";\nexport * from \"./opensearch/opensearch.transform\";\nexport * from \"./data.util\";\n\nexport * from \"../function/logger\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,sDAAoC;AACpC,mDAAiC;AACjC,+CAA6B;AAC7B,8CAA4B;AAC5B,gDAA8B;AAC9B,qDAAmC;AACnC,8CAA4B;AAC5B,mDAAiC;AACjC,6CAA2B;AAC3B,+CAA6B;AAC7B,8CAA4B;AAC5B,qDAAmC;AACnC,oDAAkC;AAClC,oDAAkC;AAClC,iEAA+C;AAC/C,oEAAkD;AAClD,8CAA4B;AAE5B,qDAAmC","sourcesContent":["export * from \"./http/http.util\";\nexport * from \"./http/http-request\";\nexport * from \"./http/api-event\";\nexport * from \"./array.util\";\nexport * from \"./auth.util\";\nexport * from \"./auth/caller\";\nexport * from \"./auth/policy-view\";\nexport * from \"./date.util\";\nexport * from \"./dynamodb.utils\";\nexport * from \"./env.util\";\nexport * from \"./error.util\";\nexport * from \"./json.util\";\nexport * from \"./opensearch.utils\";\nexport * from \"./reflection.util\";\nexport * from \"./validation.util\";\nexport * from \"./opensearch/opensearch.parser\";\nexport * from \"./opensearch/opensearch.transform\";\nexport * from \"./data.util\";\n\nexport * from \"../function/logger\";\n"]}
|
|
@@ -2,8 +2,9 @@ import { AggTypeOS } from "../../model/index.js";
|
|
|
2
2
|
export interface AggInstruction {
|
|
3
3
|
type: AggTypeOS;
|
|
4
4
|
field: string;
|
|
5
|
+
name?: string;
|
|
5
6
|
sub?: string;
|
|
6
7
|
}
|
|
7
|
-
export declare function buildAggregations(params: Record<string, string>):
|
|
8
|
+
export declare function buildAggregations(params: Record<string, string>): Record<string, any>;
|
|
8
9
|
export declare function buildNativeOSQuery(instructions: AggInstruction[]): any;
|
|
9
10
|
//# sourceMappingURL=opensearch.parser.aggs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opensearch.parser.aggs.d.ts","sourceRoot":"","sources":["../../../src/utils/opensearch/opensearch.parser.aggs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"opensearch.parser.aggs.d.ts","sourceRoot":"","sources":["../../../src/utils/opensearch/opensearch.parser.aggs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAsCrF;AAmDD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,cAAc,EAAE,OAqBhE"}
|
|
@@ -38,6 +38,7 @@ function buildAggregations(params) {
|
|
|
38
38
|
instructions.push({
|
|
39
39
|
type,
|
|
40
40
|
field: value,
|
|
41
|
+
name: parts[2],
|
|
41
42
|
});
|
|
42
43
|
continue;
|
|
43
44
|
}
|
|
@@ -59,13 +60,41 @@ function buildQuery(type, field) {
|
|
|
59
60
|
// ----------------------------
|
|
60
61
|
// Build final aggregations
|
|
61
62
|
// ----------------------------
|
|
63
|
+
/**
|
|
64
|
+
* The response key for one instruction.
|
|
65
|
+
*
|
|
66
|
+
* Metric aggregations used to be keyed by their field alone, so asking for the min and the max
|
|
67
|
+
* of one field in a single request silently produced a single aggregation - whichever came last
|
|
68
|
+
* won, and the caller read the same number for both bounds. A metric is keyed by the name the
|
|
69
|
+
* caller supplied in `agg__<type>__<name>`, or by `<field>__<type>` when it supplied none.
|
|
70
|
+
* Terms and tree aggregations keep their existing field-based keys.
|
|
71
|
+
*/
|
|
72
|
+
function resolveAggName(inst) {
|
|
73
|
+
if (inst.type === types_1.AggTypeOS.TREE)
|
|
74
|
+
return inst.field.split(",")[0];
|
|
75
|
+
if (inst.type === types_1.AggTypeOS.TERMS)
|
|
76
|
+
return inst.field;
|
|
77
|
+
return inst.name ?? `${inst.field}__${inst.type}`;
|
|
78
|
+
}
|
|
79
|
+
/** Metrics that are the only one on their field also answer to the old bare-field key. */
|
|
80
|
+
function legacyMetricNames(instructions) {
|
|
81
|
+
const byField = new Map();
|
|
82
|
+
for (const inst of instructions) {
|
|
83
|
+
if (inst.type === types_1.AggTypeOS.TERMS || inst.type === types_1.AggTypeOS.TREE)
|
|
84
|
+
continue;
|
|
85
|
+
byField.set(inst.field, [...(byField.get(inst.field) ?? []), inst]);
|
|
86
|
+
}
|
|
87
|
+
const unambiguous = new Map();
|
|
88
|
+
for (const [field, forField] of byField) {
|
|
89
|
+
if (forField.length === 1)
|
|
90
|
+
unambiguous.set(field, forField[0]);
|
|
91
|
+
}
|
|
92
|
+
return unambiguous;
|
|
93
|
+
}
|
|
62
94
|
function buildNativeOSQuery(instructions) {
|
|
63
95
|
const aggs = {};
|
|
64
96
|
for (const inst of instructions) {
|
|
65
|
-
|
|
66
|
-
if (inst.type === types_1.AggTypeOS.TREE) {
|
|
67
|
-
aggName = inst.field.split(",")[0];
|
|
68
|
-
}
|
|
97
|
+
const aggName = resolveAggName(inst);
|
|
69
98
|
aggs[aggName] = buildQuery(inst.type, inst.field);
|
|
70
99
|
if (inst.sub && aggs[aggName]) {
|
|
71
100
|
aggs[aggName].aggs = {
|
|
@@ -73,6 +102,11 @@ function buildNativeOSQuery(instructions) {
|
|
|
73
102
|
};
|
|
74
103
|
}
|
|
75
104
|
}
|
|
105
|
+
for (const [field, inst] of legacyMetricNames(instructions)) {
|
|
106
|
+
if (aggs[field])
|
|
107
|
+
continue;
|
|
108
|
+
aggs[field] = buildQuery(inst.type, inst.field);
|
|
109
|
+
}
|
|
76
110
|
return aggs;
|
|
77
111
|
}
|
|
78
112
|
function buildTreeQuery(tree) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opensearch.parser.aggs.js","sourceRoot":"","sources":["../../../src/utils/opensearch/opensearch.parser.aggs.ts"],"names":[],"mappings":";AAAA,wCAAwC;AACxC,4CAA4C;AAC5C,wCAAwC;;;;AAExC,2CAA4C;
|
|
1
|
+
{"version":3,"file":"opensearch.parser.aggs.js","sourceRoot":"","sources":["../../../src/utils/opensearch/opensearch.parser.aggs.ts"],"names":[],"mappings":"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","sourcesContent":["// =====================================\n// AGG BUILDER (MULTI ROOT + 1 SUB PER ROOT)\n// =====================================\n\nimport { AggTypeOS } from \"@chinggis/types\";\n\nexport interface AggInstruction {\n type: AggTypeOS;\n field: string;\n name?: string; // caller-supplied from agg__<type>__<name>\n sub?: string; // only for agg__xxx__sub\n}\n\n// ----------------------------\n// Parse aggregations\n// ----------------------------\nexport function buildAggregations(params: Record<string, string>): Record<string, any> {\n const instructions: AggInstruction[] = [];\n\n for (const [key, value] of Object.entries(params)) {\n if (!key.startsWith(\"agg__\")) continue;\n\n const parts = key.split(\"__\"); // [\"agg\", \"terms\", \"sub\"?]\n const type = parts[1] as AggTypeOS;\n\n if (!Object.values(AggTypeOS).includes(type)) continue;\n\n // root = agg__terms=status\n if (parts.length === 2) {\n instructions.push({\n type,\n field: value,\n });\n continue;\n }\n\n // sub = agg__terms__sub=customerId\n if (parts.length === 3 && parts[2] === \"sub\") {\n // attach to last root\n const lastRoot = instructions.find((i) => i.type === type && !i.sub);\n\n if (lastRoot) lastRoot.sub = value;\n continue;\n } else {\n instructions.push({\n type,\n field: value,\n name: parts[2],\n });\n continue;\n }\n }\n\n return buildNativeOSQuery(instructions);\n}\n\n// ----------------------------\n// Build ES agg object\n// ----------------------------\nfunction buildQuery(type: AggTypeOS, field: string) {\n if (type === AggTypeOS.TERMS)\n return {\n [AggTypeOS.TERMS]: { size: 1000, field: field },\n };\n\n if (type === AggTypeOS.TREE) return buildTreeQuery(field);\n return { [type]: { field: field } };\n}\n\n// ----------------------------\n// Build final aggregations\n// ----------------------------\n/**\n * The response key for one instruction.\n *\n * Metric aggregations used to be keyed by their field alone, so asking for the min and the max\n * of one field in a single request silently produced a single aggregation - whichever came last\n * won, and the caller read the same number for both bounds. A metric is keyed by the name the\n * caller supplied in `agg__<type>__<name>`, or by `<field>__<type>` when it supplied none.\n * Terms and tree aggregations keep their existing field-based keys.\n */\nfunction resolveAggName(inst: AggInstruction): string {\n if (inst.type === AggTypeOS.TREE) return inst.field.split(\",\")[0];\n if (inst.type === AggTypeOS.TERMS) return inst.field;\n\n return inst.name ?? `${inst.field}__${inst.type}`;\n}\n\n/** Metrics that are the only one on their field also answer to the old bare-field key. */\nfunction legacyMetricNames(instructions: AggInstruction[]): Map<string, AggInstruction> {\n const byField = new Map<string, AggInstruction[]>();\n\n for (const inst of instructions) {\n if (inst.type === AggTypeOS.TERMS || inst.type === AggTypeOS.TREE) continue;\n byField.set(inst.field, [...(byField.get(inst.field) ?? []), inst]);\n }\n\n const unambiguous = new Map<string, AggInstruction>();\n for (const [field, forField] of byField) {\n if (forField.length === 1) unambiguous.set(field, forField[0]);\n }\n\n return unambiguous;\n}\n\nexport function buildNativeOSQuery(instructions: AggInstruction[]) {\n const aggs: any = {};\n\n for (const inst of instructions) {\n const aggName = resolveAggName(inst);\n\n aggs[aggName] = buildQuery(inst.type, inst.field);\n\n if (inst.sub && aggs[aggName]) {\n aggs[aggName].aggs = {\n [inst.sub]: buildQuery(inst.type, inst.sub),\n };\n }\n }\n\n for (const [field, inst] of legacyMetricNames(instructions)) {\n if (aggs[field]) continue;\n aggs[field] = buildQuery(inst.type, inst.field);\n }\n\n return aggs;\n}\n\nfunction buildTreeQuery(tree: string) {\n let include = \".*\\\\/.*\";\n let exclude = \".*\\\\/.*\\\\/.*\";\n const [field, treeValue] = tree.split(\",\");\n\n if (treeValue) {\n let level = treeValue.split(\"/\").length;\n include = treeValue + include;\n\n if (level > 1) {\n include = treeValue + \".*\\\\/.*\";\n exclude = \"\";\n }\n\n return {\n terms: {\n field: `${field}.tree`,\n include: include,\n exclude: exclude,\n size: 300,\n },\n };\n } else {\n return {\n terms: {\n field: `${field}.tree`,\n exclude: exclude,\n size: 300,\n },\n };\n }\n}\n"]}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { ChangedField, DynamoIndexMap, Filter, TraceChange } from "../model/index.js";
|
|
2
|
+
/** Tags a forced-view array (non-enumerable, survives object spreads) and returns it */
|
|
3
|
+
export declare function markForcedIn<T extends unknown[]>(values: T): T;
|
|
4
|
+
/** True for an array marked by markForcedIn */
|
|
5
|
+
export declare function isForcedIn(value: unknown): boolean;
|
|
2
6
|
export declare const hasField: (obj: object, fieldName: string) => boolean;
|
|
3
7
|
export declare function isMethodeHasKeyword(methodName: string, keywords: string[]): boolean;
|
|
4
8
|
export declare function handleRangeFilters(filter: Filter): Filter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reflection.util.d.ts","sourceRoot":"","sources":["../../src/utils/reflection.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAiB,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"reflection.util.d.ts","sourceRoot":"","sources":["../../src/utils/reflection.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAiB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAOnG,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAG9D;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElD;AAED,eAAO,MAAM,QAAQ,QAAS,MAAM,aAAa,MAAM,KAAG,OAEzD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAGnF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6CzD;AAoDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAkD3F;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,uBAS5E;AAKD,eAAO,MAAM,aAAa,WAAY,GAAG,aAAa,MAAM,EAAE,KAAG,GAehE,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,GAAG,iBAAiB,MAAM,eAAe,MAAM,KAAG,GAGnF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CA8BpH;AA8BD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAU5C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAoB/C;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,WAAW,EAAE,WAAW,GACvB,YAAY,EAAE,CAShB;AAiJD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAU7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA0BvD"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.copyField = exports.fieldsInclude = exports.hasField = void 0;
|
|
4
|
+
exports.markForcedIn = markForcedIn;
|
|
5
|
+
exports.isForcedIn = isForcedIn;
|
|
4
6
|
exports.isMethodeHasKeyword = isMethodeHasKeyword;
|
|
5
7
|
exports.handleRangeFilters = handleRangeFilters;
|
|
6
8
|
exports.parseIndexFilter = parseIndexFilter;
|
|
@@ -14,6 +16,17 @@ exports.pickDefinedDeep = pickDefinedDeep;
|
|
|
14
16
|
const types_1 = require("../model/index.js");
|
|
15
17
|
const http_util_1 = require("./http/http.util");
|
|
16
18
|
const string_util_1 = require("./string.util");
|
|
19
|
+
/** Marks an array that comes from a forced policy-view key (an IN list that must never become an index key) */
|
|
20
|
+
const FORCED_IN = Symbol.for("aws-service-stack.forcedIn");
|
|
21
|
+
/** Tags a forced-view array (non-enumerable, survives object spreads) and returns it */
|
|
22
|
+
function markForcedIn(values) {
|
|
23
|
+
Object.defineProperty(values, FORCED_IN, { value: true, enumerable: false });
|
|
24
|
+
return values;
|
|
25
|
+
}
|
|
26
|
+
/** True for an array marked by markForcedIn */
|
|
27
|
+
function isForcedIn(value) {
|
|
28
|
+
return Array.isArray(value) && value[FORCED_IN] === true;
|
|
29
|
+
}
|
|
17
30
|
const hasField = (obj, fieldName) => {
|
|
18
31
|
return Object.hasOwn(obj, fieldName);
|
|
19
32
|
};
|
|
@@ -119,6 +132,10 @@ function parseIndexFilter(filter, indexMap) {
|
|
|
119
132
|
const allFieldsPresent = rFields.every((field) => Object.hasOwn(filter, field));
|
|
120
133
|
if (!allFieldsPresent)
|
|
121
134
|
continue;
|
|
135
|
+
// A forced-view array (IN list) cannot be a key condition: joined it would query one bogus key.
|
|
136
|
+
// It stays in the filter expression as an IN condition. Other arrays keep the joined index value.
|
|
137
|
+
if ([...rFields, sortKeyField].some((field) => field && isForcedIn(filter[field])))
|
|
138
|
+
continue;
|
|
122
139
|
const hasSortField = !!sortKeyField && Object.hasOwn(filter, sortKeyField);
|
|
123
140
|
const bestIndexInfo = bestMatch ? indexMap.get(bestMatch.indexName) : undefined;
|
|
124
141
|
const bestHasSortField = !!bestIndexInfo?.sortKeyField && Object.hasOwn(filter, bestIndexInfo.sortKeyField);
|