aws-service-stack 0.18.325 → 0.18.327
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 +57 -18
- package/dist/utils/dynamodb.utils.js +4 -2
- package/dist/utils/dynamodb.utils.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ npm install aws-service-stack
|
|
|
49
49
|
This package requires the following AWS SDK v3 packages as peer dependencies:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
npm install
|
|
52
|
+
npm install
|
|
53
53
|
@aws-sdk/client-dynamodb
|
|
54
54
|
@aws-sdk/client-cognito-identity-provider
|
|
55
55
|
@aws-sdk/client-secrets-manager
|
|
@@ -84,7 +84,6 @@ export class ProductControllerApi extends ControllerApi<Product, ProductService>
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
|
|
88
87
|
```
|
|
89
88
|
|
|
90
89
|
### 2. Entity Configuration
|
|
@@ -138,7 +137,6 @@ export class ProductConfig extends EntityConfigImpl {
|
|
|
138
137
|
|
|
139
138
|
// Export default Product configuration
|
|
140
139
|
export const CONFIG_PRODUCT = new ProductConfig();
|
|
141
|
-
|
|
142
140
|
```
|
|
143
141
|
|
|
144
142
|
### 3. Repository Definition - DynamoDB
|
|
@@ -151,8 +149,7 @@ import { ProductRepoDB } from "./product-repo-db.interface";
|
|
|
151
149
|
import "./product-repo-db";
|
|
152
150
|
|
|
153
151
|
@Service("ProductRepoDB")
|
|
154
|
-
export class ProductRepoDBImpl extends BaseRepoDBImpl<Product> implements ProductRepoDB {
|
|
155
|
-
}
|
|
152
|
+
export class ProductRepoDBImpl extends BaseRepoDBImpl<Product> implements ProductRepoDB {}
|
|
156
153
|
|
|
157
154
|
/** additional custom repo methode for dynamodb integration**/
|
|
158
155
|
//...
|
|
@@ -168,8 +165,7 @@ import { ProductRepoES } from "./product-repo-es.interface";
|
|
|
168
165
|
import "./product-repo-es";
|
|
169
166
|
|
|
170
167
|
@Service("ProductRepoES")
|
|
171
|
-
export class ProductRepoESImpl extends BaseRepoESImpl<Product> implements ProductRepoES {
|
|
172
|
-
}
|
|
168
|
+
export class ProductRepoESImpl extends BaseRepoESImpl<Product> implements ProductRepoES {}
|
|
173
169
|
|
|
174
170
|
/** additional custom repo methode for openSearch integration**/
|
|
175
171
|
//...
|
|
@@ -189,14 +185,16 @@ import { CrudServiceImpl } from "@chinggis/core";
|
|
|
189
185
|
import { Product } from "../model-shared/example.model";
|
|
190
186
|
|
|
191
187
|
@Service("ProfileService")
|
|
192
|
-
export class ProductServiceImpl
|
|
188
|
+
export class ProductServiceImpl
|
|
189
|
+
extends CrudServiceImpl<Product, ProductRepoDB, ProductRepoES>
|
|
190
|
+
implements ProductService
|
|
191
|
+
{
|
|
193
192
|
constructor() {
|
|
194
193
|
super(Container.get("ProductRepoDB"), Container.get("ProductRepoES"));
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
/** Custom service methode **/
|
|
198
197
|
//...
|
|
199
|
-
|
|
200
198
|
}
|
|
201
199
|
```
|
|
202
200
|
|
|
@@ -211,6 +209,7 @@ POST /products # Insert new product (create)
|
|
|
211
209
|
GET /products/{id} # Get single product by ID
|
|
212
210
|
GET /products # List products via DynamoDB Query (by categoryId, ProductId, status, …)
|
|
213
211
|
GET /products/search # Search products via OpenSearch (full-text, sort, pagination)
|
|
212
|
+
GET /products/search/query # Search Query products via OpenSearch (aggregations, multi-filters, full-text, sort, pagination)
|
|
214
213
|
GET /products/scan # Scan all products (Admin only, expensive in DynamoDB)
|
|
215
214
|
PUT /products/{id} # Update full product (replace all fields)
|
|
216
215
|
PATCH /products/{id} # Update partial product (only specific fields)
|
|
@@ -233,10 +232,50 @@ dynamoDB: .../products/?category=Toys&color=red&age_from=5&age_to=8&size=50&la
|
|
|
233
232
|
- **[customFieldName]**=[matchValue]
|
|
234
233
|
- **size**=20
|
|
235
234
|
- **page**=3 or **lastKey**=...
|
|
236
|
-
- **[dateOrNumberFieldName]_from**=[Value]
|
|
237
|
-
- **[dateOrNumberFieldName]_to**=[Value]
|
|
238
|
-
- **
|
|
239
|
-
- **
|
|
235
|
+
- **[dateOrNumberFieldName]\_from**=[Value]
|
|
236
|
+
- **[dateOrNumberFieldName]\_to**=[Value]
|
|
237
|
+
- **begin\_[dateOrNumberFieldName]**=[Value]
|
|
238
|
+
- **end\_[dateOrNumberFieldName]**=[Value]
|
|
239
|
+
|
|
240
|
+
### **OpenSearch V2 List Operation - URL Filter**
|
|
241
|
+
|
|
242
|
+
multi-filter, aggregations, search keyword, multi-sort
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
openSearch v2: .../products/search/query?category__eq=Toys&color__in=red,yellow&age__gte=5&age__lte=8&page=5&size=50&agg__terms=status&agg__terms__sub=customerId
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
- **field\_\_in**=red,yellow
|
|
249
|
+
- **field\_\_eq**=Toys
|
|
250
|
+
- **field\_\_gte**=5
|
|
251
|
+
- **field\_\_lte**=8
|
|
252
|
+
- **field\_\_ne**=Book
|
|
253
|
+
- **field\_\_exists**=true
|
|
254
|
+
- **field\_\_exists**=false
|
|
255
|
+
- **field\_\_regex**=^Foo.\*
|
|
256
|
+
|
|
257
|
+
- **agg\_\_terms**=status
|
|
258
|
+
- **agg\_\_terms\_\_sub**=customerId
|
|
259
|
+
- **agg\_\_sum**=price
|
|
260
|
+
- **agg\_\_avg**=price
|
|
261
|
+
- **agg\_\_min**=price
|
|
262
|
+
- **agg\_\_max**=price
|
|
263
|
+
|
|
264
|
+
- **search**=marvel
|
|
265
|
+
- **searchFields**=name,manufacture,description
|
|
266
|
+
- **searchOperator**=or
|
|
267
|
+
- **searchOperator**=and
|
|
268
|
+
|
|
269
|
+
- **sort**=desc,asc
|
|
270
|
+
- **sortField**=price,category
|
|
271
|
+
|
|
272
|
+
- **color\_\_in**=red,yellow
|
|
273
|
+
- **category\_\_eq**=Toys
|
|
274
|
+
- **status\_\_exists**=true
|
|
275
|
+
- **age\_\_gte**=5
|
|
276
|
+
- **age\_\_lte**=8
|
|
277
|
+
- **size**=20
|
|
278
|
+
- **page**=3
|
|
240
279
|
|
|
241
280
|
### **Advanced Features**
|
|
242
281
|
|
|
@@ -372,12 +411,12 @@ functions:
|
|
|
372
411
|
### AWS CDK
|
|
373
412
|
|
|
374
413
|
```typescript
|
|
375
|
-
import { Function, Runtime } from
|
|
414
|
+
import { Function, Runtime } from "aws-cdk-lib/aws-lambda";
|
|
376
415
|
|
|
377
|
-
new Function(this,
|
|
416
|
+
new Function(this, "MyFunction", {
|
|
378
417
|
runtime: Runtime.NODEJS_18_X,
|
|
379
|
-
handler:
|
|
380
|
-
code: Code.fromAsset(
|
|
418
|
+
handler: "dist/handler.handler",
|
|
419
|
+
code: Code.fromAsset("dist"),
|
|
381
420
|
});
|
|
382
421
|
```
|
|
383
422
|
|
|
@@ -422,4 +461,4 @@ Built by [Chinggis Systems](https://chinggis.systems) - Enterprise software solu
|
|
|
422
461
|
|
|
423
462
|
---
|
|
424
463
|
|
|
425
|
-
**Made with ❤️ for the AWS community**
|
|
464
|
+
**Made with ❤️ for the AWS community**
|
|
@@ -208,8 +208,10 @@ exports.buildDynamoDBQueryCommand = buildDynamoDBQueryCommand;
|
|
|
208
208
|
const generateIndexValues = (input, indexMap) => {
|
|
209
209
|
const result = { ...input };
|
|
210
210
|
for (const [, { field, rFields, fieldSeparator }] of indexMap.entries()) {
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
const definedValues = rFields.filter((key) => input[key] !== undefined).map((key) => input[key]);
|
|
212
|
+
if (definedValues.length > 0) {
|
|
213
|
+
result[field] = definedValues.join(fieldSeparator ?? "");
|
|
214
|
+
}
|
|
213
215
|
}
|
|
214
216
|
return result;
|
|
215
217
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamodb.utils.js","sourceRoot":"","sources":["../../src/utils/dynamodb.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AttributeValue, QueryCommandInput, ScanCommandInput } from \"@aws-sdk/client-dynamodb\";\nimport { marshall, unmarshall } from \"@aws-sdk/util-dynamodb\";\nimport { excludeKeys } from \"./reflection.util\";\nimport { ErrorDynamoDB, MissingParameterError } from \"../exception/errors\";\nimport { Filter, SortOrder } from \"../model\";\nimport { ActionDynamoDB, DynamoIndexMap } from \"../model/dynamodb.model\";\n\nexport const generateUUID = (): string => {\n return crypto.randomUUID();\n};\n\nexport const buildDynamoDBFilterConditions = (filter: Filter, indexMap: DynamoIndexMap): FilterExpression => {\n if (!filter) throw new MissingParameterError(\"filter\");\n\n const rFields = indexMap.get(filter.indexName)?.rFields ?? [];\n\n const ignoredKeys = [\n ...rFields,\n \"page\",\n \"size\",\n \"sortBy\",\n \"sort\",\n \"searchBy\",\n \"searchKeyword\",\n \"rangeFilterBy\",\n \"rangeFilterMin\",\n \"rangeFilterMax\",\n \"lastKey\",\n \"indexName\",\n \"indexValue\",\n \"fieldsInclude\",\n \"fieldsExclude\",\n ];\n\n const dynamicFilters = excludeKeys(filter, ignoredKeys);\n\n const expressions: string[] = [];\n const attrNames: Record<string, string> = {};\n const attrValues: Record<string, any> = {};\n\n let counter = 0;\n\n const genPlaceholder = (key: string) => {\n const safeKey = key.replace(/\\W+/g, \"_\");\n return {\n name: `#${safeKey}_${counter}`,\n value: `:${safeKey}_val_${counter++}`,\n };\n };\n\n // Range Filter\n if (filter.rangeFilterBy) {\n const key = filter.rangeFilterBy;\n const { name, value } = genPlaceholder(key);\n\n attrNames[name] = key;\n\n if (filter.rangeFilterMin !== undefined && filter.rangeFilterMax !== undefined) {\n attrValues[value + \"_min\"] = filter.rangeFilterMin;\n attrValues[value + \"_max\"] = filter.rangeFilterMax;\n expressions.push(`${name} BETWEEN ${value}_min AND ${value}_max`);\n } else if (filter.rangeFilterMin !== undefined) {\n attrValues[value] = filter.rangeFilterMin;\n expressions.push(`${name} >= ${value}`);\n } else if (filter.rangeFilterMax !== undefined) {\n attrValues[value] = filter.rangeFilterMax;\n expressions.push(`${name} <= ${value}`);\n }\n }\n\n // Search Filter\n if (filter.searchBy && filter.searchKeyword) {\n const fields = Array.isArray(filter.searchBy) ? filter.searchBy : [filter.searchBy];\n\n for (const key of fields) {\n const { name, value } = genPlaceholder(key);\n\n attrNames[name] = key;\n attrValues[value] = filter.searchKeyword;\n\n expressions.push(`contains(${name}, ${value})`);\n }\n }\n\n // General filters\n for (const [key, raw] of Object.entries(dynamicFilters)) {\n if (key === \"lastKey\") continue;\n const value = String(raw);\n const { name, value: valName } = genPlaceholder(key);\n attrNames[name] = key;\n\n if (value.startsWith(\"*\") && value.endsWith(\"*\")) {\n attrValues[valName] = checkFieldType(key, value.slice(1, -1), indexMap);\n expressions.push(`contains(${name}, ${valName})`);\n } else if (!value.startsWith(\"*\") && value.endsWith(\"*\")) {\n attrValues[valName] = checkFieldType(key, value.slice(0, -1), indexMap);\n expressions.push(`begins_with(${name}, ${valName})`);\n } else if (value.startsWith(\"!\")) {\n attrValues[valName] = checkFieldType(key, value.slice(1), indexMap);\n expressions.push(`${name} <> ${valName}`);\n } else if (value.includes(\",\")) {\n const values = value.split(\",\").map((v) => v.trim());\n const placeholders: string[] = [];\n\n values.forEach((v, i) => {\n const subVal = `${valName}_${i}`;\n attrValues[subVal] = checkFieldType(key, v, indexMap);\n placeholders.push(subVal);\n });\n\n expressions.push(`${name} IN (${placeholders.join(\", \")})`);\n } else {\n attrValues[valName] = checkFieldType(key, value, indexMap);\n expressions.push(`${name} = ${valName}`);\n }\n }\n\n if (expressions.length === 0) return {};\n\n return {\n filter: expressions.join(\" AND \"),\n attributeNames: attrNames,\n attributeValues: attrValues,\n };\n};\n\nexport const buildQueryDB = (\n tableName: string,\n filter: Filter,\n indexMap: DynamoIndexMap,\n): QueryCommandInput | ScanCommandInput => {\n if (!tableName || !filter) throw new MissingParameterError(\"tableName or filter\");\n\n const filterCondition: any = buildDynamoDBFilterConditions(filter, indexMap);\n const indexField = indexMap.get(filter.indexName)?.field;\n\n if (indexField) {\n return buildDynamoDBQueryCommand({\n filterCondition,\n tableName,\n filter,\n indexMap,\n });\n }\n return buildDynamoDBScanCommand({\n tableName,\n filter,\n expression: filterCondition,\n });\n};\n\nexport const buildDynamoDBScanCommand = ({\n tableName,\n filter,\n expression,\n}: {\n tableName: string;\n filter?: Filter;\n expression?: FilterExpression;\n}): ScanCommandInput => {\n const scanCommand: ScanCommandInput = { TableName: tableName, Limit: filter?.size ?? 25 };\n\n if (filter?.lastKey && filter.lastKey != \"undefined\")\n scanCommand.ExclusiveStartKey = parseLastEvaluatedKey(filter.lastKey);\n if (isEmptyExpressions(expression)) return scanCommand;\n\n scanCommand.FilterExpression = expression.filter;\n scanCommand.ExpressionAttributeNames = expression.attributeNames;\n scanCommand.ExpressionAttributeValues = marshall(expression.attributeValues, {\n convertClassInstanceToMap: true,\n removeUndefinedValues: true,\n });\n\n return scanCommand;\n};\n\nexport const buildDynamoDBQueryCommand = ({\n filter,\n tableName,\n filterCondition,\n indexMap,\n}: {\n filterCondition: FilterExpression;\n tableName: string;\n filter?: Filter;\n indexMap: DynamoIndexMap;\n}): QueryCommandInput => {\n if (!filter.indexName) throw new Error(\"Missing indexName in filter\");\n if (filter.indexValue === undefined || filter.indexValue === null) throw new Error(\"Missing indexValue in filter\");\n\n const indexInfo = indexMap.get(filter.indexName);\n if (!indexInfo) throw new Error(`Index info not found for index: ${filter.indexName}`);\n\n const attr = indexInfo.field;\n const value = filter.indexValue;\n\n const attrKey = `#${attr}`;\n const valueKey = `:${attr}`;\n\n const keyConditionExpression = `${attrKey} = ${valueKey}`;\n\n const expressionAttributeNames: Record<string, string> = {\n [attrKey]: attr,\n };\n\n const expressionAttributeValues: Record<string, AttributeValue> = {\n [valueKey]: marshall({ val: value }).val,\n };\n\n if (filterCondition?.filter) {\n if (filterCondition.attributeNames) {\n Object.assign(expressionAttributeNames, filterCondition.attributeNames);\n }\n if (filterCondition.attributeValues) {\n const marshalled = marshall(filterCondition.attributeValues, {\n convertClassInstanceToMap: true,\n removeUndefinedValues: true,\n });\n Object.assign(expressionAttributeValues, marshalled);\n }\n }\n\n const queryCommand: QueryCommandInput = {\n TableName: tableName,\n IndexName: filter.indexName,\n KeyConditionExpression: keyConditionExpression,\n FilterExpression: filterCondition?.filter,\n ExpressionAttributeNames: expressionAttributeNames,\n ExpressionAttributeValues: expressionAttributeValues,\n Limit: filter?.size ?? 25,\n ScanIndexForward: filter.sort === SortOrder.ASC,\n };\n\n if (filter.lastKey) {\n queryCommand.ExclusiveStartKey = parseLastEvaluatedKey(filter.lastKey);\n }\n\n return queryCommand;\n};\nexport const generateIndexValues = (input: Record<string, any>, indexMap: DynamoIndexMap) => {\n const result: Record<string, string> = { ...input };\n\n for (const [, { field, rFields, fieldSeparator }] of indexMap.entries()) {\n if (rFields.every((key) => key in input))\n result[field] = rFields.map((key) => input[key]).join(fieldSeparator ?? \"\");\n }\n\n return result;\n};\n\nexport const addIndexValue = (entity: Record<string, any>, indexMap: DynamoIndexMap) => {\n if (!indexMap) return entity;\n\n const relatedIndexFields = Array.from(indexMap.values())\n .flatMap((v) => v.rFields)\n .filter((x) => !!x);\n\n if (!relatedIndexFields || relatedIndexFields.length <= 1) return entity;\n\n const indexedValues = generateIndexValues(entity, indexMap);\n return Object.assign(entity, indexedValues);\n};\nexport const validateEntityForUpdateFields = (\n entity: Record<string, any>,\n fieldNames: string[],\n tableName?: string,\n): boolean => {\n for (const field of fieldNames) {\n if (!(field in entity) || entity[field] === undefined || entity[field] === null) {\n throw new ErrorDynamoDB(tableName || \"UnknownTable\", `Entity must have value in field ${field}`);\n }\n }\n return false;\n};\n\nexport const addIndexField = (fieldNames: string[], indexMap: DynamoIndexMap): string[] => {\n // snapshot of original fields to avoid cascading through newly added fields\n const originalFields = new Set(fieldNames);\n\n // Ensure audit fields exist and are at the front in fixed order\n // Remove existing occurrences to avoid duplicates then unshift in the desired order\n for (const auditField of [\"updatedAt\", \"updatedBy\"]) {\n const idx = fieldNames.indexOf(auditField);\n if (idx !== -1) fieldNames.splice(idx, 1);\n }\n fieldNames.unshift(\"updatedBy\");\n fieldNames.unshift(\"updatedAt\");\n\n if (!indexMap) return fieldNames;\n\n // Consider only groups with more than one field\n const groups: string[][] = Array.from(indexMap.values())\n .map((v) => v.rFields?.filter(Boolean) ?? [])\n .filter((r) => r.length > 1);\n\n if (groups.length === 0) return fieldNames;\n\n // For each group, if any member existed in the ORIGINAL set, insert the missing members\n for (const rFields of groups) {\n const hasSeed = rFields.some((f) => originalFields.has(f));\n if (!hasSeed) continue;\n\n // Anchor insertion before the earliest occurrence of any ORIGINAL member of this group\n const anchorIndex = (() => {\n let minIdx = Number.POSITIVE_INFINITY;\n for (const f of rFields) {\n if (!originalFields.has(f)) continue;\n const idx = fieldNames.indexOf(f);\n if (idx !== -1 && idx < minIdx) minIdx = idx;\n }\n return isFinite(minIdx) ? minIdx : -1;\n })();\n\n // If no anchor found in the current array, skip\n if (anchorIndex === -1) continue;\n\n // Insert missing fields in the order defined by rFields before the anchor\n let insertAt = anchorIndex;\n for (const f of rFields) {\n if (originalFields.has(f)) continue; // only add fields that weren't originally present\n if (fieldNames.includes(f)) continue; // avoid duplicates anyway\n fieldNames.splice(insertAt, 0, f);\n insertAt += 1;\n }\n }\n\n return fieldNames;\n};\n\nexport function unMarshall<T>(dataRecords: Record<string, AttributeValue>[]): Array<T> {\n return dataRecords.map((data) => unmarshall(data) as T);\n}\n\nexport const isEmptyExpression = ({\n expression,\n}: {\n expression?: {\n FilterExpression?: string;\n ExpressionAttributeNames?: Record<string, string>;\n ExpressionAttributeValues?: Record<string, any>;\n };\n}): boolean => {\n if (!expression) return true;\n\n const { FilterExpression, ExpressionAttributeNames, ExpressionAttributeValues } = expression;\n\n const isEmptyObject = (obj?: object) => !obj || Object.keys(obj).length === 0;\n\n return !FilterExpression || isEmptyObject(ExpressionAttributeNames) || isEmptyObject(ExpressionAttributeValues);\n};\n\nexport function isEmptyExpressions(exp: FilterExpression) {\n const isEmptyObject = (obj?: object) => !obj || Object.keys(obj).length === 0;\n\n return !exp.filter || isEmptyObject(exp.attributeNames) || isEmptyObject(exp.attributeValues);\n}\n\nexport interface FilterExpression {\n filter?: string;\n attributeNames?: Record<string, string>;\n attributeValues?: Record<string, any>;\n}\n\nexport const checkFieldType = (key: string, value: string, indexMap: DynamoIndexMap): number | string => {\n if (indexMap?.numberFields && indexMap?.numberFields?.length > 0) {\n for (const field of indexMap.numberFields) {\n if (!field.includes(key)) continue;\n const numValue = Number(value);\n return isNaN(numValue) ? value : numValue;\n }\n }\n\n return value;\n};\n\nexport interface UpdateExpression {\n UpdateExpression: string;\n ExpressionAttributeNames: Record<string, string>;\n ExpressionAttributeValues: Record<string, any>;\n}\n\nexport function buildUpdateExpressions(data: Record<string, any>, excludeKeys: string[] = []): UpdateExpression {\n const updateParts: string[] = [];\n const names: Record<string, string> = {};\n const values: Record<string, any> = {};\n\n Object.entries(data).forEach(([key, value], idx) => {\n if (!excludeKeys.includes(key) && value !== undefined) {\n const attrKey = `#field${idx}`;\n const valueKey = `:value${idx}`;\n updateParts.push(`${attrKey} = ${valueKey}`);\n names[attrKey] = key;\n values[valueKey] = value;\n }\n });\n\n if (updateParts.length === 0) {\n throw new Error(\"Шинэчлэх талбар алга байна\");\n }\n\n return {\n UpdateExpression: `SET ${updateParts.join(\", \")}`,\n ExpressionAttributeNames: names,\n ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }),\n };\n}\n\nexport const parseLastEvaluatedKey = <T>(lastKey: string): T | undefined => {\n if (!lastKey) {\n return undefined;\n }\n const decodeToken = Buffer.from(lastKey, \"base64\").toString();\n if (decodeToken.match(/^\\{.+\\}$/)) {\n return JSON.parse(decodeToken) as T;\n } else {\n return decodeToken as T;\n }\n};\n\nexport function generateLastEvaluatedKey<T>(item: any, indexField?: string, sortField?: string): string {\n if (!item?.id && !indexField) throw new Error(\"id or indexField not found\");\n\n const result: Record<string, any> = { id: item?.id };\n\n if (indexField) Object.assign(result, { [indexField]: item[indexField] });\n if (sortField) Object.assign(result, { [sortField]: item[sortField] });\n\n return toBase64(JSON.stringify(result));\n}\n\nexport function toBase64(inputStr: any): string {\n return Buffer.from(inputStr).toString(\"base64\");\n}\n\nexport function getTableName(eventSourceARN: any): string {\n if (!eventSourceARN) {\n console.error(\"cannot fetch table name from undefined DynamoDB record\");\n return;\n }\n return eventSourceARN.split(\":\")[5].split(\"/\")[1];\n}\n\nexport function parseImage(image: any) {\n if (!image) return undefined;\n try {\n const img = image as Record<string, AttributeValue>;\n return unmarshall(img);\n } catch (error) {\n log.error(\"cannot parse stream image to dynamoDB item\");\n throw new Error(error);\n }\n}\n\nexport function parseEventToAction(action: \"INSERT\" | \"MODIFY\" | \"REMOVE\"): ActionDynamoDB {\n switch (action) {\n case \"INSERT\":\n return ActionDynamoDB.INSERT;\n case \"MODIFY\":\n return ActionDynamoDB.MODIFY;\n case \"REMOVE\":\n return ActionDynamoDB.REMOVE;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dynamodb.utils.js","sourceRoot":"","sources":["../../src/utils/dynamodb.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AttributeValue, QueryCommandInput, ScanCommandInput } from \"@aws-sdk/client-dynamodb\";\nimport { marshall, unmarshall } from \"@aws-sdk/util-dynamodb\";\nimport { excludeKeys } from \"./reflection.util\";\nimport { ErrorDynamoDB, MissingParameterError } from \"../exception/errors\";\nimport { Filter, SortOrder } from \"../model\";\nimport { ActionDynamoDB, DynamoIndexMap } from \"../model/dynamodb.model\";\n\nexport const generateUUID = (): string => {\n return crypto.randomUUID();\n};\n\nexport const buildDynamoDBFilterConditions = (filter: Filter, indexMap: DynamoIndexMap): FilterExpression => {\n if (!filter) throw new MissingParameterError(\"filter\");\n\n const rFields = indexMap.get(filter.indexName)?.rFields ?? [];\n\n const ignoredKeys = [\n ...rFields,\n \"page\",\n \"size\",\n \"sortBy\",\n \"sort\",\n \"searchBy\",\n \"searchKeyword\",\n \"rangeFilterBy\",\n \"rangeFilterMin\",\n \"rangeFilterMax\",\n \"lastKey\",\n \"indexName\",\n \"indexValue\",\n \"fieldsInclude\",\n \"fieldsExclude\",\n ];\n\n const dynamicFilters = excludeKeys(filter, ignoredKeys);\n\n const expressions: string[] = [];\n const attrNames: Record<string, string> = {};\n const attrValues: Record<string, any> = {};\n\n let counter = 0;\n\n const genPlaceholder = (key: string) => {\n const safeKey = key.replace(/\\W+/g, \"_\");\n return {\n name: `#${safeKey}_${counter}`,\n value: `:${safeKey}_val_${counter++}`,\n };\n };\n\n // Range Filter\n if (filter.rangeFilterBy) {\n const key = filter.rangeFilterBy;\n const { name, value } = genPlaceholder(key);\n\n attrNames[name] = key;\n\n if (filter.rangeFilterMin !== undefined && filter.rangeFilterMax !== undefined) {\n attrValues[value + \"_min\"] = filter.rangeFilterMin;\n attrValues[value + \"_max\"] = filter.rangeFilterMax;\n expressions.push(`${name} BETWEEN ${value}_min AND ${value}_max`);\n } else if (filter.rangeFilterMin !== undefined) {\n attrValues[value] = filter.rangeFilterMin;\n expressions.push(`${name} >= ${value}`);\n } else if (filter.rangeFilterMax !== undefined) {\n attrValues[value] = filter.rangeFilterMax;\n expressions.push(`${name} <= ${value}`);\n }\n }\n\n // Search Filter\n if (filter.searchBy && filter.searchKeyword) {\n const fields = Array.isArray(filter.searchBy) ? filter.searchBy : [filter.searchBy];\n\n for (const key of fields) {\n const { name, value } = genPlaceholder(key);\n\n attrNames[name] = key;\n attrValues[value] = filter.searchKeyword;\n\n expressions.push(`contains(${name}, ${value})`);\n }\n }\n\n // General filters\n for (const [key, raw] of Object.entries(dynamicFilters)) {\n if (key === \"lastKey\") continue;\n const value = String(raw);\n const { name, value: valName } = genPlaceholder(key);\n attrNames[name] = key;\n\n if (value.startsWith(\"*\") && value.endsWith(\"*\")) {\n attrValues[valName] = checkFieldType(key, value.slice(1, -1), indexMap);\n expressions.push(`contains(${name}, ${valName})`);\n } else if (!value.startsWith(\"*\") && value.endsWith(\"*\")) {\n attrValues[valName] = checkFieldType(key, value.slice(0, -1), indexMap);\n expressions.push(`begins_with(${name}, ${valName})`);\n } else if (value.startsWith(\"!\")) {\n attrValues[valName] = checkFieldType(key, value.slice(1), indexMap);\n expressions.push(`${name} <> ${valName}`);\n } else if (value.includes(\",\")) {\n const values = value.split(\",\").map((v) => v.trim());\n const placeholders: string[] = [];\n\n values.forEach((v, i) => {\n const subVal = `${valName}_${i}`;\n attrValues[subVal] = checkFieldType(key, v, indexMap);\n placeholders.push(subVal);\n });\n\n expressions.push(`${name} IN (${placeholders.join(\", \")})`);\n } else {\n attrValues[valName] = checkFieldType(key, value, indexMap);\n expressions.push(`${name} = ${valName}`);\n }\n }\n\n if (expressions.length === 0) return {};\n\n return {\n filter: expressions.join(\" AND \"),\n attributeNames: attrNames,\n attributeValues: attrValues,\n };\n};\n\nexport const buildQueryDB = (\n tableName: string,\n filter: Filter,\n indexMap: DynamoIndexMap,\n): QueryCommandInput | ScanCommandInput => {\n if (!tableName || !filter) throw new MissingParameterError(\"tableName or filter\");\n\n const filterCondition: any = buildDynamoDBFilterConditions(filter, indexMap);\n const indexField = indexMap.get(filter.indexName)?.field;\n\n if (indexField) {\n return buildDynamoDBQueryCommand({\n filterCondition,\n tableName,\n filter,\n indexMap,\n });\n }\n return buildDynamoDBScanCommand({\n tableName,\n filter,\n expression: filterCondition,\n });\n};\n\nexport const buildDynamoDBScanCommand = ({\n tableName,\n filter,\n expression,\n}: {\n tableName: string;\n filter?: Filter;\n expression?: FilterExpression;\n}): ScanCommandInput => {\n const scanCommand: ScanCommandInput = { TableName: tableName, Limit: filter?.size ?? 25 };\n\n if (filter?.lastKey && filter.lastKey != \"undefined\")\n scanCommand.ExclusiveStartKey = parseLastEvaluatedKey(filter.lastKey);\n if (isEmptyExpressions(expression)) return scanCommand;\n\n scanCommand.FilterExpression = expression.filter;\n scanCommand.ExpressionAttributeNames = expression.attributeNames;\n scanCommand.ExpressionAttributeValues = marshall(expression.attributeValues, {\n convertClassInstanceToMap: true,\n removeUndefinedValues: true,\n });\n\n return scanCommand;\n};\n\nexport const buildDynamoDBQueryCommand = ({\n filter,\n tableName,\n filterCondition,\n indexMap,\n}: {\n filterCondition: FilterExpression;\n tableName: string;\n filter?: Filter;\n indexMap: DynamoIndexMap;\n}): QueryCommandInput => {\n if (!filter.indexName) throw new Error(\"Missing indexName in filter\");\n if (filter.indexValue === undefined || filter.indexValue === null) throw new Error(\"Missing indexValue in filter\");\n\n const indexInfo = indexMap.get(filter.indexName);\n if (!indexInfo) throw new Error(`Index info not found for index: ${filter.indexName}`);\n\n const attr = indexInfo.field;\n const value = filter.indexValue;\n\n const attrKey = `#${attr}`;\n const valueKey = `:${attr}`;\n\n const keyConditionExpression = `${attrKey} = ${valueKey}`;\n\n const expressionAttributeNames: Record<string, string> = {\n [attrKey]: attr,\n };\n\n const expressionAttributeValues: Record<string, AttributeValue> = {\n [valueKey]: marshall({ val: value }).val,\n };\n\n if (filterCondition?.filter) {\n if (filterCondition.attributeNames) {\n Object.assign(expressionAttributeNames, filterCondition.attributeNames);\n }\n if (filterCondition.attributeValues) {\n const marshalled = marshall(filterCondition.attributeValues, {\n convertClassInstanceToMap: true,\n removeUndefinedValues: true,\n });\n Object.assign(expressionAttributeValues, marshalled);\n }\n }\n\n const queryCommand: QueryCommandInput = {\n TableName: tableName,\n IndexName: filter.indexName,\n KeyConditionExpression: keyConditionExpression,\n FilterExpression: filterCondition?.filter,\n ExpressionAttributeNames: expressionAttributeNames,\n ExpressionAttributeValues: expressionAttributeValues,\n Limit: filter?.size ?? 25,\n ScanIndexForward: filter.sort === SortOrder.ASC,\n };\n\n if (filter.lastKey) {\n queryCommand.ExclusiveStartKey = parseLastEvaluatedKey(filter.lastKey);\n }\n\n return queryCommand;\n};\nexport const generateIndexValues = (input: Record<string, any>, indexMap: DynamoIndexMap) => {\n const result: Record<string, string> = { ...input };\n\n for (const [, { field, rFields, fieldSeparator }] of indexMap.entries()) {\n const definedValues = rFields.filter((key) => input[key] !== undefined).map((key) => input[key]);\n\n if (definedValues.length > 0) {\n result[field] = definedValues.join(fieldSeparator ?? \"\");\n }\n }\n\n return result;\n};\n\nexport const addIndexValue = (entity: Record<string, any>, indexMap: DynamoIndexMap) => {\n if (!indexMap) return entity;\n\n const relatedIndexFields = Array.from(indexMap.values())\n .flatMap((v) => v.rFields)\n .filter((x) => !!x);\n\n if (!relatedIndexFields || relatedIndexFields.length <= 1) return entity;\n\n const indexedValues = generateIndexValues(entity, indexMap);\n return Object.assign(entity, indexedValues);\n};\nexport const validateEntityForUpdateFields = (\n entity: Record<string, any>,\n fieldNames: string[],\n tableName?: string,\n): boolean => {\n for (const field of fieldNames) {\n if (!(field in entity) || entity[field] === undefined || entity[field] === null) {\n throw new ErrorDynamoDB(tableName || \"UnknownTable\", `Entity must have value in field ${field}`);\n }\n }\n return false;\n};\n\nexport const addIndexField = (fieldNames: string[], indexMap: DynamoIndexMap): string[] => {\n // snapshot of original fields to avoid cascading through newly added fields\n const originalFields = new Set(fieldNames);\n\n // Ensure audit fields exist and are at the front in fixed order\n // Remove existing occurrences to avoid duplicates then unshift in the desired order\n for (const auditField of [\"updatedAt\", \"updatedBy\"]) {\n const idx = fieldNames.indexOf(auditField);\n if (idx !== -1) fieldNames.splice(idx, 1);\n }\n fieldNames.unshift(\"updatedBy\");\n fieldNames.unshift(\"updatedAt\");\n\n if (!indexMap) return fieldNames;\n\n // Consider only groups with more than one field\n const groups: string[][] = Array.from(indexMap.values())\n .map((v) => v.rFields?.filter(Boolean) ?? [])\n .filter((r) => r.length > 1);\n\n if (groups.length === 0) return fieldNames;\n\n // For each group, if any member existed in the ORIGINAL set, insert the missing members\n for (const rFields of groups) {\n const hasSeed = rFields.some((f) => originalFields.has(f));\n if (!hasSeed) continue;\n\n // Anchor insertion before the earliest occurrence of any ORIGINAL member of this group\n const anchorIndex = (() => {\n let minIdx = Number.POSITIVE_INFINITY;\n for (const f of rFields) {\n if (!originalFields.has(f)) continue;\n const idx = fieldNames.indexOf(f);\n if (idx !== -1 && idx < minIdx) minIdx = idx;\n }\n return isFinite(minIdx) ? minIdx : -1;\n })();\n\n // If no anchor found in the current array, skip\n if (anchorIndex === -1) continue;\n\n // Insert missing fields in the order defined by rFields before the anchor\n let insertAt = anchorIndex;\n for (const f of rFields) {\n if (originalFields.has(f)) continue; // only add fields that weren't originally present\n if (fieldNames.includes(f)) continue; // avoid duplicates anyway\n fieldNames.splice(insertAt, 0, f);\n insertAt += 1;\n }\n }\n\n return fieldNames;\n};\n\nexport function unMarshall<T>(dataRecords: Record<string, AttributeValue>[]): Array<T> {\n return dataRecords.map((data) => unmarshall(data) as T);\n}\n\nexport const isEmptyExpression = ({\n expression,\n}: {\n expression?: {\n FilterExpression?: string;\n ExpressionAttributeNames?: Record<string, string>;\n ExpressionAttributeValues?: Record<string, any>;\n };\n}): boolean => {\n if (!expression) return true;\n\n const { FilterExpression, ExpressionAttributeNames, ExpressionAttributeValues } = expression;\n\n const isEmptyObject = (obj?: object) => !obj || Object.keys(obj).length === 0;\n\n return !FilterExpression || isEmptyObject(ExpressionAttributeNames) || isEmptyObject(ExpressionAttributeValues);\n};\n\nexport function isEmptyExpressions(exp: FilterExpression) {\n const isEmptyObject = (obj?: object) => !obj || Object.keys(obj).length === 0;\n\n return !exp.filter || isEmptyObject(exp.attributeNames) || isEmptyObject(exp.attributeValues);\n}\n\nexport interface FilterExpression {\n filter?: string;\n attributeNames?: Record<string, string>;\n attributeValues?: Record<string, any>;\n}\n\nexport const checkFieldType = (key: string, value: string, indexMap: DynamoIndexMap): number | string => {\n if (indexMap?.numberFields && indexMap?.numberFields?.length > 0) {\n for (const field of indexMap.numberFields) {\n if (!field.includes(key)) continue;\n const numValue = Number(value);\n return isNaN(numValue) ? value : numValue;\n }\n }\n\n return value;\n};\n\nexport interface UpdateExpression {\n UpdateExpression: string;\n ExpressionAttributeNames: Record<string, string>;\n ExpressionAttributeValues: Record<string, any>;\n}\n\nexport function buildUpdateExpressions(data: Record<string, any>, excludeKeys: string[] = []): UpdateExpression {\n const updateParts: string[] = [];\n const names: Record<string, string> = {};\n const values: Record<string, any> = {};\n\n Object.entries(data).forEach(([key, value], idx) => {\n if (!excludeKeys.includes(key) && value !== undefined) {\n const attrKey = `#field${idx}`;\n const valueKey = `:value${idx}`;\n updateParts.push(`${attrKey} = ${valueKey}`);\n names[attrKey] = key;\n values[valueKey] = value;\n }\n });\n\n if (updateParts.length === 0) {\n throw new Error(\"Шинэчлэх талбар алга байна\");\n }\n\n return {\n UpdateExpression: `SET ${updateParts.join(\", \")}`,\n ExpressionAttributeNames: names,\n ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }),\n };\n}\n\nexport const parseLastEvaluatedKey = <T>(lastKey: string): T | undefined => {\n if (!lastKey) {\n return undefined;\n }\n const decodeToken = Buffer.from(lastKey, \"base64\").toString();\n if (decodeToken.match(/^\\{.+\\}$/)) {\n return JSON.parse(decodeToken) as T;\n } else {\n return decodeToken as T;\n }\n};\n\nexport function generateLastEvaluatedKey<T>(item: any, indexField?: string, sortField?: string): string {\n if (!item?.id && !indexField) throw new Error(\"id or indexField not found\");\n\n const result: Record<string, any> = { id: item?.id };\n\n if (indexField) Object.assign(result, { [indexField]: item[indexField] });\n if (sortField) Object.assign(result, { [sortField]: item[sortField] });\n\n return toBase64(JSON.stringify(result));\n}\n\nexport function toBase64(inputStr: any): string {\n return Buffer.from(inputStr).toString(\"base64\");\n}\n\nexport function getTableName(eventSourceARN: any): string {\n if (!eventSourceARN) {\n console.error(\"cannot fetch table name from undefined DynamoDB record\");\n return;\n }\n return eventSourceARN.split(\":\")[5].split(\"/\")[1];\n}\n\nexport function parseImage(image: any) {\n if (!image) return undefined;\n try {\n const img = image as Record<string, AttributeValue>;\n return unmarshall(img);\n } catch (error) {\n log.error(\"cannot parse stream image to dynamoDB item\");\n throw new Error(error);\n }\n}\n\nexport function parseEventToAction(action: \"INSERT\" | \"MODIFY\" | \"REMOVE\"): ActionDynamoDB {\n switch (action) {\n case \"INSERT\":\n return ActionDynamoDB.INSERT;\n case \"MODIFY\":\n return ActionDynamoDB.MODIFY;\n case \"REMOVE\":\n return ActionDynamoDB.REMOVE;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n}\n"]}
|