@eresearchqut/ddb-repository 1.16.2 → 1.16.4
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/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +12 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -166,12 +166,10 @@ var DynamoDbRepository = class {
|
|
|
166
166
|
projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])]
|
|
167
167
|
} : query;
|
|
168
168
|
const items = await this.batchGetItems(keysBatch, batchProjectedQuery);
|
|
169
|
+
const gsiItemKey = (item) => this.rangKey ? `${String(item[this.hashKey])}\0${String(item[this.rangKey])}` : String(item[this.hashKey]);
|
|
170
|
+
const itemMap = new Map(items.map((item) => [gsiItemKey(item), item]));
|
|
169
171
|
const orderedItems = keysBatch.flatMap((key) => {
|
|
170
|
-
const
|
|
171
|
-
const match = items.find((item) => {
|
|
172
|
-
const t = item;
|
|
173
|
-
return t[this.hashKey] === k[this.hashKey] && (!this.rangKey || t[this.rangKey] === k[this.rangKey]);
|
|
174
|
-
});
|
|
172
|
+
const match = itemMap.get(gsiItemKey(key));
|
|
175
173
|
return match ? [match] : [];
|
|
176
174
|
});
|
|
177
175
|
if (projectedAttributes) {
|
|
@@ -198,8 +196,12 @@ var DynamoDbRepository = class {
|
|
|
198
196
|
...acc,
|
|
199
197
|
[`:${expressionAttributeKey(key)}`]: value
|
|
200
198
|
}), Object.assign({}));
|
|
201
|
-
const
|
|
202
|
-
const
|
|
199
|
+
const gsiKeyAttributes = index ? [this.hashKey, ...this.rangKey ? [this.rangKey] : []] : [];
|
|
200
|
+
const ProjectionExpression = index ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(",") : projectedAttributes ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(",") : void 0;
|
|
201
|
+
const projectionAttributeNames = index ? gsiKeyAttributes.reduce((acc, attr) => ({
|
|
202
|
+
...acc,
|
|
203
|
+
[`#${expressionAttributeKey(attr)}`]: attr
|
|
204
|
+
}), {}) : projectedAttributes ? projectedAttributes.reduce((reduction, attribute) => ({
|
|
203
205
|
...reduction,
|
|
204
206
|
[`#${expressionAttributeKey(attribute)}`]: attribute
|
|
205
207
|
}), Object.assign({})) : {};
|
|
@@ -244,12 +246,10 @@ var DynamoDbRepository = class {
|
|
|
244
246
|
projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])]
|
|
245
247
|
} : query;
|
|
246
248
|
const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);
|
|
249
|
+
const gsiItemKey = (item) => this.rangKey ? `${String(item[this.hashKey])}\0${String(item[this.rangKey])}` : String(item[this.hashKey]);
|
|
250
|
+
const itemMap = new Map(items.map((item) => [gsiItemKey(item), item]));
|
|
247
251
|
const orderedItems = collectedKeys.flatMap((key) => {
|
|
248
|
-
const
|
|
249
|
-
const match = items.find((item) => {
|
|
250
|
-
const t = item;
|
|
251
|
-
return t[this.hashKey] === k[this.hashKey] && (!this.rangKey || t[this.rangKey] === k[this.rangKey]);
|
|
252
|
-
});
|
|
252
|
+
const match = itemMap.get(gsiItemKey(key));
|
|
253
253
|
return match ? [match] : [];
|
|
254
254
|
});
|
|
255
255
|
if (projectedAttributes) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["GetItemCommand","PutItemCommand","DeleteItemCommand","ReturnValue","UpdateItemCommand","QueryCommand","isEqual","BatchGetItemCommand","BatchWriteItemCommand","ReturnConsumedCapacity"],"sources":["../src/DynamoDbRepository.ts","../src/consumed-capacity-middleware.ts","../src/JsonPointerRepository.ts"],"sourcesContent":["import {\n BatchGetItemCommand,\n BatchGetItemCommandInput,\n BatchWriteItemCommand,\n DeleteItemCommand,\n DynamoDBClient,\n GetItemCommand,\n paginateQuery,\n paginateScan,\n PutItemCommand,\n QueryCommand,\n QueryCommandInput,\n ReturnConsumedCapacity,\n ReturnValue,\n UpdateItemCommand,\n WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport {marshall, unmarshall, NativeAttributeValue} from \"@aws-sdk/util-dynamodb\";\nimport {replace, uniqWith, isEqual, pickBy} from \"lodash\";\n\nexport enum FilterOperator {\n EQUALS = \"=\",\n NOT_EQUALS = \"<>\",\n GREATER_THAN_OR_EQUALS = \">=\",\n GREATER_THAN = \">\",\n LESS_THAN = \"<\",\n LESS_THAN_OR_EQUALS = \"<=\",\n IN = \"IN\",\n BETWEEN = \"BETWEEN\",\n BEGINS_WITH = \"BEGINS_WITH\",\n CONTAINS = \"CONTAINS\",\n}\n\nexport interface FilterExpression {\n attribute: string;\n value:\n | string\n | number\n | boolean\n | Array<string | number>\n | [string, string]\n | [number, number];\n operator: FilterOperator;\n negate?: boolean;\n}\n\nexport interface FilterableQuery {\n filterExpressions: Array<FilterExpression>;\n}\n\nexport interface ProjectedQuery {\n projectedAttributes: string[];\n}\n\nexport interface IndexedQuery {\n index: string;\n}\n\nexport interface Query extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n [key: string]: unknown;\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n sortOrder?: \"ASC\" | \"DESC\";\n limit?: number\n}\n\nexport interface ScanQuery extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n limit?: number;\n}\n\nconst marshallKey = (key: unknown) =>\n marshall(key as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n\nconst expressionAttributeKey = (key: string) => replace(key, /-/g, \"_\");\n\nconst mapInKeys = (filterExpression: FilterExpression) =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.map(\n (_, index) => `:${expressionAttributeKey(filterExpression.attribute)}${index}`,\n )\n : `:${expressionAttributeKey(filterExpression.attribute)}`;\n\nconst mapFilterExpression = (filterExpression: FilterExpression) => {\n switch (filterExpression.operator) {\n case FilterOperator.IN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `(${mapInKeys(filterExpression)})`\n );\n case FilterOperator.BETWEEN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}0 AND :${expressionAttributeKey(filterExpression.attribute)}1`\n );\n case FilterOperator.BEGINS_WITH:\n case FilterOperator.CONTAINS:\n return (\n `${filterExpression.operator.toLowerCase()}(#${expressionAttributeKey(filterExpression.attribute)}, ` +\n `:${expressionAttributeKey(filterExpression.attribute)})`\n );\n default:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}`\n );\n }\n};\n\nconst mapFilterExpressions = (\n filterExpressions: Array<FilterExpression>,\n) =>\n filterExpressions\n .map((filterExpression) =>\n filterExpression.negate\n ? `NOT ${mapFilterExpression(filterExpression)}`\n : mapFilterExpression(filterExpression),\n )\n .join(\" AND \");\n\nconst mapFilterExpressionValues = (\n filterExpression: FilterExpression,\n): Record<string, string | number | boolean> =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.reduce(\n (reduction, value, index) => ({\n ...reduction,\n [`:${expressionAttributeKey(filterExpression.attribute)}${index}`]: value,\n }),\n Object.assign({}),\n )\n : {\n [`:${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.value,\n };\n\nconst paginate = <T>(array: Array<T>, pageSize: number) => {\n return array.reduce((acc, val, i) => {\n const idx = Math.floor(i / pageSize)\n const page = acc[idx] || (acc[idx] = [])\n page.push(val)\n return acc\n }, [] as Array<Array<T>>);\n}\n\nexport interface DynamoDbRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n hashKey: string;\n rangeKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\nexport interface PageResult<T> {\n items: Array<T>;\n cursor?: string;\n}\n\nexport class DynamoDbRepository<K, T> {\n private readonly dynamoDBClient: DynamoDBClient;\n private readonly tableName: string;\n private readonly hashKey: string;\n private readonly rangKey?: string;\n private readonly returnConsumedCapacity: ReturnConsumedCapacity | undefined;\n\n constructor(options: DynamoDbRepositoryOptions) {\n this.dynamoDBClient = options.client;\n this.tableName = options.tableName;\n this.hashKey = options.hashKey;\n this.rangKey = options.rangeKey;\n this.returnConsumedCapacity = options.returnConsumedCapacity ?? ReturnConsumedCapacity.TOTAL;\n }\n\n getItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient\n .send(\n new GetItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n )\n .then((result) =>\n result.Item ? unmarshall(result.Item) as T : undefined,\n )\n };\n\n putItem = async (key: K, record: T): Promise<T> => {\n const Item = marshall({...record, ...key} as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n return this.dynamoDBClient\n .send(\n new PutItemCommand({\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n Item,\n }),\n )\n .then(() => unmarshall(Item) as T);\n };\n\n deleteItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient.send(new DeleteItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnValues: ReturnValue.ALL_OLD,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })).then((result) => result.Attributes ?\n unmarshall(result.Attributes) as T : undefined);\n };\n\n\n updateItem = async (\n key: K,\n updates: Partial<T>,\n remove?: string[],\n ): Promise<T | undefined> => {\n const filteredUpdateEntries = Object.entries(updates).filter(([, value]) => value !== undefined);\n const hasUpdates = filteredUpdateEntries.length > 0;\n if (!hasUpdates && !remove?.length) {\n return this.getItem(key);\n }\n const setAttributesExpression = hasUpdates ? `SET ${filteredUpdateEntries\n .map(\n ([key]) =>\n `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`,\n )\n .join(\", \")}` : '';\n const removeAttributesExpression = remove?.length\n ? ` REMOVE ${remove.map((key) => `#${expressionAttributeKey(key)}`).join(\", \")}`\n : \"\";\n const removeAttributeNames = remove?.length\n ? remove.reduce(\n (acc, key) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n {} as Record<string, string>,\n )\n : {};\n const updateItemCommandInput = {\n TableName: this.tableName,\n Key: marshallKey(key),\n UpdateExpression: `${setAttributesExpression}${removeAttributesExpression}`,\n ExpressionAttributeNames: filteredUpdateEntries\n .reduce(\n (acc, [key]) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n Object.assign(\n removeAttributeNames,\n ),\n ) as Record<string, string>,\n ExpressionAttributeValues: hasUpdates ? marshall(\n filteredUpdateEntries.reduce(\n (acc, [key, value]) => ({\n ...acc,\n [`:${expressionAttributeKey(key)}`]: value,\n }),\n {} as Record<string, NativeAttributeValue>,\n ),\n {removeUndefinedValues: true},\n ) : undefined,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n };\n return this.dynamoDBClient\n .send(new UpdateItemCommand({...updateItemCommandInput, ReturnValues: 'ALL_NEW'}))\n .then((result) => result.Attributes ? unmarshall(result.Attributes) as T : undefined);\n };\n\n\n getItems = async (\n query: Query\n ): Promise<Array<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder,...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : {})\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (\n reduction: Record<string, string>,\n filterExpression: FilterExpression,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const Limit = limit;\n const ScanIndexForward = sortOrder === \"DESC\" ? false : undefined;\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit,\n ScanIndexForward\n };\n const paginator = paginateQuery(\n {client: this.dynamoDBClient, pageSize: 100},\n queryCommandInput,\n );\n\n if (index) {\n const collectedKeys: Array<K> = [];\n for await (const page of paginator) {\n if (page.Items) {\n collectedKeys.push(\n ...(page.Items.map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K)),\n )\n }\n if (limit && collectedKeys.length >= limit) break;\n }\n const keysBatch = limit ? collectedKeys.slice(0, limit) : collectedKeys;\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(keysBatch, batchProjectedQuery);\n const orderedItems = keysBatch.flatMap((key) => {\n const k = key as Record<string, unknown>;\n const match = items.find((item) => {\n const t = item as Record<string, unknown>;\n return t[this.hashKey] === k[this.hashKey] &&\n (!this.rangKey || t[this.rangKey] === k[this.rangKey]);\n });\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return orderedItems.map(item =>\n pickBy(item as object, (_, key) => projSet.has(key)) as T\n ) as Array<T>;\n }\n return orderedItems as Array<T>;\n }\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n getItemsPage = async (\n query: Query & { cursor?: string }\n ): Promise<PageResult<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder, cursor, ...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const ProjectionExpression = !index && projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = !index && projectedAttributes ? projectedAttributes.reduce(\n (reduction: Record<string, string>, attribute: string) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n Object.assign({}),\n ) : {};\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (reduction: Record<string, string>, filterExpression: FilterExpression) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]: filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const ExclusiveStartKey = cursor\n ? JSON.parse(Buffer.from(cursor, 'base64').toString('utf-8')) as Record<string, unknown>\n : undefined;\n\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit: limit,\n ScanIndexForward: sortOrder === \"DESC\" ? false : undefined,\n ExclusiveStartKey: ExclusiveStartKey\n ? marshall(ExclusiveStartKey as Record<string, NativeAttributeValue>, {removeUndefinedValues: true})\n : undefined,\n };\n\n const result = await this.dynamoDBClient.send(new QueryCommand(queryCommandInput));\n const nextCursor = result.LastEvaluatedKey\n ? Buffer.from(JSON.stringify(unmarshall(result.LastEvaluatedKey))).toString('base64')\n : undefined;\n\n if (index) {\n const collectedKeys = (result.Items ?? [])\n .map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K\n );\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);\n const orderedItems = collectedKeys.flatMap((key) => {\n const k = key as Record<string, unknown>;\n const match = items.find((item) => {\n const t = item as Record<string, unknown>;\n return t[this.hashKey] === k[this.hashKey] &&\n (!this.rangKey || t[this.rangKey] === k[this.rangKey]);\n });\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return {\n items: orderedItems.map(item => pickBy(item as object, (_, key) => projSet.has(key)) as T),\n cursor: nextCursor,\n };\n }\n return {items: orderedItems, cursor: nextCursor};\n }\n\n const items = (result.Items ?? []).map((item) => unmarshall(item) as T);\n return {items, cursor: nextCursor};\n };\n\n\n scan = async (options?: ScanQuery): Promise<Array<T>> => {\n const { filterExpressions, projectedAttributes, limit, index } = options ?? {};\n\n const ProjectionExpression = projectedAttributes?.length\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = projectedAttributes?.length\n ? projectedAttributes.reduce(\n (acc: Record<string, string>, attribute: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n {},\n )\n : {};\n\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc: Record<string, string>, fe: FilterExpression) => ({\n ...acc,\n [`#${expressionAttributeKey(fe.attribute)}`]: fe.attribute,\n }),\n {},\n )\n : {};\n const filterAttributeValues = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc, fe) => ({ ...acc, ...mapFilterExpressionValues(fe) }),\n {} as Record<string, unknown>,\n )\n : {};\n\n const allAttributeNames = { ...filterAttributeNames, ...projectionAttributeNames };\n const ExpressionAttributeNames = Object.keys(allAttributeNames).length > 0 ? allAttributeNames : undefined;\n const ExpressionAttributeValues = hasFilterExpressions\n ? marshall(filterAttributeValues as Record<string, NativeAttributeValue>, { removeUndefinedValues: true })\n : undefined;\n\n const paginator = paginateScan(\n { client: this.dynamoDBClient, pageSize: 100 },\n {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames,\n ExpressionAttributeValues,\n },\n );\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n batchGetItems = async (\n keys: K[], projectedQuery?: ProjectedQuery\n ): Promise<Array<T>> => {\n const uniqueKeys = uniqWith(keys, isEqual);\n const keyPages = paginate(uniqueKeys, 100);\n const {projectedAttributes} = projectedQuery || {};\n const ProjectionExpression = projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const ExpressionAttributeNames = projectedAttributes ?\n projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : undefined;\n return Promise.all((keyPages.map(async (keyPage) => {\n const batchRequest: BatchGetItemCommandInput = {\n RequestItems: {\n [this.tableName]: {\n Keys: keyPage.map((key) => marshallKey(key)),\n ProjectionExpression,\n ExpressionAttributeNames,\n }\n },\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }\n\n const fetchPage = async (request: BatchGetItemCommandInput): Promise<T[]> => {\n const result = await this.dynamoDBClient.send(new BatchGetItemCommand(request));\n const retrieved = result.Responses?.[this.tableName]?.map((item) => unmarshall(item) as T) ?? [];\n const unprocessed = result.UnprocessedKeys;\n if (!unprocessed || Object.keys(unprocessed).length === 0) return retrieved;\n return [...retrieved, ...await fetchPage({\n RequestItems: unprocessed,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })];\n };\n\n return fetchPage(batchRequest);\n })))\n .then((itemSets) => itemSets.flat());\n };\n\n batchWriteItems = async (\n puts: { key: K; item: T }[],\n deletes: K[],\n ): Promise<void> => {\n const requests: WriteRequest[] = [\n ...puts.map(({ key, item }) => ({\n PutRequest: {\n Item: marshall(\n { ...item, ...key } as Record<string, NativeAttributeValue>,\n { removeUndefinedValues: true },\n ),\n },\n })),\n ...deletes.map((key) => ({\n DeleteRequest: { Key: marshallKey(key) },\n })),\n ];\n\n const sendBatch = async (requestItems: Record<string, WriteRequest[]>): Promise<void> => {\n const result = await this.dynamoDBClient.send(\n new BatchWriteItemCommand({\n RequestItems: requestItems,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n );\n const unprocessed = result.UnprocessedItems;\n if (unprocessed && Object.keys(unprocessed).length > 0) {\n await sendBatch(unprocessed as Record<string, WriteRequest[]>);\n }\n };\n\n await Promise.all(\n paginate(requests, 25).map(batch => sendBatch({ [this.tableName]: batch })),\n );\n };\n}\n\n","import {\n ConsumedCapacity,\n ReturnConsumedCapacity,\n ServiceInputTypes,\n ServiceOutputTypes,\n} from \"@aws-sdk/client-dynamodb\";\n\nimport {\n InitializeHandler,\n InitializeHandlerArguments,\n InitializeHandlerOutput,\n} from \"@smithy/types\";\n\nimport {get} from \"lodash\";\n\nexport interface ConsumedCapacityDetail {\n ReturnConsumedCapacity: ReturnConsumedCapacity | undefined\n ConsumedCapacity: ConsumedCapacity | ConsumedCapacity[] | undefined\n}\n\nexport interface ConsumedCapacityMiddlewareConfig {\n onConsumedCapacity: (consumedCapacity: ConsumedCapacityDetail) => Promise<unknown>;\n}\n\nexport const consumedCapacityMiddleware =\n (consumedCapacityMiddlewareConfig: ConsumedCapacityMiddlewareConfig) =>\n (next: InitializeHandler<ServiceInputTypes, ServiceOutputTypes>) =>\n async (args: InitializeHandlerArguments<ServiceInputTypes>): Promise<InitializeHandlerOutput<ServiceOutputTypes>> => {\n const {input} = args;\n const returnConsumedCapacity = get(input, \"ReturnConsumedCapacity\") as ReturnConsumedCapacity | undefined;\n const response = await next(args);\n const {output} = response;\n const consumedCapacity = get(output, \"ConsumedCapacity\") as ConsumedCapacity | ConsumedCapacity[] | undefined;\n await consumedCapacityMiddlewareConfig.onConsumedCapacity({ReturnConsumedCapacity: returnConsumedCapacity, ConsumedCapacity: consumedCapacity});\n return response;\n };","import { DynamoDBClient, ReturnConsumedCapacity } from \"@aws-sdk/client-dynamodb\";\nimport { DynamoDbRepository } from \"./DynamoDbRepository\";\n\nexport type JsonPointerValue = string | number | boolean | null;\n\nexport interface JsonPointerRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n idKey?: string;\n pointerKey?: string;\n valueKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\ntype PointerKey = Record<string, string>;\ntype PointerItem = Record<string, unknown>;\n\nconst isJsonPointerValue = (value: unknown): value is JsonPointerValue =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\";\n\nconst escapeToken = (token: string): string =>\n token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n\nconst unescapeToken = (token: string): string =>\n token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nconst validatePointer = (pointer: string): void => {\n if (!pointer.startsWith(\"/\")) {\n throw new TypeError(`Invalid JSON Pointer \"${pointer}\": must start with \"/\".`);\n }\n};\n\nconst flattenDocument = (doc: unknown, prefix = \"\"): Record<string, JsonPointerValue> => {\n if (doc === null) return { [prefix]: null };\n if (typeof doc !== \"object\") {\n if (isJsonPointerValue(doc)) {\n return { [prefix]: doc };\n }\n const pointer = prefix === \"\" ? \"/\" : prefix;\n throw new TypeError(\n `Unsupported value at JSON pointer \"${pointer}\": expected string, number, boolean, or null but received ${typeof doc}.`,\n );\n }\n\n const result: Record<string, JsonPointerValue> = {};\n\n if (Array.isArray(doc)) {\n for (let i = 0; i < doc.length; i++) {\n Object.assign(result, flattenDocument(doc[i], `${prefix}/${i}`));\n }\n } else {\n for (const [key, value] of Object.entries(doc)) {\n Object.assign(result, flattenDocument(value, `${prefix}/${escapeToken(key)}`));\n }\n }\n\n return result;\n};\n\nconst setAtPointer = (\n root: Record<string, unknown>,\n pointer: string,\n value: JsonPointerValue,\n): void => {\n const tokens = pointer.split(\"/\").slice(1).map(unescapeToken);\n if (tokens.length === 0) return;\n\n let current: Record<string, unknown> = root;\n for (let i = 0; i < tokens.length - 1; i++) {\n const token = tokens[i];\n const nextToken = tokens[i + 1];\n if (current[token] == null) {\n current[token] = /^\\d+$/.test(nextToken) ? [] : {};\n } else if (typeof current[token] !== \"object\") {\n throw new TypeError(\n `Conflicting pointers: cannot traverse \"${pointer}\" because \"/${tokens.slice(0, i + 1).join(\"/\")}\" already holds a primitive value.`,\n );\n }\n current = current[token] as Record<string, unknown>;\n }\n\n const lastToken = tokens[tokens.length - 1];\n current[lastToken] = value;\n};\n\nconst reconstructDocument = <T>(\n items: Array<{ pointer: string; value: JsonPointerValue }>,\n): T => {\n const root: Record<string, unknown> = {};\n const sorted = [...items].sort((a, b) => a.pointer.localeCompare(b.pointer));\n for (const item of sorted) {\n setAtPointer(root, item.pointer, item.value);\n }\n return root as T;\n};\n\n/**\n * Stores JSON documents as individual per-pointer DynamoDB items addressed by JSON Pointer (RFC 6901).\n *\n * Only JSON objects are supported as the root document (`T extends Record<string, unknown>`).\n * Root arrays and primitives are not supported. Documents must contain at least one leaf value;\n * empty objects and empty arrays are not supported.\n */\nexport class JsonPointerRepository<T extends Record<string, unknown>> {\n private readonly repository: DynamoDbRepository<PointerKey, PointerItem>;\n private readonly idKey: string;\n private readonly pointerKey: string;\n private readonly valueKey: string;\n\n constructor(options: JsonPointerRepositoryOptions) {\n const {\n client,\n tableName,\n idKey = \"id\",\n pointerKey = \"pointer\",\n valueKey = \"value\",\n returnConsumedCapacity,\n } = options;\n\n this.idKey = idKey;\n this.pointerKey = pointerKey;\n this.valueKey = valueKey;\n\n this.repository = new DynamoDbRepository<PointerKey, PointerItem>({\n client,\n tableName,\n hashKey: idKey,\n rangeKey: pointerKey,\n returnConsumedCapacity,\n });\n }\n\n putDocument = async (id: string, document: T): Promise<void> => {\n const flat = flattenDocument(document);\n const newPointers = Object.keys(flat);\n\n if (newPointers.length === 0) {\n throw new TypeError(\n \"Cannot store a document with no leaf values. Empty objects and arrays are not supported.\",\n );\n }\n\n const newPointerSet = new Set(newPointers);\n const existing = await this.repository.getItems({ [this.idKey]: id });\n const existingPointers = existing.map(item => item[this.pointerKey] as string);\n const stalePointers = existingPointers.filter(p => !newPointerSet.has(p));\n\n const puts = Object.entries(flat).map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = stalePointers.map(\n pointer => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey),\n );\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n\n getDocument = async (id: string): Promise<T | undefined> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (!items || items.length === 0) return undefined;\n\n return reconstructDocument<T>(\n items.map(item => ({\n pointer: item[this.pointerKey] as string,\n value: item[this.valueKey] as JsonPointerValue,\n })),\n );\n };\n\n getAttribute = async <V = JsonPointerValue>(\n id: string,\n pointer: string,\n ): Promise<V | undefined> => {\n validatePointer(pointer);\n const item = await this.repository.getItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n return item ? (item[this.valueKey] as V) : undefined;\n };\n\n putAttribute = async (\n id: string,\n pointer: string,\n value: JsonPointerValue,\n ): Promise<void> => {\n validatePointer(pointer);\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n await this.repository.putItem(key, { ...key, [this.valueKey]: value } as PointerItem);\n };\n\n deleteAttribute = async (id: string, pointer: string): Promise<void> => {\n validatePointer(pointer);\n await this.repository.deleteItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n };\n\n deleteDocument = async (id: string): Promise<void> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (items.length === 0) return;\n const deleteKeys = items.map(\n item => ({ [this.idKey]: id, [this.pointerKey]: item[this.pointerKey] as string } as PointerKey),\n );\n await this.repository.batchWriteItems([], deleteKeys);\n };\n\n listDocumentIds = async (): Promise<string[]> => {\n const items = await this.repository.scan({ projectedAttributes: [this.idKey] });\n const seen = new Set<string>();\n for (const item of items) {\n seen.add(item[this.idKey] as string);\n }\n return [...seen];\n };\n\n patchDocument = async (\n id: string,\n updates: Record<string, JsonPointerValue | undefined>,\n ): Promise<void> => {\n const entries = Object.entries(updates);\n if (entries.length === 0) return;\n entries.forEach(([pointer]) => validatePointer(pointer));\n const puts = entries\n .filter((entry): entry is [string, JsonPointerValue] => entry[1] !== undefined)\n .map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = entries\n .filter(([, value]) => value === undefined)\n .map(([pointer]) => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey));\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["GetItemCommand","PutItemCommand","DeleteItemCommand","ReturnValue","UpdateItemCommand","QueryCommand","isEqual","BatchGetItemCommand","BatchWriteItemCommand","ReturnConsumedCapacity"],"sources":["../src/DynamoDbRepository.ts","../src/consumed-capacity-middleware.ts","../src/JsonPointerRepository.ts"],"sourcesContent":["import {\n BatchGetItemCommand,\n BatchGetItemCommandInput,\n BatchWriteItemCommand,\n DeleteItemCommand,\n DynamoDBClient,\n GetItemCommand,\n paginateQuery,\n paginateScan,\n PutItemCommand,\n QueryCommand,\n QueryCommandInput,\n ReturnConsumedCapacity,\n ReturnValue,\n UpdateItemCommand,\n WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport {marshall, unmarshall, NativeAttributeValue} from \"@aws-sdk/util-dynamodb\";\nimport {replace, uniqWith, isEqual, pickBy} from \"lodash\";\n\nexport enum FilterOperator {\n EQUALS = \"=\",\n NOT_EQUALS = \"<>\",\n GREATER_THAN_OR_EQUALS = \">=\",\n GREATER_THAN = \">\",\n LESS_THAN = \"<\",\n LESS_THAN_OR_EQUALS = \"<=\",\n IN = \"IN\",\n BETWEEN = \"BETWEEN\",\n BEGINS_WITH = \"BEGINS_WITH\",\n CONTAINS = \"CONTAINS\",\n}\n\nexport interface FilterExpression {\n attribute: string;\n value:\n | string\n | number\n | boolean\n | Array<string | number>\n | [string, string]\n | [number, number];\n operator: FilterOperator;\n negate?: boolean;\n}\n\nexport interface FilterableQuery {\n filterExpressions: Array<FilterExpression>;\n}\n\nexport interface ProjectedQuery {\n projectedAttributes: string[];\n}\n\nexport interface IndexedQuery {\n index: string;\n}\n\nexport interface Query extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n [key: string]: unknown;\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n sortOrder?: \"ASC\" | \"DESC\";\n limit?: number\n}\n\nexport interface ScanQuery extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n limit?: number;\n}\n\nconst marshallKey = (key: unknown) =>\n marshall(key as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n\nconst expressionAttributeKey = (key: string) => replace(key, /-/g, \"_\");\n\nconst mapInKeys = (filterExpression: FilterExpression) =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.map(\n (_, index) => `:${expressionAttributeKey(filterExpression.attribute)}${index}`,\n )\n : `:${expressionAttributeKey(filterExpression.attribute)}`;\n\nconst mapFilterExpression = (filterExpression: FilterExpression) => {\n switch (filterExpression.operator) {\n case FilterOperator.IN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `(${mapInKeys(filterExpression)})`\n );\n case FilterOperator.BETWEEN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}0 AND :${expressionAttributeKey(filterExpression.attribute)}1`\n );\n case FilterOperator.BEGINS_WITH:\n case FilterOperator.CONTAINS:\n return (\n `${filterExpression.operator.toLowerCase()}(#${expressionAttributeKey(filterExpression.attribute)}, ` +\n `:${expressionAttributeKey(filterExpression.attribute)})`\n );\n default:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}`\n );\n }\n};\n\nconst mapFilterExpressions = (\n filterExpressions: Array<FilterExpression>,\n) =>\n filterExpressions\n .map((filterExpression) =>\n filterExpression.negate\n ? `NOT ${mapFilterExpression(filterExpression)}`\n : mapFilterExpression(filterExpression),\n )\n .join(\" AND \");\n\nconst mapFilterExpressionValues = (\n filterExpression: FilterExpression,\n): Record<string, string | number | boolean> =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.reduce(\n (reduction, value, index) => ({\n ...reduction,\n [`:${expressionAttributeKey(filterExpression.attribute)}${index}`]: value,\n }),\n Object.assign({}),\n )\n : {\n [`:${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.value,\n };\n\nconst paginate = <T>(array: Array<T>, pageSize: number) => {\n return array.reduce((acc, val, i) => {\n const idx = Math.floor(i / pageSize)\n const page = acc[idx] || (acc[idx] = [])\n page.push(val)\n return acc\n }, [] as Array<Array<T>>);\n}\n\nexport interface DynamoDbRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n hashKey: string;\n rangeKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\nexport interface PageResult<T> {\n items: Array<T>;\n cursor?: string;\n}\n\nexport class DynamoDbRepository<K, T> {\n private readonly dynamoDBClient: DynamoDBClient;\n private readonly tableName: string;\n private readonly hashKey: string;\n private readonly rangKey?: string;\n private readonly returnConsumedCapacity: ReturnConsumedCapacity | undefined;\n\n constructor(options: DynamoDbRepositoryOptions) {\n this.dynamoDBClient = options.client;\n this.tableName = options.tableName;\n this.hashKey = options.hashKey;\n this.rangKey = options.rangeKey;\n this.returnConsumedCapacity = options.returnConsumedCapacity ?? ReturnConsumedCapacity.TOTAL;\n }\n\n getItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient\n .send(\n new GetItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n )\n .then((result) =>\n result.Item ? unmarshall(result.Item) as T : undefined,\n )\n };\n\n putItem = async (key: K, record: T): Promise<T> => {\n const Item = marshall({...record, ...key} as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n return this.dynamoDBClient\n .send(\n new PutItemCommand({\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n Item,\n }),\n )\n .then(() => unmarshall(Item) as T);\n };\n\n deleteItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient.send(new DeleteItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnValues: ReturnValue.ALL_OLD,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })).then((result) => result.Attributes ?\n unmarshall(result.Attributes) as T : undefined);\n };\n\n\n updateItem = async (\n key: K,\n updates: Partial<T>,\n remove?: string[],\n ): Promise<T | undefined> => {\n const filteredUpdateEntries = Object.entries(updates).filter(([, value]) => value !== undefined);\n const hasUpdates = filteredUpdateEntries.length > 0;\n if (!hasUpdates && !remove?.length) {\n return this.getItem(key);\n }\n const setAttributesExpression = hasUpdates ? `SET ${filteredUpdateEntries\n .map(\n ([key]) =>\n `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`,\n )\n .join(\", \")}` : '';\n const removeAttributesExpression = remove?.length\n ? ` REMOVE ${remove.map((key) => `#${expressionAttributeKey(key)}`).join(\", \")}`\n : \"\";\n const removeAttributeNames = remove?.length\n ? remove.reduce(\n (acc, key) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n {} as Record<string, string>,\n )\n : {};\n const updateItemCommandInput = {\n TableName: this.tableName,\n Key: marshallKey(key),\n UpdateExpression: `${setAttributesExpression}${removeAttributesExpression}`,\n ExpressionAttributeNames: filteredUpdateEntries\n .reduce(\n (acc, [key]) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n Object.assign(\n removeAttributeNames,\n ),\n ) as Record<string, string>,\n ExpressionAttributeValues: hasUpdates ? marshall(\n filteredUpdateEntries.reduce(\n (acc, [key, value]) => ({\n ...acc,\n [`:${expressionAttributeKey(key)}`]: value,\n }),\n {} as Record<string, NativeAttributeValue>,\n ),\n {removeUndefinedValues: true},\n ) : undefined,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n };\n return this.dynamoDBClient\n .send(new UpdateItemCommand({...updateItemCommandInput, ReturnValues: 'ALL_NEW'}))\n .then((result) => result.Attributes ? unmarshall(result.Attributes) as T : undefined);\n };\n\n\n getItems = async (\n query: Query\n ): Promise<Array<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder,...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : {})\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (\n reduction: Record<string, string>,\n filterExpression: FilterExpression,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const Limit = limit;\n const ScanIndexForward = sortOrder === \"DESC\" ? false : undefined;\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit,\n ScanIndexForward\n };\n const paginator = paginateQuery(\n {client: this.dynamoDBClient, pageSize: 100},\n queryCommandInput,\n );\n\n if (index) {\n const collectedKeys: Array<K> = [];\n for await (const page of paginator) {\n if (page.Items) {\n collectedKeys.push(\n ...(page.Items.map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K)),\n )\n }\n if (limit && collectedKeys.length >= limit) break;\n }\n const keysBatch = limit ? collectedKeys.slice(0, limit) : collectedKeys;\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(keysBatch, batchProjectedQuery);\n const gsiItemKey = (item: Record<string, unknown>): string =>\n this.rangKey\n ? `${String(item[this.hashKey])}\\0${String(item[this.rangKey])}`\n : String(item[this.hashKey]);\n const itemMap = new Map<string, T>(\n items.map(item => [gsiItemKey(item as Record<string, unknown>), item])\n );\n const orderedItems = keysBatch.flatMap((key) => {\n const match = itemMap.get(gsiItemKey(key as Record<string, unknown>));\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return orderedItems.map(item =>\n pickBy(item as object, (_, key) => projSet.has(key)) as T\n ) as Array<T>;\n }\n return orderedItems as Array<T>;\n }\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n getItemsPage = async (\n query: Query & { cursor?: string }\n ): Promise<PageResult<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder, cursor, ...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (reduction: Record<string, string>, attribute: string) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n Object.assign({}),\n ) : {});\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (reduction: Record<string, string>, filterExpression: FilterExpression) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]: filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const ExclusiveStartKey = cursor\n ? JSON.parse(Buffer.from(cursor, 'base64').toString('utf-8')) as Record<string, unknown>\n : undefined;\n\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit: limit,\n ScanIndexForward: sortOrder === \"DESC\" ? false : undefined,\n ExclusiveStartKey: ExclusiveStartKey\n ? marshall(ExclusiveStartKey as Record<string, NativeAttributeValue>, {removeUndefinedValues: true})\n : undefined,\n };\n\n const result = await this.dynamoDBClient.send(new QueryCommand(queryCommandInput));\n const nextCursor = result.LastEvaluatedKey\n ? Buffer.from(JSON.stringify(unmarshall(result.LastEvaluatedKey))).toString('base64')\n : undefined;\n\n if (index) {\n const collectedKeys = (result.Items ?? [])\n .map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K\n );\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);\n const gsiItemKey = (item: Record<string, unknown>): string =>\n this.rangKey\n ? `${String(item[this.hashKey])}\\0${String(item[this.rangKey])}`\n : String(item[this.hashKey]);\n const itemMap = new Map<string, T>(\n items.map(item => [gsiItemKey(item as Record<string, unknown>), item])\n );\n const orderedItems = collectedKeys.flatMap((key) => {\n const match = itemMap.get(gsiItemKey(key as Record<string, unknown>));\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return {\n items: orderedItems.map(item => pickBy(item as object, (_, key) => projSet.has(key)) as T),\n cursor: nextCursor,\n };\n }\n return {items: orderedItems, cursor: nextCursor};\n }\n\n const items = (result.Items ?? []).map((item) => unmarshall(item) as T);\n return {items, cursor: nextCursor};\n };\n\n\n scan = async (options?: ScanQuery): Promise<Array<T>> => {\n const { filterExpressions, projectedAttributes, limit, index } = options ?? {};\n\n const ProjectionExpression = projectedAttributes?.length\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = projectedAttributes?.length\n ? projectedAttributes.reduce(\n (acc: Record<string, string>, attribute: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n {},\n )\n : {};\n\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc: Record<string, string>, fe: FilterExpression) => ({\n ...acc,\n [`#${expressionAttributeKey(fe.attribute)}`]: fe.attribute,\n }),\n {},\n )\n : {};\n const filterAttributeValues = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc, fe) => ({ ...acc, ...mapFilterExpressionValues(fe) }),\n {} as Record<string, unknown>,\n )\n : {};\n\n const allAttributeNames = { ...filterAttributeNames, ...projectionAttributeNames };\n const ExpressionAttributeNames = Object.keys(allAttributeNames).length > 0 ? allAttributeNames : undefined;\n const ExpressionAttributeValues = hasFilterExpressions\n ? marshall(filterAttributeValues as Record<string, NativeAttributeValue>, { removeUndefinedValues: true })\n : undefined;\n\n const paginator = paginateScan(\n { client: this.dynamoDBClient, pageSize: 100 },\n {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames,\n ExpressionAttributeValues,\n },\n );\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n batchGetItems = async (\n keys: K[], projectedQuery?: ProjectedQuery\n ): Promise<Array<T>> => {\n const uniqueKeys = uniqWith(keys, isEqual);\n const keyPages = paginate(uniqueKeys, 100);\n const {projectedAttributes} = projectedQuery || {};\n const ProjectionExpression = projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const ExpressionAttributeNames = projectedAttributes ?\n projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : undefined;\n return Promise.all((keyPages.map(async (keyPage) => {\n const batchRequest: BatchGetItemCommandInput = {\n RequestItems: {\n [this.tableName]: {\n Keys: keyPage.map((key) => marshallKey(key)),\n ProjectionExpression,\n ExpressionAttributeNames,\n }\n },\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }\n\n const fetchPage = async (request: BatchGetItemCommandInput): Promise<T[]> => {\n const result = await this.dynamoDBClient.send(new BatchGetItemCommand(request));\n const retrieved = result.Responses?.[this.tableName]?.map((item) => unmarshall(item) as T) ?? [];\n const unprocessed = result.UnprocessedKeys;\n if (!unprocessed || Object.keys(unprocessed).length === 0) return retrieved;\n return [...retrieved, ...await fetchPage({\n RequestItems: unprocessed,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })];\n };\n\n return fetchPage(batchRequest);\n })))\n .then((itemSets) => itemSets.flat());\n };\n\n batchWriteItems = async (\n puts: { key: K; item: T }[],\n deletes: K[],\n ): Promise<void> => {\n const requests: WriteRequest[] = [\n ...puts.map(({ key, item }) => ({\n PutRequest: {\n Item: marshall(\n { ...item, ...key } as Record<string, NativeAttributeValue>,\n { removeUndefinedValues: true },\n ),\n },\n })),\n ...deletes.map((key) => ({\n DeleteRequest: { Key: marshallKey(key) },\n })),\n ];\n\n const sendBatch = async (requestItems: Record<string, WriteRequest[]>): Promise<void> => {\n const result = await this.dynamoDBClient.send(\n new BatchWriteItemCommand({\n RequestItems: requestItems,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n );\n const unprocessed = result.UnprocessedItems;\n if (unprocessed && Object.keys(unprocessed).length > 0) {\n await sendBatch(unprocessed as Record<string, WriteRequest[]>);\n }\n };\n\n await Promise.all(\n paginate(requests, 25).map(batch => sendBatch({ [this.tableName]: batch })),\n );\n };\n}\n\n","import {\n ConsumedCapacity,\n ReturnConsumedCapacity,\n ServiceInputTypes,\n ServiceOutputTypes,\n} from \"@aws-sdk/client-dynamodb\";\n\nimport {\n InitializeHandler,\n InitializeHandlerArguments,\n InitializeHandlerOutput,\n} from \"@smithy/types\";\n\nimport {get} from \"lodash\";\n\nexport interface ConsumedCapacityDetail {\n ReturnConsumedCapacity: ReturnConsumedCapacity | undefined\n ConsumedCapacity: ConsumedCapacity | ConsumedCapacity[] | undefined\n}\n\nexport interface ConsumedCapacityMiddlewareConfig {\n onConsumedCapacity: (consumedCapacity: ConsumedCapacityDetail) => Promise<unknown>;\n}\n\nexport const consumedCapacityMiddleware =\n (consumedCapacityMiddlewareConfig: ConsumedCapacityMiddlewareConfig) =>\n (next: InitializeHandler<ServiceInputTypes, ServiceOutputTypes>) =>\n async (args: InitializeHandlerArguments<ServiceInputTypes>): Promise<InitializeHandlerOutput<ServiceOutputTypes>> => {\n const {input} = args;\n const returnConsumedCapacity = get(input, \"ReturnConsumedCapacity\") as ReturnConsumedCapacity | undefined;\n const response = await next(args);\n const {output} = response;\n const consumedCapacity = get(output, \"ConsumedCapacity\") as ConsumedCapacity | ConsumedCapacity[] | undefined;\n await consumedCapacityMiddlewareConfig.onConsumedCapacity({ReturnConsumedCapacity: returnConsumedCapacity, ConsumedCapacity: consumedCapacity});\n return response;\n };","import { DynamoDBClient, ReturnConsumedCapacity } from \"@aws-sdk/client-dynamodb\";\nimport { DynamoDbRepository } from \"./DynamoDbRepository\";\n\nexport type JsonPointerValue = string | number | boolean | null;\n\nexport interface JsonPointerRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n idKey?: string;\n pointerKey?: string;\n valueKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\ntype PointerKey = Record<string, string>;\ntype PointerItem = Record<string, unknown>;\n\nconst isJsonPointerValue = (value: unknown): value is JsonPointerValue =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\";\n\nconst escapeToken = (token: string): string =>\n token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n\nconst unescapeToken = (token: string): string =>\n token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nconst validatePointer = (pointer: string): void => {\n if (!pointer.startsWith(\"/\")) {\n throw new TypeError(`Invalid JSON Pointer \"${pointer}\": must start with \"/\".`);\n }\n};\n\nconst flattenDocument = (doc: unknown, prefix = \"\"): Record<string, JsonPointerValue> => {\n if (doc === null) return { [prefix]: null };\n if (typeof doc !== \"object\") {\n if (isJsonPointerValue(doc)) {\n return { [prefix]: doc };\n }\n const pointer = prefix === \"\" ? \"/\" : prefix;\n throw new TypeError(\n `Unsupported value at JSON pointer \"${pointer}\": expected string, number, boolean, or null but received ${typeof doc}.`,\n );\n }\n\n const result: Record<string, JsonPointerValue> = {};\n\n if (Array.isArray(doc)) {\n for (let i = 0; i < doc.length; i++) {\n Object.assign(result, flattenDocument(doc[i], `${prefix}/${i}`));\n }\n } else {\n for (const [key, value] of Object.entries(doc)) {\n Object.assign(result, flattenDocument(value, `${prefix}/${escapeToken(key)}`));\n }\n }\n\n return result;\n};\n\nconst setAtPointer = (\n root: Record<string, unknown>,\n pointer: string,\n value: JsonPointerValue,\n): void => {\n const tokens = pointer.split(\"/\").slice(1).map(unescapeToken);\n if (tokens.length === 0) return;\n\n let current: Record<string, unknown> = root;\n for (let i = 0; i < tokens.length - 1; i++) {\n const token = tokens[i];\n const nextToken = tokens[i + 1];\n if (current[token] == null) {\n current[token] = /^\\d+$/.test(nextToken) ? [] : {};\n } else if (typeof current[token] !== \"object\") {\n throw new TypeError(\n `Conflicting pointers: cannot traverse \"${pointer}\" because \"/${tokens.slice(0, i + 1).join(\"/\")}\" already holds a primitive value.`,\n );\n }\n current = current[token] as Record<string, unknown>;\n }\n\n const lastToken = tokens[tokens.length - 1];\n current[lastToken] = value;\n};\n\nconst reconstructDocument = <T>(\n items: Array<{ pointer: string; value: JsonPointerValue }>,\n): T => {\n const root: Record<string, unknown> = {};\n const sorted = [...items].sort((a, b) => a.pointer.localeCompare(b.pointer));\n for (const item of sorted) {\n setAtPointer(root, item.pointer, item.value);\n }\n return root as T;\n};\n\n/**\n * Stores JSON documents as individual per-pointer DynamoDB items addressed by JSON Pointer (RFC 6901).\n *\n * Only JSON objects are supported as the root document (`T extends Record<string, unknown>`).\n * Root arrays and primitives are not supported. Documents must contain at least one leaf value;\n * empty objects and empty arrays are not supported.\n */\nexport class JsonPointerRepository<T extends Record<string, unknown>> {\n private readonly repository: DynamoDbRepository<PointerKey, PointerItem>;\n private readonly idKey: string;\n private readonly pointerKey: string;\n private readonly valueKey: string;\n\n constructor(options: JsonPointerRepositoryOptions) {\n const {\n client,\n tableName,\n idKey = \"id\",\n pointerKey = \"pointer\",\n valueKey = \"value\",\n returnConsumedCapacity,\n } = options;\n\n this.idKey = idKey;\n this.pointerKey = pointerKey;\n this.valueKey = valueKey;\n\n this.repository = new DynamoDbRepository<PointerKey, PointerItem>({\n client,\n tableName,\n hashKey: idKey,\n rangeKey: pointerKey,\n returnConsumedCapacity,\n });\n }\n\n putDocument = async (id: string, document: T): Promise<void> => {\n const flat = flattenDocument(document);\n const newPointers = Object.keys(flat);\n\n if (newPointers.length === 0) {\n throw new TypeError(\n \"Cannot store a document with no leaf values. Empty objects and arrays are not supported.\",\n );\n }\n\n const newPointerSet = new Set(newPointers);\n const existing = await this.repository.getItems({ [this.idKey]: id });\n const existingPointers = existing.map(item => item[this.pointerKey] as string);\n const stalePointers = existingPointers.filter(p => !newPointerSet.has(p));\n\n const puts = Object.entries(flat).map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = stalePointers.map(\n pointer => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey),\n );\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n\n getDocument = async (id: string): Promise<T | undefined> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (!items || items.length === 0) return undefined;\n\n return reconstructDocument<T>(\n items.map(item => ({\n pointer: item[this.pointerKey] as string,\n value: item[this.valueKey] as JsonPointerValue,\n })),\n );\n };\n\n getAttribute = async <V = JsonPointerValue>(\n id: string,\n pointer: string,\n ): Promise<V | undefined> => {\n validatePointer(pointer);\n const item = await this.repository.getItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n return item ? (item[this.valueKey] as V) : undefined;\n };\n\n putAttribute = async (\n id: string,\n pointer: string,\n value: JsonPointerValue,\n ): Promise<void> => {\n validatePointer(pointer);\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n await this.repository.putItem(key, { ...key, [this.valueKey]: value } as PointerItem);\n };\n\n deleteAttribute = async (id: string, pointer: string): Promise<void> => {\n validatePointer(pointer);\n await this.repository.deleteItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n };\n\n deleteDocument = async (id: string): Promise<void> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (items.length === 0) return;\n const deleteKeys = items.map(\n item => ({ [this.idKey]: id, [this.pointerKey]: item[this.pointerKey] as string } as PointerKey),\n );\n await this.repository.batchWriteItems([], deleteKeys);\n };\n\n listDocumentIds = async (): Promise<string[]> => {\n const items = await this.repository.scan({ projectedAttributes: [this.idKey] });\n const seen = new Set<string>();\n for (const item of items) {\n seen.add(item[this.idKey] as string);\n }\n return [...seen];\n };\n\n patchDocument = async (\n id: string,\n updates: Record<string, JsonPointerValue | undefined>,\n ): Promise<void> => {\n const entries = Object.entries(updates);\n if (entries.length === 0) return;\n entries.forEach(([pointer]) => validatePointer(pointer));\n const puts = entries\n .filter((entry): entry is [string, JsonPointerValue] => entry[1] !== undefined)\n .map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = entries\n .filter(([, value]) => value === undefined)\n .map(([pointer]) => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey));\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n}\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -165,12 +165,10 @@ var DynamoDbRepository = class {
|
|
|
165
165
|
projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])]
|
|
166
166
|
} : query;
|
|
167
167
|
const items = await this.batchGetItems(keysBatch, batchProjectedQuery);
|
|
168
|
+
const gsiItemKey = (item) => this.rangKey ? `${String(item[this.hashKey])}\0${String(item[this.rangKey])}` : String(item[this.hashKey]);
|
|
169
|
+
const itemMap = new Map(items.map((item) => [gsiItemKey(item), item]));
|
|
168
170
|
const orderedItems = keysBatch.flatMap((key) => {
|
|
169
|
-
const
|
|
170
|
-
const match = items.find((item) => {
|
|
171
|
-
const t = item;
|
|
172
|
-
return t[this.hashKey] === k[this.hashKey] && (!this.rangKey || t[this.rangKey] === k[this.rangKey]);
|
|
173
|
-
});
|
|
171
|
+
const match = itemMap.get(gsiItemKey(key));
|
|
174
172
|
return match ? [match] : [];
|
|
175
173
|
});
|
|
176
174
|
if (projectedAttributes) {
|
|
@@ -197,8 +195,12 @@ var DynamoDbRepository = class {
|
|
|
197
195
|
...acc,
|
|
198
196
|
[`:${expressionAttributeKey(key)}`]: value
|
|
199
197
|
}), Object.assign({}));
|
|
200
|
-
const
|
|
201
|
-
const
|
|
198
|
+
const gsiKeyAttributes = index ? [this.hashKey, ...this.rangKey ? [this.rangKey] : []] : [];
|
|
199
|
+
const ProjectionExpression = index ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(",") : projectedAttributes ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(",") : void 0;
|
|
200
|
+
const projectionAttributeNames = index ? gsiKeyAttributes.reduce((acc, attr) => ({
|
|
201
|
+
...acc,
|
|
202
|
+
[`#${expressionAttributeKey(attr)}`]: attr
|
|
203
|
+
}), {}) : projectedAttributes ? projectedAttributes.reduce((reduction, attribute) => ({
|
|
202
204
|
...reduction,
|
|
203
205
|
[`#${expressionAttributeKey(attribute)}`]: attribute
|
|
204
206
|
}), Object.assign({})) : {};
|
|
@@ -243,12 +245,10 @@ var DynamoDbRepository = class {
|
|
|
243
245
|
projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])]
|
|
244
246
|
} : query;
|
|
245
247
|
const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);
|
|
248
|
+
const gsiItemKey = (item) => this.rangKey ? `${String(item[this.hashKey])}\0${String(item[this.rangKey])}` : String(item[this.hashKey]);
|
|
249
|
+
const itemMap = new Map(items.map((item) => [gsiItemKey(item), item]));
|
|
246
250
|
const orderedItems = collectedKeys.flatMap((key) => {
|
|
247
|
-
const
|
|
248
|
-
const match = items.find((item) => {
|
|
249
|
-
const t = item;
|
|
250
|
-
return t[this.hashKey] === k[this.hashKey] && (!this.rangKey || t[this.rangKey] === k[this.rangKey]);
|
|
251
|
-
});
|
|
251
|
+
const match = itemMap.get(gsiItemKey(key));
|
|
252
252
|
return match ? [match] : [];
|
|
253
253
|
});
|
|
254
254
|
if (projectedAttributes) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/DynamoDbRepository.ts","../src/consumed-capacity-middleware.ts","../src/JsonPointerRepository.ts"],"sourcesContent":["import {\n BatchGetItemCommand,\n BatchGetItemCommandInput,\n BatchWriteItemCommand,\n DeleteItemCommand,\n DynamoDBClient,\n GetItemCommand,\n paginateQuery,\n paginateScan,\n PutItemCommand,\n QueryCommand,\n QueryCommandInput,\n ReturnConsumedCapacity,\n ReturnValue,\n UpdateItemCommand,\n WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport {marshall, unmarshall, NativeAttributeValue} from \"@aws-sdk/util-dynamodb\";\nimport {replace, uniqWith, isEqual, pickBy} from \"lodash\";\n\nexport enum FilterOperator {\n EQUALS = \"=\",\n NOT_EQUALS = \"<>\",\n GREATER_THAN_OR_EQUALS = \">=\",\n GREATER_THAN = \">\",\n LESS_THAN = \"<\",\n LESS_THAN_OR_EQUALS = \"<=\",\n IN = \"IN\",\n BETWEEN = \"BETWEEN\",\n BEGINS_WITH = \"BEGINS_WITH\",\n CONTAINS = \"CONTAINS\",\n}\n\nexport interface FilterExpression {\n attribute: string;\n value:\n | string\n | number\n | boolean\n | Array<string | number>\n | [string, string]\n | [number, number];\n operator: FilterOperator;\n negate?: boolean;\n}\n\nexport interface FilterableQuery {\n filterExpressions: Array<FilterExpression>;\n}\n\nexport interface ProjectedQuery {\n projectedAttributes: string[];\n}\n\nexport interface IndexedQuery {\n index: string;\n}\n\nexport interface Query extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n [key: string]: unknown;\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n sortOrder?: \"ASC\" | \"DESC\";\n limit?: number\n}\n\nexport interface ScanQuery extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n limit?: number;\n}\n\nconst marshallKey = (key: unknown) =>\n marshall(key as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n\nconst expressionAttributeKey = (key: string) => replace(key, /-/g, \"_\");\n\nconst mapInKeys = (filterExpression: FilterExpression) =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.map(\n (_, index) => `:${expressionAttributeKey(filterExpression.attribute)}${index}`,\n )\n : `:${expressionAttributeKey(filterExpression.attribute)}`;\n\nconst mapFilterExpression = (filterExpression: FilterExpression) => {\n switch (filterExpression.operator) {\n case FilterOperator.IN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `(${mapInKeys(filterExpression)})`\n );\n case FilterOperator.BETWEEN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}0 AND :${expressionAttributeKey(filterExpression.attribute)}1`\n );\n case FilterOperator.BEGINS_WITH:\n case FilterOperator.CONTAINS:\n return (\n `${filterExpression.operator.toLowerCase()}(#${expressionAttributeKey(filterExpression.attribute)}, ` +\n `:${expressionAttributeKey(filterExpression.attribute)})`\n );\n default:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}`\n );\n }\n};\n\nconst mapFilterExpressions = (\n filterExpressions: Array<FilterExpression>,\n) =>\n filterExpressions\n .map((filterExpression) =>\n filterExpression.negate\n ? `NOT ${mapFilterExpression(filterExpression)}`\n : mapFilterExpression(filterExpression),\n )\n .join(\" AND \");\n\nconst mapFilterExpressionValues = (\n filterExpression: FilterExpression,\n): Record<string, string | number | boolean> =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.reduce(\n (reduction, value, index) => ({\n ...reduction,\n [`:${expressionAttributeKey(filterExpression.attribute)}${index}`]: value,\n }),\n Object.assign({}),\n )\n : {\n [`:${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.value,\n };\n\nconst paginate = <T>(array: Array<T>, pageSize: number) => {\n return array.reduce((acc, val, i) => {\n const idx = Math.floor(i / pageSize)\n const page = acc[idx] || (acc[idx] = [])\n page.push(val)\n return acc\n }, [] as Array<Array<T>>);\n}\n\nexport interface DynamoDbRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n hashKey: string;\n rangeKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\nexport interface PageResult<T> {\n items: Array<T>;\n cursor?: string;\n}\n\nexport class DynamoDbRepository<K, T> {\n private readonly dynamoDBClient: DynamoDBClient;\n private readonly tableName: string;\n private readonly hashKey: string;\n private readonly rangKey?: string;\n private readonly returnConsumedCapacity: ReturnConsumedCapacity | undefined;\n\n constructor(options: DynamoDbRepositoryOptions) {\n this.dynamoDBClient = options.client;\n this.tableName = options.tableName;\n this.hashKey = options.hashKey;\n this.rangKey = options.rangeKey;\n this.returnConsumedCapacity = options.returnConsumedCapacity ?? ReturnConsumedCapacity.TOTAL;\n }\n\n getItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient\n .send(\n new GetItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n )\n .then((result) =>\n result.Item ? unmarshall(result.Item) as T : undefined,\n )\n };\n\n putItem = async (key: K, record: T): Promise<T> => {\n const Item = marshall({...record, ...key} as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n return this.dynamoDBClient\n .send(\n new PutItemCommand({\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n Item,\n }),\n )\n .then(() => unmarshall(Item) as T);\n };\n\n deleteItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient.send(new DeleteItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnValues: ReturnValue.ALL_OLD,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })).then((result) => result.Attributes ?\n unmarshall(result.Attributes) as T : undefined);\n };\n\n\n updateItem = async (\n key: K,\n updates: Partial<T>,\n remove?: string[],\n ): Promise<T | undefined> => {\n const filteredUpdateEntries = Object.entries(updates).filter(([, value]) => value !== undefined);\n const hasUpdates = filteredUpdateEntries.length > 0;\n if (!hasUpdates && !remove?.length) {\n return this.getItem(key);\n }\n const setAttributesExpression = hasUpdates ? `SET ${filteredUpdateEntries\n .map(\n ([key]) =>\n `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`,\n )\n .join(\", \")}` : '';\n const removeAttributesExpression = remove?.length\n ? ` REMOVE ${remove.map((key) => `#${expressionAttributeKey(key)}`).join(\", \")}`\n : \"\";\n const removeAttributeNames = remove?.length\n ? remove.reduce(\n (acc, key) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n {} as Record<string, string>,\n )\n : {};\n const updateItemCommandInput = {\n TableName: this.tableName,\n Key: marshallKey(key),\n UpdateExpression: `${setAttributesExpression}${removeAttributesExpression}`,\n ExpressionAttributeNames: filteredUpdateEntries\n .reduce(\n (acc, [key]) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n Object.assign(\n removeAttributeNames,\n ),\n ) as Record<string, string>,\n ExpressionAttributeValues: hasUpdates ? marshall(\n filteredUpdateEntries.reduce(\n (acc, [key, value]) => ({\n ...acc,\n [`:${expressionAttributeKey(key)}`]: value,\n }),\n {} as Record<string, NativeAttributeValue>,\n ),\n {removeUndefinedValues: true},\n ) : undefined,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n };\n return this.dynamoDBClient\n .send(new UpdateItemCommand({...updateItemCommandInput, ReturnValues: 'ALL_NEW'}))\n .then((result) => result.Attributes ? unmarshall(result.Attributes) as T : undefined);\n };\n\n\n getItems = async (\n query: Query\n ): Promise<Array<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder,...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : {})\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (\n reduction: Record<string, string>,\n filterExpression: FilterExpression,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const Limit = limit;\n const ScanIndexForward = sortOrder === \"DESC\" ? false : undefined;\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit,\n ScanIndexForward\n };\n const paginator = paginateQuery(\n {client: this.dynamoDBClient, pageSize: 100},\n queryCommandInput,\n );\n\n if (index) {\n const collectedKeys: Array<K> = [];\n for await (const page of paginator) {\n if (page.Items) {\n collectedKeys.push(\n ...(page.Items.map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K)),\n )\n }\n if (limit && collectedKeys.length >= limit) break;\n }\n const keysBatch = limit ? collectedKeys.slice(0, limit) : collectedKeys;\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(keysBatch, batchProjectedQuery);\n const orderedItems = keysBatch.flatMap((key) => {\n const k = key as Record<string, unknown>;\n const match = items.find((item) => {\n const t = item as Record<string, unknown>;\n return t[this.hashKey] === k[this.hashKey] &&\n (!this.rangKey || t[this.rangKey] === k[this.rangKey]);\n });\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return orderedItems.map(item =>\n pickBy(item as object, (_, key) => projSet.has(key)) as T\n ) as Array<T>;\n }\n return orderedItems as Array<T>;\n }\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n getItemsPage = async (\n query: Query & { cursor?: string }\n ): Promise<PageResult<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder, cursor, ...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const ProjectionExpression = !index && projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = !index && projectedAttributes ? projectedAttributes.reduce(\n (reduction: Record<string, string>, attribute: string) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n Object.assign({}),\n ) : {};\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (reduction: Record<string, string>, filterExpression: FilterExpression) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]: filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const ExclusiveStartKey = cursor\n ? JSON.parse(Buffer.from(cursor, 'base64').toString('utf-8')) as Record<string, unknown>\n : undefined;\n\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit: limit,\n ScanIndexForward: sortOrder === \"DESC\" ? false : undefined,\n ExclusiveStartKey: ExclusiveStartKey\n ? marshall(ExclusiveStartKey as Record<string, NativeAttributeValue>, {removeUndefinedValues: true})\n : undefined,\n };\n\n const result = await this.dynamoDBClient.send(new QueryCommand(queryCommandInput));\n const nextCursor = result.LastEvaluatedKey\n ? Buffer.from(JSON.stringify(unmarshall(result.LastEvaluatedKey))).toString('base64')\n : undefined;\n\n if (index) {\n const collectedKeys = (result.Items ?? [])\n .map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K\n );\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);\n const orderedItems = collectedKeys.flatMap((key) => {\n const k = key as Record<string, unknown>;\n const match = items.find((item) => {\n const t = item as Record<string, unknown>;\n return t[this.hashKey] === k[this.hashKey] &&\n (!this.rangKey || t[this.rangKey] === k[this.rangKey]);\n });\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return {\n items: orderedItems.map(item => pickBy(item as object, (_, key) => projSet.has(key)) as T),\n cursor: nextCursor,\n };\n }\n return {items: orderedItems, cursor: nextCursor};\n }\n\n const items = (result.Items ?? []).map((item) => unmarshall(item) as T);\n return {items, cursor: nextCursor};\n };\n\n\n scan = async (options?: ScanQuery): Promise<Array<T>> => {\n const { filterExpressions, projectedAttributes, limit, index } = options ?? {};\n\n const ProjectionExpression = projectedAttributes?.length\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = projectedAttributes?.length\n ? projectedAttributes.reduce(\n (acc: Record<string, string>, attribute: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n {},\n )\n : {};\n\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc: Record<string, string>, fe: FilterExpression) => ({\n ...acc,\n [`#${expressionAttributeKey(fe.attribute)}`]: fe.attribute,\n }),\n {},\n )\n : {};\n const filterAttributeValues = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc, fe) => ({ ...acc, ...mapFilterExpressionValues(fe) }),\n {} as Record<string, unknown>,\n )\n : {};\n\n const allAttributeNames = { ...filterAttributeNames, ...projectionAttributeNames };\n const ExpressionAttributeNames = Object.keys(allAttributeNames).length > 0 ? allAttributeNames : undefined;\n const ExpressionAttributeValues = hasFilterExpressions\n ? marshall(filterAttributeValues as Record<string, NativeAttributeValue>, { removeUndefinedValues: true })\n : undefined;\n\n const paginator = paginateScan(\n { client: this.dynamoDBClient, pageSize: 100 },\n {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames,\n ExpressionAttributeValues,\n },\n );\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n batchGetItems = async (\n keys: K[], projectedQuery?: ProjectedQuery\n ): Promise<Array<T>> => {\n const uniqueKeys = uniqWith(keys, isEqual);\n const keyPages = paginate(uniqueKeys, 100);\n const {projectedAttributes} = projectedQuery || {};\n const ProjectionExpression = projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const ExpressionAttributeNames = projectedAttributes ?\n projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : undefined;\n return Promise.all((keyPages.map(async (keyPage) => {\n const batchRequest: BatchGetItemCommandInput = {\n RequestItems: {\n [this.tableName]: {\n Keys: keyPage.map((key) => marshallKey(key)),\n ProjectionExpression,\n ExpressionAttributeNames,\n }\n },\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }\n\n const fetchPage = async (request: BatchGetItemCommandInput): Promise<T[]> => {\n const result = await this.dynamoDBClient.send(new BatchGetItemCommand(request));\n const retrieved = result.Responses?.[this.tableName]?.map((item) => unmarshall(item) as T) ?? [];\n const unprocessed = result.UnprocessedKeys;\n if (!unprocessed || Object.keys(unprocessed).length === 0) return retrieved;\n return [...retrieved, ...await fetchPage({\n RequestItems: unprocessed,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })];\n };\n\n return fetchPage(batchRequest);\n })))\n .then((itemSets) => itemSets.flat());\n };\n\n batchWriteItems = async (\n puts: { key: K; item: T }[],\n deletes: K[],\n ): Promise<void> => {\n const requests: WriteRequest[] = [\n ...puts.map(({ key, item }) => ({\n PutRequest: {\n Item: marshall(\n { ...item, ...key } as Record<string, NativeAttributeValue>,\n { removeUndefinedValues: true },\n ),\n },\n })),\n ...deletes.map((key) => ({\n DeleteRequest: { Key: marshallKey(key) },\n })),\n ];\n\n const sendBatch = async (requestItems: Record<string, WriteRequest[]>): Promise<void> => {\n const result = await this.dynamoDBClient.send(\n new BatchWriteItemCommand({\n RequestItems: requestItems,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n );\n const unprocessed = result.UnprocessedItems;\n if (unprocessed && Object.keys(unprocessed).length > 0) {\n await sendBatch(unprocessed as Record<string, WriteRequest[]>);\n }\n };\n\n await Promise.all(\n paginate(requests, 25).map(batch => sendBatch({ [this.tableName]: batch })),\n );\n };\n}\n\n","import {\n ConsumedCapacity,\n ReturnConsumedCapacity,\n ServiceInputTypes,\n ServiceOutputTypes,\n} from \"@aws-sdk/client-dynamodb\";\n\nimport {\n InitializeHandler,\n InitializeHandlerArguments,\n InitializeHandlerOutput,\n} from \"@smithy/types\";\n\nimport {get} from \"lodash\";\n\nexport interface ConsumedCapacityDetail {\n ReturnConsumedCapacity: ReturnConsumedCapacity | undefined\n ConsumedCapacity: ConsumedCapacity | ConsumedCapacity[] | undefined\n}\n\nexport interface ConsumedCapacityMiddlewareConfig {\n onConsumedCapacity: (consumedCapacity: ConsumedCapacityDetail) => Promise<unknown>;\n}\n\nexport const consumedCapacityMiddleware =\n (consumedCapacityMiddlewareConfig: ConsumedCapacityMiddlewareConfig) =>\n (next: InitializeHandler<ServiceInputTypes, ServiceOutputTypes>) =>\n async (args: InitializeHandlerArguments<ServiceInputTypes>): Promise<InitializeHandlerOutput<ServiceOutputTypes>> => {\n const {input} = args;\n const returnConsumedCapacity = get(input, \"ReturnConsumedCapacity\") as ReturnConsumedCapacity | undefined;\n const response = await next(args);\n const {output} = response;\n const consumedCapacity = get(output, \"ConsumedCapacity\") as ConsumedCapacity | ConsumedCapacity[] | undefined;\n await consumedCapacityMiddlewareConfig.onConsumedCapacity({ReturnConsumedCapacity: returnConsumedCapacity, ConsumedCapacity: consumedCapacity});\n return response;\n };","import { DynamoDBClient, ReturnConsumedCapacity } from \"@aws-sdk/client-dynamodb\";\nimport { DynamoDbRepository } from \"./DynamoDbRepository\";\n\nexport type JsonPointerValue = string | number | boolean | null;\n\nexport interface JsonPointerRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n idKey?: string;\n pointerKey?: string;\n valueKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\ntype PointerKey = Record<string, string>;\ntype PointerItem = Record<string, unknown>;\n\nconst isJsonPointerValue = (value: unknown): value is JsonPointerValue =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\";\n\nconst escapeToken = (token: string): string =>\n token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n\nconst unescapeToken = (token: string): string =>\n token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nconst validatePointer = (pointer: string): void => {\n if (!pointer.startsWith(\"/\")) {\n throw new TypeError(`Invalid JSON Pointer \"${pointer}\": must start with \"/\".`);\n }\n};\n\nconst flattenDocument = (doc: unknown, prefix = \"\"): Record<string, JsonPointerValue> => {\n if (doc === null) return { [prefix]: null };\n if (typeof doc !== \"object\") {\n if (isJsonPointerValue(doc)) {\n return { [prefix]: doc };\n }\n const pointer = prefix === \"\" ? \"/\" : prefix;\n throw new TypeError(\n `Unsupported value at JSON pointer \"${pointer}\": expected string, number, boolean, or null but received ${typeof doc}.`,\n );\n }\n\n const result: Record<string, JsonPointerValue> = {};\n\n if (Array.isArray(doc)) {\n for (let i = 0; i < doc.length; i++) {\n Object.assign(result, flattenDocument(doc[i], `${prefix}/${i}`));\n }\n } else {\n for (const [key, value] of Object.entries(doc)) {\n Object.assign(result, flattenDocument(value, `${prefix}/${escapeToken(key)}`));\n }\n }\n\n return result;\n};\n\nconst setAtPointer = (\n root: Record<string, unknown>,\n pointer: string,\n value: JsonPointerValue,\n): void => {\n const tokens = pointer.split(\"/\").slice(1).map(unescapeToken);\n if (tokens.length === 0) return;\n\n let current: Record<string, unknown> = root;\n for (let i = 0; i < tokens.length - 1; i++) {\n const token = tokens[i];\n const nextToken = tokens[i + 1];\n if (current[token] == null) {\n current[token] = /^\\d+$/.test(nextToken) ? [] : {};\n } else if (typeof current[token] !== \"object\") {\n throw new TypeError(\n `Conflicting pointers: cannot traverse \"${pointer}\" because \"/${tokens.slice(0, i + 1).join(\"/\")}\" already holds a primitive value.`,\n );\n }\n current = current[token] as Record<string, unknown>;\n }\n\n const lastToken = tokens[tokens.length - 1];\n current[lastToken] = value;\n};\n\nconst reconstructDocument = <T>(\n items: Array<{ pointer: string; value: JsonPointerValue }>,\n): T => {\n const root: Record<string, unknown> = {};\n const sorted = [...items].sort((a, b) => a.pointer.localeCompare(b.pointer));\n for (const item of sorted) {\n setAtPointer(root, item.pointer, item.value);\n }\n return root as T;\n};\n\n/**\n * Stores JSON documents as individual per-pointer DynamoDB items addressed by JSON Pointer (RFC 6901).\n *\n * Only JSON objects are supported as the root document (`T extends Record<string, unknown>`).\n * Root arrays and primitives are not supported. Documents must contain at least one leaf value;\n * empty objects and empty arrays are not supported.\n */\nexport class JsonPointerRepository<T extends Record<string, unknown>> {\n private readonly repository: DynamoDbRepository<PointerKey, PointerItem>;\n private readonly idKey: string;\n private readonly pointerKey: string;\n private readonly valueKey: string;\n\n constructor(options: JsonPointerRepositoryOptions) {\n const {\n client,\n tableName,\n idKey = \"id\",\n pointerKey = \"pointer\",\n valueKey = \"value\",\n returnConsumedCapacity,\n } = options;\n\n this.idKey = idKey;\n this.pointerKey = pointerKey;\n this.valueKey = valueKey;\n\n this.repository = new DynamoDbRepository<PointerKey, PointerItem>({\n client,\n tableName,\n hashKey: idKey,\n rangeKey: pointerKey,\n returnConsumedCapacity,\n });\n }\n\n putDocument = async (id: string, document: T): Promise<void> => {\n const flat = flattenDocument(document);\n const newPointers = Object.keys(flat);\n\n if (newPointers.length === 0) {\n throw new TypeError(\n \"Cannot store a document with no leaf values. Empty objects and arrays are not supported.\",\n );\n }\n\n const newPointerSet = new Set(newPointers);\n const existing = await this.repository.getItems({ [this.idKey]: id });\n const existingPointers = existing.map(item => item[this.pointerKey] as string);\n const stalePointers = existingPointers.filter(p => !newPointerSet.has(p));\n\n const puts = Object.entries(flat).map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = stalePointers.map(\n pointer => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey),\n );\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n\n getDocument = async (id: string): Promise<T | undefined> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (!items || items.length === 0) return undefined;\n\n return reconstructDocument<T>(\n items.map(item => ({\n pointer: item[this.pointerKey] as string,\n value: item[this.valueKey] as JsonPointerValue,\n })),\n );\n };\n\n getAttribute = async <V = JsonPointerValue>(\n id: string,\n pointer: string,\n ): Promise<V | undefined> => {\n validatePointer(pointer);\n const item = await this.repository.getItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n return item ? (item[this.valueKey] as V) : undefined;\n };\n\n putAttribute = async (\n id: string,\n pointer: string,\n value: JsonPointerValue,\n ): Promise<void> => {\n validatePointer(pointer);\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n await this.repository.putItem(key, { ...key, [this.valueKey]: value } as PointerItem);\n };\n\n deleteAttribute = async (id: string, pointer: string): Promise<void> => {\n validatePointer(pointer);\n await this.repository.deleteItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n };\n\n deleteDocument = async (id: string): Promise<void> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (items.length === 0) return;\n const deleteKeys = items.map(\n item => ({ [this.idKey]: id, [this.pointerKey]: item[this.pointerKey] as string } as PointerKey),\n );\n await this.repository.batchWriteItems([], deleteKeys);\n };\n\n listDocumentIds = async (): Promise<string[]> => {\n const items = await this.repository.scan({ projectedAttributes: [this.idKey] });\n const seen = new Set<string>();\n for (const item of items) {\n seen.add(item[this.idKey] as string);\n }\n return [...seen];\n };\n\n patchDocument = async (\n id: string,\n updates: Record<string, JsonPointerValue | undefined>,\n ): Promise<void> => {\n const entries = Object.entries(updates);\n if (entries.length === 0) return;\n entries.forEach(([pointer]) => validatePointer(pointer));\n const puts = entries\n .filter((entry): entry is [string, JsonPointerValue] => entry[1] !== undefined)\n .map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = entries\n .filter(([, value]) => value === undefined)\n .map(([pointer]) => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey));\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/DynamoDbRepository.ts","../src/consumed-capacity-middleware.ts","../src/JsonPointerRepository.ts"],"sourcesContent":["import {\n BatchGetItemCommand,\n BatchGetItemCommandInput,\n BatchWriteItemCommand,\n DeleteItemCommand,\n DynamoDBClient,\n GetItemCommand,\n paginateQuery,\n paginateScan,\n PutItemCommand,\n QueryCommand,\n QueryCommandInput,\n ReturnConsumedCapacity,\n ReturnValue,\n UpdateItemCommand,\n WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport {marshall, unmarshall, NativeAttributeValue} from \"@aws-sdk/util-dynamodb\";\nimport {replace, uniqWith, isEqual, pickBy} from \"lodash\";\n\nexport enum FilterOperator {\n EQUALS = \"=\",\n NOT_EQUALS = \"<>\",\n GREATER_THAN_OR_EQUALS = \">=\",\n GREATER_THAN = \">\",\n LESS_THAN = \"<\",\n LESS_THAN_OR_EQUALS = \"<=\",\n IN = \"IN\",\n BETWEEN = \"BETWEEN\",\n BEGINS_WITH = \"BEGINS_WITH\",\n CONTAINS = \"CONTAINS\",\n}\n\nexport interface FilterExpression {\n attribute: string;\n value:\n | string\n | number\n | boolean\n | Array<string | number>\n | [string, string]\n | [number, number];\n operator: FilterOperator;\n negate?: boolean;\n}\n\nexport interface FilterableQuery {\n filterExpressions: Array<FilterExpression>;\n}\n\nexport interface ProjectedQuery {\n projectedAttributes: string[];\n}\n\nexport interface IndexedQuery {\n index: string;\n}\n\nexport interface Query extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n [key: string]: unknown;\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n sortOrder?: \"ASC\" | \"DESC\";\n limit?: number\n}\n\nexport interface ScanQuery extends Partial<FilterableQuery>, Partial<ProjectedQuery>, Partial<IndexedQuery> {\n filterExpressions?: Array<FilterExpression>;\n projectedAttributes?: string[];\n index?: string;\n limit?: number;\n}\n\nconst marshallKey = (key: unknown) =>\n marshall(key as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n\nconst expressionAttributeKey = (key: string) => replace(key, /-/g, \"_\");\n\nconst mapInKeys = (filterExpression: FilterExpression) =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.map(\n (_, index) => `:${expressionAttributeKey(filterExpression.attribute)}${index}`,\n )\n : `:${expressionAttributeKey(filterExpression.attribute)}`;\n\nconst mapFilterExpression = (filterExpression: FilterExpression) => {\n switch (filterExpression.operator) {\n case FilterOperator.IN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `(${mapInKeys(filterExpression)})`\n );\n case FilterOperator.BETWEEN:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}0 AND :${expressionAttributeKey(filterExpression.attribute)}1`\n );\n case FilterOperator.BEGINS_WITH:\n case FilterOperator.CONTAINS:\n return (\n `${filterExpression.operator.toLowerCase()}(#${expressionAttributeKey(filterExpression.attribute)}, ` +\n `:${expressionAttributeKey(filterExpression.attribute)})`\n );\n default:\n return (\n `#${expressionAttributeKey(filterExpression.attribute)} ${filterExpression.operator} ` +\n `:${expressionAttributeKey(filterExpression.attribute)}`\n );\n }\n};\n\nconst mapFilterExpressions = (\n filterExpressions: Array<FilterExpression>,\n) =>\n filterExpressions\n .map((filterExpression) =>\n filterExpression.negate\n ? `NOT ${mapFilterExpression(filterExpression)}`\n : mapFilterExpression(filterExpression),\n )\n .join(\" AND \");\n\nconst mapFilterExpressionValues = (\n filterExpression: FilterExpression,\n): Record<string, string | number | boolean> =>\n Array.isArray(filterExpression.value)\n ? filterExpression.value.reduce(\n (reduction, value, index) => ({\n ...reduction,\n [`:${expressionAttributeKey(filterExpression.attribute)}${index}`]: value,\n }),\n Object.assign({}),\n )\n : {\n [`:${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.value,\n };\n\nconst paginate = <T>(array: Array<T>, pageSize: number) => {\n return array.reduce((acc, val, i) => {\n const idx = Math.floor(i / pageSize)\n const page = acc[idx] || (acc[idx] = [])\n page.push(val)\n return acc\n }, [] as Array<Array<T>>);\n}\n\nexport interface DynamoDbRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n hashKey: string;\n rangeKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\nexport interface PageResult<T> {\n items: Array<T>;\n cursor?: string;\n}\n\nexport class DynamoDbRepository<K, T> {\n private readonly dynamoDBClient: DynamoDBClient;\n private readonly tableName: string;\n private readonly hashKey: string;\n private readonly rangKey?: string;\n private readonly returnConsumedCapacity: ReturnConsumedCapacity | undefined;\n\n constructor(options: DynamoDbRepositoryOptions) {\n this.dynamoDBClient = options.client;\n this.tableName = options.tableName;\n this.hashKey = options.hashKey;\n this.rangKey = options.rangeKey;\n this.returnConsumedCapacity = options.returnConsumedCapacity ?? ReturnConsumedCapacity.TOTAL;\n }\n\n getItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient\n .send(\n new GetItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n )\n .then((result) =>\n result.Item ? unmarshall(result.Item) as T : undefined,\n )\n };\n\n putItem = async (key: K, record: T): Promise<T> => {\n const Item = marshall({...record, ...key} as Record<string, NativeAttributeValue>, {removeUndefinedValues: true});\n return this.dynamoDBClient\n .send(\n new PutItemCommand({\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n Item,\n }),\n )\n .then(() => unmarshall(Item) as T);\n };\n\n deleteItem = async (key: K): Promise<T | undefined> => {\n return this.dynamoDBClient.send(new DeleteItemCommand({\n TableName: this.tableName,\n Key: marshallKey(key),\n ReturnValues: ReturnValue.ALL_OLD,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })).then((result) => result.Attributes ?\n unmarshall(result.Attributes) as T : undefined);\n };\n\n\n updateItem = async (\n key: K,\n updates: Partial<T>,\n remove?: string[],\n ): Promise<T | undefined> => {\n const filteredUpdateEntries = Object.entries(updates).filter(([, value]) => value !== undefined);\n const hasUpdates = filteredUpdateEntries.length > 0;\n if (!hasUpdates && !remove?.length) {\n return this.getItem(key);\n }\n const setAttributesExpression = hasUpdates ? `SET ${filteredUpdateEntries\n .map(\n ([key]) =>\n `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`,\n )\n .join(\", \")}` : '';\n const removeAttributesExpression = remove?.length\n ? ` REMOVE ${remove.map((key) => `#${expressionAttributeKey(key)}`).join(\", \")}`\n : \"\";\n const removeAttributeNames = remove?.length\n ? remove.reduce(\n (acc, key) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n {} as Record<string, string>,\n )\n : {};\n const updateItemCommandInput = {\n TableName: this.tableName,\n Key: marshallKey(key),\n UpdateExpression: `${setAttributesExpression}${removeAttributesExpression}`,\n ExpressionAttributeNames: filteredUpdateEntries\n .reduce(\n (acc, [key]) => ({\n ...acc,\n [`#${expressionAttributeKey(key)}`]: key,\n }),\n Object.assign(\n removeAttributeNames,\n ),\n ) as Record<string, string>,\n ExpressionAttributeValues: hasUpdates ? marshall(\n filteredUpdateEntries.reduce(\n (acc, [key, value]) => ({\n ...acc,\n [`:${expressionAttributeKey(key)}`]: value,\n }),\n {} as Record<string, NativeAttributeValue>,\n ),\n {removeUndefinedValues: true},\n ) : undefined,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n };\n return this.dynamoDBClient\n .send(new UpdateItemCommand({...updateItemCommandInput, ReturnValues: 'ALL_NEW'}))\n .then((result) => result.Attributes ? unmarshall(result.Attributes) as T : undefined);\n };\n\n\n getItems = async (\n query: Query\n ): Promise<Array<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder,...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : {})\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (\n reduction: Record<string, string>,\n filterExpression: FilterExpression,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]:\n filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const Limit = limit;\n const ScanIndexForward = sortOrder === \"DESC\" ? false : undefined;\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit,\n ScanIndexForward\n };\n const paginator = paginateQuery(\n {client: this.dynamoDBClient, pageSize: 100},\n queryCommandInput,\n );\n\n if (index) {\n const collectedKeys: Array<K> = [];\n for await (const page of paginator) {\n if (page.Items) {\n collectedKeys.push(\n ...(page.Items.map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K)),\n )\n }\n if (limit && collectedKeys.length >= limit) break;\n }\n const keysBatch = limit ? collectedKeys.slice(0, limit) : collectedKeys;\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(keysBatch, batchProjectedQuery);\n const gsiItemKey = (item: Record<string, unknown>): string =>\n this.rangKey\n ? `${String(item[this.hashKey])}\\0${String(item[this.rangKey])}`\n : String(item[this.hashKey]);\n const itemMap = new Map<string, T>(\n items.map(item => [gsiItemKey(item as Record<string, unknown>), item])\n );\n const orderedItems = keysBatch.flatMap((key) => {\n const match = itemMap.get(gsiItemKey(key as Record<string, unknown>));\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return orderedItems.map(item =>\n pickBy(item as object, (_, key) => projSet.has(key)) as T\n ) as Array<T>;\n }\n return orderedItems as Array<T>;\n }\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n getItemsPage = async (\n query: Query & { cursor?: string }\n ): Promise<PageResult<T>> => {\n const {index, filterExpressions, projectedAttributes, limit, sortOrder, cursor, ...keys} = query;\n const KeyConditionExpression = Object.keys(keys)\n .map((key) => `#${expressionAttributeKey(key)} = :${expressionAttributeKey(key)}`).join(' AND ');\n const keyExpressionAttributeNames = Object.keys(keys)\n .reduce((acc, key) => ({...acc, [`#${expressionAttributeKey(key)}`]: key}), Object.assign({}));\n const keyExpressionAttributeValues = Object.entries(keys)\n .reduce((acc, [key, value]) => ({...acc, [`:${expressionAttributeKey(key)}`]: value}), Object.assign({}));\n\n const gsiKeyAttributes = index\n ? [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])]\n : [];\n const ProjectionExpression = index\n ? gsiKeyAttributes.map((attr) => `#${expressionAttributeKey(attr)}`).join(',')\n : (projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined);\n const projectionAttributeNames: Record<string, string> = index\n ? gsiKeyAttributes.reduce(\n (acc: Record<string, string>, attr: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attr)}`]: attr,\n }),\n {},\n )\n : (projectedAttributes ? projectedAttributes.reduce(\n (reduction: Record<string, string>, attribute: string) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n Object.assign({}),\n ) : {});\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (reduction: Record<string, string>, filterExpression: FilterExpression) => ({\n ...reduction,\n [`#${expressionAttributeKey(filterExpression.attribute)}`]: filterExpression.attribute,\n }),\n Object.assign({}),\n )\n : {};\n const filterAttributeValues = filterExpressions\n ? filterExpressions.reduce(\n (reduction, filterExpression) => ({\n ...reduction,\n ...mapFilterExpressionValues(filterExpression),\n }),\n Object.assign({}),\n )\n : {};\n\n const ExclusiveStartKey = cursor\n ? JSON.parse(Buffer.from(cursor, 'base64').toString('utf-8')) as Record<string, unknown>\n : undefined;\n\n const queryCommandInput: QueryCommandInput = {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n KeyConditionExpression,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames: {\n ...keyExpressionAttributeNames,\n ...filterAttributeNames,\n ...projectionAttributeNames\n },\n ExpressionAttributeValues: marshall(\n {...keyExpressionAttributeValues, ...filterAttributeValues} as Record<string, NativeAttributeValue>,\n {removeUndefinedValues: true},\n ),\n Limit: limit,\n ScanIndexForward: sortOrder === \"DESC\" ? false : undefined,\n ExclusiveStartKey: ExclusiveStartKey\n ? marshall(ExclusiveStartKey as Record<string, NativeAttributeValue>, {removeUndefinedValues: true})\n : undefined,\n };\n\n const result = await this.dynamoDBClient.send(new QueryCommand(queryCommandInput));\n const nextCursor = result.LastEvaluatedKey\n ? Buffer.from(JSON.stringify(unmarshall(result.LastEvaluatedKey))).toString('base64')\n : undefined;\n\n if (index) {\n const collectedKeys = (result.Items ?? [])\n .map((item) => unmarshall(item) as T)\n .map((item: T) =>\n pickBy(item as object, (_, key) => (key === this.hashKey || key === this.rangKey)) as K\n );\n const keyAttrs = [this.hashKey, ...(this.rangKey ? [this.rangKey] : [])];\n const batchProjectedQuery = projectedAttributes\n ? { ...query, projectedAttributes: [...new Set([...projectedAttributes, ...keyAttrs])] } as ProjectedQuery\n : query as ProjectedQuery;\n const items = await this.batchGetItems(collectedKeys, batchProjectedQuery);\n const gsiItemKey = (item: Record<string, unknown>): string =>\n this.rangKey\n ? `${String(item[this.hashKey])}\\0${String(item[this.rangKey])}`\n : String(item[this.hashKey]);\n const itemMap = new Map<string, T>(\n items.map(item => [gsiItemKey(item as Record<string, unknown>), item])\n );\n const orderedItems = collectedKeys.flatMap((key) => {\n const match = itemMap.get(gsiItemKey(key as Record<string, unknown>));\n return match ? [match] : [];\n });\n if (projectedAttributes) {\n const projSet = new Set(projectedAttributes);\n return {\n items: orderedItems.map(item => pickBy(item as object, (_, key) => projSet.has(key)) as T),\n cursor: nextCursor,\n };\n }\n return {items: orderedItems, cursor: nextCursor};\n }\n\n const items = (result.Items ?? []).map((item) => unmarshall(item) as T);\n return {items, cursor: nextCursor};\n };\n\n\n scan = async (options?: ScanQuery): Promise<Array<T>> => {\n const { filterExpressions, projectedAttributes, limit, index } = options ?? {};\n\n const ProjectionExpression = projectedAttributes?.length\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const projectionAttributeNames: Record<string, string> = projectedAttributes?.length\n ? projectedAttributes.reduce(\n (acc: Record<string, string>, attribute: string) => ({\n ...acc,\n [`#${expressionAttributeKey(attribute)}`]: attribute,\n }),\n {},\n )\n : {};\n\n const hasFilterExpressions = Array.isArray(filterExpressions) && filterExpressions.length > 0;\n const FilterExpression = hasFilterExpressions\n ? mapFilterExpressions(filterExpressions!)\n : undefined;\n const filterAttributeNames: Record<string, string> = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc: Record<string, string>, fe: FilterExpression) => ({\n ...acc,\n [`#${expressionAttributeKey(fe.attribute)}`]: fe.attribute,\n }),\n {},\n )\n : {};\n const filterAttributeValues = hasFilterExpressions\n ? filterExpressions!.reduce(\n (acc, fe) => ({ ...acc, ...mapFilterExpressionValues(fe) }),\n {} as Record<string, unknown>,\n )\n : {};\n\n const allAttributeNames = { ...filterAttributeNames, ...projectionAttributeNames };\n const ExpressionAttributeNames = Object.keys(allAttributeNames).length > 0 ? allAttributeNames : undefined;\n const ExpressionAttributeValues = hasFilterExpressions\n ? marshall(filterAttributeValues as Record<string, NativeAttributeValue>, { removeUndefinedValues: true })\n : undefined;\n\n const paginator = paginateScan(\n { client: this.dynamoDBClient, pageSize: 100 },\n {\n TableName: this.tableName,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n IndexName: index,\n FilterExpression,\n ProjectionExpression,\n ExpressionAttributeNames,\n ExpressionAttributeValues,\n },\n );\n\n const items: Array<T> = [];\n for await (const page of paginator) {\n if (page.Items) {\n items.push(...page.Items.map((item) => unmarshall(item) as T));\n }\n if (limit && items.length >= limit) break;\n }\n return limit ? items.slice(0, limit) : items;\n };\n\n\n batchGetItems = async (\n keys: K[], projectedQuery?: ProjectedQuery\n ): Promise<Array<T>> => {\n const uniqueKeys = uniqWith(keys, isEqual);\n const keyPages = paginate(uniqueKeys, 100);\n const {projectedAttributes} = projectedQuery || {};\n const ProjectionExpression = projectedAttributes\n ? projectedAttributes.map((attribute) => `#${expressionAttributeKey(attribute)}`).join(',')\n : undefined;\n const ExpressionAttributeNames = projectedAttributes ?\n projectedAttributes.reduce(\n (\n reduction: Record<string, string>,\n attribute: string,\n ) => ({\n ...reduction,\n [`#${expressionAttributeKey(attribute)}`]:\n attribute,\n }),\n Object.assign({}),\n ) : undefined;\n return Promise.all((keyPages.map(async (keyPage) => {\n const batchRequest: BatchGetItemCommandInput = {\n RequestItems: {\n [this.tableName]: {\n Keys: keyPage.map((key) => marshallKey(key)),\n ProjectionExpression,\n ExpressionAttributeNames,\n }\n },\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }\n\n const fetchPage = async (request: BatchGetItemCommandInput): Promise<T[]> => {\n const result = await this.dynamoDBClient.send(new BatchGetItemCommand(request));\n const retrieved = result.Responses?.[this.tableName]?.map((item) => unmarshall(item) as T) ?? [];\n const unprocessed = result.UnprocessedKeys;\n if (!unprocessed || Object.keys(unprocessed).length === 0) return retrieved;\n return [...retrieved, ...await fetchPage({\n RequestItems: unprocessed,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n })];\n };\n\n return fetchPage(batchRequest);\n })))\n .then((itemSets) => itemSets.flat());\n };\n\n batchWriteItems = async (\n puts: { key: K; item: T }[],\n deletes: K[],\n ): Promise<void> => {\n const requests: WriteRequest[] = [\n ...puts.map(({ key, item }) => ({\n PutRequest: {\n Item: marshall(\n { ...item, ...key } as Record<string, NativeAttributeValue>,\n { removeUndefinedValues: true },\n ),\n },\n })),\n ...deletes.map((key) => ({\n DeleteRequest: { Key: marshallKey(key) },\n })),\n ];\n\n const sendBatch = async (requestItems: Record<string, WriteRequest[]>): Promise<void> => {\n const result = await this.dynamoDBClient.send(\n new BatchWriteItemCommand({\n RequestItems: requestItems,\n ReturnConsumedCapacity: this.returnConsumedCapacity,\n }),\n );\n const unprocessed = result.UnprocessedItems;\n if (unprocessed && Object.keys(unprocessed).length > 0) {\n await sendBatch(unprocessed as Record<string, WriteRequest[]>);\n }\n };\n\n await Promise.all(\n paginate(requests, 25).map(batch => sendBatch({ [this.tableName]: batch })),\n );\n };\n}\n\n","import {\n ConsumedCapacity,\n ReturnConsumedCapacity,\n ServiceInputTypes,\n ServiceOutputTypes,\n} from \"@aws-sdk/client-dynamodb\";\n\nimport {\n InitializeHandler,\n InitializeHandlerArguments,\n InitializeHandlerOutput,\n} from \"@smithy/types\";\n\nimport {get} from \"lodash\";\n\nexport interface ConsumedCapacityDetail {\n ReturnConsumedCapacity: ReturnConsumedCapacity | undefined\n ConsumedCapacity: ConsumedCapacity | ConsumedCapacity[] | undefined\n}\n\nexport interface ConsumedCapacityMiddlewareConfig {\n onConsumedCapacity: (consumedCapacity: ConsumedCapacityDetail) => Promise<unknown>;\n}\n\nexport const consumedCapacityMiddleware =\n (consumedCapacityMiddlewareConfig: ConsumedCapacityMiddlewareConfig) =>\n (next: InitializeHandler<ServiceInputTypes, ServiceOutputTypes>) =>\n async (args: InitializeHandlerArguments<ServiceInputTypes>): Promise<InitializeHandlerOutput<ServiceOutputTypes>> => {\n const {input} = args;\n const returnConsumedCapacity = get(input, \"ReturnConsumedCapacity\") as ReturnConsumedCapacity | undefined;\n const response = await next(args);\n const {output} = response;\n const consumedCapacity = get(output, \"ConsumedCapacity\") as ConsumedCapacity | ConsumedCapacity[] | undefined;\n await consumedCapacityMiddlewareConfig.onConsumedCapacity({ReturnConsumedCapacity: returnConsumedCapacity, ConsumedCapacity: consumedCapacity});\n return response;\n };","import { DynamoDBClient, ReturnConsumedCapacity } from \"@aws-sdk/client-dynamodb\";\nimport { DynamoDbRepository } from \"./DynamoDbRepository\";\n\nexport type JsonPointerValue = string | number | boolean | null;\n\nexport interface JsonPointerRepositoryOptions {\n client: DynamoDBClient;\n tableName: string;\n idKey?: string;\n pointerKey?: string;\n valueKey?: string;\n returnConsumedCapacity?: ReturnConsumedCapacity;\n}\n\ntype PointerKey = Record<string, string>;\ntype PointerItem = Record<string, unknown>;\n\nconst isJsonPointerValue = (value: unknown): value is JsonPointerValue =>\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\";\n\nconst escapeToken = (token: string): string =>\n token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n\nconst unescapeToken = (token: string): string =>\n token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nconst validatePointer = (pointer: string): void => {\n if (!pointer.startsWith(\"/\")) {\n throw new TypeError(`Invalid JSON Pointer \"${pointer}\": must start with \"/\".`);\n }\n};\n\nconst flattenDocument = (doc: unknown, prefix = \"\"): Record<string, JsonPointerValue> => {\n if (doc === null) return { [prefix]: null };\n if (typeof doc !== \"object\") {\n if (isJsonPointerValue(doc)) {\n return { [prefix]: doc };\n }\n const pointer = prefix === \"\" ? \"/\" : prefix;\n throw new TypeError(\n `Unsupported value at JSON pointer \"${pointer}\": expected string, number, boolean, or null but received ${typeof doc}.`,\n );\n }\n\n const result: Record<string, JsonPointerValue> = {};\n\n if (Array.isArray(doc)) {\n for (let i = 0; i < doc.length; i++) {\n Object.assign(result, flattenDocument(doc[i], `${prefix}/${i}`));\n }\n } else {\n for (const [key, value] of Object.entries(doc)) {\n Object.assign(result, flattenDocument(value, `${prefix}/${escapeToken(key)}`));\n }\n }\n\n return result;\n};\n\nconst setAtPointer = (\n root: Record<string, unknown>,\n pointer: string,\n value: JsonPointerValue,\n): void => {\n const tokens = pointer.split(\"/\").slice(1).map(unescapeToken);\n if (tokens.length === 0) return;\n\n let current: Record<string, unknown> = root;\n for (let i = 0; i < tokens.length - 1; i++) {\n const token = tokens[i];\n const nextToken = tokens[i + 1];\n if (current[token] == null) {\n current[token] = /^\\d+$/.test(nextToken) ? [] : {};\n } else if (typeof current[token] !== \"object\") {\n throw new TypeError(\n `Conflicting pointers: cannot traverse \"${pointer}\" because \"/${tokens.slice(0, i + 1).join(\"/\")}\" already holds a primitive value.`,\n );\n }\n current = current[token] as Record<string, unknown>;\n }\n\n const lastToken = tokens[tokens.length - 1];\n current[lastToken] = value;\n};\n\nconst reconstructDocument = <T>(\n items: Array<{ pointer: string; value: JsonPointerValue }>,\n): T => {\n const root: Record<string, unknown> = {};\n const sorted = [...items].sort((a, b) => a.pointer.localeCompare(b.pointer));\n for (const item of sorted) {\n setAtPointer(root, item.pointer, item.value);\n }\n return root as T;\n};\n\n/**\n * Stores JSON documents as individual per-pointer DynamoDB items addressed by JSON Pointer (RFC 6901).\n *\n * Only JSON objects are supported as the root document (`T extends Record<string, unknown>`).\n * Root arrays and primitives are not supported. Documents must contain at least one leaf value;\n * empty objects and empty arrays are not supported.\n */\nexport class JsonPointerRepository<T extends Record<string, unknown>> {\n private readonly repository: DynamoDbRepository<PointerKey, PointerItem>;\n private readonly idKey: string;\n private readonly pointerKey: string;\n private readonly valueKey: string;\n\n constructor(options: JsonPointerRepositoryOptions) {\n const {\n client,\n tableName,\n idKey = \"id\",\n pointerKey = \"pointer\",\n valueKey = \"value\",\n returnConsumedCapacity,\n } = options;\n\n this.idKey = idKey;\n this.pointerKey = pointerKey;\n this.valueKey = valueKey;\n\n this.repository = new DynamoDbRepository<PointerKey, PointerItem>({\n client,\n tableName,\n hashKey: idKey,\n rangeKey: pointerKey,\n returnConsumedCapacity,\n });\n }\n\n putDocument = async (id: string, document: T): Promise<void> => {\n const flat = flattenDocument(document);\n const newPointers = Object.keys(flat);\n\n if (newPointers.length === 0) {\n throw new TypeError(\n \"Cannot store a document with no leaf values. Empty objects and arrays are not supported.\",\n );\n }\n\n const newPointerSet = new Set(newPointers);\n const existing = await this.repository.getItems({ [this.idKey]: id });\n const existingPointers = existing.map(item => item[this.pointerKey] as string);\n const stalePointers = existingPointers.filter(p => !newPointerSet.has(p));\n\n const puts = Object.entries(flat).map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = stalePointers.map(\n pointer => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey),\n );\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n\n getDocument = async (id: string): Promise<T | undefined> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (!items || items.length === 0) return undefined;\n\n return reconstructDocument<T>(\n items.map(item => ({\n pointer: item[this.pointerKey] as string,\n value: item[this.valueKey] as JsonPointerValue,\n })),\n );\n };\n\n getAttribute = async <V = JsonPointerValue>(\n id: string,\n pointer: string,\n ): Promise<V | undefined> => {\n validatePointer(pointer);\n const item = await this.repository.getItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n return item ? (item[this.valueKey] as V) : undefined;\n };\n\n putAttribute = async (\n id: string,\n pointer: string,\n value: JsonPointerValue,\n ): Promise<void> => {\n validatePointer(pointer);\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n await this.repository.putItem(key, { ...key, [this.valueKey]: value } as PointerItem);\n };\n\n deleteAttribute = async (id: string, pointer: string): Promise<void> => {\n validatePointer(pointer);\n await this.repository.deleteItem({\n [this.idKey]: id,\n [this.pointerKey]: pointer,\n } as PointerKey);\n };\n\n deleteDocument = async (id: string): Promise<void> => {\n const items = await this.repository.getItems({ [this.idKey]: id });\n if (items.length === 0) return;\n const deleteKeys = items.map(\n item => ({ [this.idKey]: id, [this.pointerKey]: item[this.pointerKey] as string } as PointerKey),\n );\n await this.repository.batchWriteItems([], deleteKeys);\n };\n\n listDocumentIds = async (): Promise<string[]> => {\n const items = await this.repository.scan({ projectedAttributes: [this.idKey] });\n const seen = new Set<string>();\n for (const item of items) {\n seen.add(item[this.idKey] as string);\n }\n return [...seen];\n };\n\n patchDocument = async (\n id: string,\n updates: Record<string, JsonPointerValue | undefined>,\n ): Promise<void> => {\n const entries = Object.entries(updates);\n if (entries.length === 0) return;\n entries.forEach(([pointer]) => validatePointer(pointer));\n const puts = entries\n .filter((entry): entry is [string, JsonPointerValue] => entry[1] !== undefined)\n .map(([pointer, value]) => {\n const key = { [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey;\n return { key, item: { ...key, [this.valueKey]: value } as PointerItem };\n });\n const deleteKeys = entries\n .filter(([, value]) => value === undefined)\n .map(([pointer]) => ({ [this.idKey]: id, [this.pointerKey]: pointer } as PointerKey));\n await this.repository.batchWriteItems(puts, deleteKeys);\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eresearchqut/ddb-repository",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A TypeScript library providing a generic repository pattern implementation for AWS DynamoDB, simplifying CRUD operations and common database interactions.",
|
|
6
6
|
"main": "./dist/index.cjs",
|