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 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 extends CrudServiceImpl<Product, ProductRepoDB, ProductRepoES> implements ProductService {
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
- - **begin_[dateOrNumberFieldName]**=[Value]
239
- - **end_[dateOrNumberFieldName]**=[Value]
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 'aws-cdk-lib/aws-lambda';
414
+ import { Function, Runtime } from "aws-cdk-lib/aws-lambda";
376
415
 
377
- new Function(this, 'MyFunction', {
416
+ new Function(this, "MyFunction", {
378
417
  runtime: Runtime.NODEJS_18_X,
379
- handler: 'dist/handler.handler',
380
- code: Code.fromAsset('dist')
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
- if (rFields.every((key) => key in input))
212
- result[field] = rFields.map((key) => input[key]).join(fieldSeparator ?? "");
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-service-stack",
3
- "version": "0.18.325",
3
+ "version": "0.18.327",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "author": "chinggis.systems",