aws-service-stack 0.18.314 → 0.18.315
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/dist/service/crud.service.d.ts +1 -1
- package/dist/service/crud.service.interface.d.ts +1 -1
- package/dist/service/crud.service.interface.js.map +1 -1
- package/dist/service/crud.service.js +2 -0
- package/dist/service/crud.service.js.map +1 -1
- package/dist/utils/dynamodb.utils.js +8 -2
- package/dist/utils/dynamodb.utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ export declare abstract class CrudServiceImpl<T extends BaseEntity, D extends Ba
|
|
|
26
26
|
getIndexMapDB(): DynamoIndexMap;
|
|
27
27
|
setIndexMapDB(indexMap: DynamoIndexMap): boolean;
|
|
28
28
|
findAll(): Promise<T[]>;
|
|
29
|
-
findAllMatch(filter: Filter): Promise<T[]>;
|
|
29
|
+
findAllMatch(filter: Filter | string): Promise<T[]>;
|
|
30
30
|
findAllByIndex(indexName: string, indexValue: any): Promise<T[]>;
|
|
31
31
|
findByField(fieldName: string, fieldValue: any): Promise<List<T>>;
|
|
32
32
|
findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T>;
|
|
@@ -86,7 +86,7 @@ export interface CrudService<T extends BaseEntity> {
|
|
|
86
86
|
findQuery(queryParams: string): Promise<List<Partial<T>>>;
|
|
87
87
|
searchQuery(queryParams: string): Promise<Partial<T>[]>;
|
|
88
88
|
findAll(): Promise<T[]>;
|
|
89
|
-
findAllMatch(filter: Filter): Promise<T[]>;
|
|
89
|
+
findAllMatch(filter: Filter | string): Promise<T[]>;
|
|
90
90
|
findAllByIndex(indexName: string, indexValue: any): Promise<T[]>;
|
|
91
91
|
findByField(fieldName: string, fieldValue: any): Promise<List<T>>;
|
|
92
92
|
findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crud.service.interface.js","sourceRoot":"","sources":["../../src/service/crud.service.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { BaseEntity, CognitoUser, DynamoIndexMap, Filter, List } from \"../index\";\nimport { EntityConfig } from \"@chinggis/types\";\n\n/**\n * Defines a generic base service interface for working with entities in both\n * DynamoDB and OpenSearch.\n */\nexport interface CrudService<T extends BaseEntity> {\n setConfig(config: EntityConfig): void;\n\n getTableName(): string;\n /**\n * Creates a new entity for the given user.\n * @param ownerId - The ID of the user who owns the entity.\n * @param entity - The entity to be created.\n * @param parentId\n * @param createdByUserId - The created userId.\n * @returns The created entity.\n */\n save(entity: Partial<T>, ownerId: string, parentId?: string, createdByUserId?: string): Promise<T>;\n\n /**\n * Creates multiple new entities for the given user.\n * @param ownerId - The ID of the user who owns the entities.\n * @param entity - An array of entities to be created.\n * @param parentId\n * @param createdByUserId - The created userId.\n * @param isTransactional - Whether to perform the operation in a transaction.\n * @returns An array of created entities.\n */\n saveAll(\n entity: Partial<T>[],\n ownerId: string,\n parentId?: string,\n createdByUserId?: string,\n isTransactional?: boolean,\n ): Promise<Partial<T>[]>;\n\n /**\n * Applies partial updates to an entity for the given user.\n * Only the specified fields will be updated.\n * @param requestUser - Cognito user, system if not exist\n * @param entity - The entity with updated fields.\n * @returns The updated entity.\n */\n update(entity: T, requestUser?: CognitoUser): Promise<T>;\n\n /**\n * Applies partial updates to multiple entities for the given user.\n * Only the specified fields will be updated for each entity.\n * @param requestUser - Cognito user, system if not exist\n * @param entity - An array of entities with updated fields.\n * @param fields - The list of field names to update in each entity.\n * @param isTransactional - Whether to perform the operation in a transaction.\n * @returns True if all entities were successfully updated.\n */\n updateAll(entity: T[], fields: string[], requestUser?: CognitoUser, isTransactional?: boolean): Promise<boolean>;\n\n /**\n * Deletes an entity by ID for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityId - The ID of the entity to delete.\n * @returns True if the entity was successfully deleted.\n */\n remove(entityId: string, requestUser?: CognitoUser): Promise<boolean>;\n\n /**\n * Deletes multiple entities by their IDs for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityIds - An array of entity IDs to delete.\n * @returns True if all entities were successfully deleted.\n */\n removeAll(entityIds: string[], requestUser?: CognitoUser): Promise<boolean>;\n\n /**\n * Retrieves an entity by its ID for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityId - The ID of the entity to retrieve.\n * @returns The requested entity.\n */\n findById(entityId: string, requestUser?: CognitoUser): Promise<T>;\n\n /**\n * Retrieves multiple entities by their IDs for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityIds - An array of entity IDs to retrieve.\n * @returns An array of found entities.\n */\n findByIds(entityIds: string[], requestUser?: CognitoUser): Promise<T[]>;\n\n /**\n * Retrieves a paginated and filtered list of entities from DynamoDB.\n *\n * @param filter - Filtering and sorting options.\n * @returns A promise resolving to a paginated list of entities.\n */\n find(filter: Filter): Promise<List<Partial<T>>>;\n\n /**\n * Scans the table with non-index filters. Expensive; avoid it for hot paths.\n */\n scan(filter: Filter): Promise<List<Partial<T>>>;\n\n findQuery(queryParams: string): Promise<List<Partial<T>>>;\n\n searchQuery(queryParams: string): Promise<Partial<T>[]>;\n\n findAll(): Promise<T[]>;\n\n findAllMatch(filter: Filter): Promise<T[]>;\n\n findAllByIndex(indexName: string, indexValue: any): Promise<T[]>;\n\n findByField(fieldName: string, fieldValue: any): Promise<List<T>>;\n\n findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T>;\n\n throwError(code: number, message: string, errorContent?: any): void;\n\n throwErrorHttp(error: { message: string; code: number }, message: string, errorContent?: any): void;\n\n throwErrorDatabase(tableName: string, command: any, errorContent?: any): void;\n\n throwErrorValidation(entityName: string, validation: Map<string, any>, errorContent?: any): void;\n\n // throwError(httpStatus: number, message: string): void;\n /**\n * Retrieves a filtered and sorted list of entities from OpenSearch.\n *\n * @param filter - Filtering and sorting options.\n * @returns A promise resolving to the list of matching entities.\n */\n search(filter: Filter): Promise<T[]>;\n\n searchFieldNotExist(fieldName: string, from: number, size: number): Promise<Partial<T>[]>;\n\n /**\n * Changes the owner of an entity.\n * @param ownerId - The new owner's ID.\n * @param entityId - The ID of the entity to transfer.\n * @returns The updated entity with the new owner.\n */\n changeOwner(entityId: string, ownerId: string): Promise<T>;\n\n setTable(tableName: string, dynamoIndexMap: DynamoIndexMap): boolean;\n\n setOpensearch(indexName: string, opensearchEndpoint: string): boolean;\n\n getIndexES(): string;\n\n getIndexMapDB(): DynamoIndexMap;\n\n setIndexMapDB(indexMap: DynamoIndexMap): boolean;\n\n incrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T>;\n\n decrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"crud.service.interface.js","sourceRoot":"","sources":["../../src/service/crud.service.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { BaseEntity, CognitoUser, DynamoIndexMap, Filter, List } from \"../index\";\nimport { EntityConfig } from \"@chinggis/types\";\n\n/**\n * Defines a generic base service interface for working with entities in both\n * DynamoDB and OpenSearch.\n */\nexport interface CrudService<T extends BaseEntity> {\n setConfig(config: EntityConfig): void;\n\n getTableName(): string;\n /**\n * Creates a new entity for the given user.\n * @param ownerId - The ID of the user who owns the entity.\n * @param entity - The entity to be created.\n * @param parentId\n * @param createdByUserId - The created userId.\n * @returns The created entity.\n */\n save(entity: Partial<T>, ownerId: string, parentId?: string, createdByUserId?: string): Promise<T>;\n\n /**\n * Creates multiple new entities for the given user.\n * @param ownerId - The ID of the user who owns the entities.\n * @param entity - An array of entities to be created.\n * @param parentId\n * @param createdByUserId - The created userId.\n * @param isTransactional - Whether to perform the operation in a transaction.\n * @returns An array of created entities.\n */\n saveAll(\n entity: Partial<T>[],\n ownerId: string,\n parentId?: string,\n createdByUserId?: string,\n isTransactional?: boolean,\n ): Promise<Partial<T>[]>;\n\n /**\n * Applies partial updates to an entity for the given user.\n * Only the specified fields will be updated.\n * @param requestUser - Cognito user, system if not exist\n * @param entity - The entity with updated fields.\n * @returns The updated entity.\n */\n update(entity: T, requestUser?: CognitoUser): Promise<T>;\n\n /**\n * Applies partial updates to multiple entities for the given user.\n * Only the specified fields will be updated for each entity.\n * @param requestUser - Cognito user, system if not exist\n * @param entity - An array of entities with updated fields.\n * @param fields - The list of field names to update in each entity.\n * @param isTransactional - Whether to perform the operation in a transaction.\n * @returns True if all entities were successfully updated.\n */\n updateAll(entity: T[], fields: string[], requestUser?: CognitoUser, isTransactional?: boolean): Promise<boolean>;\n\n /**\n * Deletes an entity by ID for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityId - The ID of the entity to delete.\n * @returns True if the entity was successfully deleted.\n */\n remove(entityId: string, requestUser?: CognitoUser): Promise<boolean>;\n\n /**\n * Deletes multiple entities by their IDs for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityIds - An array of entity IDs to delete.\n * @returns True if all entities were successfully deleted.\n */\n removeAll(entityIds: string[], requestUser?: CognitoUser): Promise<boolean>;\n\n /**\n * Retrieves an entity by its ID for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityId - The ID of the entity to retrieve.\n * @returns The requested entity.\n */\n findById(entityId: string, requestUser?: CognitoUser): Promise<T>;\n\n /**\n * Retrieves multiple entities by their IDs for the given user.\n * @param requestUser - Cognito user, system if not exist\n * @param entityIds - An array of entity IDs to retrieve.\n * @returns An array of found entities.\n */\n findByIds(entityIds: string[], requestUser?: CognitoUser): Promise<T[]>;\n\n /**\n * Retrieves a paginated and filtered list of entities from DynamoDB.\n *\n * @param filter - Filtering and sorting options.\n * @returns A promise resolving to a paginated list of entities.\n */\n find(filter: Filter): Promise<List<Partial<T>>>;\n\n /**\n * Scans the table with non-index filters. Expensive; avoid it for hot paths.\n */\n scan(filter: Filter): Promise<List<Partial<T>>>;\n\n findQuery(queryParams: string): Promise<List<Partial<T>>>;\n\n searchQuery(queryParams: string): Promise<Partial<T>[]>;\n\n findAll(): Promise<T[]>;\n\n findAllMatch(filter: Filter | string): Promise<T[]>;\n\n findAllByIndex(indexName: string, indexValue: any): Promise<T[]>;\n\n findByField(fieldName: string, fieldValue: any): Promise<List<T>>;\n\n findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T>;\n\n throwError(code: number, message: string, errorContent?: any): void;\n\n throwErrorHttp(error: { message: string; code: number }, message: string, errorContent?: any): void;\n\n throwErrorDatabase(tableName: string, command: any, errorContent?: any): void;\n\n throwErrorValidation(entityName: string, validation: Map<string, any>, errorContent?: any): void;\n\n // throwError(httpStatus: number, message: string): void;\n /**\n * Retrieves a filtered and sorted list of entities from OpenSearch.\n *\n * @param filter - Filtering and sorting options.\n * @returns A promise resolving to the list of matching entities.\n */\n search(filter: Filter): Promise<T[]>;\n\n searchFieldNotExist(fieldName: string, from: number, size: number): Promise<Partial<T>[]>;\n\n /**\n * Changes the owner of an entity.\n * @param ownerId - The new owner's ID.\n * @param entityId - The ID of the entity to transfer.\n * @returns The updated entity with the new owner.\n */\n changeOwner(entityId: string, ownerId: string): Promise<T>;\n\n setTable(tableName: string, dynamoIndexMap: DynamoIndexMap): boolean;\n\n setOpensearch(indexName: string, opensearchEndpoint: string): boolean;\n\n getIndexES(): string;\n\n getIndexMapDB(): DynamoIndexMap;\n\n setIndexMapDB(indexMap: DynamoIndexMap): boolean;\n\n incrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T>;\n\n decrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T>;\n}\n"]}
|
|
@@ -147,6 +147,8 @@ class CrudServiceImpl {
|
|
|
147
147
|
return result;
|
|
148
148
|
}
|
|
149
149
|
async findAllMatch(filter) {
|
|
150
|
+
if (typeof filter === "string")
|
|
151
|
+
filter = (0, index_1.parseIndexFilter)(filter, this.getIndexMapDB());
|
|
150
152
|
this.checkIsIndexedField(filter);
|
|
151
153
|
return await this.fetchAll(filter);
|
|
152
154
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crud.service.js","sourceRoot":"","sources":["../../src/service/crud.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Action,\n BaseEntity,\n BaseRepoDB,\n BaseRepoDBImpl,\n BaseRepoES,\n BaseRepoESImpl,\n ChangeHistory,\n CognitoUser,\n computeChangedFields,\n DynamoIndexMap,\n Filter,\n List,\n parseFilter,\n parseIndexFilter,\n} from \"../index\";\nimport { ErrorBase, ErrorDynamoDB, ErrorHttp, ErrorValidation } from \"../exception\";\n\nimport { EntityConfig } from \"@chinggis/types\";\nimport { CrudService } from \"./crud.service.interface\";\nimport dayjs from \"dayjs\";\n\nexport abstract class CrudServiceImpl<T extends BaseEntity, D extends BaseRepoDB<T>, S extends BaseRepoES<T>>\n implements CrudService<T>\n{\n protected repoDB: D;\n protected repoES: S;\n protected config: EntityConfig;\n\n protected constructor(repoDB: D, repoES: S) {\n if (repoDB != null && !(repoDB instanceof BaseRepoDBImpl))\n console.error(\"repoDB is not an instance of BaseRepoDBImpl\");\n\n if (repoES != null && !(repoES instanceof BaseRepoESImpl))\n console.error(\"repoES is not an instance of BaseRepoESImpl\");\n\n if (repoDB == null && repoES == null) console.error(\"repo initialization is required\");\n\n this.repoDB = repoDB;\n this.repoES = repoES;\n }\n\n getTableName(): string {\n return this.repoDB.getTableName();\n }\n\n async findQuery(queryParams: string): Promise<List<Partial<T>>> {\n const filter = parseIndexFilter(queryParams, this.getIndexMapDB());\n this.checkIsIndexedField(filter);\n return await this.find(filter);\n }\n\n async searchQuery(queryParams: string): Promise<Partial<T>[]> {\n let filter = parseIndexFilter(queryParams);\n filter = this.parseOwnerFields(filter, this.config);\n this.checkIsIndexedField(filter);\n\n filter = this.setIndexField(filter, this.config);\n\n return await this.search(filter);\n }\n\n async incrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T> {\n return await this.repoDB.incrementValueByField(entityId, fieldName, value);\n }\n\n async decrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T> {\n return await this.repoDB.decrementValueByField(entityId, fieldName, value);\n }\n\n async search(filter: Filter): Promise<T[]> {\n let parsedFilter = this.parseOwnerFields(filter, this.config);\n parsedFilter = this.setIndexField(parsedFilter, this.config);\n\n return (await this.repoES.find(parsedFilter)).items as T[];\n }\n\n async searchFieldNotExist(fieldName: string, from: number, size: number): Promise<Partial<T>[]> {\n return await this.repoES.fieldNotExists(fieldName, from, size);\n }\n\n async save(entity: Partial<T>, ownerId: string, parentId?: string, createdByUser?: string | CognitoUser): Promise<T> {\n entity = this.setSystemData(entity, Action.CREATE, createdByUser);\n\n if (ownerId) {\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n entity.createdBy = createdByUser || ownerId;\n }\n if (parentId) entity[this.config.OWNER_PARENT_ID_FIELD_NAME] = parentId;\n\n return await this.repoDB.save(entity);\n }\n\n async saveAll(\n entities: Partial<T>[],\n ownerId: string,\n parentId?: string,\n createdByUser?: string | CognitoUser,\n isTransactional?: boolean,\n ): Promise<Partial<T>[]> {\n const entitiesUpdated = [];\n\n for (const item of entities) {\n // const entity = addDatesAndId(item);\n const entity = this.setSystemData(item, Action.CREATE, createdByUser || ownerId);\n\n if (parentId) entity[this.config.OWNER_PARENT_ID_FIELD_NAME] = parentId;\n\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n\n entitiesUpdated.push(entity);\n }\n\n return await this.repoDB.saveMany(entitiesUpdated, isTransactional);\n }\n\n async update(entity: T, requestUser?: CognitoUser): Promise<T> {\n const fieldName = this.config.DYNAMO_DB?.MAP?.partitionKey ?? \"id\";\n if (!entity || !entity[fieldName]) throw new ErrorHttp({ code: 400, error: \"BadRequest\" }, `id required`);\n\n const item = await this.repoDB.findById(entity[fieldName]);\n\n if (!entity || !item) throw new ErrorHttp({ code: 400, error: \"BadRequest\" }, `id not found`);\n\n if (\n requestUser &&\n !requestUser.isAdmin &&\n (item[this.config.OWNER_ID_FIELD_NAME] !== requestUser.profile ||\n item[this.config.OWNER_PARENT_ID_FIELD_NAME] !== requestUser.parentId)\n )\n throw new ErrorHttp({ code: 403, error: \"PermissionDenied\" }, `No permission to resource: ${entity.id}`);\n\n entity = this.setSystemData(entity, Action.UPDATE, requestUser, item);\n\n // if (!hasPermission(entity, userId, Permission.UPDATE)) throw new Error(\"Unauthorized access\");\n return await this.repoDB.update(entity);\n }\n\n async updateAll(\n entities: Partial<T>[],\n fields: string[],\n requestUser?: CognitoUser,\n isTransactional?: boolean,\n ): Promise<boolean> {\n if (requestUser) log.warn(\"this methode is under development, cannot check ownership by updateAll\");\n\n return await this.repoDB.updateMany(entities, fields, isTransactional);\n }\n\n async remove(entityId: string, requestUser: CognitoUser): Promise<boolean> {\n if (!entityId) throw new Error(\"Entity id required\");\n\n if (requestUser.isAdmin) return await this.repoDB.delete(entityId);\n\n const entity = await this.repoDB.findById(entityId);\n if (!entity) throw new Error(\"Entity not found\");\n\n if (\n entity[this.config.OWNER_ID_FIELD_NAME] !== requestUser.profile ||\n entity[this.config.OWNER_PARENT_ID_FIELD_NAME] !== requestUser.parentId\n )\n throw new ErrorHttp({ code: 403, error: \"PermissionDenied\" }, `No permission to resource: ${entity.id}`);\n\n return await this.repoDB.delete(entityId);\n }\n\n async removeAll(entityIds: string[], requestUser: CognitoUser): Promise<boolean> {\n if (requestUser) log.warn(\"this methode is under development, cannot check ownership by removeAll\");\n return await this.repoDB.deleteMany(entityIds);\n }\n\n async changeOwner(entityId: string, ownerId: string): Promise<T> {\n const entity = await this.repoDB.findById(entityId);\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n return this.repoDB.update(entity);\n }\n\n setTable(tableName: string, dynamoIndexMap: DynamoIndexMap): boolean {\n this.repoDB.setTable(tableName);\n this.repoDB.setIndexMap(dynamoIndexMap);\n return true;\n }\n\n setOpensearch(indexName: string, opensearchEndpoint: string): boolean {\n this.repoES.setIndexName(indexName);\n this.repoES.setEndpoint(opensearchEndpoint);\n return true;\n }\n\n getIndexES(): string {\n return this.repoES.getIndexName();\n }\n\n getIndexMapDB(): DynamoIndexMap {\n return this.repoDB.getIndexMap();\n }\n\n setIndexMapDB(indexMap: DynamoIndexMap): boolean {\n this.repoDB.setIndexMap(indexMap);\n return true;\n }\n\n async findAll(): Promise<T[]> {\n const result: T[] = [];\n\n const filter = parseIndexFilter(\"size=250\");\n\n do {\n const response = await this.repoDB.find(filter);\n result.push(...(response.items as T[]));\n filter.lastKey = response.lastKey;\n } while (filter.lastKey);\n\n return result;\n }\n\n async findAllMatch(filter: Filter): Promise<T[]> {\n this.checkIsIndexedField(filter);\n return await this.fetchAll(filter);\n }\n\n async findAllByIndex(indexName: string, indexValue: any): Promise<T[]> {\n // Create a filter object for validation\n const filter = { indexName: indexName, indexValue: indexValue };\n this.checkIsIndexedField(filter);\n\n const parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return this.fetchAll(parsedFilter);\n }\n\n async findByField(fieldName: string, fieldValue: any): Promise<List<T>> {\n // Create a filter object for validation\n const filter = { [fieldName]: fieldValue, size: 100 };\n this.checkIsIndexedField(filter);\n const parsedFilter = parseIndexFilter(fieldName + \"=\" + fieldValue + \"&size=100\", this.getIndexMapDB());\n return (await this.find(parsedFilter)) as List<T>;\n }\n\n async findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T> {\n // Validate that the field name exists in the index map\n const filter = { [fieldName]: fieldValue };\n this.checkIsIndexedField(filter);\n\n const result = await this.findByField(fieldName, fieldValue);\n return result.items.length > 0 ? result.items[0] : null;\n }\n\n async find(filter: Filter): Promise<List<Partial<T>>> {\n // Validate that all field names in the filter exist in the index map\n let parsedFilter = this.parseOwnerFields(filter, this.config);\n\n this.checkIsIndexedField(parsedFilter);\n\n parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return await this.repoDB.find(parsedFilter);\n }\n\n async findById(entityId: string, requestUser?: CognitoUser): Promise<T> {\n const entity = await this.repoDB.findById(entityId);\n\n if (!entity) return null;\n\n if (!requestUser || requestUser.isAdmin) return entity;\n\n const isOwnerParent = entity[this.config.OWNER_PARENT_ID_FIELD_NAME] == requestUser.profile;\n const isParent = entity[this.config.OWNER_ID_FIELD_NAME] == requestUser.profile;\n\n if (!requestUser.profile || isOwnerParent || isParent) {\n return entity;\n }\n\n return null;\n }\n\n async findByIds(entityIds: string[], requestUser?: CognitoUser): Promise<T[]> {\n if (entityIds.length > 25) throw new ErrorDynamoDB(this.getTableName(), \"findByIds\", \"Too many entities\");\n\n const entities = await this.repoDB.findByIds(entityIds);\n\n if (!requestUser || requestUser.isAdmin) return entities;\n\n const ownEntities = [];\n for (const entity of entities) {\n if (\n entity[this.config.OWNER_PARENT_ID_FIELD_NAME] == requestUser.profile ||\n entity[this.config.OWNER_ID_FIELD_NAME] == requestUser.profile\n ) {\n ownEntities.push(entity);\n }\n }\n return ownEntities;\n }\n\n async scan(filter: Filter): Promise<List<Partial<T>>> {\n this.checkIsIndexedField(filter);\n const parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return await this.repoDB.scan(parsedFilter);\n }\n\n throwErrorHttp(error: { message: string; code: number }, message?: string, errorContent?: any): void {\n throw new ErrorHttp({ code: error.code, error: error.message }, message, errorContent);\n }\n\n throwErrorDatabase(tableName: string, command: any, errorContent?: any): void {\n throw new ErrorDynamoDB(tableName, command, errorContent);\n }\n\n throwErrorValidation(entityName: string, validation: Map<string, any>, errorContent?: any): void {\n throw new ErrorValidation(entityName, validation, errorContent);\n }\n\n throwError(code: number, message: string, errorContent?: any): void {\n throw new ErrorBase(code, message, errorContent);\n }\n\n setConfig(config: EntityConfig) {\n this.config = config;\n\n if (this.repoDB) {\n this.repoDB.setIndexMap(config.DYNAMO_DB?.MAP);\n this.repoDB.setTable(config.DYNAMO_DB?.NAME);\n }\n\n if (this.repoES) {\n this.repoES.setEndpoint(config.OPEN_SEARCH.DOMAIN);\n this.repoES.setIndexName(config.OPEN_SEARCH.INDEX);\n }\n }\n\n /**\n * Validates that all field names in the filter exist in the index map.\n * Throws a Bad Request error if any field is not found in the available indexes.\n *\n * @param filter - The filter object containing field names to validate\n * @throws ErrorHttp with status 400 if validation fails\n */\n private checkIsIndexedField(filter: Filter): void {\n if (!filter || typeof filter !== \"object\") {\n return; // Skip validation for invalid filters\n }\n\n const indexMap = this.getIndexMapDB();\n if (!indexMap || indexMap.size === 0) {\n throw new ErrorHttp({ code: 400, error: \"Bad Request\" }, \"No indexes configured for this table\");\n }\n\n // Get all valid field names from all indexes\n const validFields = new Set<string>();\n\n // Add a partition key\n if (indexMap.partitionKey) {\n validFields.add(indexMap.partitionKey);\n }\n\n // Add fields from all indexes\n for (const [indexName, indexConfig] of indexMap.entries()) {\n if (indexConfig.field) {\n validFields.add(indexConfig.field);\n }\n if (indexConfig.rFields) {\n indexConfig.rFields.forEach((field) => validFields.add(field));\n }\n if (indexConfig.sortKeyField) {\n validFields.add(indexConfig.sortKeyField);\n }\n }\n\n // Check each field in the filter\n const invalidFields: string[] = [];\n for (const fieldName of Object.keys(filter)) {\n // Skip special filter properties that are not field names\n if (\n [\"indexName\", \"indexValue\", \"size\", \"lastKey\", \"fieldsInclude\", \"fieldsExclude\", \"rangeFilters\"].includes(\n fieldName,\n )\n ) {\n continue;\n }\n\n // Skip range filter fields (ageMin, ageMax, etc.)\n const rangeSuffixes = [\"Min\", \"Max\", \"From\", \"To\", \"Start\", \"End\"];\n const isRangeField = rangeSuffixes.some((suffix) => fieldName.endsWith(suffix));\n if (isRangeField) {\n continue;\n }\n\n if (!validFields.has(fieldName)) {\n invalidFields.push(fieldName);\n }\n }\n\n if (invalidFields.length > 0) {\n const availableFields = Array.from(validFields).sort();\n throw new ErrorHttp(\n { code: 400, error: \"Bad Request\" },\n `Invalid field names in filter: ${invalidFields.join(\", \")}. Available fields: ${availableFields.join(\", \")}`,\n );\n }\n }\n\n private async fetchAll(filter: Filter | string): Promise<T[]> {\n if (typeof filter === \"string\") filter = parseFilter(filter);\n\n const result: Partial<T>[] = [];\n do {\n const response = await this.repoDB.find(filter);\n result.push(...response.items);\n filter.lastKey = response.lastKey;\n } while (filter.lastKey);\n\n return result as T[];\n }\n\n private parseOwnerFields(filter: Filter, entityConfig: EntityConfig) {\n const parsedFilter = filter;\n\n log.debug(\"input filter\", parsedFilter);\n\n if (parsedFilter.ownerParentId && !entityConfig.OWNER_PARENT_ID_FIELD_NAME) {\n parsedFilter.profileId = parsedFilter.ownerParentId;\n delete parsedFilter.ownerParentId;\n }\n if (!parsedFilter.profileId) delete parsedFilter.profileId;\n\n if (parsedFilter.ownerParentId && entityConfig.OWNER_PARENT_ID_FIELD_NAME) {\n parsedFilter[entityConfig.OWNER_PARENT_ID_FIELD_NAME] = parsedFilter.ownerParentId;\n if (entityConfig.OWNER_PARENT_ID_FIELD_NAME !== parsedFilter.ownerParentId) delete parsedFilter.ownerParentId;\n }\n\n if (parsedFilter.profileId && entityConfig.OWNER_ID_FIELD_NAME) {\n parsedFilter[entityConfig.OWNER_ID_FIELD_NAME] = parsedFilter.profileId;\n if (entityConfig.OWNER_ID_FIELD_NAME !== parsedFilter.owderId) delete parsedFilter.profileId;\n }\n\n // if (parsedFilter.ownerId && entityConfig.OWNER_ID_FIELD_NAME) {\n // parsedFilter[entityConfig.OWNER_ID_FIELD_NAME] = parsedFilter.ownerId;\n // if (entityConfig.OWNER_ID_FIELD_NAME !== parsedFilter.ownerId) delete parsedFilter.ownerId;\n // }\n log.debug(\"parsedFilter\", parsedFilter);\n\n return parsedFilter;\n }\n private setSystemData(itemNew: Partial<T>, action: Action, requestUser?: string | CognitoUser, itemOld?: T): T {\n if (!action || action === Action.DELETE || action === Action.READ) return itemNew as T;\n\n const date = dayjs().toISOString();\n const user = this.extractUser(requestUser);\n\n switch (action) {\n case Action.CREATE:\n return this.handleCreate(itemNew, user, date);\n case Action.UPDATE:\n return this.handleUpdate(itemNew, itemOld, user, date);\n default:\n return itemNew as T;\n }\n }\n\n private extractUser(requestUser?: string | CognitoUser): string {\n if (!requestUser) return \"system\";\n return typeof requestUser === \"string\" ? requestUser : requestUser.username;\n }\n\n private handleCreate(itemNew: Partial<T>, user: string, date: string): T {\n const dayjsData = dayjs(new Date(date));\n itemNew[this.config.DYNAMO_DB.MAP.partitionKey ?? \"id\"] = crypto.randomUUID();\n itemNew.createdAt = date;\n itemNew.createdBy = user;\n itemNew.year = dayjsData.year().toString();\n itemNew.yearMonth = dayjsData.year() + \"-\" + (dayjsData.month() + 1);\n\n if (!this.config.TRACE_CHANGE?.fields) return itemNew as T;\n\n itemNew.history = this.addHistory(itemNew.history, { action: Action.CREATE, user, date });\n return itemNew as T;\n }\n\n private handleUpdate(itemNew: Partial<T>, itemOld: T | undefined, user: string, date: string): T {\n itemNew.createdBy = itemNew.createdBy || itemOld?.createdBy;\n itemNew.updatedBy = itemNew.updatedBy || { username: user };\n itemNew.history = itemNew.history || itemOld?.history;\n\n if (!this.config.TRACE_CHANGE?.fields || !itemOld) return itemNew as T;\n\n delete itemNew.updatedBy;\n\n const changes = computeChangedFields(itemOld, itemNew, this.config.TRACE_CHANGE);\n if (changes.length > 0) {\n itemNew.history = this.addHistory(itemNew.history, {\n action: Action.UPDATE,\n user,\n date,\n changes,\n });\n }\n\n return itemNew as T;\n }\n\n private addHistory(history: ChangeHistory[] | undefined, entry: ChangeHistory): ChangeHistory[] {\n // skip empty or invalid history entries\n if (!entry.changes || entry.changes.length === 0) {\n return history || [];\n }\n\n // clone to avoid accidental mutation\n const newHistory = [...(history || [])];\n\n // optional: limit max history size (e.g., last 100 changes)\n const MAX_HISTORY_ENTRIES = 100;\n if (newHistory.length >= MAX_HISTORY_ENTRIES) {\n newHistory.shift(); // remove oldest\n }\n\n newHistory.push(entry);\n return newHistory;\n }\n\n private setIndexField(filter: Filter, config: EntityConfig) {\n if (!filter.indexName || !filter.indexValue) return filter;\n\n const indexMap = config.DYNAMO_DB.MAP;\n if (!indexMap || indexMap.size === 0) return filter;\n\n const indexConfig = indexMap.get(filter.indexName);\n if (!indexConfig) return filter;\n\n filter.indexName = indexConfig.field;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"crud.service.js","sourceRoot":"","sources":["../../src/service/crud.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Action,\n BaseEntity,\n BaseRepoDB,\n BaseRepoDBImpl,\n BaseRepoES,\n BaseRepoESImpl,\n ChangeHistory,\n CognitoUser,\n computeChangedFields,\n DynamoIndexMap,\n Filter,\n List,\n parseFilter,\n parseIndexFilter,\n} from \"../index\";\nimport { ErrorBase, ErrorDynamoDB, ErrorHttp, ErrorValidation } from \"../exception\";\n\nimport { EntityConfig } from \"@chinggis/types\";\nimport { CrudService } from \"./crud.service.interface\";\nimport dayjs from \"dayjs\";\n\nexport abstract class CrudServiceImpl<T extends BaseEntity, D extends BaseRepoDB<T>, S extends BaseRepoES<T>>\n implements CrudService<T>\n{\n protected repoDB: D;\n protected repoES: S;\n protected config: EntityConfig;\n\n protected constructor(repoDB: D, repoES: S) {\n if (repoDB != null && !(repoDB instanceof BaseRepoDBImpl))\n console.error(\"repoDB is not an instance of BaseRepoDBImpl\");\n\n if (repoES != null && !(repoES instanceof BaseRepoESImpl))\n console.error(\"repoES is not an instance of BaseRepoESImpl\");\n\n if (repoDB == null && repoES == null) console.error(\"repo initialization is required\");\n\n this.repoDB = repoDB;\n this.repoES = repoES;\n }\n\n getTableName(): string {\n return this.repoDB.getTableName();\n }\n\n async findQuery(queryParams: string): Promise<List<Partial<T>>> {\n const filter = parseIndexFilter(queryParams, this.getIndexMapDB());\n this.checkIsIndexedField(filter);\n return await this.find(filter);\n }\n\n async searchQuery(queryParams: string): Promise<Partial<T>[]> {\n let filter = parseIndexFilter(queryParams);\n filter = this.parseOwnerFields(filter, this.config);\n this.checkIsIndexedField(filter);\n\n filter = this.setIndexField(filter, this.config);\n\n return await this.search(filter);\n }\n\n async incrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T> {\n return await this.repoDB.incrementValueByField(entityId, fieldName, value);\n }\n\n async decrementValueByField(entityId: string, fieldName: string, value?: number): Promise<T> {\n return await this.repoDB.decrementValueByField(entityId, fieldName, value);\n }\n\n async search(filter: Filter): Promise<T[]> {\n let parsedFilter = this.parseOwnerFields(filter, this.config);\n parsedFilter = this.setIndexField(parsedFilter, this.config);\n\n return (await this.repoES.find(parsedFilter)).items as T[];\n }\n\n async searchFieldNotExist(fieldName: string, from: number, size: number): Promise<Partial<T>[]> {\n return await this.repoES.fieldNotExists(fieldName, from, size);\n }\n\n async save(entity: Partial<T>, ownerId: string, parentId?: string, createdByUser?: string | CognitoUser): Promise<T> {\n entity = this.setSystemData(entity, Action.CREATE, createdByUser);\n\n if (ownerId) {\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n entity.createdBy = createdByUser || ownerId;\n }\n if (parentId) entity[this.config.OWNER_PARENT_ID_FIELD_NAME] = parentId;\n\n return await this.repoDB.save(entity);\n }\n\n async saveAll(\n entities: Partial<T>[],\n ownerId: string,\n parentId?: string,\n createdByUser?: string | CognitoUser,\n isTransactional?: boolean,\n ): Promise<Partial<T>[]> {\n const entitiesUpdated = [];\n\n for (const item of entities) {\n // const entity = addDatesAndId(item);\n const entity = this.setSystemData(item, Action.CREATE, createdByUser || ownerId);\n\n if (parentId) entity[this.config.OWNER_PARENT_ID_FIELD_NAME] = parentId;\n\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n\n entitiesUpdated.push(entity);\n }\n\n return await this.repoDB.saveMany(entitiesUpdated, isTransactional);\n }\n\n async update(entity: T, requestUser?: CognitoUser): Promise<T> {\n const fieldName = this.config.DYNAMO_DB?.MAP?.partitionKey ?? \"id\";\n if (!entity || !entity[fieldName]) throw new ErrorHttp({ code: 400, error: \"BadRequest\" }, `id required`);\n\n const item = await this.repoDB.findById(entity[fieldName]);\n\n if (!entity || !item) throw new ErrorHttp({ code: 400, error: \"BadRequest\" }, `id not found`);\n\n if (\n requestUser &&\n !requestUser.isAdmin &&\n (item[this.config.OWNER_ID_FIELD_NAME] !== requestUser.profile ||\n item[this.config.OWNER_PARENT_ID_FIELD_NAME] !== requestUser.parentId)\n )\n throw new ErrorHttp({ code: 403, error: \"PermissionDenied\" }, `No permission to resource: ${entity.id}`);\n\n entity = this.setSystemData(entity, Action.UPDATE, requestUser, item);\n\n // if (!hasPermission(entity, userId, Permission.UPDATE)) throw new Error(\"Unauthorized access\");\n return await this.repoDB.update(entity);\n }\n\n async updateAll(\n entities: Partial<T>[],\n fields: string[],\n requestUser?: CognitoUser,\n isTransactional?: boolean,\n ): Promise<boolean> {\n if (requestUser) log.warn(\"this methode is under development, cannot check ownership by updateAll\");\n\n return await this.repoDB.updateMany(entities, fields, isTransactional);\n }\n\n async remove(entityId: string, requestUser: CognitoUser): Promise<boolean> {\n if (!entityId) throw new Error(\"Entity id required\");\n\n if (requestUser.isAdmin) return await this.repoDB.delete(entityId);\n\n const entity = await this.repoDB.findById(entityId);\n if (!entity) throw new Error(\"Entity not found\");\n\n if (\n entity[this.config.OWNER_ID_FIELD_NAME] !== requestUser.profile ||\n entity[this.config.OWNER_PARENT_ID_FIELD_NAME] !== requestUser.parentId\n )\n throw new ErrorHttp({ code: 403, error: \"PermissionDenied\" }, `No permission to resource: ${entity.id}`);\n\n return await this.repoDB.delete(entityId);\n }\n\n async removeAll(entityIds: string[], requestUser: CognitoUser): Promise<boolean> {\n if (requestUser) log.warn(\"this methode is under development, cannot check ownership by removeAll\");\n return await this.repoDB.deleteMany(entityIds);\n }\n\n async changeOwner(entityId: string, ownerId: string): Promise<T> {\n const entity = await this.repoDB.findById(entityId);\n entity[this.config.OWNER_ID_FIELD_NAME] = ownerId;\n return this.repoDB.update(entity);\n }\n\n setTable(tableName: string, dynamoIndexMap: DynamoIndexMap): boolean {\n this.repoDB.setTable(tableName);\n this.repoDB.setIndexMap(dynamoIndexMap);\n return true;\n }\n\n setOpensearch(indexName: string, opensearchEndpoint: string): boolean {\n this.repoES.setIndexName(indexName);\n this.repoES.setEndpoint(opensearchEndpoint);\n return true;\n }\n\n getIndexES(): string {\n return this.repoES.getIndexName();\n }\n\n getIndexMapDB(): DynamoIndexMap {\n return this.repoDB.getIndexMap();\n }\n\n setIndexMapDB(indexMap: DynamoIndexMap): boolean {\n this.repoDB.setIndexMap(indexMap);\n return true;\n }\n\n async findAll(): Promise<T[]> {\n const result: T[] = [];\n\n const filter = parseIndexFilter(\"size=250\");\n\n do {\n const response = await this.repoDB.find(filter);\n result.push(...(response.items as T[]));\n filter.lastKey = response.lastKey;\n } while (filter.lastKey);\n\n return result;\n }\n\n async findAllMatch(filter: Filter | string): Promise<T[]> {\n if (typeof filter === \"string\") filter = parseIndexFilter(filter, this.getIndexMapDB());\n this.checkIsIndexedField(filter);\n return await this.fetchAll(filter);\n }\n\n async findAllByIndex(indexName: string, indexValue: any): Promise<T[]> {\n // Create a filter object for validation\n const filter = { indexName: indexName, indexValue: indexValue };\n this.checkIsIndexedField(filter);\n\n const parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return this.fetchAll(parsedFilter);\n }\n\n async findByField(fieldName: string, fieldValue: any): Promise<List<T>> {\n // Create a filter object for validation\n const filter = { [fieldName]: fieldValue, size: 100 };\n this.checkIsIndexedField(filter);\n const parsedFilter = parseIndexFilter(fieldName + \"=\" + fieldValue + \"&size=100\", this.getIndexMapDB());\n return (await this.find(parsedFilter)) as List<T>;\n }\n\n async findFirst(fieldName: string, fieldValue: string | boolean | number | Date): Promise<T> {\n // Validate that the field name exists in the index map\n const filter = { [fieldName]: fieldValue };\n this.checkIsIndexedField(filter);\n\n const result = await this.findByField(fieldName, fieldValue);\n return result.items.length > 0 ? result.items[0] : null;\n }\n\n async find(filter: Filter): Promise<List<Partial<T>>> {\n // Validate that all field names in the filter exist in the index map\n let parsedFilter = this.parseOwnerFields(filter, this.config);\n\n this.checkIsIndexedField(parsedFilter);\n\n parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return await this.repoDB.find(parsedFilter);\n }\n\n async findById(entityId: string, requestUser?: CognitoUser): Promise<T> {\n const entity = await this.repoDB.findById(entityId);\n\n if (!entity) return null;\n\n if (!requestUser || requestUser.isAdmin) return entity;\n\n const isOwnerParent = entity[this.config.OWNER_PARENT_ID_FIELD_NAME] == requestUser.profile;\n const isParent = entity[this.config.OWNER_ID_FIELD_NAME] == requestUser.profile;\n\n if (!requestUser.profile || isOwnerParent || isParent) {\n return entity;\n }\n\n return null;\n }\n\n async findByIds(entityIds: string[], requestUser?: CognitoUser): Promise<T[]> {\n if (entityIds.length > 25) throw new ErrorDynamoDB(this.getTableName(), \"findByIds\", \"Too many entities\");\n\n const entities = await this.repoDB.findByIds(entityIds);\n\n if (!requestUser || requestUser.isAdmin) return entities;\n\n const ownEntities = [];\n for (const entity of entities) {\n if (\n entity[this.config.OWNER_PARENT_ID_FIELD_NAME] == requestUser.profile ||\n entity[this.config.OWNER_ID_FIELD_NAME] == requestUser.profile\n ) {\n ownEntities.push(entity);\n }\n }\n return ownEntities;\n }\n\n async scan(filter: Filter): Promise<List<Partial<T>>> {\n this.checkIsIndexedField(filter);\n const parsedFilter = parseIndexFilter(filter, this.getIndexMapDB());\n return await this.repoDB.scan(parsedFilter);\n }\n\n throwErrorHttp(error: { message: string; code: number }, message?: string, errorContent?: any): void {\n throw new ErrorHttp({ code: error.code, error: error.message }, message, errorContent);\n }\n\n throwErrorDatabase(tableName: string, command: any, errorContent?: any): void {\n throw new ErrorDynamoDB(tableName, command, errorContent);\n }\n\n throwErrorValidation(entityName: string, validation: Map<string, any>, errorContent?: any): void {\n throw new ErrorValidation(entityName, validation, errorContent);\n }\n\n throwError(code: number, message: string, errorContent?: any): void {\n throw new ErrorBase(code, message, errorContent);\n }\n\n setConfig(config: EntityConfig) {\n this.config = config;\n\n if (this.repoDB) {\n this.repoDB.setIndexMap(config.DYNAMO_DB?.MAP);\n this.repoDB.setTable(config.DYNAMO_DB?.NAME);\n }\n\n if (this.repoES) {\n this.repoES.setEndpoint(config.OPEN_SEARCH.DOMAIN);\n this.repoES.setIndexName(config.OPEN_SEARCH.INDEX);\n }\n }\n\n /**\n * Validates that all field names in the filter exist in the index map.\n * Throws a Bad Request error if any field is not found in the available indexes.\n *\n * @param filter - The filter object containing field names to validate\n * @throws ErrorHttp with status 400 if validation fails\n */\n private checkIsIndexedField(filter: Filter): void {\n if (!filter || typeof filter !== \"object\") {\n return; // Skip validation for invalid filters\n }\n\n const indexMap = this.getIndexMapDB();\n if (!indexMap || indexMap.size === 0) {\n throw new ErrorHttp({ code: 400, error: \"Bad Request\" }, \"No indexes configured for this table\");\n }\n\n // Get all valid field names from all indexes\n const validFields = new Set<string>();\n\n // Add a partition key\n if (indexMap.partitionKey) {\n validFields.add(indexMap.partitionKey);\n }\n\n // Add fields from all indexes\n for (const [indexName, indexConfig] of indexMap.entries()) {\n if (indexConfig.field) {\n validFields.add(indexConfig.field);\n }\n if (indexConfig.rFields) {\n indexConfig.rFields.forEach((field) => validFields.add(field));\n }\n if (indexConfig.sortKeyField) {\n validFields.add(indexConfig.sortKeyField);\n }\n }\n\n // Check each field in the filter\n const invalidFields: string[] = [];\n for (const fieldName of Object.keys(filter)) {\n // Skip special filter properties that are not field names\n if (\n [\"indexName\", \"indexValue\", \"size\", \"lastKey\", \"fieldsInclude\", \"fieldsExclude\", \"rangeFilters\"].includes(\n fieldName,\n )\n ) {\n continue;\n }\n\n // Skip range filter fields (ageMin, ageMax, etc.)\n const rangeSuffixes = [\"Min\", \"Max\", \"From\", \"To\", \"Start\", \"End\"];\n const isRangeField = rangeSuffixes.some((suffix) => fieldName.endsWith(suffix));\n if (isRangeField) {\n continue;\n }\n\n if (!validFields.has(fieldName)) {\n invalidFields.push(fieldName);\n }\n }\n\n if (invalidFields.length > 0) {\n const availableFields = Array.from(validFields).sort();\n throw new ErrorHttp(\n { code: 400, error: \"Bad Request\" },\n `Invalid field names in filter: ${invalidFields.join(\", \")}. Available fields: ${availableFields.join(\", \")}`,\n );\n }\n }\n\n private async fetchAll(filter: Filter | string): Promise<T[]> {\n if (typeof filter === \"string\") filter = parseFilter(filter);\n\n const result: Partial<T>[] = [];\n do {\n const response = await this.repoDB.find(filter);\n result.push(...response.items);\n filter.lastKey = response.lastKey;\n } while (filter.lastKey);\n\n return result as T[];\n }\n\n private parseOwnerFields(filter: Filter, entityConfig: EntityConfig) {\n const parsedFilter = filter;\n\n log.debug(\"input filter\", parsedFilter);\n\n if (parsedFilter.ownerParentId && !entityConfig.OWNER_PARENT_ID_FIELD_NAME) {\n parsedFilter.profileId = parsedFilter.ownerParentId;\n delete parsedFilter.ownerParentId;\n }\n if (!parsedFilter.profileId) delete parsedFilter.profileId;\n\n if (parsedFilter.ownerParentId && entityConfig.OWNER_PARENT_ID_FIELD_NAME) {\n parsedFilter[entityConfig.OWNER_PARENT_ID_FIELD_NAME] = parsedFilter.ownerParentId;\n if (entityConfig.OWNER_PARENT_ID_FIELD_NAME !== parsedFilter.ownerParentId) delete parsedFilter.ownerParentId;\n }\n\n if (parsedFilter.profileId && entityConfig.OWNER_ID_FIELD_NAME) {\n parsedFilter[entityConfig.OWNER_ID_FIELD_NAME] = parsedFilter.profileId;\n if (entityConfig.OWNER_ID_FIELD_NAME !== parsedFilter.owderId) delete parsedFilter.profileId;\n }\n\n // if (parsedFilter.ownerId && entityConfig.OWNER_ID_FIELD_NAME) {\n // parsedFilter[entityConfig.OWNER_ID_FIELD_NAME] = parsedFilter.ownerId;\n // if (entityConfig.OWNER_ID_FIELD_NAME !== parsedFilter.ownerId) delete parsedFilter.ownerId;\n // }\n log.debug(\"parsedFilter\", parsedFilter);\n\n return parsedFilter;\n }\n private setSystemData(itemNew: Partial<T>, action: Action, requestUser?: string | CognitoUser, itemOld?: T): T {\n if (!action || action === Action.DELETE || action === Action.READ) return itemNew as T;\n\n const date = dayjs().toISOString();\n const user = this.extractUser(requestUser);\n\n switch (action) {\n case Action.CREATE:\n return this.handleCreate(itemNew, user, date);\n case Action.UPDATE:\n return this.handleUpdate(itemNew, itemOld, user, date);\n default:\n return itemNew as T;\n }\n }\n\n private extractUser(requestUser?: string | CognitoUser): string {\n if (!requestUser) return \"system\";\n return typeof requestUser === \"string\" ? requestUser : requestUser.username;\n }\n\n private handleCreate(itemNew: Partial<T>, user: string, date: string): T {\n const dayjsData = dayjs(new Date(date));\n itemNew[this.config.DYNAMO_DB.MAP.partitionKey ?? \"id\"] = crypto.randomUUID();\n itemNew.createdAt = date;\n itemNew.createdBy = user;\n itemNew.year = dayjsData.year().toString();\n itemNew.yearMonth = dayjsData.year() + \"-\" + (dayjsData.month() + 1);\n\n if (!this.config.TRACE_CHANGE?.fields) return itemNew as T;\n\n itemNew.history = this.addHistory(itemNew.history, { action: Action.CREATE, user, date });\n return itemNew as T;\n }\n\n private handleUpdate(itemNew: Partial<T>, itemOld: T | undefined, user: string, date: string): T {\n itemNew.createdBy = itemNew.createdBy || itemOld?.createdBy;\n itemNew.updatedBy = itemNew.updatedBy || { username: user };\n itemNew.history = itemNew.history || itemOld?.history;\n\n if (!this.config.TRACE_CHANGE?.fields || !itemOld) return itemNew as T;\n\n delete itemNew.updatedBy;\n\n const changes = computeChangedFields(itemOld, itemNew, this.config.TRACE_CHANGE);\n if (changes.length > 0) {\n itemNew.history = this.addHistory(itemNew.history, {\n action: Action.UPDATE,\n user,\n date,\n changes,\n });\n }\n\n return itemNew as T;\n }\n\n private addHistory(history: ChangeHistory[] | undefined, entry: ChangeHistory): ChangeHistory[] {\n // skip empty or invalid history entries\n if (!entry.changes || entry.changes.length === 0) {\n return history || [];\n }\n\n // clone to avoid accidental mutation\n const newHistory = [...(history || [])];\n\n // optional: limit max history size (e.g., last 100 changes)\n const MAX_HISTORY_ENTRIES = 100;\n if (newHistory.length >= MAX_HISTORY_ENTRIES) {\n newHistory.shift(); // remove oldest\n }\n\n newHistory.push(entry);\n return newHistory;\n }\n\n private setIndexField(filter: Filter, config: EntityConfig) {\n if (!filter.indexName || !filter.indexValue) return filter;\n\n const indexMap = config.DYNAMO_DB.MAP;\n if (!indexMap || indexMap.size === 0) return filter;\n\n const indexConfig = indexMap.get(filter.indexName);\n if (!indexConfig) return filter;\n\n filter.indexName = indexConfig.field;\n }\n}\n"]}
|
|
@@ -374,8 +374,14 @@ function getTableName(eventSourceARN) {
|
|
|
374
374
|
function parseImage(image) {
|
|
375
375
|
if (!image)
|
|
376
376
|
return undefined;
|
|
377
|
-
|
|
378
|
-
|
|
377
|
+
try {
|
|
378
|
+
const img = image;
|
|
379
|
+
return (0, util_dynamodb_1.unmarshall)(img);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
log.error("cannot parse stream image to dynamoDB item");
|
|
383
|
+
throw new Error(error);
|
|
384
|
+
}
|
|
379
385
|
}
|
|
380
386
|
function parseEventToAction(action) {
|
|
381
387
|
switch (action) {
|
|
@@ -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 const img = image as Record<string, AttributeValue>;\n return unmarshall(img);\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 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"]}
|