dinah 0.15.1 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -105,7 +105,7 @@ const UserTable = new Table(
105
105
  const userRepo = db.makeRepo(UserTable);
106
106
 
107
107
  const userRepo = db.makeRepo(UserTable, {
108
- defaultPutData: () => ({ createdAt: Date.now() }),
108
+ defaultCreateData: () => ({ createdAt: Date.now() }),
109
109
  defaultUpdateData: () => ({ updatedAt: Date.now() }),
110
110
  });
111
111
  ```
@@ -116,7 +116,7 @@ To create a named, reusable repo class, use the standalone `makeRepo` (see [Repo
116
116
  import { makeRepo } from "dinah";
117
117
 
118
118
  class UserRepo extends makeRepo(UserTable, {
119
- defaultPutData: () => ({ createdAt: Date.now() }),
119
+ defaultCreateData: () => ({ createdAt: Date.now() }),
120
120
  defaultUpdateData: () => ({ updatedAt: Date.now() }),
121
121
  }) {}
122
122
 
@@ -195,8 +195,8 @@ Queries use a MongoDB-like syntax with operators like `$gt`, `$between`, `$prefi
195
195
  // Query by partition key
196
196
  const posts = await postRepo.query({ authorId: "u1" });
197
197
 
198
- // Query with sort key condition
199
- const recent = await postRepo.query({ authorId: "u1" }, { postId: { $gte: "2024-" } });
198
+ // Query with sort key condition (sort-key operators go in the query object)
199
+ const recent = await postRepo.query({ authorId: "u1", postId: { $gte: "2024-" } });
200
200
 
201
201
  // Query a GSI
202
202
  const adminsByDate = await userRepo.queryGsi("byRole", {
@@ -302,23 +302,22 @@ await db.trxWrite(
302
302
 
303
303
  ```typescript
304
304
  class UserRepo extends makeRepo(UserTable, {
305
- defaultPutData: () => ({ createdAt: Date.now() }),
305
+ defaultCreateData: () => ({ createdAt: Date.now() }),
306
306
  defaultUpdateData: () => ({ updatedAt: Date.now() }),
307
307
  }) {}
308
308
  ```
309
309
 
310
- `defaultPutData` is merged under every `put` / `create` / `batchWrite` put / `trxPut` / `trxCreate`. `defaultUpdateData` is merged under every `update` / `batchUpdate` / `trxUpdate`. Caller-provided values always win.
310
+ `defaultCreateData` is merged under every `create` / `trxCreate`. `defaultUpdateData` is merged under every `update` / `batchUpdate` / `trxUpdate`. Caller-provided values always win, and any key covered by a default becomes optional at the call site. (`put` / `batchWrite` puts / `trxPut` are raw upserts and do not apply these.)
311
311
 
312
- ### transformInput / transformOutput
312
+ ### transformAttributes / transformOutput
313
313
 
314
- `transformInput` runs on every write (after defaults are merged) and receives a partial of the schema. `transformOutput` runs on every read and maps the stored shape to your desired return type:
314
+ `transformAttributes` is a per-field map of normalizers applied to write inputs (on `create` and `update`). `transformOutput` runs on every non-projected read and maps the stored shape to your desired return type:
315
315
 
316
316
  ```typescript
317
317
  class UserRepo extends makeRepo(UserTable, {
318
- transformInput: (item) => ({
319
- ...item,
320
- email: item.email?.toLowerCase(),
321
- }),
318
+ transformAttributes: {
319
+ email: (email) => email.toLowerCase(),
320
+ },
322
321
  transformOutput: (item): UserWithDisplayName => ({
323
322
  ...item,
324
323
  displayName: `${item.name} <${item.email}>`,
@@ -326,23 +325,26 @@ class UserRepo extends makeRepo(UserTable, {
326
325
  }) {}
327
326
  ```
328
327
 
329
- Transforms are skipped when a `projection` option is provided, since only a subset of fields is available.
328
+ `transformOutput` is skipped when a `projection` option is provided, or when reading a GSI with a `KEYS_ONLY` / `INCLUDE` projection, since only a subset of fields is available.
330
329
 
331
- ### derivedAttributes / immutableAttributes
330
+ ### computedAttributes
332
331
 
333
- `derivedAttributes` lists fields that are computed by `transformInput` and should never be written directly by the caller. They are stripped from put and update inputs:
332
+ `computedAttributes` declaratively derives a field from one or more other fields. Computed fields are recomputed on `create` / `update` and cannot be set directly by the caller (attempting to do so throws):
334
333
 
335
334
  ```typescript
336
335
  class UserRepo extends makeRepo(UserTable, {
337
- transformInput: (item) => ({
338
- ...item,
339
- emailDomain: item.email ? item.email.split("@")[1] : undefined,
340
- }),
341
- derivedAttributes: ["emailDomain"],
336
+ computedAttributes: {
337
+ // single source field
338
+ emailDomain: { from: "email", compute: (email) => email?.split("@")[1] },
339
+ // multiple source fields
340
+ displayName: { from: ["name", "email"], compute: (name, email) => name || email },
341
+ },
342
342
  }) {}
343
343
  ```
344
344
 
345
- `immutableAttributes` lists fields that may be set on create but must not be changed by updates:
345
+ ### immutableAttributes
346
+
347
+ `immutableAttributes` lists fields that may be set on create but must not be changed by updates (attempting to update one throws):
346
348
 
347
349
  ```typescript
348
350
  class UserRepo extends makeRepo(UserTable, {
@@ -350,7 +352,18 @@ class UserRepo extends makeRepo(UserTable, {
350
352
  }) {}
351
353
  ```
352
354
 
353
- Both arrays are inferred as literal types — no `as const` needed.
355
+ Both `computedAttributes` keys and `immutableAttributes` are inferred as literal types — no `as const` needed.
356
+
357
+ ### discriminator / resourceName
358
+
359
+ `discriminator` names a schema field that tags a discriminated-union item type; Dinah uses it to narrow update inputs and results to the matching variant and to guard writes. `resourceName` sets the label used in thrown `DinahError`s (defaults to the class name without the `Repo` suffix, else the table name).
360
+
361
+ ```typescript
362
+ class EventRepo extends makeRepo(EventTable, {
363
+ discriminator: "kind",
364
+ resourceName: "Event",
365
+ }) {}
366
+ ```
354
367
 
355
368
  ## License
356
369