@qezor/dynakit
v1.0.3
Published
Modular DynamoDB toolkit with precise exports, expression builders, and ergonomic document-client helpers
Downloads
47
Maintainers
Readme
@qezor/dynakit
Modular DynamoDB helpers with precise exports, expression builders, and document-client utilities.
dynakit is built for the stuff we keep writing over and over in Lambda services:
- create DynamoDB clients and document clients
- build update, projection, and condition expressions
- run get/put/update/delete/query/scan operations
- handle batch and transaction patterns
- paginate cleanly
- keep imports precise when the package grows
Installation
npm install @qezor/dynakitPrecise Imports
Use only what you need:
const { createDocClient } = require("@qezor/dynakit/client")
const { getItem, updateItem } = require("@qezor/dynakit/crud")
const { eq, and, buildConditionExpression } = require("@qezor/dynakit/conditions")
const { buildUpdateExpression, ifNotExists, attribute } = require("@qezor/dynakit/expressions")Or use the full entry:
const { createDocClient, getItem, queryAll } = require("@qezor/dynakit")Package Surface
@qezor/dynakit/client@qezor/dynakit/errors@qezor/dynakit/helpers@qezor/dynakit/expressions@qezor/dynakit/conditions@qezor/dynakit/crud@qezor/dynakit/query@qezor/dynakit/batch@qezor/dynakit/transact@qezor/dynakit/paging
Quick Start
const { createDocClient } = require("@qezor/dynakit/client")
const { getItem, updateItem } = require("@qezor/dynakit/crud")
const { eq } = require("@qezor/dynakit/conditions")
const ddb = createDocClient()
const user = await getItem(ddb, {
tableName: "qezor-users",
key: { userId: "u_123" },
})
await updateItem(ddb, {
tableName: "qezor-users",
key: { userId: "u_123" },
set: {
lastLoginAt: Date.now(),
},
condition: eq("userId", "u_123"),
returnValues: "ALL_NEW",
})Expression Builders
Projection
const { buildProjectionExpression } = require("@qezor/dynakit/expressions")
buildProjectionExpression(["userId", "profile.displayName"])Update
const { buildUpdateExpression, ifNotExists, listAppend, attribute } = require("@qezor/dynakit/expressions")
buildUpdateExpression({
set: {
updatedAt: Date.now(),
loginCount: ifNotExists("loginCount", 0),
tags: listAppend(attribute("tags"), ["new"]),
},
remove: ["legacyField"],
})Conditions
const { and, eq, notExists, beginsWith } = require("@qezor/dynakit/conditions")
const condition = and(
eq("tenantId", "tenant_1"),
notExists("deletedAt"),
beginsWith("usernameNormalized", "ab")
)Query + Scan
const { queryItems, queryAll, scanItems } = require("@qezor/dynakit/query")
const { eq, beginsWith } = require("@qezor/dynakit/conditions")
const firstPage = await queryItems(ddb, {
tableName: "qezor-users",
indexName: "emailNormalized-index",
keyCondition: eq("emailNormalized", "[email protected]"),
})
const all = await queryAll(ddb, {
tableName: "qezor-users",
indexName: "usernameNormalized-index",
keyCondition: beginsWith("usernameNormalized", "ab"),
})Batch + Transaction Helpers
Batch Get for One Table
const { batchGetTable } = require("@qezor/dynakit/batch")
const users = await batchGetTable(ddb, {
tableName: "qezor-users",
keys: [{ userId: "u1" }, { userId: "u2" }],
})Transaction Write
const { transactWriteItems } = require("@qezor/dynakit/transact")
await transactWriteItems(ddb, {
items: [
{
Put: {
TableName: "qezor-sessions",
Item: { sessionId: "s1", userId: "u1" },
},
},
{
Delete: {
TableName: "qezor-sessions",
Key: { sessionId: "s0" },
},
},
],
})Pagination
const { paginateQuery } = require("@qezor/dynakit/paging")
for await (const page of paginateQuery(ddb, {
tableName: "qezor-users",
indexName: "usernameNormalized-index",
keyCondition: beginsWith("usernameNormalized", "ab"),
})) {
console.log(page.items)
}Helper Utilities
nowEpoch()ttlFromNow(seconds, now?)chunk(list, size)compactUndefined(object)withTimestamps(item, options?)touchUpdatedAt(item, options?)
Notes
- AWS SDK modules are loaded lazily, so pure helpers can still be used and tested without touching DynamoDB.
dynakitis built aroundDynamoDBDocumentClientstyle usage.- Condition builders are generic and do not enforce DynamoDB key-condition restrictions for you. That stays the caller's responsibility.
- This package stays focused on reusable DynamoDB mechanics, not domain rules.
