dinah 0.15.2 → 0.15.3

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/cdk.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Table } from "./table-CcZ5Kv5z.cjs";
1
+ import { t as Table } from "./table-BFzl8QMs.cjs";
2
2
  import { TSchema } from "typebox";
3
3
  import * as cdk from "aws-cdk-lib/aws-dynamodb";
4
4
 
package/dist/cdk.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Table } from "./table-CcZ5Kv5z.mjs";
1
+ import { t as Table } from "./table-BFzl8QMs.mjs";
2
2
  import { TSchema } from "typebox";
3
3
  import * as cdk from "aws-cdk-lib/aws-dynamodb";
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["matchesPartial","DynamoDBClient","DynamoDB","Lib","CreateTableCommand","extractTableDesc","DeleteTableCommand","ListTablesCommand","matchesPartial","removeUndefined","ConditionalCheckFailedException","TransactionCanceledException"],"sources":["../src/error.ts","../src/expression-builder.ts","../src/repo.ts","../src/db.ts","../src/table.ts"],"sourcesContent":["export type DinahErrorDetails =\n | { type: \"NOT_FOUND\"; key: Record<string, unknown>; resource?: string }\n | { type: \"ALREADY_EXISTS\"; key: Record<string, unknown>; resource?: string }\n | { type: \"CONDITIONAL_CHECK_FAILED\"; key?: Record<string, unknown>; resource?: string }\n | { type: \"VALIDATION\"; message: string }\n | { type: \"TRANSACTION_CANCELED\"; reasons: Array<{ type: string; message?: string }> }\n | { type: \"DATA_INTEGRITY\"; message: string };\n\nfunction dinahErrorMessage(details: DinahErrorDetails): string {\n switch (details.type) {\n case \"NOT_FOUND\":\n return `${details.resource ?? \"Item\"} not found.`;\n case \"ALREADY_EXISTS\":\n return `${details.resource ?? \"Item\"} already exists.`;\n case \"CONDITIONAL_CHECK_FAILED\":\n return `${details.resource ?? \"Item\"} condition check failed.`;\n case \"VALIDATION\":\n return `Validation error: ${details.message}`;\n case \"DATA_INTEGRITY\":\n return `Data integrity error: ${details.message}`;\n case \"TRANSACTION_CANCELED\":\n return `Transaction canceled: ${details.reasons.map((r) => r.type).join(\", \")}`;\n }\n}\n\nexport class DinahError extends Error {\n readonly details: DinahErrorDetails;\n\n constructor(details: DinahErrorDetails, options?: ErrorOptions) {\n super(dinahErrorMessage(details), options);\n this.name = \"DinahError\";\n this.details = details;\n }\n}\n\nexport const isDinahError = (err: unknown): err is DinahError => err instanceof DinahError;\n","import { DinahError } from \"./error\";\nimport type { Obj } from \"./types\";\n\nconst attrTypes = [\"S\", \"SS\", \"N\", \"NS\", \"B\", \"BS\", \"BOOL\", \"NULL\", \"L\", \"M\"] as const;\nconst comparatorOps: Obj<string> = {\n $eq: \"=\",\n $ne: \"<>\",\n $gt: \">\",\n $gte: \">=\",\n $lt: \"<\",\n $lte: \"<=\",\n};\n\n// TODO should { $eq: undefined } and { $ne: undefined } be converted into attribute_not_exists and attribute_exists ?\n\nexport const isOperation = (val: unknown): val is Obj => {\n if (!val || typeof val !== \"object\" || Array.isArray(val)) return false;\n return Object.keys(val).every((op) => op.startsWith(\"$\"));\n};\n\nexport class ExpressionBuilder {\n protected readonly attrNames = new Map<string, string>();\n protected readonly attrValues = new Map<unknown, string>();\n\n get attributeNames(): Obj<string> | undefined {\n return this.attrNames.size\n ? Object.fromEntries(\n [...this.attrNames.entries()].map(([name, placeholder]) => [placeholder, name]),\n )\n : undefined;\n }\n\n get attributeValues(): Obj | undefined {\n return this.attrValues.size\n ? Object.fromEntries(\n [...this.attrValues.entries()].map(([value, placeholder]) => [placeholder, value]),\n )\n : undefined;\n }\n\n reset(): void {\n this.attrNames.clear();\n this.attrValues.clear();\n }\n\n getPathSub(path: string): string {\n const segments = path.split(\".\");\n const placeholders: string[] = [];\n\n for (const segment of segments) {\n let placeholder = this.attrNames.get(segment);\n if (!placeholder) {\n placeholder = `#${this.attrNames.size}`;\n this.attrNames.set(segment, placeholder);\n }\n\n placeholders.push(placeholder);\n }\n\n return placeholders.join(\".\");\n }\n\n getValueSub(value: unknown): string {\n let placeholder = this.attrValues.get(value);\n if (!placeholder) {\n placeholder = `:${this.attrValues.size}`;\n this.attrValues.set(value, placeholder);\n }\n\n return placeholder;\n }\n\n getValueOrPathSub(pathOrValue: unknown): string {\n if (isOperation(pathOrValue)) {\n if (pathOrValue.$path) return this.getPathSub(pathOrValue.$path);\n throw new Error(\"Expected $path or operand.\");\n }\n\n return this.getValueSub(pathOrValue);\n }\n\n projection<T extends string[] | undefined>(paths: T): T extends undefined ? undefined : string {\n return paths?.map((path) => this.getPathSub(path)).join(\", \") as never;\n }\n\n condition<T extends Obj | undefined>(expression: T): T extends undefined ? undefined : string {\n if (!expression) return undefined as never;\n\n const expressions: string[] = [];\n for (const [key, val] of Object.entries(expression)) {\n if (key === \"$and\") {\n if (!Array.isArray(val)) throw new Error(\"$and expects an array operand.\");\n expressions.push(`(${val.map((v) => this.condition(v)).join(\" AND \")})`);\n } else if (key === \"$or\" && Array.isArray(val)) {\n if (!Array.isArray(val)) throw new Error(\"$or expects an array operand.\");\n expressions.push(`(${val.map((v) => this.condition(v)).join(\" OR \")})`);\n } else if (key === \"$not\") {\n if (!val || typeof val !== \"object\") throw new Error(\"$not expects an object operand.\");\n expressions.push(`NOT ${this.condition(val)}`);\n } else if (!key.startsWith(\"$\")) {\n expressions.push(this.resolveCondition(key, val));\n } else {\n throw new Error(\n `Unexpected operator \"${key}\". Expected attribute path or compound operator.`,\n );\n }\n }\n\n return expressions.join(\" AND \") as never;\n }\n\n update<T extends Obj | undefined>(expression: T): T extends undefined ? undefined : string {\n if (expression === undefined) return undefined as never;\n\n const setOperations: string[] = [];\n const removeOperations: string[] = [];\n const setAddOperations: string[] = [];\n const setDelOperations: string[] = [];\n\n for (const [path, valOrOperation] of Object.entries(expression)) {\n const placeholder = this.getPathSub(path);\n\n if (valOrOperation === undefined) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${path}\" cannot be set to undefined in an update expression. Use { $remove: true } to remove an optional attribute.`,\n });\n } else if (isOperation(valOrOperation)) {\n if (valOrOperation.$remove === true) {\n removeOperations.push(placeholder);\n } else if (valOrOperation.$setAdd !== undefined || valOrOperation.$setDel !== undefined) {\n const operations = valOrOperation.$setAdd ? setAddOperations : setDelOperations;\n const operand = valOrOperation.$setAdd ?? valOrOperation.$setDel;\n operations.push(\n `${placeholder} ${this.getValueSub(operand instanceof Set ? operand : new Set([operand].flat()))}`,\n );\n } else {\n setOperations.push(`${placeholder} = ${this.resolveSetOperand(path, valOrOperation)}`);\n }\n } else {\n setOperations.push(`${placeholder} = ${this.getValueSub(valOrOperation)}`);\n }\n }\n\n let updateExpression = \"\";\n if (setOperations.length) {\n updateExpression += `SET ${setOperations.join(\", \")} `;\n }\n\n if (removeOperations.length) {\n updateExpression += `REMOVE ${removeOperations.join(\", \")} `;\n }\n\n if (setAddOperations.length) {\n updateExpression += `ADD ${setAddOperations.join(\", \")} `;\n }\n\n if (setDelOperations.length) {\n updateExpression += `DELETE ${setDelOperations.join(\", \")} `;\n }\n\n return updateExpression as never;\n }\n\n protected resolveCondition(path: string, exp: unknown): string {\n if (!exp || typeof exp !== \"object\" || !Object.keys(exp).at(0)?.startsWith(\"$\")) {\n return this.resolveCondition(path, { $eq: exp });\n }\n\n const placeholder = this.getPathSub(path);\n const [operator, operand] = Object.entries(exp).at(0) ?? [\"\"];\n\n if (comparatorOps[operator]) {\n if (isOperation(operand) && operand.$path) {\n return `${placeholder} ${comparatorOps[operator]} ${this.getPathSub(operand.$path)}`;\n }\n\n if (![\"string\", \"boolean\", \"number\"].includes(typeof operand)) {\n throw new Error(`${operator} expects a primitive/scalar operand.`);\n }\n return `${placeholder} ${comparatorOps[operator]} ${this.getValueSub(operand)}`;\n }\n\n switch (operator) {\n case \"$in\":\n if (!Array.isArray(operand)) {\n throw new Error(\"$in operator expects an array operand.\");\n }\n return `${placeholder} IN (${operand.map((op) => this.getValueSub(op)).join(\", \")})`;\n\n case \"$nin\":\n if (!Array.isArray(operand)) {\n throw new Error(\"$nin operator expects an array operand.\");\n }\n return `${placeholder} NOT IN (${operand.map((op) => this.getValueSub(op)).join(\", \")})`;\n\n case \"$prefix\":\n if (typeof operand !== \"string\") {\n throw new Error(\"$prefix operator expects a string operand.\");\n }\n return `begins_with(${placeholder}, ${this.getValueSub(operand)})`;\n\n case \"$includes\":\n return `contains(${placeholder}, ${this.getValueSub(operand)})`;\n\n case \"$between\":\n if (!Array.isArray(operand) || operand.length !== 2) {\n throw new Error(\"$between operator expects an array operand of exactly two values.\");\n }\n return `${placeholder} BETWEEN ${this.getValueSub(operand[0])} AND ${this.getValueSub(operand[1])}`;\n\n case \"$exists\":\n if (typeof operand !== \"boolean\") {\n throw new Error(\"$exists operator expects a boolean operand.\");\n }\n return operand\n ? `attribute_exists(${placeholder})`\n : `attribute_not_exists(${placeholder})`;\n\n case \"$type\":\n if (!attrTypes.includes(operand as any)) {\n throw new Error(`$type operator expects operand to be one of ${attrTypes.join(\",\")}`);\n }\n return `attribute_type(${placeholder})`;\n\n case \"$size\": {\n const sizeExp = typeof operand === \"number\" ? { $eq: operand } : operand;\n if (\n !sizeExp ||\n typeof sizeExp !== \"object\" ||\n !Object.keys(sizeExp).at(0)?.startsWith(\"$\")\n ) {\n throw new Error(\"$size operator expects a number operand or a comparator object.\");\n }\n const [sizeOperator, sizeOperand] = Object.entries(sizeExp).at(0) ?? [\"\"];\n\n if (!comparatorOps[sizeOperator]) {\n throw new Error(\"$size operator expects a number operand or a comparator object.\");\n }\n\n if (![\"string\", \"boolean\", \"number\"].includes(typeof sizeOperand)) {\n throw new Error(`${operator} expects a primitive/scalar operand.`);\n }\n\n return `size(${placeholder}) ${comparatorOps[sizeOperator]} ${this.getValueSub(sizeOperand)}`;\n }\n\n default:\n throw new Error(`Invalid operator \"${operator}\"`);\n }\n }\n\n protected resolveSetOperand(path: string, operand: unknown): string {\n if (isOperation(operand)) {\n if (operand.$ifNotExists) {\n const params = Array.isArray(operand.$ifNotExists)\n ? operand.$ifNotExists\n : [path, operand.$ifNotExists];\n return `if_not_exists(${this.getPathSub(params[0])}, ${this.resolveSetOperand(path, params[1])})`;\n }\n\n if (operand.$set) {\n return this.resolveSetOperand(path, operand.$set);\n }\n\n if (operand.$plus !== undefined || operand.$minus !== undefined) {\n const mathOperator = operand.$plus ? \"+\" : \"-\";\n const mathOperand = operand.$plus ?? operand.$minus;\n const params = Array.isArray(mathOperand) ? mathOperand : [{ $path: path }, mathOperand];\n return `${params.map((param) => this.resolveSetOperand(path, param)).join(` ${mathOperator} `)}`;\n }\n\n if (operand.$append !== undefined || operand.$prepend !== undefined) {\n const listOperand = operand.$append ?? operand.$prepend;\n const resolvedListOperand = isOperation(listOperand) ? listOperand : [listOperand].flat();\n const params = operand.$append\n ? [{ $path: path }, resolvedListOperand]\n : [resolvedListOperand, { $path: path }];\n return `list_append(${params.map((param) => this.resolveSetOperand(path, param)).join(\", \")})`;\n }\n }\n\n return this.getValueOrPathSub(operand);\n }\n\n // ── PartiQL update (for BatchExecuteStatement) ───────────────────────────────\n\n partiqlUpdate(expression: Obj): { sets: string[]; removes: string[]; params: unknown[] } {\n const sets: string[] = [];\n const removes: string[] = [];\n const params: unknown[] = [];\n\n for (const [path, valOrOp] of Object.entries(expression)) {\n if (valOrOp === undefined) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${path}\" cannot be set to undefined in an update expression. Use { $remove: true } to remove an optional attribute.`,\n });\n } else if (isOperation(valOrOp)) {\n if (valOrOp.$remove === true) {\n removes.push(`\"${path}\"`);\n } else {\n sets.push(`\"${path}\"=${this.resolvePartiQLSetOperand(path, valOrOp, params)}`);\n }\n } else {\n sets.push(`\"${path}\"=?`);\n params.push(valOrOp);\n }\n }\n\n return { sets, removes, params };\n }\n\n protected resolvePartiQLSetOperand(path: string, operand: unknown, params: unknown[]): string {\n if (isOperation(operand)) {\n if (operand.$set !== undefined) {\n return this.resolvePartiQLSetOperand(path, operand.$set, params);\n }\n if (operand.$plus !== undefined || operand.$minus !== undefined) {\n const op = operand.$plus ? \"+\" : \"-\";\n const mathOperand = operand.$plus ?? operand.$minus;\n const parts = Array.isArray(mathOperand) ? mathOperand : [{ $path: path }, mathOperand];\n return parts.map((p: any) => this.resolvePartiQLSetOperand(path, p, params)).join(op);\n }\n if (operand.$path) {\n return `\"${operand.$path}\"`;\n }\n }\n params.push(operand);\n return \"?\";\n }\n}\n","import type { Db } from \"./db\";\nimport type { Table } from \"./table\";\nimport type { DbTrxGetRequest, DbTrxWriteRequest } from \"./db.types\";\nimport type {\n GsiNames,\n RepoBatchGetOptions,\n RepoBatchGetOrThrowResult,\n RepoBatchGetResult,\n RepoBatchUpdateResult,\n RepoBatchWrite,\n RepoBatchWriteResult,\n RepoCreateItem,\n RepoCreateResult,\n RepoDeleteOptions,\n RepoDeleteOrThrowResult,\n RepoDeleteResult,\n RepoExistsOptions,\n RepoGetGsiOptions,\n RepoGetGsiOrThrowResult,\n RepoGetGsiResult,\n RepoGetOptions,\n RepoGetOrThrowResult,\n RepoGetResult,\n RepoKey,\n RepoPutOptions,\n RepoPutItem,\n RepoPutResult,\n RepoQueryGsiOptions,\n RepoQueryGsiPagedResult,\n RepoQueryGsiResult,\n RepoQueryOptions,\n RepoQueryPagedResult,\n RepoQueryResult,\n RepoScanGsiOptions,\n RepoScanGsiPagedResult,\n RepoScanGsiResult,\n RepoScanOptions,\n RepoScanPagedResult,\n RepoScanResult,\n RepoTrxGetOptions,\n RepoTrxGetOrThrowResult,\n RepoTrxGetResult,\n RepoTrxWriteRequest,\n RepoUpdateInput,\n RepoUpdateInputFor,\n RepoUpdateOptions,\n RepoUpdateResult,\n RepoQueryGsiQuery,\n RepoQueryQuery,\n} from \"./repo.types\";\nimport type { AllKeys, Condition, ExtractTableDef, ExtractTableSchema, Obj } from \"./types\";\nimport { isOperation } from \"./expression-builder\";\nimport { DinahError } from \"./error\";\nimport { matchesPartial } from \"./util\";\n\n// TODO: query/queryGsi needs strongly typed \"key\" argument\n// allows =,>,>=,<,<=,begins_with, between on sort key\n// util -> extractExclusiveStartKey(item)\n\n// Minimal structural interface used as the constraint in repo.types.ts.\n// Keeps type helper constraints simple (R extends RepoBase) while the full\n// Repo class retains separate generic params for inference quality.\nexport interface RepoBase {\n readonly $schema: object;\n readonly $def: { readonly partitionKey: string; readonly sortKey?: string };\n readonly $computedAttributes: PropertyKey;\n readonly $immutableAttributes: PropertyKey;\n readonly $discriminator: PropertyKey;\n readonly table: Table;\n readonly defaultCreateData: object;\n readonly defaultUpdateData: object;\n transformOutput(item: never): unknown;\n}\n\nexport type ComputedFieldDef<TSchema extends object, K extends keyof TSchema> =\n | { [J in keyof TSchema]: { from: J; compute: (val: TSchema[J]) => TSchema[K] } }[keyof TSchema]\n | { from: readonly (keyof TSchema)[]; compute: (...vals: any[]) => TSchema[K] };\n\n// Recursively maps a tuple of schema keys to a tuple of their value types.\ntype ComputeArgs<\n TSchema extends object,\n Js extends readonly (keyof TSchema)[],\n> = Js extends readonly [\n infer Head extends keyof TSchema,\n ...infer Tail extends readonly (keyof TSchema)[],\n]\n ? [TSchema[Head], ...ComputeArgs<TSchema, Tail>]\n : [];\n\n// Post-inference constraint. Maps each computed attribute key to its expected shape so\n// TypeScript's structural assignability check enforces correct param and return types.\n// Catching too-narrow param annotations (missing | undefined) and too-broad return types\n// falls out of normal contravariant/covariant function subtype checking automatically.\nexport type ValidComputedMap<TSchema extends object, TComputed> = {\n [K in keyof TComputed]?: K extends keyof TSchema\n ? TComputed[K] extends { from: infer Js extends readonly (keyof TSchema)[]; compute: any }\n ? { from: Js; compute: (...vals: ComputeArgs<TSchema, Js>) => TSchema[K] }\n : TComputed[K] extends { from: infer J extends keyof TSchema; compute: any }\n ? { from: J; compute: (val: TSchema[J]) => TSchema[K] }\n : never\n : never;\n};\n\nexport interface RepoConfig<\n TSchema extends object,\n TDefaults extends Partial<TSchema> = {},\n TUpdateDefaults extends Partial<TSchema> = {},\n TOutput = TSchema,\n TComputed extends ValidComputedMap<TSchema, TComputed> = {},\n TImmutable extends AllKeys<TSchema> = never,\n TDiscriminator extends keyof TSchema = never,\n> {\n resourceName?: string;\n discriminator?: TDiscriminator;\n defaultCreateData?: () => TDefaults;\n defaultUpdateData?: () => TUpdateDefaults;\n transformAttributes?: { [K in keyof TSchema]?: (val: TSchema[K]) => TSchema[K] };\n computedAttributes?: TComputed & { [K in keyof TSchema]?: ComputedFieldDef<TSchema, K> };\n transformOutput?: (item: TSchema) => TOutput;\n immutableAttributes?: readonly TImmutable[];\n}\n\n// Concrete reconstruction of this repo's `RepoBase` shape, derived from the\n// class type parameters rather than from `this`. It mirrors the phantom `$*`\n// declarations below. This exists to feed the `Self` type parameter (see the\n// `Repo` class): the helper types in repo.types.ts do indexed-access and\n// conditional lookups (R[\"$schema\"], R[\"table\"][\"def\"], GsiProjectionType<R>,\n// NarrowByDiscriminator<..., R[\"$discriminator\"]>, ...). Those reduce only when\n// their `R` is bound to concrete types. `this` is a polymorphic type parameter,\n// and TypeScript defers indexed access on a type parameter, so `this`-based\n// helpers never reduce inside a (sub)class method body — even though they do\n// reduce at an external call site where `this` binds to the concrete receiver.\n// The ordinary class params (T, TDiscriminator, ...) ARE bound to concrete\n// types through a subclass's heritage clause, so a `Self` rebuilt from them\n// reduces everywhere, including inside subclass methods like\n// `class LogRepo extends makeRepo(t) { m() { this.queryGsi(...) } }`.\ntype RepoSelf<\n T extends Table,\n TDefaults extends object,\n TUpdateDefaults extends object,\n TOutput,\n TComputed,\n TImmutable extends PropertyKey,\n TDiscriminator extends PropertyKey,\n> = {\n readonly $schema: ExtractTableSchema<T>;\n readonly $def: ExtractTableDef<T>;\n readonly $computedAttributes: keyof TComputed;\n readonly $immutableAttributes: TImmutable;\n readonly $discriminator: TDiscriminator;\n readonly table: T;\n readonly defaultCreateData: TDefaults;\n readonly defaultUpdateData: TUpdateDefaults;\n // Mirrors the class method's real signature. The param must NOT be `never`\n // (as in the RepoBase constraint): `ReturnType<(x: never) => R>` resolves to\n // `any`, which would poison RepoOutput<Self> and every result type built on it.\n transformOutput(item: ExtractTableSchema<T>): TOutput;\n};\n\nexport class Repo<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n TDiscriminator extends keyof ExtractTableSchema<T> = never,\n // Synthetic, never passed explicitly. Bound to its default at every use site;\n // because the default is built from the params above (concrete in a subclass\n // heritage clause), method signatures written against `Self` reduce inside\n // subclass method bodies where `this`-based ones do not. See RepoSelf above.\n Self extends RepoBase = RepoSelf<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n> {\n // Concrete self-type (the `Self` reconstruction) exposed as a phantom so it\n // can be named when authoring an override. Base method signatures are written\n // against `Self`, which a subclass cannot name via `this` (and `this` would\n // not reduce inside a method body anyway). To override a generic base method,\n // write its signature against `<BaseRepoType>[\"$self\"]`, e.g.:\n // class LogRepo extends makeRepo(logTable) {\n // override async get<const O extends RepoGetOptions<Repo<typeof logTable>[\"$self\"]>>(\n // key: RepoKey<Repo<typeof logTable>[\"$self\"]>, options?: O,\n // ): Promise<RepoGetResult<Repo<typeof logTable>[\"$self\"], O>> {\n // return super.get(key, options);\n // }\n // }\n declare readonly $self: Self;\n\n // these phantom properties are used to pre-compute types derived from T\n // which allows easy lookups using the \"this\" Repo type\n declare readonly $schema: ExtractTableSchema<T>;\n declare readonly $def: ExtractTableDef<T>;\n declare readonly $computedAttributes: keyof TComputed;\n declare readonly $immutableAttributes: TImmutable;\n declare readonly $discriminator: TDiscriminator;\n\n readonly table: T;\n readonly db: Db;\n private readonly config: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >;\n\n constructor(\n db: Db,\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n ) {\n this.db = db;\n this.table = table;\n this.config = config ?? {};\n }\n\n get tableName(): string {\n return `${this.db.config?.tableNamePrefix ?? \"\"}${this.table.def.name}`;\n }\n\n get resourceName(): string {\n if (this.config.resourceName) return this.config.resourceName;\n const clsName = this.constructor.name;\n if (clsName && clsName !== \"Repo\") {\n return clsName.replace(/Repo$/i, \"\") || clsName;\n }\n const t = this.table.def.name;\n return t.charAt(0).toUpperCase() + t.slice(1);\n }\n\n get defaultCreateData(): TDefaults {\n return (this.config.defaultCreateData?.() ?? {}) as TDefaults;\n }\n\n get defaultUpdateData(): TUpdateDefaults {\n return (this.config.defaultUpdateData?.() ?? {}) as TUpdateDefaults;\n }\n\n transformOutput(item: ExtractTableSchema<T>): TOutput {\n return (this.config.transformOutput?.(item) ?? item) as TOutput;\n }\n\n // TODO: should this throw if pk is missing?\n // should return type by narrower?\n extractKey(item: RepoKey<Self>): RepoKey<Self> {\n const { partitionKey, sortKey } = this.table.def;\n if (sortKey) {\n return {\n [partitionKey]: item[partitionKey as keyof RepoKey<Self>],\n [sortKey]: item[sortKey as keyof RepoKey<Self>],\n } as RepoKey<Self>;\n }\n\n return { [partitionKey]: item[partitionKey as keyof RepoKey<Self>] } as RepoKey<Self>;\n }\n\n async get<const O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): Promise<RepoGetResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetOptions<Self>;\n const item = await this.db.get({\n table: this.tableName,\n key: this.extractKey(key),\n filter,\n ...restOptions,\n } as any);\n return (item && this.applyTransformIfNeeded(item, options)) as any;\n }\n\n async getOrThrow<const O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): Promise<RepoGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetOptions<Self>;\n const item = await this.db.getOrThrow({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n filter,\n ...restOptions,\n } as any);\n return this.applyTransformIfNeeded(item, options) as any;\n }\n\n async put<const T extends RepoPutItem<Self>>(\n item: T,\n options?: RepoPutOptions<Self>,\n ): Promise<RepoPutResult<Self, T>> {\n const result = await this.db.put({\n table: this.tableName,\n item: item as any,\n resource: this.resourceName,\n ...options,\n });\n return this.applyTransformIfNeeded(result) as any;\n }\n\n async update<const K extends RepoKey<Self>>(\n key: K,\n update: RepoUpdateInputFor<Self, K>,\n options?: RepoUpdateOptions<Self>,\n ): Promise<RepoUpdateResult<Self>> {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n const result = await this.db.update({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n update: updateWithDefaults as any,\n ...options,\n condition: this.withDiscriminatorCondition(key, options?.condition),\n });\n return this.applyTransformIfNeeded(result);\n }\n\n async create<const T extends RepoCreateItem<Self>>(item: T): Promise<RepoCreateResult<Self, T>> {\n const condition = { $and: [{ [this.table.def.partitionKey]: { $exists: false } }] } as any;\n\n const normalizedItem = this.applyCreateTransforms(item as Obj);\n\n let result: Obj;\n try {\n result = await this.db.put({\n table: this.tableName,\n item: normalizedItem,\n resource: this.resourceName,\n condition,\n });\n } catch (err) {\n // The only condition `create` applies is the `<pk> not exists` guard, so a\n // conditional check failure means an item with this key already exists.\n if (err instanceof DinahError && err.details.type === \"CONDITIONAL_CHECK_FAILED\") {\n throw new DinahError(\n {\n type: \"ALREADY_EXISTS\",\n key: this.extractKey(item as unknown as RepoKey<Self>) as Record<string, unknown>,\n resource: this.resourceName,\n },\n { cause: err },\n );\n }\n throw err;\n }\n return this.applyTransformIfNeeded(result) as any;\n }\n\n async delete(\n key: RepoKey<Self>,\n options?: RepoDeleteOptions<Self>,\n ): Promise<RepoDeleteResult<Self>> {\n const item = await this.db.delete({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n ...options,\n });\n return item && this.applyTransformIfNeeded(item);\n }\n\n async deleteOrThrow(\n key: RepoKey<Self>,\n options?: RepoDeleteOptions<Self>,\n ): Promise<RepoDeleteOrThrowResult<Self>> {\n const item = await this.db.deleteOrThrow({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n ...options,\n });\n return this.applyTransformIfNeeded(item);\n }\n\n async query<const O extends RepoQueryOptions<Self>>(\n query: RepoQueryQuery<Self>,\n options?: O,\n ): Promise<RepoQueryResult<Self, O>> {\n const items = await this.db.query({ table: this.tableName, query, ...options } as any);\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async *queryPaged<const O extends RepoQueryOptions<Self>>(\n query: RepoQueryQuery<Self>,\n options?: O,\n ): RepoQueryPagedResult<Self, O> {\n for await (const page of this.db.queryPaged({\n table: this.tableName,\n query,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, options) as any;\n }\n }\n\n async queryGsi<G extends GsiNames<Self>, const O extends RepoQueryGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoQueryGsiResult<Self, O, G>> {\n const items = await this.db.query({\n table: this.tableName,\n index: gsi,\n query,\n ...options,\n } as any);\n return this.applyTransformsIfNeeded(items, { ...options, gsi }) as any;\n }\n\n async *queryGsiPaged<G extends GsiNames<Self>, const O extends RepoQueryGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): RepoQueryGsiPagedResult<Self, O, G> {\n for await (const page of this.db.queryPaged({\n table: this.tableName,\n index: gsi,\n query,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, { ...options, gsi }) as any;\n }\n }\n\n async getGsi<G extends GsiNames<Self>, const O extends RepoGetGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoGetGsiResult<Self, O, G>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetGsiOptions<Self, T, G>;\n const items = await this.db.query({\n table: this.tableName,\n index: gsi,\n query,\n ...restOptions,\n } as any);\n if (items.length > 1) {\n throw new DinahError({\n type: \"DATA_INTEGRITY\",\n message: `getGsi on \"${gsi}\" returned ${items.length} items; expected at most 1.`,\n });\n }\n const item = items[0];\n if (!item) return undefined;\n if (filter && !matchesPartial(filter, item as any)) return undefined;\n return this.applyTransformIfNeeded(item, { ...options, gsi }) as any;\n }\n\n async getGsiOrThrow<G extends GsiNames<Self>, const O extends RepoGetGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoGetGsiOrThrowResult<Self, O, G>> {\n const item = await this.getGsi(gsi, query, options);\n if (item === undefined) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: query as Record<string, unknown>,\n resource: this.resourceName,\n });\n }\n return item as any;\n }\n\n async scan<const O extends RepoScanOptions<Self>>(options?: O): Promise<RepoScanResult<Self, O>> {\n const items = await this.db.scan({ table: this.tableName, ...options });\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async *scanPaged<const O extends RepoScanOptions<Self>>(\n options?: O,\n ): RepoScanPagedResult<Self, O> {\n for await (const page of this.db.scanPaged({ table: this.tableName, ...options })) {\n yield this.applyTransformsIfNeeded(page, options) as any;\n }\n }\n\n async scanGsi<G extends GsiNames<Self>, const O extends RepoScanGsiOptions<Self, T, G>>(\n gsi: G,\n options?: O,\n ): Promise<RepoScanGsiResult<Self, O, G>> {\n const items = await this.db.scan({ table: this.tableName, index: gsi, ...options } as any);\n return this.applyTransformsIfNeeded(items, { ...options, gsi }) as any;\n }\n\n async *scanGsiPaged<G extends GsiNames<Self>, const O extends RepoScanGsiOptions<Self, T, G>>(\n gsi: G,\n options?: O,\n ): RepoScanGsiPagedResult<Self, O, G> {\n for await (const page of this.db.scanPaged({\n table: this.tableName,\n index: gsi,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, { ...options, gsi }) as any;\n }\n }\n\n async exists(options?: RepoExistsOptions<Self>): Promise<boolean> {\n return this.db.exists({\n table: this.tableName,\n projection: [this.table.def.partitionKey] as any,\n ...options,\n });\n }\n\n async existsGsi(gsi: GsiNames<Self>, options?: RepoExistsOptions<Self>): Promise<boolean> {\n return this.db.exists({\n table: this.tableName,\n index: gsi,\n projection: [this.table.def.partitionKey] as any,\n ...options,\n });\n }\n\n async batchGet<const O extends RepoBatchGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoBatchGetResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoBatchGetOptions<Self>;\n const { items, unprocessed } = await this.db.batchGet({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n filter,\n ...restOptions,\n },\n } as any);\n const tableItems = items[this.tableName];\n return {\n items: (tableItems && this.applyTransformsIfNeeded(tableItems, options)) as any,\n unprocessed: unprocessed?.[this.tableName]?.keys as RepoKey<Self>[] | undefined,\n };\n }\n\n async batchGetOrThrow<const O extends RepoBatchGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoBatchGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoBatchGetOptions<Self>;\n const result = await this.db.batchGetOrThrow({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n resource: this.resourceName,\n filter,\n ...restOptions,\n },\n } as any);\n return this.applyTransformsIfNeeded(result[this.tableName] ?? [], options) as any;\n }\n\n async batchWrite(requests: RepoBatchWrite<Self>): Promise<RepoBatchWriteResult<Self>> {\n const { items, unprocessed } = await this.db.batchWrite({\n [this.tableName]: requests.map((request) => {\n if (request.type === \"DELETE\") {\n return { type: \"DELETE\", key: this.extractKey(request.key) };\n } else {\n return { type: \"PUT\", item: request.item };\n }\n }),\n });\n\n return {\n items: items[this.tableName],\n unprocessed: unprocessed?.[this.tableName],\n } as RepoBatchWriteResult<Self>;\n }\n\n async batchUpdate(\n keys: RepoKey<Self>[],\n update: RepoUpdateInput<Self>,\n ): Promise<RepoBatchUpdateResult<Self>> {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n const result = await this.db.batchUpdate({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n update: updateWithDefaults as any,\n },\n } as any);\n return {\n unprocessed: result.unprocessed?.[this.tableName]?.keys as RepoKey<Self>[] | undefined,\n };\n }\n\n async trxGet<const O extends RepoTrxGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoTrxGetResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoTrxGetOptions<Self>;\n const items = await this.db.trxGet(\n ...keys.map(\n (key) =>\n ({\n table: this.tableName,\n key: this.extractKey(key),\n filter,\n ...restOptions,\n }) as any,\n ),\n );\n return items.map((item: any) => item && this.applyTransformIfNeeded(item, options)) as any;\n }\n\n async trxGetOrThrow<const O extends RepoTrxGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoTrxGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoTrxGetOptions<Self>;\n const items = await this.db.trxGetOrThrow(\n ...keys.map(\n (key) =>\n ({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n filter,\n ...restOptions,\n }) as any,\n ),\n );\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async trxWrite(...requests: RepoTrxWriteRequest<Self>[]): Promise<void> {\n await this.db.trxWrite(\n ...requests.map((request) => {\n switch (request.type) {\n case \"CONDITION\": {\n const { key, condition } = request;\n return this.trxConditionRequest(key, condition);\n }\n\n case \"DELETE\": {\n const { key, ...options } = request;\n return this.trxDeleteRequest(key, options);\n }\n\n case \"PUT\": {\n const { item, ...options } = request;\n return this.trxPutRequest(item, options);\n }\n\n case \"UPDATE\": {\n const { key, update, ...options } = request;\n return this.trxUpdateRequest(\n key,\n update as RepoUpdateInputFor<Self, typeof key>,\n options,\n );\n }\n\n default:\n throw new Error(\"Unexpected request type.\");\n }\n }),\n );\n }\n\n async trxDelete(keys: RepoKey<Self>[], options?: RepoDeleteOptions<Self>): Promise<void> {\n return this.db.trxWrite(...keys.map((key) => this.trxDeleteRequest(key, options)));\n }\n\n // todo: return items\n async trxPut(items: RepoPutItem<Self>[], options?: RepoPutOptions<Self>): Promise<void> {\n return this.db.trxWrite(...items.map((item) => this.trxPutRequest(item, options)));\n }\n\n async trxUpdate(\n keys: RepoKey<Self>[],\n update: RepoUpdateInput<Self>,\n options?: RepoUpdateOptions<Self>,\n ): Promise<void> {\n return this.db.trxWrite(\n ...keys.map((key) =>\n this.trxUpdateRequest(key, update as RepoUpdateInputFor<Self, typeof key>, options),\n ),\n );\n }\n\n // todo: return items\n async trxCreate(items: RepoCreateItem<Self>[]): Promise<void> {\n return this.db.trxWrite(...items.map((item) => this.trxCreateRequest(item)));\n }\n\n trxGetRequest<O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): DbTrxGetRequest<RepoGetOrThrowResult<Self, O>> {\n return { table: this.tableName, key: this.extractKey(key), ...options } as any;\n }\n\n trxDeleteRequest(key: RepoKey<Self>, options?: RepoDeleteOptions<Self>): DbTrxWriteRequest {\n return { table: this.tableName, type: \"DELETE\", key: this.extractKey(key), ...options };\n }\n\n trxConditionRequest(\n key: RepoKey<Self>,\n condition: Condition<Self[\"$schema\"]>,\n ): DbTrxWriteRequest {\n return {\n table: this.tableName,\n type: \"CONDITION\",\n key: this.extractKey(key),\n condition,\n };\n }\n\n trxPutRequest(item: RepoPutItem<Self>, options?: RepoPutOptions<Self>): DbTrxWriteRequest {\n return { table: this.tableName, type: \"PUT\", item: item as any, ...options };\n }\n\n trxUpdateRequest<const K extends RepoKey<Self>>(\n key: K,\n update: RepoUpdateInputFor<Self, K>,\n options?: RepoUpdateOptions<Self>,\n ): DbTrxWriteRequest {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n return {\n table: this.tableName,\n type: \"UPDATE\",\n key: this.extractKey(key),\n update: updateWithDefaults as any,\n ...options,\n condition: this.withDiscriminatorCondition(key, options?.condition),\n };\n }\n\n trxCreateRequest(item: RepoCreateItem<Self>): DbTrxWriteRequest {\n const condition = { $and: [{ [this.table.def.partitionKey]: { $exists: false } }] } as any;\n\n const normalizedItem = this.applyCreateTransforms(item as Obj);\n\n return {\n table: this.tableName,\n type: \"PUT\",\n item: normalizedItem,\n condition,\n };\n }\n\n private applyCreateTransforms(item: Obj): Partial<ExtractTableSchema<T>> {\n const { transformAttributes, computedAttributes } = this.config;\n\n if (computedAttributes) {\n for (const key of Object.keys(computedAttributes)) {\n if (key in item) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" is a computed attribute and cannot be set directly. Remove it from the create input.`,\n });\n }\n }\n }\n\n const merged: Obj = { ...this.defaultCreateData, ...item };\n\n if (transformAttributes) {\n for (const [key, transform] of Object.entries(transformAttributes)) {\n if (key in merged && merged[key] !== undefined) {\n merged[key] = (transform as (v: unknown) => unknown)(merged[key]);\n }\n }\n }\n\n if (computedAttributes) {\n for (const [key, def] of Object.entries(computedAttributes)) {\n const { from, compute } = def as {\n from: string | readonly string[];\n compute: (...v: unknown[]) => unknown;\n };\n const args = Array.isArray(from)\n ? (from as string[]).map((k) => merged[k])\n : [merged[from as string]];\n const computed = compute(...args);\n if (computed !== undefined) {\n merged[key] = computed;\n } else {\n delete merged[key];\n }\n }\n }\n\n return merged as Partial<ExtractTableSchema<T>>;\n }\n\n private applyNormalizersToExpression(userUpdate: Obj): Obj {\n const { transformAttributes, computedAttributes, immutableAttributes } = this.config;\n\n if (computedAttributes) {\n for (const key of Object.keys(computedAttributes)) {\n if (key in userUpdate) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" is a computed attribute and cannot be set directly in an update. Update the source field instead.`,\n });\n }\n }\n }\n\n for (const key of immutableAttributes ?? []) {\n if ((key as string) in userUpdate) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key as string}\" is immutable and cannot be updated.`,\n });\n }\n }\n\n const result: Obj = { ...this.defaultUpdateData, ...userUpdate };\n\n if (transformAttributes) {\n for (const [key, transform] of Object.entries(transformAttributes)) {\n if (!(key in result)) continue;\n const val = result[key];\n const fn = transform as (v: unknown) => unknown;\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n // nothing to transform\n } else if (!isOperation(val)) {\n result[key] = fn(val);\n } else if (val.$set !== undefined) {\n result[key] = { ...val, $set: fn(val.$set) };\n } else if (val.$ifNotExists !== undefined) {\n const ifne = val.$ifNotExists as unknown;\n result[key] = {\n ...val,\n $ifNotExists: Array.isArray(ifne)\n ? [(ifne as unknown[])[0], fn((ifne as unknown[])[1])]\n : fn(ifne),\n };\n }\n }\n }\n\n if (computedAttributes) {\n for (const [computedKey, def] of Object.entries(computedAttributes)) {\n const { from, compute } = def as {\n from: string | readonly string[];\n compute: (...v: unknown[]) => unknown;\n };\n\n if (Array.isArray(from)) {\n const fromArr = from as string[];\n const presentKeys = fromArr.filter((k) => k in result);\n if (presentKeys.length === 0) continue;\n const missingKeys = fromArr.filter((k) => !(k in result));\n if (missingKeys.length > 0) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${computedKey}\" is computed from [${fromArr.join(\", \")}]. All source fields must be included in the update or none. Missing: [${missingKeys.join(\", \")}].`,\n });\n }\n const args: unknown[] = [];\n for (const key of fromArr) {\n const val = result[key];\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n args.push(undefined);\n } else if (!isOperation(val)) {\n args.push(val);\n } else if (val.$set !== undefined) {\n args.push(val.$set);\n } else {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" drives computed field \"${computedKey}\" and cannot use arithmetic or list operators in updates.`,\n });\n }\n }\n const computed = compute(...args);\n result[computedKey] = computed !== undefined ? computed : { $remove: true };\n } else {\n const fromKey = from as string;\n if (!(fromKey in result)) continue;\n\n const val = result[fromKey];\n let resolvedVal: unknown;\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n resolvedVal = undefined;\n } else if (!isOperation(val)) {\n resolvedVal = val;\n } else if (val.$set !== undefined) {\n resolvedVal = val.$set;\n } else {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${fromKey}\" drives computed field \"${computedKey}\" and cannot use arithmetic or list operators in updates.`,\n });\n }\n const computed = compute(resolvedVal);\n result[computedKey] = computed !== undefined ? computed : { $remove: true };\n }\n }\n }\n\n return result;\n }\n\n // If the caller passed a key that carries the configured discriminator\n // value, AND condition that field against the same value. Guards against the\n // row on the wire having a different variant than the type-level narrowing\n // assumed.\n private withDiscriminatorCondition(\n key: Obj,\n condition: Condition<ExtractTableSchema<T>> | undefined,\n ): Condition<ExtractTableSchema<T>> | undefined {\n const discriminator = this.config.discriminator as string | undefined;\n if (!discriminator) return condition;\n const value = key[discriminator];\n if (value === undefined) return condition;\n const guard = { [discriminator]: value } as Condition<ExtractTableSchema<T>>;\n if (!condition) return guard;\n return { $and: [guard, condition] } as Condition<ExtractTableSchema<T>>;\n }\n\n protected applyTransformsIfNeeded(\n items: Obj[],\n options?: { projection?: any[]; gsi?: string },\n ): any[] {\n // transforms aren't applied when applying a projection\n if (options?.projection?.length) return items;\n if (options?.gsi) {\n // projections inherited to GSIs also prevent transformation\n const gsiProj = this.table.def.gsis?.[options.gsi]?.projection;\n if (gsiProj === \"KEYS_ONLY\" || Array.isArray(gsiProj)) return items;\n }\n\n return items.map((item) => this.transformOutput(item as ExtractTableSchema<T>));\n }\n\n protected applyTransformIfNeeded(item: Obj, options?: { projection?: any[]; gsi?: string }): any {\n const [transformedItem] = this.applyTransformsIfNeeded([item], options);\n return transformedItem;\n }\n}\n\nexport interface MakeRepoResult<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n TDiscriminator extends keyof ExtractTableSchema<T> = never,\n> {\n new (db: Db): Repo<T, TDefaults, TUpdateDefaults, TOutput, TComputed, TImmutable, TDiscriminator>;\n readonly table: T;\n}\n\nexport const makeRepo = <\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n const TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n const TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n const TDiscriminator extends keyof ExtractTableSchema<T> = never,\n>(\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n): MakeRepoResult<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n> => {\n return class extends Repo<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n > {\n static readonly table = table;\n constructor(db: Db) {\n super(db, table, config);\n }\n };\n};\n","import {\n type BatchGetItemInput,\n type BatchWriteItemInput,\n ConditionalCheckFailedException,\n CreateTableCommand,\n DeleteTableCommand,\n DynamoDB,\n DynamoDBClient,\n type DynamoDBClientConfig,\n ListTablesCommand,\n TransactionCanceledException,\n type WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport { DinahError } from \"./error\";\n//import { DynamoDBStreams } from '@aws-sdk/client-dynamodb-streams';\nimport type { TransactGetCommandInput, TransactWriteCommandInput } from \"@aws-sdk/lib-dynamodb\";\nimport * as Lib from \"@aws-sdk/lib-dynamodb\";\nimport { ExpressionBuilder } from \"./expression-builder\";\nimport { Repo, type RepoConfig, type ValidComputedMap } from \"./repo\";\nimport type { Table } from \"./table\";\nimport type {\n DbBatchGet,\n DbBatchGetResponse,\n DbBatchUpdate,\n DbBatchUpdateResponse,\n DbBatchWrite,\n DbBatchWriteResponse,\n DbConfig,\n DbDelete,\n DbExists,\n DbGet,\n DbListTables,\n DbPut,\n DbQuery,\n DbScan,\n DbTrxGetOrThrowResult,\n DbTrxGetRequest,\n DbTrxGetResult,\n DbTrxWriteRequest,\n DbUpdate,\n} from \"./db.types\";\nimport type { AllKeys, ExtractTableSchema, Obj } from \"./types\";\nimport { extractTableDesc, matchesPartial, removeUndefined } from \"./util\";\n\n// TODO\n// - caching support?\n// - consider special \"limit\" handling for paged scans, maybe have \"scanLimit\" too\n// - consider \"sort\" shorthand for methods that return unpaginated collections\n// i.e. sort: { by: 'createdAt', dir: 'ASC' } or sort: (a,b) => a.createdAt - b.createdAt\n// - consider support for batchUpdates leveraging BatchExecute and PartiQL\n// - consider batchPut (batchPutOrThrow) and batchDelete that operate on a single table\n// - getGsi? throws if > 1 result, allows for assert, and filtering\n// - bug $in doesn't handle empty arrays, I imagine other operators are affected\n// - consider beforeCreate, beforePut, beforeUpdate, beforeDelete, after, etc.\n// - type out repo update data\n// - does it handle nested undefined removal? nested $remove\n// - maybe extract resourceName from schema?\n\nexport class Db {\n readonly client: Lib.DynamoDBDocumentClient;\n readonly config: DbConfig | undefined;\n\n //protected streamEventListeners: DbStreamEventListener[] = [];\n\n constructor(\n clientOrConfig: DynamoDBClient | DynamoDB | DynamoDBClientConfig,\n dbConfig?: DbConfig,\n ) {\n if (clientOrConfig instanceof DynamoDBClient || clientOrConfig instanceof DynamoDB) {\n this.client = Lib.DynamoDBDocumentClient.from(new DynamoDBClient(clientOrConfig));\n } else {\n const { endpoint, ...clientConfig } = clientOrConfig;\n // client doesn't interpret an empty string endpoint as falsy so normalize things\n // here so consumers don't have to worry about that quirk\n this.client = Lib.DynamoDBDocumentClient.from(\n new DynamoDBClient({\n ...(endpoint ? { endpoint } : {}),\n ...clientConfig,\n }),\n );\n }\n\n this.config = dbConfig;\n }\n\n private normalizeUpdate(expression: Obj): Obj {\n const behavior = this.config?.updateUndefinedBehavior ?? \"throw\";\n if (behavior === \"throw\") return expression;\n const entries = Object.entries(expression);\n if (behavior === \"strip\") return Object.fromEntries(entries.filter(([, v]) => v !== undefined));\n return Object.fromEntries(\n entries.map(([k, v]) => [k, v === undefined ? { $remove: true } : v]),\n );\n }\n\n makeRepo<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n const TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n const TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n const TDiscriminator extends keyof ExtractTableSchema<T> = never,\n >(\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n ): Repo<T, TDefaults, TUpdateDefaults, TOutput, TComputed, TImmutable, TDiscriminator> {\n return new Repo(this, table, config);\n }\n\n async createTable(table: Table): Promise<void> {\n await this.client.send(new CreateTableCommand(extractTableDesc(table)));\n }\n\n async deleteTable(tableName: string): Promise<void> {\n await this.client.send(new DeleteTableCommand({ TableName: tableName }));\n }\n\n async listTables(data?: DbListTables): Promise<string[]> {\n const tables: string[] = [];\n let lastEvaluatedTableName: string | undefined;\n do {\n const output = await this.client.send(\n new ListTablesCommand({\n Limit: data?.limit,\n ExclusiveStartTableName: lastEvaluatedTableName,\n }),\n );\n\n tables.push(...(output.TableNames ?? []));\n lastEvaluatedTableName = output.LastEvaluatedTableName;\n } while (lastEvaluatedTableName);\n return tables;\n }\n\n async get<T = Obj>(data: DbGet<T>): Promise<T | undefined> {\n const exp = new ExpressionBuilder();\n\n const input = new Lib.GetCommand({\n TableName: data.table,\n Key: data.key,\n ConsistentRead: data.consistent,\n ProjectionExpression: exp.projection(data.projection),\n ExpressionAttributeNames: exp.attributeNames,\n });\n\n const output = await this.client.send(input);\n\n if (output.Item && data.filter && !matchesPartial(data.filter as any, output.Item as any)) {\n return undefined;\n }\n\n return output.Item as T;\n }\n\n async getOrThrow<T = Obj>(data: DbGet<T>): Promise<T> {\n const item = await this.get<T>(data);\n if (!item) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n });\n }\n return item;\n }\n\n async put<T = Obj>(data: DbPut<T>): Promise<T> {\n const exp = new ExpressionBuilder();\n\n const item = removeUndefined(data.item as Obj);\n\n const input = new Lib.PutCommand({\n TableName: data.table,\n Item: item,\n ReturnValues: data.returnOld ? \"ALL_OLD\" : \"NONE\",\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n ConditionExpression: exp.condition(data.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return (data.returnOld ? output.Attributes : item) as T;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n { type: \"CONDITIONAL_CHECK_FAILED\", resource: data.resource },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async update<T = Obj>(data: DbUpdate<T>): Promise<T> {\n const exp = new ExpressionBuilder();\n\n const condition: any = {\n $and: Object.keys(data.key).map((field) => ({\n [field]: { $exists: true },\n })),\n };\n\n if (data.condition) {\n condition.$and.push(data.condition);\n }\n\n const input = new Lib.UpdateCommand({\n TableName: data.table,\n Key: data.key,\n ReturnValues: \"ALL_NEW\",\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n UpdateExpression: exp.update(this.normalizeUpdate(data.update as Obj)),\n ConditionExpression: exp.condition(condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return output.Attributes as T;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n {\n type: \"CONDITIONAL_CHECK_FAILED\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async delete<T = Obj>(data: DbDelete<T>): Promise<T | undefined> {\n const exp = new ExpressionBuilder();\n\n const input = new Lib.DeleteCommand({\n TableName: data.table,\n Key: data.key,\n ReturnValues: \"ALL_OLD\",\n ConditionExpression: exp.condition(data.condition),\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return output.Attributes as T | undefined;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n {\n type: \"CONDITIONAL_CHECK_FAILED\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async deleteOrThrow<T = Obj>(data: DbDelete<T>): Promise<T> {\n const item = await this.delete<T>(data);\n if (!item) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n });\n }\n return item;\n }\n\n async *queryPaged<T = Obj>(data: DbQuery<T>): AsyncGenerator<T[]> {\n const exp = new ExpressionBuilder();\n\n let lastEvaluatedKey: Obj | undefined = data.startKey as Obj | undefined;\n do {\n const input = new Lib.QueryCommand({\n TableName: data.table,\n IndexName: data.index,\n ExclusiveStartKey: lastEvaluatedKey,\n Limit: data.limit,\n ScanIndexForward: data.sort !== \"DESC\",\n ConsistentRead: data.consistent,\n KeyConditionExpression: exp.condition(data.query),\n ProjectionExpression: exp.projection(data.projection),\n FilterExpression: exp.condition(data.filter),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n const output = await this.client.send(input);\n\n if (output.Items?.length) {\n yield output.Items as T[];\n }\n lastEvaluatedKey = output.LastEvaluatedKey;\n } while (lastEvaluatedKey);\n }\n\n async query<T = Obj>(data: DbQuery<T>): Promise<T[]> {\n const items: T[] = [];\n\n for await (const page of this.queryPaged(data)) {\n items.push(...page);\n }\n\n return items;\n }\n\n async *scanPaged<T = Obj>(data: DbScan<T>): AsyncGenerator<T[]> {\n const exp = new ExpressionBuilder();\n\n const totalSegments = data.parallel ?? 1;\n const segments = [...Array(totalSegments).keys()];\n\n // undefined: initial value when a start key isn't specified\n // null: scanning a particular segment is finished\n const lastEvaluatedKeys: (Obj | undefined | null)[] = segments.map(\n () => data.startKey as Obj | undefined,\n );\n do {\n const results = await Promise.all(\n segments.map(async (segment) => {\n if (lastEvaluatedKeys[segment] === null) return [];\n\n const input = new Lib.ScanCommand({\n ExclusiveStartKey: lastEvaluatedKeys[segment],\n Segment: segment,\n TotalSegments: totalSegments,\n TableName: data.table,\n IndexName: data.index,\n Limit: data.limit,\n ConsistentRead: data.consistent,\n ProjectionExpression: exp.projection(data.projection),\n FilterExpression: exp.condition(data.filter),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n const output = await this.client.send(input);\n lastEvaluatedKeys[segment] = output.LastEvaluatedKey ?? null;\n return output.Items ?? [];\n }),\n );\n\n const items = results.flat();\n\n if (items.length) {\n yield items as T[];\n }\n } while (lastEvaluatedKeys.some((key) => key !== null));\n }\n\n async scan<T = Obj>(data: DbScan<T>): Promise<T[]> {\n const items: T[] = [];\n\n for await (const page of this.scanPaged(data)) {\n items.push(...(page as T[]));\n }\n\n return items;\n }\n\n async exists<T = Obj>(data: DbExists<T>): Promise<boolean> {\n const { query, ...otherOptions } = data;\n\n // we can't rely on the limit when a filter is being applied, since the filter is\n // applied after the scan/query page, so we only apply a limit of 1 when there is no filter.\n // otherwise, we page through the results and return true as soon as we see a single item\n const sharedOptions = {\n ...otherOptions,\n limit: data.filter ? undefined : 1,\n };\n\n const pagedItems = query\n ? this.queryPaged({ query, ...sharedOptions })\n : this.scanPaged(sharedOptions);\n\n for await (const items of pagedItems) {\n if (items.length) return true;\n }\n\n return false;\n }\n\n // TODO: test wildly different item sizes to make\n // sure retry algorithm works properly\n async batchGet(data: DbBatchGet): Promise<DbBatchGetResponse> {\n const result: DbBatchGetResponse = { items: {} };\n\n const tableData = Object.fromEntries(\n Object.entries(data).map(([table, request]) => {\n const exp = new ExpressionBuilder();\n\n result.items[table] = [];\n\n return [\n table,\n {\n request: {\n ConsistentRead: request?.consistent,\n ProjectionExpression: exp.projection(request?.projection),\n ExpressionAttributeNames: exp.attributeNames,\n },\n keyNames: Object.keys(request.keys.at(0) ?? {}),\n itemIndexMap: new Map<string, number>(),\n filter: request.filter,\n },\n ];\n }),\n );\n\n const flattenedBatches = Object.entries(data).flatMap(([table, request]) => {\n return request.keys.map((key, i) => {\n const itemIndexKey =\n tableData[table]?.keyNames.map((keyName) => key[keyName]).join(\"|\") ?? \"\";\n tableData[table]?.itemIndexMap.set(itemIndexKey, i);\n return [table, key] as const;\n });\n });\n\n let batchSize = 100;\n let retryCount = 0;\n\n while (flattenedBatches.length && retryCount < 5) {\n const batch = flattenedBatches.splice(0, batchSize || 1);\n\n const request: BatchGetItemInput[\"RequestItems\"] = {};\n for (const [table, key] of batch) {\n if (!request[table]) {\n request[table] = { ...tableData[table]?.request, Keys: [] };\n }\n\n request[table].Keys?.push(key);\n }\n\n const input = new Lib.BatchGetCommand({ RequestItems: request });\n const output = await this.client.send(input);\n\n for (const [table, items] of Object.entries(output.Responses ?? {})) {\n //just to appease typescript\n if (!result.items[table]) continue;\n\n const filteredItems = tableData[table]?.filter\n ? items.filter((item) => matchesPartial(tableData[table]!.filter as any, item as any))\n : items;\n\n result.items[table].push(...filteredItems);\n }\n\n // handle unprocessed requests\n let unprocessedKeyCount = 0;\n for (const [table, request] of Object.entries(output.UnprocessedKeys ?? {})) {\n const unprocessed = (request.Keys ?? []).map((key) => [table, key] as const);\n flattenedBatches.push(...unprocessed);\n unprocessedKeyCount += unprocessed.length;\n }\n\n //move immediately to next batch if all requests were processed\n if (!unprocessedKeyCount) {\n retryCount = 0;\n continue;\n }\n\n // reduce batch size so we don't continue to overfetch,\n // but do it gradually by only splitting the difference\n batchSize -= Math.floor(unprocessedKeyCount / 2);\n\n retryCount++;\n }\n\n // anything left in flattened batches needs to be returned in unprocessed\n if (flattenedBatches.length) {\n result.unprocessed = {};\n for (const [table, key] of flattenedBatches) {\n if (!result.unprocessed[table]) {\n result.unprocessed[table] = {\n ...tableData[table]?.request,\n keys: [],\n };\n }\n result.unprocessed[table].keys.push(key);\n }\n }\n\n // finally, sort any returned items by their original index to preserve order\n for (const [table, items] of Object.entries(result.items)) {\n const itemIndexMap = tableData[table]?.itemIndexMap;\n const keyNames = tableData[table]?.keyNames;\n\n if (!itemIndexMap || !keyNames) continue;\n\n items.sort((item1, item2) => {\n const item1IndexKey = keyNames.map((keyName) => item1[keyName]).join(\"|\");\n const item2IndexKey = keyNames.map((keyName) => item2[keyName]).join(\"|\");\n\n return (itemIndexMap.get(item1IndexKey) ?? 0) - (itemIndexMap.get(item2IndexKey) ?? 0);\n });\n }\n\n return result;\n }\n\n async batchGetOrThrow(data: DbBatchGet): Promise<DbBatchGetResponse[\"items\"]> {\n const { items, unprocessed } = await this.batchGet(data);\n\n for (const table of Object.keys(data)) {\n if (unprocessed?.[table]) {\n throw new Error(`One or more batch get requests were not processed in \"${table}\" table.`);\n }\n\n if (items[table]?.length !== data[table]?.keys?.length) {\n // Key identity is not tracked through batchGet — key: {} is a known limitation here.\n throw new DinahError({ type: \"NOT_FOUND\", key: {}, resource: data[table]?.resource });\n }\n }\n\n return items;\n }\n\n // TODO: test wildly different item sizes to make\n // sure retry algorithm works properly\n async batchWrite(data: DbBatchWrite): Promise<DbBatchWriteResponse> {\n const result: DbBatchWriteResponse = { items: {} };\n\n const flattenedBatches = Object.keys(data).flatMap((table) => {\n return (\n data[table]?.map((r) => {\n if (r.type === \"DELETE\") {\n return [table, { DeleteRequest: { Key: r.key } }] as [string, WriteRequest];\n } else {\n return [table, { PutRequest: { Item: r.item } }] as [string, WriteRequest];\n }\n }) ?? []\n );\n });\n\n let batchSize = 25;\n let retryCount = 0;\n\n while (flattenedBatches.length && retryCount < 5) {\n const batch = flattenedBatches.splice(0, batchSize || 1);\n\n const request: BatchWriteItemInput[\"RequestItems\"] = {};\n for (const [table, req] of batch) {\n if (!request[table]) {\n request[table] = [];\n }\n request[table].push(req);\n }\n\n const input = new Lib.BatchWriteCommand({ RequestItems: request });\n const output = await this.client.send(input);\n\n // handle unprocessed requests\n let unprocessedKeyCount = 0;\n for (const [table, requests] of Object.entries(output.UnprocessedItems ?? {})) {\n for (const request of requests) {\n flattenedBatches.push([table, request]);\n unprocessedKeyCount++;\n }\n }\n\n //move immediately to next batch if all requests were processed\n if (!unprocessedKeyCount) {\n retryCount = 0;\n continue;\n }\n\n // reduce batch size so we don't continue to overwrite,\n // but do it gradually by only splitting the difference\n batchSize -= Math.floor(unprocessedKeyCount / 2);\n\n retryCount++;\n }\n\n // anything left in flattened batches needs to be returned in unprocessed\n if (flattenedBatches.length) {\n result.unprocessed = {};\n for (const [table, request] of flattenedBatches) {\n if (!result.unprocessed[table]) {\n result.unprocessed[table] = [];\n }\n\n if (\"DeleteRequest\" in request && request.DeleteRequest?.Key) {\n result.unprocessed[table].push({\n type: \"DELETE\",\n key: request.DeleteRequest.Key,\n });\n } else if (\"PutRequest\" in request && request.PutRequest?.Item) {\n result.unprocessed[table].push({\n type: \"PUT\",\n item: request.PutRequest.Item,\n });\n }\n }\n }\n\n return result;\n }\n\n async batchUpdate(data: DbBatchUpdate): Promise<DbBatchUpdateResponse> {\n const queue = Object.entries(data).flatMap(([table, req]) =>\n req.keys.map((key) => [table, key, req.update] as [string, Obj, Obj]),\n );\n\n let batchSize = 25;\n let retryCount = 0;\n\n while (queue.length && retryCount < 5) {\n const batch = queue.splice(0, batchSize || 1);\n\n const statements = batch.map(([table, key, update]) => {\n const exp = new ExpressionBuilder();\n const { sets, removes, params } = exp.partiqlUpdate(this.normalizeUpdate(update));\n\n const whereParts: string[] = [];\n for (const [field, value] of Object.entries(key)) {\n whereParts.push(`\"${field}\"=?`);\n params.push(value);\n }\n\n const clauses = [...sets.map((s) => `SET ${s}`), ...removes.map((r) => `REMOVE ${r}`)].join(\n \" \",\n );\n\n return {\n Statement: `UPDATE \"${table}\" ${clauses} WHERE ${whereParts.join(\" AND \")}`,\n Parameters: params,\n };\n });\n\n const output = await this.client.send(\n new Lib.BatchExecuteStatementCommand({ Statements: statements }),\n );\n\n let failCount = 0;\n output.Responses?.forEach((response, i) => {\n if (response.Error && batch[i]) {\n queue.push(batch[i]);\n failCount++;\n }\n });\n\n if (!failCount) {\n retryCount = 0;\n continue;\n }\n\n batchSize -= Math.floor(failCount / 2);\n retryCount++;\n }\n\n if (queue.length) {\n const unprocessed: DbBatchUpdate = {};\n for (const [table, key, update] of queue) {\n if (!unprocessed[table]) {\n unprocessed[table] = { keys: [], update };\n }\n unprocessed[table].keys.push(key);\n }\n return { unprocessed };\n }\n\n return {};\n }\n\n async trxGet<R extends DbTrxGetRequest[]>(...requests: R): Promise<DbTrxGetResult<R>> {\n const trxItems: TransactGetCommandInput[\"TransactItems\"] = requests.map((request) => {\n const exp = new ExpressionBuilder();\n return {\n Get: {\n Key: request.key,\n TableName: request.table,\n ProjectionExpression: exp.projection(request?.projection),\n ExpressionAttributeNames: exp.attributeNames,\n },\n };\n });\n\n const input = new Lib.TransactGetCommand({ TransactItems: trxItems });\n const output = await this.client.send(input);\n\n return (\n (output.Responses?.map((response, i) => {\n if (!response.Item) return;\n\n if (!requests[i]?.filter) return response.Item;\n\n return matchesPartial(requests[i].filter!, response.Item as any)\n ? response.Item\n : undefined;\n }) as DbTrxGetResult<R>) ?? []\n );\n }\n\n async trxGetOrThrow<R extends DbTrxGetRequest[]>(\n ...requests: R\n ): Promise<DbTrxGetOrThrowResult<R>> {\n const items = await this.trxGet(...requests);\n for (let i = 0; i < items.length; i++) {\n if (!items[i]) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: (requests[i]?.key ?? {}) as Record<string, unknown>,\n resource: requests[i]?.resource,\n });\n }\n }\n\n return items as DbTrxGetOrThrowResult<R>;\n }\n\n async trxWrite(...requests: DbTrxWriteRequest[]): Promise<void> {\n const trxItems: TransactWriteCommandInput[\"TransactItems\"] = requests.map((request) => {\n const exp = new ExpressionBuilder();\n\n if (request.type === \"CONDITION\" || request.type === \"DELETE\") {\n return {\n [request.type === \"CONDITION\" ? \"ConditionCheck\" : \"Delete\"]: {\n TableName: request.table,\n Key: request.key,\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n }\n\n if (request.type === \"PUT\") {\n return {\n Put: {\n TableName: request.table,\n Item: removeUndefined(request.item),\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n }\n\n return {\n Update: {\n Key: request.key,\n TableName: request.table,\n UpdateExpression: exp.update(this.normalizeUpdate(request.update as Obj)),\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n });\n\n const input = new Lib.TransactWriteCommand({ TransactItems: trxItems });\n try {\n await this.client.send(input);\n } catch (err) {\n if (err instanceof TransactionCanceledException) {\n throw new DinahError(\n {\n type: \"TRANSACTION_CANCELED\",\n reasons: (err.CancellationReasons ?? []).map((r) => ({\n type: r.Code ?? \"Unknown\",\n message: r.Message,\n })),\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n /* Dynamodb Streams */\n\n /*\n\n\tasync enableStreamEvents(data?: DbEnableEventStreams): Promise<void> {\n\t\tconst tables = data?.tables ?? (await this.listTables());\n\n\t\tconst streamsClient = new DynamoDBStreams({\n\t\t\tendpoint: this.client.config.endpoint,\n\t\t\tcredentials: this.client.config.credentials,\n\t\t\tregion: this.client.config.region,\n\t\t});\n\n\t\tawait Promise.all(\n\t\t\ttables.map(async (table) => {\n\t\t\t\tconst tableDesc = await this.client.send(new DescribeTableCommand({ TableName: table }));\n\n\t\t\t\tconst latestStreamArn = tableDesc.Table?.LatestStreamArn;\n\n\t\t\t\tif (!latestStreamArn) {\n\t\t\t\t\tif (data?.tables) {\n\t\t\t\t\t\tthrow new Error(`Table \"${table}\" does not have streaming enabled.`);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst eventStreamer = new EventStreamer(streamsClient, latestStreamArn);\n\t\t\t\teventStreamer.startPolling();\n\t\t\t}),\n\t\t);\n\t}\n\n\tasync disableStreamEvents(): Promise<void> {}\n\n\tsubscribe(listener: DbStreamEventListener): void {\n\t\tthis.streamEventListeners.push(listener);\n\t}\n\n\tunsubscribe(listener: DbStreamEventListener): void {\n\t\tthis.streamEventListeners = this.streamEventListeners.filter((l) => l !== listener);\n\t}\n\n\tunsubscribeAll(): void {\n\t\tthis.streamEventListeners = [];\n\t}\n\t*/\n}\n\n// respondentRepo.onChange((respondent) => , { filter: (r1, r2) => r1.status !== r2.status } )\n/*\nconst time = new Date(record.dynamodb.ApproximateCreationDateTime).getTime();\nif (time >= startTime) {\n\tfor (const listener of this.streamEventListeners) {\n\t\tlistener({\n\t\t\ttable,\n\t\t\ttime,\n\t\t\tid: record.eventID,\n\t\t\ttype: record.eventName,\n\t\t\tkey: record.dynamodb.Keys,\n\t\t\toldItem: record.dynamodb.OldImage,\n\t\t\tnewItem: record.dynamodb.NewImage,\n\t\t});\n\t}\n}\n*/\n","import type { Static, TSchema } from \"typebox\";\nimport type { TableDef } from \"./types\";\n\ntype SchemaStatic<Schema extends TSchema> = unknown extends Static<Schema> ? any : Static<Schema>;\n\nexport class Table<\n Schema extends TSchema = TSchema,\n const Def extends TableDef<SchemaStatic<Schema>> = TableDef<SchemaStatic<Schema>>,\n> {\n readonly schema: Schema;\n readonly def: Def;\n\n constructor(schema: Schema, def: Def) {\n this.schema = schema;\n this.def = def;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["matchesPartial","DynamoDBClient","DynamoDB","Lib","CreateTableCommand","extractTableDesc","DeleteTableCommand","ListTablesCommand","matchesPartial","removeUndefined","ConditionalCheckFailedException","TransactionCanceledException"],"sources":["../src/error.ts","../src/expression-builder.ts","../src/repo.ts","../src/db.ts","../src/table.ts"],"sourcesContent":["export type DinahErrorDetails =\n | { type: \"NOT_FOUND\"; key: Record<string, unknown>; resource?: string }\n | { type: \"ALREADY_EXISTS\"; key: Record<string, unknown>; resource?: string }\n | { type: \"CONDITIONAL_CHECK_FAILED\"; key?: Record<string, unknown>; resource?: string }\n | { type: \"VALIDATION\"; message: string }\n | { type: \"TRANSACTION_CANCELED\"; reasons: Array<{ type: string; message?: string }> }\n | { type: \"DATA_INTEGRITY\"; message: string };\n\nfunction dinahErrorMessage(details: DinahErrorDetails): string {\n switch (details.type) {\n case \"NOT_FOUND\":\n return `${details.resource ?? \"Item\"} not found.`;\n case \"ALREADY_EXISTS\":\n return `${details.resource ?? \"Item\"} already exists.`;\n case \"CONDITIONAL_CHECK_FAILED\":\n return `${details.resource ?? \"Item\"} condition check failed.`;\n case \"VALIDATION\":\n return `Validation error: ${details.message}`;\n case \"DATA_INTEGRITY\":\n return `Data integrity error: ${details.message}`;\n case \"TRANSACTION_CANCELED\":\n return `Transaction canceled: ${details.reasons.map((r) => r.type).join(\", \")}`;\n }\n}\n\nexport class DinahError extends Error {\n readonly details: DinahErrorDetails;\n\n constructor(details: DinahErrorDetails, options?: ErrorOptions) {\n super(dinahErrorMessage(details), options);\n this.name = \"DinahError\";\n this.details = details;\n }\n}\n\nexport const isDinahError = (err: unknown): err is DinahError => err instanceof DinahError;\n","import { DinahError } from \"./error\";\nimport type { Obj } from \"./types\";\n\nconst attrTypes = [\"S\", \"SS\", \"N\", \"NS\", \"B\", \"BS\", \"BOOL\", \"NULL\", \"L\", \"M\"] as const;\nconst comparatorOps: Obj<string> = {\n $eq: \"=\",\n $ne: \"<>\",\n $gt: \">\",\n $gte: \">=\",\n $lt: \"<\",\n $lte: \"<=\",\n};\n\n// TODO should { $eq: undefined } and { $ne: undefined } be converted into attribute_not_exists and attribute_exists ?\n\nexport const isOperation = (val: unknown): val is Obj => {\n if (!val || typeof val !== \"object\" || Array.isArray(val)) return false;\n return Object.keys(val).every((op) => op.startsWith(\"$\"));\n};\n\nexport class ExpressionBuilder {\n protected readonly attrNames = new Map<string, string>();\n protected readonly attrValues = new Map<unknown, string>();\n\n get attributeNames(): Obj<string> | undefined {\n return this.attrNames.size\n ? Object.fromEntries(\n [...this.attrNames.entries()].map(([name, placeholder]) => [placeholder, name]),\n )\n : undefined;\n }\n\n get attributeValues(): Obj | undefined {\n return this.attrValues.size\n ? Object.fromEntries(\n [...this.attrValues.entries()].map(([value, placeholder]) => [placeholder, value]),\n )\n : undefined;\n }\n\n reset(): void {\n this.attrNames.clear();\n this.attrValues.clear();\n }\n\n getPathSub(path: string): string {\n const segments = path.split(\".\");\n const placeholders: string[] = [];\n\n for (const segment of segments) {\n let placeholder = this.attrNames.get(segment);\n if (!placeholder) {\n placeholder = `#${this.attrNames.size}`;\n this.attrNames.set(segment, placeholder);\n }\n\n placeholders.push(placeholder);\n }\n\n return placeholders.join(\".\");\n }\n\n getValueSub(value: unknown): string {\n let placeholder = this.attrValues.get(value);\n if (!placeholder) {\n placeholder = `:${this.attrValues.size}`;\n this.attrValues.set(value, placeholder);\n }\n\n return placeholder;\n }\n\n getValueOrPathSub(pathOrValue: unknown): string {\n if (isOperation(pathOrValue)) {\n if (pathOrValue.$path) return this.getPathSub(pathOrValue.$path);\n throw new Error(\"Expected $path or operand.\");\n }\n\n return this.getValueSub(pathOrValue);\n }\n\n projection<T extends string[] | undefined>(paths: T): T extends undefined ? undefined : string {\n return paths?.map((path) => this.getPathSub(path)).join(\", \") as never;\n }\n\n condition<T extends Obj | undefined>(expression: T): T extends undefined ? undefined : string {\n if (!expression) return undefined as never;\n\n const expressions: string[] = [];\n for (const [key, val] of Object.entries(expression)) {\n if (key === \"$and\") {\n if (!Array.isArray(val)) throw new Error(\"$and expects an array operand.\");\n expressions.push(`(${val.map((v) => this.condition(v)).join(\" AND \")})`);\n } else if (key === \"$or\" && Array.isArray(val)) {\n if (!Array.isArray(val)) throw new Error(\"$or expects an array operand.\");\n expressions.push(`(${val.map((v) => this.condition(v)).join(\" OR \")})`);\n } else if (key === \"$not\") {\n if (!val || typeof val !== \"object\") throw new Error(\"$not expects an object operand.\");\n expressions.push(`NOT ${this.condition(val)}`);\n } else if (!key.startsWith(\"$\")) {\n expressions.push(this.resolveCondition(key, val));\n } else {\n throw new Error(\n `Unexpected operator \"${key}\". Expected attribute path or compound operator.`,\n );\n }\n }\n\n return expressions.join(\" AND \") as never;\n }\n\n update<T extends Obj | undefined>(expression: T): T extends undefined ? undefined : string {\n if (expression === undefined) return undefined as never;\n\n const setOperations: string[] = [];\n const removeOperations: string[] = [];\n const setAddOperations: string[] = [];\n const setDelOperations: string[] = [];\n\n for (const [path, valOrOperation] of Object.entries(expression)) {\n const placeholder = this.getPathSub(path);\n\n if (valOrOperation === undefined) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${path}\" cannot be set to undefined in an update expression. Use { $remove: true } to remove an optional attribute.`,\n });\n } else if (isOperation(valOrOperation)) {\n if (valOrOperation.$remove === true) {\n removeOperations.push(placeholder);\n } else if (valOrOperation.$setAdd !== undefined || valOrOperation.$setDel !== undefined) {\n const operations = valOrOperation.$setAdd ? setAddOperations : setDelOperations;\n const operand = valOrOperation.$setAdd ?? valOrOperation.$setDel;\n operations.push(\n `${placeholder} ${this.getValueSub(operand instanceof Set ? operand : new Set([operand].flat()))}`,\n );\n } else {\n setOperations.push(`${placeholder} = ${this.resolveSetOperand(path, valOrOperation)}`);\n }\n } else {\n setOperations.push(`${placeholder} = ${this.getValueSub(valOrOperation)}`);\n }\n }\n\n let updateExpression = \"\";\n if (setOperations.length) {\n updateExpression += `SET ${setOperations.join(\", \")} `;\n }\n\n if (removeOperations.length) {\n updateExpression += `REMOVE ${removeOperations.join(\", \")} `;\n }\n\n if (setAddOperations.length) {\n updateExpression += `ADD ${setAddOperations.join(\", \")} `;\n }\n\n if (setDelOperations.length) {\n updateExpression += `DELETE ${setDelOperations.join(\", \")} `;\n }\n\n return updateExpression as never;\n }\n\n protected resolveCondition(path: string, exp: unknown): string {\n if (!exp || typeof exp !== \"object\" || !Object.keys(exp).at(0)?.startsWith(\"$\")) {\n return this.resolveCondition(path, { $eq: exp });\n }\n\n const placeholder = this.getPathSub(path);\n const [operator, operand] = Object.entries(exp).at(0) ?? [\"\"];\n\n if (comparatorOps[operator]) {\n if (isOperation(operand) && operand.$path) {\n return `${placeholder} ${comparatorOps[operator]} ${this.getPathSub(operand.$path)}`;\n }\n\n if (![\"string\", \"boolean\", \"number\"].includes(typeof operand)) {\n throw new Error(`${operator} expects a primitive/scalar operand.`);\n }\n return `${placeholder} ${comparatorOps[operator]} ${this.getValueSub(operand)}`;\n }\n\n switch (operator) {\n case \"$in\":\n if (!Array.isArray(operand)) {\n throw new Error(\"$in operator expects an array operand.\");\n }\n return `${placeholder} IN (${operand.map((op) => this.getValueSub(op)).join(\", \")})`;\n\n case \"$nin\":\n if (!Array.isArray(operand)) {\n throw new Error(\"$nin operator expects an array operand.\");\n }\n return `${placeholder} NOT IN (${operand.map((op) => this.getValueSub(op)).join(\", \")})`;\n\n case \"$prefix\":\n if (typeof operand !== \"string\") {\n throw new Error(\"$prefix operator expects a string operand.\");\n }\n return `begins_with(${placeholder}, ${this.getValueSub(operand)})`;\n\n case \"$includes\":\n return `contains(${placeholder}, ${this.getValueSub(operand)})`;\n\n case \"$between\":\n if (!Array.isArray(operand) || operand.length !== 2) {\n throw new Error(\"$between operator expects an array operand of exactly two values.\");\n }\n return `${placeholder} BETWEEN ${this.getValueSub(operand[0])} AND ${this.getValueSub(operand[1])}`;\n\n case \"$exists\":\n if (typeof operand !== \"boolean\") {\n throw new Error(\"$exists operator expects a boolean operand.\");\n }\n return operand\n ? `attribute_exists(${placeholder})`\n : `attribute_not_exists(${placeholder})`;\n\n case \"$type\":\n if (!attrTypes.includes(operand as any)) {\n throw new Error(`$type operator expects operand to be one of ${attrTypes.join(\",\")}`);\n }\n return `attribute_type(${placeholder})`;\n\n case \"$size\": {\n const sizeExp = typeof operand === \"number\" ? { $eq: operand } : operand;\n if (\n !sizeExp ||\n typeof sizeExp !== \"object\" ||\n !Object.keys(sizeExp).at(0)?.startsWith(\"$\")\n ) {\n throw new Error(\"$size operator expects a number operand or a comparator object.\");\n }\n const [sizeOperator, sizeOperand] = Object.entries(sizeExp).at(0) ?? [\"\"];\n\n if (!comparatorOps[sizeOperator]) {\n throw new Error(\"$size operator expects a number operand or a comparator object.\");\n }\n\n if (![\"string\", \"boolean\", \"number\"].includes(typeof sizeOperand)) {\n throw new Error(`${operator} expects a primitive/scalar operand.`);\n }\n\n return `size(${placeholder}) ${comparatorOps[sizeOperator]} ${this.getValueSub(sizeOperand)}`;\n }\n\n default:\n throw new Error(`Invalid operator \"${operator}\"`);\n }\n }\n\n protected resolveSetOperand(path: string, operand: unknown): string {\n if (isOperation(operand)) {\n if (operand.$ifNotExists) {\n const params = Array.isArray(operand.$ifNotExists)\n ? operand.$ifNotExists\n : [path, operand.$ifNotExists];\n return `if_not_exists(${this.getPathSub(params[0])}, ${this.resolveSetOperand(path, params[1])})`;\n }\n\n if (operand.$set) {\n return this.resolveSetOperand(path, operand.$set);\n }\n\n if (operand.$plus !== undefined || operand.$minus !== undefined) {\n const mathOperator = operand.$plus ? \"+\" : \"-\";\n const mathOperand = operand.$plus ?? operand.$minus;\n const params = Array.isArray(mathOperand) ? mathOperand : [{ $path: path }, mathOperand];\n return `${params.map((param) => this.resolveSetOperand(path, param)).join(` ${mathOperator} `)}`;\n }\n\n if (operand.$append !== undefined || operand.$prepend !== undefined) {\n const listOperand = operand.$append ?? operand.$prepend;\n const resolvedListOperand = isOperation(listOperand) ? listOperand : [listOperand].flat();\n const params = operand.$append\n ? [{ $path: path }, resolvedListOperand]\n : [resolvedListOperand, { $path: path }];\n return `list_append(${params.map((param) => this.resolveSetOperand(path, param)).join(\", \")})`;\n }\n }\n\n return this.getValueOrPathSub(operand);\n }\n\n // ── PartiQL update (for BatchExecuteStatement) ───────────────────────────────\n\n partiqlUpdate(expression: Obj): { sets: string[]; removes: string[]; params: unknown[] } {\n const sets: string[] = [];\n const removes: string[] = [];\n const params: unknown[] = [];\n\n for (const [path, valOrOp] of Object.entries(expression)) {\n if (valOrOp === undefined) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${path}\" cannot be set to undefined in an update expression. Use { $remove: true } to remove an optional attribute.`,\n });\n } else if (isOperation(valOrOp)) {\n if (valOrOp.$remove === true) {\n removes.push(`\"${path}\"`);\n } else {\n sets.push(`\"${path}\"=${this.resolvePartiQLSetOperand(path, valOrOp, params)}`);\n }\n } else {\n sets.push(`\"${path}\"=?`);\n params.push(valOrOp);\n }\n }\n\n return { sets, removes, params };\n }\n\n protected resolvePartiQLSetOperand(path: string, operand: unknown, params: unknown[]): string {\n if (isOperation(operand)) {\n if (operand.$set !== undefined) {\n return this.resolvePartiQLSetOperand(path, operand.$set, params);\n }\n if (operand.$plus !== undefined || operand.$minus !== undefined) {\n const op = operand.$plus ? \"+\" : \"-\";\n const mathOperand = operand.$plus ?? operand.$minus;\n const parts = Array.isArray(mathOperand) ? mathOperand : [{ $path: path }, mathOperand];\n return parts.map((p: any) => this.resolvePartiQLSetOperand(path, p, params)).join(op);\n }\n if (operand.$path) {\n return `\"${operand.$path}\"`;\n }\n }\n params.push(operand);\n return \"?\";\n }\n}\n","import type { Db } from \"./db\";\nimport type { Table } from \"./table\";\nimport type { DbTrxGetRequest, DbTrxWriteRequest } from \"./db.types\";\nimport type {\n GsiNames,\n RepoBatchGetOptions,\n RepoBatchGetOrThrowResult,\n RepoBatchGetResult,\n RepoBatchUpdateResult,\n RepoBatchWrite,\n RepoBatchWriteResult,\n RepoCreateItem,\n RepoCreateResult,\n RepoDeleteOptions,\n RepoDeleteOrThrowResult,\n RepoExistsOptions,\n RepoGetGsiOptions,\n RepoGetGsiOrThrowResult,\n RepoGetOptions,\n RepoGetOrThrowResult,\n RepoKey,\n RepoPutOptions,\n RepoPutItem,\n RepoPutResult,\n RepoQueryGsiOptions,\n RepoQueryGsiPagedResult,\n RepoQueryGsiResult,\n RepoQueryOptions,\n RepoQueryPagedResult,\n RepoQueryResult,\n RepoScanGsiOptions,\n RepoScanGsiPagedResult,\n RepoScanGsiResult,\n RepoScanOptions,\n RepoScanPagedResult,\n RepoScanResult,\n RepoTrxGetOptions,\n RepoTrxGetOrThrowResult,\n RepoTrxGetResult,\n RepoTrxWriteRequest,\n RepoUpdateInput,\n RepoUpdateInputFor,\n RepoUpdateOptions,\n RepoUpdateResult,\n RepoQueryGsiQuery,\n RepoQueryQuery,\n} from \"./repo.types\";\nimport type { AllKeys, Condition, ExtractTableDef, ExtractTableSchema, Obj } from \"./types\";\nimport { isOperation } from \"./expression-builder\";\nimport { DinahError } from \"./error\";\nimport { matchesPartial } from \"./util\";\n\n// TODO: query/queryGsi needs strongly typed \"key\" argument\n// allows =,>,>=,<,<=,begins_with, between on sort key\n// util -> extractExclusiveStartKey(item)\n\n// Minimal structural interface used as the constraint in repo.types.ts.\n// Keeps type helper constraints simple (R extends RepoBase) while the full\n// Repo class retains separate generic params for inference quality.\nexport interface RepoBase {\n readonly $schema: object;\n readonly $def: { readonly partitionKey: string; readonly sortKey?: string };\n readonly $computedAttributes: PropertyKey;\n readonly $immutableAttributes: PropertyKey;\n readonly $discriminator: PropertyKey;\n readonly table: Table;\n readonly defaultCreateData: object;\n readonly defaultUpdateData: object;\n transformOutput(item: never): unknown;\n}\n\nexport type ComputedFieldDef<TSchema extends object, K extends keyof TSchema> =\n | { [J in keyof TSchema]: { from: J; compute: (val: TSchema[J]) => TSchema[K] } }[keyof TSchema]\n | { from: readonly (keyof TSchema)[]; compute: (...vals: any[]) => TSchema[K] };\n\n// Recursively maps a tuple of schema keys to a tuple of their value types.\ntype ComputeArgs<\n TSchema extends object,\n Js extends readonly (keyof TSchema)[],\n> = Js extends readonly [\n infer Head extends keyof TSchema,\n ...infer Tail extends readonly (keyof TSchema)[],\n]\n ? [TSchema[Head], ...ComputeArgs<TSchema, Tail>]\n : [];\n\n// Post-inference constraint. Maps each computed attribute key to its expected shape so\n// TypeScript's structural assignability check enforces correct param and return types.\n// Catching too-narrow param annotations (missing | undefined) and too-broad return types\n// falls out of normal contravariant/covariant function subtype checking automatically.\nexport type ValidComputedMap<TSchema extends object, TComputed> = {\n [K in keyof TComputed]?: K extends keyof TSchema\n ? TComputed[K] extends { from: infer Js extends readonly (keyof TSchema)[]; compute: any }\n ? { from: Js; compute: (...vals: ComputeArgs<TSchema, Js>) => TSchema[K] }\n : TComputed[K] extends { from: infer J extends keyof TSchema; compute: any }\n ? { from: J; compute: (val: TSchema[J]) => TSchema[K] }\n : never\n : never;\n};\n\nexport interface RepoConfig<\n TSchema extends object,\n TDefaults extends Partial<TSchema> = {},\n TUpdateDefaults extends Partial<TSchema> = {},\n TOutput = TSchema,\n TComputed extends ValidComputedMap<TSchema, TComputed> = {},\n TImmutable extends AllKeys<TSchema> = never,\n TDiscriminator extends keyof TSchema = never,\n> {\n resourceName?: string;\n discriminator?: TDiscriminator;\n defaultCreateData?: () => TDefaults;\n defaultUpdateData?: () => TUpdateDefaults;\n transformAttributes?: { [K in keyof TSchema]?: (val: TSchema[K]) => TSchema[K] };\n computedAttributes?: TComputed & { [K in keyof TSchema]?: ComputedFieldDef<TSchema, K> };\n transformOutput?: (item: TSchema) => TOutput;\n immutableAttributes?: readonly TImmutable[];\n}\n\n// Concrete reconstruction of this repo's `RepoBase` shape, derived from the\n// class type parameters rather than from `this`. It mirrors the phantom `$*`\n// declarations below. This exists to feed the `Self` type parameter (see the\n// `Repo` class): the helper types in repo.types.ts do indexed-access and\n// conditional lookups (R[\"$schema\"], R[\"table\"][\"def\"], GsiProjectionType<R>,\n// NarrowByDiscriminator<..., R[\"$discriminator\"]>, ...). Those reduce only when\n// their `R` is bound to concrete types. `this` is a polymorphic type parameter,\n// and TypeScript defers indexed access on a type parameter, so `this`-based\n// helpers never reduce inside a (sub)class method body — even though they do\n// reduce at an external call site where `this` binds to the concrete receiver.\n// The ordinary class params (T, TDiscriminator, ...) ARE bound to concrete\n// types through a subclass's heritage clause, so a `Self` rebuilt from them\n// reduces everywhere, including inside subclass methods like\n// `class LogRepo extends makeRepo(t) { m() { this.queryGsi(...) } }`.\ntype RepoSelf<\n T extends Table,\n TDefaults extends object,\n TUpdateDefaults extends object,\n TOutput,\n TComputed,\n TImmutable extends PropertyKey,\n TDiscriminator extends PropertyKey,\n> = {\n readonly $schema: ExtractTableSchema<T>;\n readonly $def: ExtractTableDef<T>;\n readonly $computedAttributes: keyof TComputed;\n readonly $immutableAttributes: TImmutable;\n readonly $discriminator: TDiscriminator;\n readonly table: T;\n readonly defaultCreateData: TDefaults;\n readonly defaultUpdateData: TUpdateDefaults;\n // Mirrors the class method's real signature. The param must NOT be `never`\n // (as in the RepoBase constraint): `ReturnType<(x: never) => R>` resolves to\n // `any`, which would poison RepoOutput<Self> and every result type built on it.\n transformOutput(item: ExtractTableSchema<T>): TOutput;\n};\n\nexport class Repo<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n TDiscriminator extends keyof ExtractTableSchema<T> = never,\n // Synthetic, never passed explicitly. Bound to its default at every use site;\n // because the default is built from the params above (concrete in a subclass\n // heritage clause), method signatures written against `Self` reduce inside\n // subclass method bodies where `this`-based ones do not. See RepoSelf above.\n Self extends RepoBase = RepoSelf<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n> {\n // Concrete self-type (the `Self` reconstruction) exposed as a phantom so it\n // can be named when authoring an override. Base method signatures are written\n // against `Self`, which a subclass cannot name via `this` (and `this` would\n // not reduce inside a method body anyway). To override a generic base method,\n // write its signature against `<BaseRepoType>[\"$self\"]`, e.g.:\n // class LogRepo extends makeRepo(logTable) {\n // override async get<const O extends RepoGetOptions<Repo<typeof logTable>[\"$self\"]>>(\n // key: RepoKey<Repo<typeof logTable>[\"$self\"]>, options?: O,\n // ): Promise<RepoGetResult<Repo<typeof logTable>[\"$self\"], O>> {\n // return super.get(key, options);\n // }\n // }\n declare readonly $self: Self;\n\n // these phantom properties are used to pre-compute types derived from T\n // which allows easy lookups using the \"this\" Repo type\n declare readonly $schema: ExtractTableSchema<T>;\n declare readonly $def: ExtractTableDef<T>;\n declare readonly $computedAttributes: keyof TComputed;\n declare readonly $immutableAttributes: TImmutable;\n declare readonly $discriminator: TDiscriminator;\n\n readonly table: T;\n readonly db: Db;\n private readonly config: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >;\n\n constructor(\n db: Db,\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n ) {\n this.db = db;\n this.table = table;\n this.config = config ?? {};\n }\n\n get tableName(): string {\n return `${this.db.config?.tableNamePrefix ?? \"\"}${this.table.def.name}`;\n }\n\n get resourceName(): string {\n if (this.config.resourceName) return this.config.resourceName;\n const clsName = this.constructor.name;\n if (clsName && clsName !== \"Repo\") {\n return clsName.replace(/Repo$/i, \"\") || clsName;\n }\n const t = this.table.def.name;\n return t.charAt(0).toUpperCase() + t.slice(1);\n }\n\n get defaultCreateData(): TDefaults {\n return (this.config.defaultCreateData?.() ?? {}) as TDefaults;\n }\n\n get defaultUpdateData(): TUpdateDefaults {\n return (this.config.defaultUpdateData?.() ?? {}) as TUpdateDefaults;\n }\n\n transformOutput(item: ExtractTableSchema<T>): TOutput {\n return (this.config.transformOutput?.(item) ?? item) as TOutput;\n }\n\n // TODO: should this throw if pk is missing?\n // should return type by narrower?\n extractKey(item: RepoKey<Self>): RepoKey<Self> {\n const { partitionKey, sortKey } = this.table.def;\n if (sortKey) {\n return {\n [partitionKey]: item[partitionKey as keyof RepoKey<Self>],\n [sortKey]: item[sortKey as keyof RepoKey<Self>],\n } as RepoKey<Self>;\n }\n\n return { [partitionKey]: item[partitionKey as keyof RepoKey<Self>] } as RepoKey<Self>;\n }\n\n async get<const O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): Promise<RepoGetOrThrowResult<Self, O> | undefined> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetOptions<Self>;\n const item = await this.db.get({\n table: this.tableName,\n key: this.extractKey(key),\n filter,\n ...restOptions,\n } as any);\n return (item && this.applyTransformIfNeeded(item, options)) as any;\n }\n\n async getOrThrow<const O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): Promise<RepoGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetOptions<Self>;\n const item = await this.db.getOrThrow({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n filter,\n ...restOptions,\n } as any);\n return this.applyTransformIfNeeded(item, options) as any;\n }\n\n async put<const T extends RepoPutItem<Self>>(\n item: T,\n options?: RepoPutOptions<Self>,\n ): Promise<RepoPutResult<Self, T>> {\n const result = await this.db.put({\n table: this.tableName,\n item: item as any,\n resource: this.resourceName,\n ...options,\n });\n return this.applyTransformIfNeeded(result) as any;\n }\n\n async update<const K extends RepoKey<Self>>(\n key: K,\n update: RepoUpdateInputFor<Self, K>,\n options?: RepoUpdateOptions<Self>,\n ): Promise<RepoUpdateResult<Self>> {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n const result = await this.db.update({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n update: updateWithDefaults as any,\n ...options,\n condition: this.withDiscriminatorCondition(key, options?.condition),\n });\n return this.applyTransformIfNeeded(result);\n }\n\n async create<const T extends RepoCreateItem<Self>>(item: T): Promise<RepoCreateResult<Self, T>> {\n const condition = { $and: [{ [this.table.def.partitionKey]: { $exists: false } }] } as any;\n\n const normalizedItem = this.applyCreateTransforms(item as Obj);\n\n let result: Obj;\n try {\n result = await this.db.put({\n table: this.tableName,\n item: normalizedItem,\n resource: this.resourceName,\n condition,\n });\n } catch (err) {\n // The only condition `create` applies is the `<pk> not exists` guard, so a\n // conditional check failure means an item with this key already exists.\n if (err instanceof DinahError && err.details.type === \"CONDITIONAL_CHECK_FAILED\") {\n throw new DinahError(\n {\n type: \"ALREADY_EXISTS\",\n key: this.extractKey(item as unknown as RepoKey<Self>) as Record<string, unknown>,\n resource: this.resourceName,\n },\n { cause: err },\n );\n }\n throw err;\n }\n return this.applyTransformIfNeeded(result) as any;\n }\n\n async delete(\n key: RepoKey<Self>,\n options?: RepoDeleteOptions<Self>,\n ): Promise<RepoDeleteOrThrowResult<Self> | undefined> {\n const item = await this.db.delete({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n ...options,\n });\n return item && this.applyTransformIfNeeded(item);\n }\n\n async deleteOrThrow(\n key: RepoKey<Self>,\n options?: RepoDeleteOptions<Self>,\n ): Promise<RepoDeleteOrThrowResult<Self>> {\n const item = await this.db.deleteOrThrow({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n ...options,\n });\n return this.applyTransformIfNeeded(item);\n }\n\n async query<const O extends RepoQueryOptions<Self>>(\n query: RepoQueryQuery<Self>,\n options?: O,\n ): Promise<RepoQueryResult<Self, O>> {\n const items = await this.db.query({ table: this.tableName, query, ...options } as any);\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async *queryPaged<const O extends RepoQueryOptions<Self>>(\n query: RepoQueryQuery<Self>,\n options?: O,\n ): RepoQueryPagedResult<Self, O> {\n for await (const page of this.db.queryPaged({\n table: this.tableName,\n query,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, options) as any;\n }\n }\n\n async queryGsi<G extends GsiNames<Self>, const O extends RepoQueryGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoQueryGsiResult<Self, O, G>> {\n const items = await this.db.query({\n table: this.tableName,\n index: gsi,\n query,\n ...options,\n } as any);\n return this.applyTransformsIfNeeded(items, { ...options, gsi }) as any;\n }\n\n async *queryGsiPaged<G extends GsiNames<Self>, const O extends RepoQueryGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): RepoQueryGsiPagedResult<Self, O, G> {\n for await (const page of this.db.queryPaged({\n table: this.tableName,\n index: gsi,\n query,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, { ...options, gsi }) as any;\n }\n }\n\n async getGsi<G extends GsiNames<Self>, const O extends RepoGetGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoGetGsiOrThrowResult<Self, O, G> | undefined> {\n const { filter, ...restOptions } = (options ?? {}) as RepoGetGsiOptions<Self, T, G>;\n const items = await this.db.query({\n table: this.tableName,\n index: gsi,\n query,\n ...restOptions,\n } as any);\n if (items.length > 1) {\n throw new DinahError({\n type: \"DATA_INTEGRITY\",\n message: `getGsi on \"${gsi}\" returned ${items.length} items; expected at most 1.`,\n });\n }\n const item = items[0];\n if (!item) return undefined;\n if (filter && !matchesPartial(filter, item as any)) return undefined;\n return this.applyTransformIfNeeded(item, { ...options, gsi }) as any;\n }\n\n async getGsiOrThrow<G extends GsiNames<Self>, const O extends RepoGetGsiOptions<Self, T, G>>(\n gsi: G,\n query: RepoQueryGsiQuery<T, G>,\n options?: O,\n ): Promise<RepoGetGsiOrThrowResult<Self, O, G>> {\n const item = await this.getGsi(gsi, query, options);\n if (item === undefined) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: query as Record<string, unknown>,\n resource: this.resourceName,\n });\n }\n return item as any;\n }\n\n async scan<const O extends RepoScanOptions<Self>>(options?: O): Promise<RepoScanResult<Self, O>> {\n const items = await this.db.scan({ table: this.tableName, ...options });\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async *scanPaged<const O extends RepoScanOptions<Self>>(\n options?: O,\n ): RepoScanPagedResult<Self, O> {\n for await (const page of this.db.scanPaged({ table: this.tableName, ...options })) {\n yield this.applyTransformsIfNeeded(page, options) as any;\n }\n }\n\n async scanGsi<G extends GsiNames<Self>, const O extends RepoScanGsiOptions<Self, T, G>>(\n gsi: G,\n options?: O,\n ): Promise<RepoScanGsiResult<Self, O, G>> {\n const items = await this.db.scan({ table: this.tableName, index: gsi, ...options } as any);\n return this.applyTransformsIfNeeded(items, { ...options, gsi }) as any;\n }\n\n async *scanGsiPaged<G extends GsiNames<Self>, const O extends RepoScanGsiOptions<Self, T, G>>(\n gsi: G,\n options?: O,\n ): RepoScanGsiPagedResult<Self, O, G> {\n for await (const page of this.db.scanPaged({\n table: this.tableName,\n index: gsi,\n ...options,\n } as any)) {\n yield this.applyTransformsIfNeeded(page, { ...options, gsi }) as any;\n }\n }\n\n async exists(options?: RepoExistsOptions<Self>): Promise<boolean> {\n return this.db.exists({\n table: this.tableName,\n projection: [this.table.def.partitionKey] as any,\n ...options,\n });\n }\n\n async existsGsi(gsi: GsiNames<Self>, options?: RepoExistsOptions<Self>): Promise<boolean> {\n return this.db.exists({\n table: this.tableName,\n index: gsi,\n projection: [this.table.def.partitionKey] as any,\n ...options,\n });\n }\n\n async batchGet<const O extends RepoBatchGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoBatchGetResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoBatchGetOptions<Self>;\n const { items, unprocessed } = await this.db.batchGet({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n filter,\n ...restOptions,\n },\n } as any);\n const tableItems = items[this.tableName];\n return {\n items: (tableItems && this.applyTransformsIfNeeded(tableItems, options)) as any,\n unprocessed: unprocessed?.[this.tableName]?.keys as RepoKey<Self>[] | undefined,\n };\n }\n\n async batchGetOrThrow<const O extends RepoBatchGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoBatchGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoBatchGetOptions<Self>;\n const result = await this.db.batchGetOrThrow({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n resource: this.resourceName,\n filter,\n ...restOptions,\n },\n } as any);\n return this.applyTransformsIfNeeded(result[this.tableName] ?? [], options) as any;\n }\n\n async batchWrite(requests: RepoBatchWrite<Self>): Promise<RepoBatchWriteResult<Self>> {\n const { items, unprocessed } = await this.db.batchWrite({\n [this.tableName]: requests.map((request) => {\n if (request.type === \"DELETE\") {\n return { type: \"DELETE\", key: this.extractKey(request.key) };\n } else {\n return { type: \"PUT\", item: request.item };\n }\n }),\n });\n\n return {\n items: items[this.tableName],\n unprocessed: unprocessed?.[this.tableName],\n } as RepoBatchWriteResult<Self>;\n }\n\n async batchUpdate(\n keys: RepoKey<Self>[],\n update: RepoUpdateInput<Self>,\n ): Promise<RepoBatchUpdateResult<Self>> {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n const result = await this.db.batchUpdate({\n [this.tableName]: {\n keys: keys.map((key) => this.extractKey(key)),\n update: updateWithDefaults as any,\n },\n } as any);\n return {\n unprocessed: result.unprocessed?.[this.tableName]?.keys as RepoKey<Self>[] | undefined,\n };\n }\n\n async trxGet<const O extends RepoTrxGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoTrxGetResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoTrxGetOptions<Self>;\n const items = await this.db.trxGet(\n ...keys.map(\n (key) =>\n ({\n table: this.tableName,\n key: this.extractKey(key),\n filter,\n ...restOptions,\n }) as any,\n ),\n );\n return items.map((item: any) => item && this.applyTransformIfNeeded(item, options)) as any;\n }\n\n async trxGetOrThrow<const O extends RepoTrxGetOptions<Self>>(\n keys: RepoKey<Self>[],\n options?: O,\n ): Promise<RepoTrxGetOrThrowResult<Self, O>> {\n const { filter, ...restOptions } = (options ?? {}) as RepoTrxGetOptions<Self>;\n const items = await this.db.trxGetOrThrow(\n ...keys.map(\n (key) =>\n ({\n table: this.tableName,\n key: this.extractKey(key),\n resource: this.resourceName,\n filter,\n ...restOptions,\n }) as any,\n ),\n );\n return this.applyTransformsIfNeeded(items, options) as any;\n }\n\n async trxWrite(...requests: RepoTrxWriteRequest<Self>[]): Promise<void> {\n await this.db.trxWrite(\n ...requests.map((request) => {\n switch (request.type) {\n case \"CONDITION\": {\n const { key, condition } = request;\n return this.trxConditionRequest(key, condition);\n }\n\n case \"DELETE\": {\n const { key, ...options } = request;\n return this.trxDeleteRequest(key, options);\n }\n\n case \"PUT\": {\n const { item, ...options } = request;\n return this.trxPutRequest(item, options);\n }\n\n case \"UPDATE\": {\n const { key, update, ...options } = request;\n return this.trxUpdateRequest(\n key,\n update as RepoUpdateInputFor<Self, typeof key>,\n options,\n );\n }\n\n default:\n throw new Error(\"Unexpected request type.\");\n }\n }),\n );\n }\n\n async trxDelete(keys: RepoKey<Self>[], options?: RepoDeleteOptions<Self>): Promise<void> {\n return this.db.trxWrite(...keys.map((key) => this.trxDeleteRequest(key, options)));\n }\n\n // todo: return items\n async trxPut(items: RepoPutItem<Self>[], options?: RepoPutOptions<Self>): Promise<void> {\n return this.db.trxWrite(...items.map((item) => this.trxPutRequest(item, options)));\n }\n\n async trxUpdate(\n keys: RepoKey<Self>[],\n update: RepoUpdateInput<Self>,\n options?: RepoUpdateOptions<Self>,\n ): Promise<void> {\n return this.db.trxWrite(\n ...keys.map((key) =>\n this.trxUpdateRequest(key, update as RepoUpdateInputFor<Self, typeof key>, options),\n ),\n );\n }\n\n // todo: return items\n async trxCreate(items: RepoCreateItem<Self>[]): Promise<void> {\n return this.db.trxWrite(...items.map((item) => this.trxCreateRequest(item)));\n }\n\n trxGetRequest<O extends RepoGetOptions<Self>>(\n key: RepoKey<Self>,\n options?: O,\n ): DbTrxGetRequest<RepoGetOrThrowResult<Self, O>> {\n return { table: this.tableName, key: this.extractKey(key), ...options } as any;\n }\n\n trxDeleteRequest(key: RepoKey<Self>, options?: RepoDeleteOptions<Self>): DbTrxWriteRequest {\n return { table: this.tableName, type: \"DELETE\", key: this.extractKey(key), ...options };\n }\n\n trxConditionRequest(\n key: RepoKey<Self>,\n condition: Condition<Self[\"$schema\"]>,\n ): DbTrxWriteRequest {\n return {\n table: this.tableName,\n type: \"CONDITION\",\n key: this.extractKey(key),\n condition,\n };\n }\n\n trxPutRequest(item: RepoPutItem<Self>, options?: RepoPutOptions<Self>): DbTrxWriteRequest {\n return { table: this.tableName, type: \"PUT\", item: item as any, ...options };\n }\n\n trxUpdateRequest<const K extends RepoKey<Self>>(\n key: K,\n update: RepoUpdateInputFor<Self, K>,\n options?: RepoUpdateOptions<Self>,\n ): DbTrxWriteRequest {\n const updateWithDefaults = this.applyNormalizersToExpression(update as Obj);\n return {\n table: this.tableName,\n type: \"UPDATE\",\n key: this.extractKey(key),\n update: updateWithDefaults as any,\n ...options,\n condition: this.withDiscriminatorCondition(key, options?.condition),\n };\n }\n\n trxCreateRequest(item: RepoCreateItem<Self>): DbTrxWriteRequest {\n const condition = { $and: [{ [this.table.def.partitionKey]: { $exists: false } }] } as any;\n\n const normalizedItem = this.applyCreateTransforms(item as Obj);\n\n return {\n table: this.tableName,\n type: \"PUT\",\n item: normalizedItem,\n condition,\n };\n }\n\n private applyCreateTransforms(item: Obj): Partial<ExtractTableSchema<T>> {\n const { transformAttributes, computedAttributes } = this.config;\n\n if (computedAttributes) {\n for (const key of Object.keys(computedAttributes)) {\n if (key in item) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" is a computed attribute and cannot be set directly. Remove it from the create input.`,\n });\n }\n }\n }\n\n const merged: Obj = { ...this.defaultCreateData, ...item };\n\n if (transformAttributes) {\n for (const [key, transform] of Object.entries(transformAttributes)) {\n if (key in merged && merged[key] !== undefined) {\n merged[key] = (transform as (v: unknown) => unknown)(merged[key]);\n }\n }\n }\n\n if (computedAttributes) {\n for (const [key, def] of Object.entries(computedAttributes)) {\n const { from, compute } = def as {\n from: string | readonly string[];\n compute: (...v: unknown[]) => unknown;\n };\n const args = Array.isArray(from)\n ? (from as string[]).map((k) => merged[k])\n : [merged[from as string]];\n const computed = compute(...args);\n if (computed !== undefined) {\n merged[key] = computed;\n } else {\n delete merged[key];\n }\n }\n }\n\n return merged as Partial<ExtractTableSchema<T>>;\n }\n\n private applyNormalizersToExpression(userUpdate: Obj): Obj {\n const { transformAttributes, computedAttributes, immutableAttributes } = this.config;\n\n if (computedAttributes) {\n for (const key of Object.keys(computedAttributes)) {\n if (key in userUpdate) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" is a computed attribute and cannot be set directly in an update. Update the source field instead.`,\n });\n }\n }\n }\n\n for (const key of immutableAttributes ?? []) {\n if ((key as string) in userUpdate) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key as string}\" is immutable and cannot be updated.`,\n });\n }\n }\n\n const result: Obj = { ...this.defaultUpdateData, ...userUpdate };\n\n if (transformAttributes) {\n for (const [key, transform] of Object.entries(transformAttributes)) {\n if (!(key in result)) continue;\n const val = result[key];\n const fn = transform as (v: unknown) => unknown;\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n // nothing to transform\n } else if (!isOperation(val)) {\n result[key] = fn(val);\n } else if (val.$set !== undefined) {\n result[key] = { ...val, $set: fn(val.$set) };\n } else if (val.$ifNotExists !== undefined) {\n const ifne = val.$ifNotExists as unknown;\n result[key] = {\n ...val,\n $ifNotExists: Array.isArray(ifne)\n ? [(ifne as unknown[])[0], fn((ifne as unknown[])[1])]\n : fn(ifne),\n };\n }\n }\n }\n\n if (computedAttributes) {\n for (const [computedKey, def] of Object.entries(computedAttributes)) {\n const { from, compute } = def as {\n from: string | readonly string[];\n compute: (...v: unknown[]) => unknown;\n };\n\n if (Array.isArray(from)) {\n const fromArr = from as string[];\n const presentKeys = fromArr.filter((k) => k in result);\n if (presentKeys.length === 0) continue;\n const missingKeys = fromArr.filter((k) => !(k in result));\n if (missingKeys.length > 0) {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${computedKey}\" is computed from [${fromArr.join(\", \")}]. All source fields must be included in the update or none. Missing: [${missingKeys.join(\", \")}].`,\n });\n }\n const args: unknown[] = [];\n for (const key of fromArr) {\n const val = result[key];\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n args.push(undefined);\n } else if (!isOperation(val)) {\n args.push(val);\n } else if (val.$set !== undefined) {\n args.push(val.$set);\n } else {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${key}\" drives computed field \"${computedKey}\" and cannot use arithmetic or list operators in updates.`,\n });\n }\n }\n const computed = compute(...args);\n result[computedKey] = computed !== undefined ? computed : { $remove: true };\n } else {\n const fromKey = from as string;\n if (!(fromKey in result)) continue;\n\n const val = result[fromKey];\n let resolvedVal: unknown;\n if (val === undefined || (isOperation(val) && val.$remove === true)) {\n resolvedVal = undefined;\n } else if (!isOperation(val)) {\n resolvedVal = val;\n } else if (val.$set !== undefined) {\n resolvedVal = val.$set;\n } else {\n throw new DinahError({\n type: \"VALIDATION\",\n message: `Field \"${fromKey}\" drives computed field \"${computedKey}\" and cannot use arithmetic or list operators in updates.`,\n });\n }\n const computed = compute(resolvedVal);\n result[computedKey] = computed !== undefined ? computed : { $remove: true };\n }\n }\n }\n\n return result;\n }\n\n // If the caller passed a key that carries the configured discriminator\n // value, AND condition that field against the same value. Guards against the\n // row on the wire having a different variant than the type-level narrowing\n // assumed.\n private withDiscriminatorCondition(\n key: Obj,\n condition: Condition<ExtractTableSchema<T>> | undefined,\n ): Condition<ExtractTableSchema<T>> | undefined {\n const discriminator = this.config.discriminator as string | undefined;\n if (!discriminator) return condition;\n const value = key[discriminator];\n if (value === undefined) return condition;\n const guard = { [discriminator]: value } as Condition<ExtractTableSchema<T>>;\n if (!condition) return guard;\n return { $and: [guard, condition] } as Condition<ExtractTableSchema<T>>;\n }\n\n protected applyTransformsIfNeeded(\n items: Obj[],\n options?: { projection?: any[]; gsi?: string },\n ): any[] {\n // transforms aren't applied when applying a projection\n if (options?.projection?.length) return items;\n if (options?.gsi) {\n // projections inherited to GSIs also prevent transformation\n const gsiProj = this.table.def.gsis?.[options.gsi]?.projection;\n if (gsiProj === \"KEYS_ONLY\" || Array.isArray(gsiProj)) return items;\n }\n\n return items.map((item) => this.transformOutput(item as ExtractTableSchema<T>));\n }\n\n protected applyTransformIfNeeded(item: Obj, options?: { projection?: any[]; gsi?: string }): any {\n const [transformedItem] = this.applyTransformsIfNeeded([item], options);\n return transformedItem;\n }\n}\n\nexport interface MakeRepoResult<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n TDiscriminator extends keyof ExtractTableSchema<T> = never,\n> {\n new (db: Db): Repo<T, TDefaults, TUpdateDefaults, TOutput, TComputed, TImmutable, TDiscriminator>;\n readonly table: T;\n}\n\nexport const makeRepo = <\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n const TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n const TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n const TDiscriminator extends keyof ExtractTableSchema<T> = never,\n>(\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n): MakeRepoResult<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n> => {\n return class extends Repo<\n T,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n > {\n static readonly table = table;\n constructor(db: Db) {\n super(db, table, config);\n }\n };\n};\n","import {\n type BatchGetItemInput,\n type BatchWriteItemInput,\n ConditionalCheckFailedException,\n CreateTableCommand,\n DeleteTableCommand,\n DynamoDB,\n DynamoDBClient,\n type DynamoDBClientConfig,\n ListTablesCommand,\n TransactionCanceledException,\n type WriteRequest,\n} from \"@aws-sdk/client-dynamodb\";\nimport { DinahError } from \"./error\";\n//import { DynamoDBStreams } from '@aws-sdk/client-dynamodb-streams';\nimport type { TransactGetCommandInput, TransactWriteCommandInput } from \"@aws-sdk/lib-dynamodb\";\nimport * as Lib from \"@aws-sdk/lib-dynamodb\";\nimport { ExpressionBuilder } from \"./expression-builder\";\nimport { Repo, type RepoConfig, type ValidComputedMap } from \"./repo\";\nimport type { Table } from \"./table\";\nimport type {\n DbBatchGet,\n DbBatchGetResponse,\n DbBatchUpdate,\n DbBatchUpdateResponse,\n DbBatchWrite,\n DbBatchWriteResponse,\n DbConfig,\n DbDelete,\n DbExists,\n DbGet,\n DbListTables,\n DbPut,\n DbQuery,\n DbScan,\n DbTrxGetOrThrowResult,\n DbTrxGetRequest,\n DbTrxGetResult,\n DbTrxWriteRequest,\n DbUpdate,\n} from \"./db.types\";\nimport type { AllKeys, ExtractTableSchema, Obj } from \"./types\";\nimport { extractTableDesc, matchesPartial, removeUndefined } from \"./util\";\n\n// TODO\n// - caching support?\n// - consider special \"limit\" handling for paged scans, maybe have \"scanLimit\" too\n// - consider \"sort\" shorthand for methods that return unpaginated collections\n// i.e. sort: { by: 'createdAt', dir: 'ASC' } or sort: (a,b) => a.createdAt - b.createdAt\n// - consider support for batchUpdates leveraging BatchExecute and PartiQL\n// - consider batchPut (batchPutOrThrow) and batchDelete that operate on a single table\n// - getGsi? throws if > 1 result, allows for assert, and filtering\n// - bug $in doesn't handle empty arrays, I imagine other operators are affected\n// - consider beforeCreate, beforePut, beforeUpdate, beforeDelete, after, etc.\n// - type out repo update data\n// - does it handle nested undefined removal? nested $remove\n// - maybe extract resourceName from schema?\n\nexport class Db {\n readonly client: Lib.DynamoDBDocumentClient;\n readonly config: DbConfig | undefined;\n\n //protected streamEventListeners: DbStreamEventListener[] = [];\n\n constructor(\n clientOrConfig: DynamoDBClient | DynamoDB | DynamoDBClientConfig,\n dbConfig?: DbConfig,\n ) {\n if (clientOrConfig instanceof DynamoDBClient || clientOrConfig instanceof DynamoDB) {\n this.client = Lib.DynamoDBDocumentClient.from(new DynamoDBClient(clientOrConfig));\n } else {\n const { endpoint, ...clientConfig } = clientOrConfig;\n // client doesn't interpret an empty string endpoint as falsy so normalize things\n // here so consumers don't have to worry about that quirk\n this.client = Lib.DynamoDBDocumentClient.from(\n new DynamoDBClient({\n ...(endpoint ? { endpoint } : {}),\n ...clientConfig,\n }),\n );\n }\n\n this.config = dbConfig;\n }\n\n private normalizeUpdate(expression: Obj): Obj {\n const behavior = this.config?.updateUndefinedBehavior ?? \"throw\";\n if (behavior === \"throw\") return expression;\n const entries = Object.entries(expression);\n if (behavior === \"strip\") return Object.fromEntries(entries.filter(([, v]) => v !== undefined));\n return Object.fromEntries(\n entries.map(([k, v]) => [k, v === undefined ? { $remove: true } : v]),\n );\n }\n\n makeRepo<\n T extends Table,\n TDefaults extends Partial<ExtractTableSchema<T>> = {},\n TUpdateDefaults extends Partial<ExtractTableSchema<T>> = {},\n TOutput = ExtractTableSchema<T>,\n const TComputed extends ValidComputedMap<ExtractTableSchema<T>, TComputed> = {},\n const TImmutable extends AllKeys<ExtractTableSchema<T>> = never,\n const TDiscriminator extends keyof ExtractTableSchema<T> = never,\n >(\n table: T,\n config?: RepoConfig<\n ExtractTableSchema<T>,\n TDefaults,\n TUpdateDefaults,\n TOutput,\n TComputed,\n TImmutable,\n TDiscriminator\n >,\n ): Repo<T, TDefaults, TUpdateDefaults, TOutput, TComputed, TImmutable, TDiscriminator> {\n return new Repo(this, table, config);\n }\n\n async createTable(table: Table): Promise<void> {\n await this.client.send(new CreateTableCommand(extractTableDesc(table)));\n }\n\n async deleteTable(tableName: string): Promise<void> {\n await this.client.send(new DeleteTableCommand({ TableName: tableName }));\n }\n\n async listTables(data?: DbListTables): Promise<string[]> {\n const tables: string[] = [];\n let lastEvaluatedTableName: string | undefined;\n do {\n const output = await this.client.send(\n new ListTablesCommand({\n Limit: data?.limit,\n ExclusiveStartTableName: lastEvaluatedTableName,\n }),\n );\n\n tables.push(...(output.TableNames ?? []));\n lastEvaluatedTableName = output.LastEvaluatedTableName;\n } while (lastEvaluatedTableName);\n return tables;\n }\n\n async get<T = Obj>(data: DbGet<T>): Promise<T | undefined> {\n const exp = new ExpressionBuilder();\n\n const input = new Lib.GetCommand({\n TableName: data.table,\n Key: data.key,\n ConsistentRead: data.consistent,\n ProjectionExpression: exp.projection(data.projection),\n ExpressionAttributeNames: exp.attributeNames,\n });\n\n const output = await this.client.send(input);\n\n if (output.Item && data.filter && !matchesPartial(data.filter as any, output.Item as any)) {\n return undefined;\n }\n\n return output.Item as T;\n }\n\n async getOrThrow<T = Obj>(data: DbGet<T>): Promise<T> {\n const item = await this.get<T>(data);\n if (!item) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n });\n }\n return item;\n }\n\n async put<T = Obj>(data: DbPut<T>): Promise<T> {\n const exp = new ExpressionBuilder();\n\n const item = removeUndefined(data.item as Obj);\n\n const input = new Lib.PutCommand({\n TableName: data.table,\n Item: item,\n ReturnValues: data.returnOld ? \"ALL_OLD\" : \"NONE\",\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n ConditionExpression: exp.condition(data.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return (data.returnOld ? output.Attributes : item) as T;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n { type: \"CONDITIONAL_CHECK_FAILED\", resource: data.resource },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async update<T = Obj>(data: DbUpdate<T>): Promise<T> {\n const exp = new ExpressionBuilder();\n\n const condition: any = {\n $and: Object.keys(data.key).map((field) => ({\n [field]: { $exists: true },\n })),\n };\n\n if (data.condition) {\n condition.$and.push(data.condition);\n }\n\n const input = new Lib.UpdateCommand({\n TableName: data.table,\n Key: data.key,\n ReturnValues: \"ALL_NEW\",\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n UpdateExpression: exp.update(this.normalizeUpdate(data.update as Obj)),\n ConditionExpression: exp.condition(condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return output.Attributes as T;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n {\n type: \"CONDITIONAL_CHECK_FAILED\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async delete<T = Obj>(data: DbDelete<T>): Promise<T | undefined> {\n const exp = new ExpressionBuilder();\n\n const input = new Lib.DeleteCommand({\n TableName: data.table,\n Key: data.key,\n ReturnValues: \"ALL_OLD\",\n ConditionExpression: exp.condition(data.condition),\n ReturnValuesOnConditionCheckFailure: \"ALL_OLD\",\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n try {\n const output = await this.client.send(input);\n return output.Attributes as T | undefined;\n } catch (err) {\n if (err instanceof ConditionalCheckFailedException) {\n throw new DinahError(\n {\n type: \"CONDITIONAL_CHECK_FAILED\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n async deleteOrThrow<T = Obj>(data: DbDelete<T>): Promise<T> {\n const item = await this.delete<T>(data);\n if (!item) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: data.key as Record<string, unknown>,\n resource: data.resource,\n });\n }\n return item;\n }\n\n async *queryPaged<T = Obj>(data: DbQuery<T>): AsyncGenerator<T[]> {\n const exp = new ExpressionBuilder();\n\n let lastEvaluatedKey: Obj | undefined = data.startKey as Obj | undefined;\n do {\n const input = new Lib.QueryCommand({\n TableName: data.table,\n IndexName: data.index,\n ExclusiveStartKey: lastEvaluatedKey,\n Limit: data.limit,\n ScanIndexForward: data.sort !== \"DESC\",\n ConsistentRead: data.consistent,\n KeyConditionExpression: exp.condition(data.query),\n ProjectionExpression: exp.projection(data.projection),\n FilterExpression: exp.condition(data.filter),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n const output = await this.client.send(input);\n\n if (output.Items?.length) {\n yield output.Items as T[];\n }\n lastEvaluatedKey = output.LastEvaluatedKey;\n } while (lastEvaluatedKey);\n }\n\n async query<T = Obj>(data: DbQuery<T>): Promise<T[]> {\n const items: T[] = [];\n\n for await (const page of this.queryPaged(data)) {\n items.push(...page);\n }\n\n return items;\n }\n\n async *scanPaged<T = Obj>(data: DbScan<T>): AsyncGenerator<T[]> {\n const exp = new ExpressionBuilder();\n\n const totalSegments = data.parallel ?? 1;\n const segments = [...Array(totalSegments).keys()];\n\n // undefined: initial value when a start key isn't specified\n // null: scanning a particular segment is finished\n const lastEvaluatedKeys: (Obj | undefined | null)[] = segments.map(\n () => data.startKey as Obj | undefined,\n );\n do {\n const results = await Promise.all(\n segments.map(async (segment) => {\n if (lastEvaluatedKeys[segment] === null) return [];\n\n const input = new Lib.ScanCommand({\n ExclusiveStartKey: lastEvaluatedKeys[segment],\n Segment: segment,\n TotalSegments: totalSegments,\n TableName: data.table,\n IndexName: data.index,\n Limit: data.limit,\n ConsistentRead: data.consistent,\n ProjectionExpression: exp.projection(data.projection),\n FilterExpression: exp.condition(data.filter),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n });\n\n const output = await this.client.send(input);\n lastEvaluatedKeys[segment] = output.LastEvaluatedKey ?? null;\n return output.Items ?? [];\n }),\n );\n\n const items = results.flat();\n\n if (items.length) {\n yield items as T[];\n }\n } while (lastEvaluatedKeys.some((key) => key !== null));\n }\n\n async scan<T = Obj>(data: DbScan<T>): Promise<T[]> {\n const items: T[] = [];\n\n for await (const page of this.scanPaged(data)) {\n items.push(...(page as T[]));\n }\n\n return items;\n }\n\n async exists<T = Obj>(data: DbExists<T>): Promise<boolean> {\n const { query, ...otherOptions } = data;\n\n // we can't rely on the limit when a filter is being applied, since the filter is\n // applied after the scan/query page, so we only apply a limit of 1 when there is no filter.\n // otherwise, we page through the results and return true as soon as we see a single item\n const sharedOptions = {\n ...otherOptions,\n limit: data.filter ? undefined : 1,\n };\n\n const pagedItems = query\n ? this.queryPaged({ query, ...sharedOptions })\n : this.scanPaged(sharedOptions);\n\n for await (const items of pagedItems) {\n if (items.length) return true;\n }\n\n return false;\n }\n\n // TODO: test wildly different item sizes to make\n // sure retry algorithm works properly\n async batchGet(data: DbBatchGet): Promise<DbBatchGetResponse> {\n const result: DbBatchGetResponse = { items: {} };\n\n const tableData = Object.fromEntries(\n Object.entries(data).map(([table, request]) => {\n const exp = new ExpressionBuilder();\n\n result.items[table] = [];\n\n return [\n table,\n {\n request: {\n ConsistentRead: request?.consistent,\n ProjectionExpression: exp.projection(request?.projection),\n ExpressionAttributeNames: exp.attributeNames,\n },\n keyNames: Object.keys(request.keys.at(0) ?? {}),\n itemIndexMap: new Map<string, number>(),\n filter: request.filter,\n },\n ];\n }),\n );\n\n const flattenedBatches = Object.entries(data).flatMap(([table, request]) => {\n return request.keys.map((key, i) => {\n const itemIndexKey =\n tableData[table]?.keyNames.map((keyName) => key[keyName]).join(\"|\") ?? \"\";\n tableData[table]?.itemIndexMap.set(itemIndexKey, i);\n return [table, key] as const;\n });\n });\n\n let batchSize = 100;\n let retryCount = 0;\n\n while (flattenedBatches.length && retryCount < 5) {\n const batch = flattenedBatches.splice(0, batchSize || 1);\n\n const request: BatchGetItemInput[\"RequestItems\"] = {};\n for (const [table, key] of batch) {\n if (!request[table]) {\n request[table] = { ...tableData[table]?.request, Keys: [] };\n }\n\n request[table].Keys?.push(key);\n }\n\n const input = new Lib.BatchGetCommand({ RequestItems: request });\n const output = await this.client.send(input);\n\n for (const [table, items] of Object.entries(output.Responses ?? {})) {\n //just to appease typescript\n if (!result.items[table]) continue;\n\n const filteredItems = tableData[table]?.filter\n ? items.filter((item) => matchesPartial(tableData[table]!.filter as any, item as any))\n : items;\n\n result.items[table].push(...filteredItems);\n }\n\n // handle unprocessed requests\n let unprocessedKeyCount = 0;\n for (const [table, request] of Object.entries(output.UnprocessedKeys ?? {})) {\n const unprocessed = (request.Keys ?? []).map((key) => [table, key] as const);\n flattenedBatches.push(...unprocessed);\n unprocessedKeyCount += unprocessed.length;\n }\n\n //move immediately to next batch if all requests were processed\n if (!unprocessedKeyCount) {\n retryCount = 0;\n continue;\n }\n\n // reduce batch size so we don't continue to overfetch,\n // but do it gradually by only splitting the difference\n batchSize -= Math.floor(unprocessedKeyCount / 2);\n\n retryCount++;\n }\n\n // anything left in flattened batches needs to be returned in unprocessed\n if (flattenedBatches.length) {\n result.unprocessed = {};\n for (const [table, key] of flattenedBatches) {\n if (!result.unprocessed[table]) {\n result.unprocessed[table] = {\n ...tableData[table]?.request,\n keys: [],\n };\n }\n result.unprocessed[table].keys.push(key);\n }\n }\n\n // finally, sort any returned items by their original index to preserve order\n for (const [table, items] of Object.entries(result.items)) {\n const itemIndexMap = tableData[table]?.itemIndexMap;\n const keyNames = tableData[table]?.keyNames;\n\n if (!itemIndexMap || !keyNames) continue;\n\n items.sort((item1, item2) => {\n const item1IndexKey = keyNames.map((keyName) => item1[keyName]).join(\"|\");\n const item2IndexKey = keyNames.map((keyName) => item2[keyName]).join(\"|\");\n\n return (itemIndexMap.get(item1IndexKey) ?? 0) - (itemIndexMap.get(item2IndexKey) ?? 0);\n });\n }\n\n return result;\n }\n\n async batchGetOrThrow(data: DbBatchGet): Promise<DbBatchGetResponse[\"items\"]> {\n const { items, unprocessed } = await this.batchGet(data);\n\n for (const table of Object.keys(data)) {\n if (unprocessed?.[table]) {\n throw new Error(`One or more batch get requests were not processed in \"${table}\" table.`);\n }\n\n if (items[table]?.length !== data[table]?.keys?.length) {\n // Key identity is not tracked through batchGet — key: {} is a known limitation here.\n throw new DinahError({ type: \"NOT_FOUND\", key: {}, resource: data[table]?.resource });\n }\n }\n\n return items;\n }\n\n // TODO: test wildly different item sizes to make\n // sure retry algorithm works properly\n async batchWrite(data: DbBatchWrite): Promise<DbBatchWriteResponse> {\n const result: DbBatchWriteResponse = { items: {} };\n\n const flattenedBatches = Object.keys(data).flatMap((table) => {\n return (\n data[table]?.map((r) => {\n if (r.type === \"DELETE\") {\n return [table, { DeleteRequest: { Key: r.key } }] as [string, WriteRequest];\n } else {\n return [table, { PutRequest: { Item: r.item } }] as [string, WriteRequest];\n }\n }) ?? []\n );\n });\n\n let batchSize = 25;\n let retryCount = 0;\n\n while (flattenedBatches.length && retryCount < 5) {\n const batch = flattenedBatches.splice(0, batchSize || 1);\n\n const request: BatchWriteItemInput[\"RequestItems\"] = {};\n for (const [table, req] of batch) {\n if (!request[table]) {\n request[table] = [];\n }\n request[table].push(req);\n }\n\n const input = new Lib.BatchWriteCommand({ RequestItems: request });\n const output = await this.client.send(input);\n\n // handle unprocessed requests\n let unprocessedKeyCount = 0;\n for (const [table, requests] of Object.entries(output.UnprocessedItems ?? {})) {\n for (const request of requests) {\n flattenedBatches.push([table, request]);\n unprocessedKeyCount++;\n }\n }\n\n //move immediately to next batch if all requests were processed\n if (!unprocessedKeyCount) {\n retryCount = 0;\n continue;\n }\n\n // reduce batch size so we don't continue to overwrite,\n // but do it gradually by only splitting the difference\n batchSize -= Math.floor(unprocessedKeyCount / 2);\n\n retryCount++;\n }\n\n // anything left in flattened batches needs to be returned in unprocessed\n if (flattenedBatches.length) {\n result.unprocessed = {};\n for (const [table, request] of flattenedBatches) {\n if (!result.unprocessed[table]) {\n result.unprocessed[table] = [];\n }\n\n if (\"DeleteRequest\" in request && request.DeleteRequest?.Key) {\n result.unprocessed[table].push({\n type: \"DELETE\",\n key: request.DeleteRequest.Key,\n });\n } else if (\"PutRequest\" in request && request.PutRequest?.Item) {\n result.unprocessed[table].push({\n type: \"PUT\",\n item: request.PutRequest.Item,\n });\n }\n }\n }\n\n return result;\n }\n\n async batchUpdate(data: DbBatchUpdate): Promise<DbBatchUpdateResponse> {\n const queue = Object.entries(data).flatMap(([table, req]) =>\n req.keys.map((key) => [table, key, req.update] as [string, Obj, Obj]),\n );\n\n let batchSize = 25;\n let retryCount = 0;\n\n while (queue.length && retryCount < 5) {\n const batch = queue.splice(0, batchSize || 1);\n\n const statements = batch.map(([table, key, update]) => {\n const exp = new ExpressionBuilder();\n const { sets, removes, params } = exp.partiqlUpdate(this.normalizeUpdate(update));\n\n const whereParts: string[] = [];\n for (const [field, value] of Object.entries(key)) {\n whereParts.push(`\"${field}\"=?`);\n params.push(value);\n }\n\n const clauses = [...sets.map((s) => `SET ${s}`), ...removes.map((r) => `REMOVE ${r}`)].join(\n \" \",\n );\n\n return {\n Statement: `UPDATE \"${table}\" ${clauses} WHERE ${whereParts.join(\" AND \")}`,\n Parameters: params,\n };\n });\n\n const output = await this.client.send(\n new Lib.BatchExecuteStatementCommand({ Statements: statements }),\n );\n\n let failCount = 0;\n output.Responses?.forEach((response, i) => {\n if (response.Error && batch[i]) {\n queue.push(batch[i]);\n failCount++;\n }\n });\n\n if (!failCount) {\n retryCount = 0;\n continue;\n }\n\n batchSize -= Math.floor(failCount / 2);\n retryCount++;\n }\n\n if (queue.length) {\n const unprocessed: DbBatchUpdate = {};\n for (const [table, key, update] of queue) {\n if (!unprocessed[table]) {\n unprocessed[table] = { keys: [], update };\n }\n unprocessed[table].keys.push(key);\n }\n return { unprocessed };\n }\n\n return {};\n }\n\n async trxGet<R extends DbTrxGetRequest[]>(...requests: R): Promise<DbTrxGetResult<R>> {\n const trxItems: TransactGetCommandInput[\"TransactItems\"] = requests.map((request) => {\n const exp = new ExpressionBuilder();\n return {\n Get: {\n Key: request.key,\n TableName: request.table,\n ProjectionExpression: exp.projection(request?.projection),\n ExpressionAttributeNames: exp.attributeNames,\n },\n };\n });\n\n const input = new Lib.TransactGetCommand({ TransactItems: trxItems });\n const output = await this.client.send(input);\n\n return (\n (output.Responses?.map((response, i) => {\n if (!response.Item) return;\n\n if (!requests[i]?.filter) return response.Item;\n\n return matchesPartial(requests[i].filter!, response.Item as any)\n ? response.Item\n : undefined;\n }) as DbTrxGetResult<R>) ?? []\n );\n }\n\n async trxGetOrThrow<R extends DbTrxGetRequest[]>(\n ...requests: R\n ): Promise<DbTrxGetOrThrowResult<R>> {\n const items = await this.trxGet(...requests);\n for (let i = 0; i < items.length; i++) {\n if (!items[i]) {\n throw new DinahError({\n type: \"NOT_FOUND\",\n key: (requests[i]?.key ?? {}) as Record<string, unknown>,\n resource: requests[i]?.resource,\n });\n }\n }\n\n return items as DbTrxGetOrThrowResult<R>;\n }\n\n async trxWrite(...requests: DbTrxWriteRequest[]): Promise<void> {\n const trxItems: TransactWriteCommandInput[\"TransactItems\"] = requests.map((request) => {\n const exp = new ExpressionBuilder();\n\n if (request.type === \"CONDITION\" || request.type === \"DELETE\") {\n return {\n [request.type === \"CONDITION\" ? \"ConditionCheck\" : \"Delete\"]: {\n TableName: request.table,\n Key: request.key,\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n }\n\n if (request.type === \"PUT\") {\n return {\n Put: {\n TableName: request.table,\n Item: removeUndefined(request.item),\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n }\n\n return {\n Update: {\n Key: request.key,\n TableName: request.table,\n UpdateExpression: exp.update(this.normalizeUpdate(request.update as Obj)),\n ConditionExpression: exp.condition(request.condition),\n ExpressionAttributeNames: exp.attributeNames,\n ExpressionAttributeValues: exp.attributeValues,\n },\n };\n });\n\n const input = new Lib.TransactWriteCommand({ TransactItems: trxItems });\n try {\n await this.client.send(input);\n } catch (err) {\n if (err instanceof TransactionCanceledException) {\n throw new DinahError(\n {\n type: \"TRANSACTION_CANCELED\",\n reasons: (err.CancellationReasons ?? []).map((r) => ({\n type: r.Code ?? \"Unknown\",\n message: r.Message,\n })),\n },\n { cause: err },\n );\n }\n throw err;\n }\n }\n\n /* Dynamodb Streams */\n\n /*\n\n\tasync enableStreamEvents(data?: DbEnableEventStreams): Promise<void> {\n\t\tconst tables = data?.tables ?? (await this.listTables());\n\n\t\tconst streamsClient = new DynamoDBStreams({\n\t\t\tendpoint: this.client.config.endpoint,\n\t\t\tcredentials: this.client.config.credentials,\n\t\t\tregion: this.client.config.region,\n\t\t});\n\n\t\tawait Promise.all(\n\t\t\ttables.map(async (table) => {\n\t\t\t\tconst tableDesc = await this.client.send(new DescribeTableCommand({ TableName: table }));\n\n\t\t\t\tconst latestStreamArn = tableDesc.Table?.LatestStreamArn;\n\n\t\t\t\tif (!latestStreamArn) {\n\t\t\t\t\tif (data?.tables) {\n\t\t\t\t\t\tthrow new Error(`Table \"${table}\" does not have streaming enabled.`);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst eventStreamer = new EventStreamer(streamsClient, latestStreamArn);\n\t\t\t\teventStreamer.startPolling();\n\t\t\t}),\n\t\t);\n\t}\n\n\tasync disableStreamEvents(): Promise<void> {}\n\n\tsubscribe(listener: DbStreamEventListener): void {\n\t\tthis.streamEventListeners.push(listener);\n\t}\n\n\tunsubscribe(listener: DbStreamEventListener): void {\n\t\tthis.streamEventListeners = this.streamEventListeners.filter((l) => l !== listener);\n\t}\n\n\tunsubscribeAll(): void {\n\t\tthis.streamEventListeners = [];\n\t}\n\t*/\n}\n\n// respondentRepo.onChange((respondent) => , { filter: (r1, r2) => r1.status !== r2.status } )\n/*\nconst time = new Date(record.dynamodb.ApproximateCreationDateTime).getTime();\nif (time >= startTime) {\n\tfor (const listener of this.streamEventListeners) {\n\t\tlistener({\n\t\t\ttable,\n\t\t\ttime,\n\t\t\tid: record.eventID,\n\t\t\ttype: record.eventName,\n\t\t\tkey: record.dynamodb.Keys,\n\t\t\toldItem: record.dynamodb.OldImage,\n\t\t\tnewItem: record.dynamodb.NewImage,\n\t\t});\n\t}\n}\n*/\n","import type { Static, TSchema } from \"typebox\";\nimport type { TableDef } from \"./types\";\n\ntype SchemaStatic<Schema extends TSchema> = unknown extends Static<Schema> ? any : Static<Schema>;\n\nexport class Table<\n Schema extends TSchema = TSchema,\n const Def extends TableDef<SchemaStatic<Schema>> = TableDef<SchemaStatic<Schema>>,\n> {\n readonly schema: Schema;\n readonly def: Def;\n\n constructor(schema: Schema, def: Def) {\n this.schema = schema;\n this.def = def;\n }\n}\n"],"mappings":"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"}