@ftschopp/dynatable-core 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/builders/query/create-query-builder.d.ts.map +1 -1
  3. package/dist/builders/query/create-query-builder.js +19 -2
  4. package/dist/builders/update/create-update-builder.d.ts.map +1 -1
  5. package/dist/builders/update/create-update-builder.js +25 -0
  6. package/dist/core/types.d.ts +5 -0
  7. package/dist/core/types.d.ts.map +1 -1
  8. package/dist/utils/model-utils.d.ts +9 -3
  9. package/dist/utils/model-utils.d.ts.map +1 -1
  10. package/dist/utils/model-utils.js +15 -7
  11. package/package.json +19 -2
  12. package/eslint.config.mjs +0 -4
  13. package/jest.config.js +0 -11
  14. package/src/builders/README.md +0 -339
  15. package/src/builders/batch-get/README.md +0 -43
  16. package/src/builders/batch-get/create-batch-get-builder.test.ts +0 -193
  17. package/src/builders/batch-get/create-batch-get-builder.ts +0 -108
  18. package/src/builders/batch-get/index.ts +0 -2
  19. package/src/builders/batch-get/types.ts +0 -28
  20. package/src/builders/batch-write/README.md +0 -204
  21. package/src/builders/batch-write/create-batch-write-builder.test.ts +0 -173
  22. package/src/builders/batch-write/create-batch-write-builder.ts +0 -49
  23. package/src/builders/batch-write/index.ts +0 -2
  24. package/src/builders/batch-write/types.ts +0 -33
  25. package/src/builders/delete/create-delete-builder.test.ts +0 -294
  26. package/src/builders/delete/create-delete-builder.ts +0 -100
  27. package/src/builders/delete/index.ts +0 -2
  28. package/src/builders/delete/types.ts +0 -17
  29. package/src/builders/get/create-get-builder.test.ts +0 -272
  30. package/src/builders/get/create-get-builder.ts +0 -117
  31. package/src/builders/get/index.ts +0 -2
  32. package/src/builders/get/types.ts +0 -39
  33. package/src/builders/index.ts +0 -14
  34. package/src/builders/put/create-put-builder.test.ts +0 -213
  35. package/src/builders/put/create-put-builder.ts +0 -160
  36. package/src/builders/put/index.ts +0 -2
  37. package/src/builders/put/types.ts +0 -24
  38. package/src/builders/query/create-query-builder.test.ts +0 -770
  39. package/src/builders/query/create-query-builder.ts +0 -455
  40. package/src/builders/query/index.ts +0 -2
  41. package/src/builders/query/types.ts +0 -109
  42. package/src/builders/scan/create-scan-builder.test.ts +0 -416
  43. package/src/builders/scan/create-scan-builder.ts +0 -265
  44. package/src/builders/scan/index.ts +0 -2
  45. package/src/builders/scan/types.ts +0 -88
  46. package/src/builders/shared/conditions.ts +0 -58
  47. package/src/builders/shared/index.ts +0 -4
  48. package/src/builders/shared/operators.test.ts +0 -270
  49. package/src/builders/shared/operators.ts +0 -208
  50. package/src/builders/shared/projection.ts +0 -28
  51. package/src/builders/shared/types.ts +0 -101
  52. package/src/builders/transact-get/README.md +0 -167
  53. package/src/builders/transact-get/create-transact-get-builder.test.ts +0 -239
  54. package/src/builders/transact-get/create-transact-get-builder.ts +0 -67
  55. package/src/builders/transact-get/index.ts +0 -2
  56. package/src/builders/transact-get/types.ts +0 -31
  57. package/src/builders/transact-write/README.md +0 -202
  58. package/src/builders/transact-write/create-transact-write-builder.test.ts +0 -288
  59. package/src/builders/transact-write/create-transact-write-builder.ts +0 -124
  60. package/src/builders/transact-write/index.ts +0 -2
  61. package/src/builders/transact-write/types.ts +0 -71
  62. package/src/builders/update/create-update-builder.test.ts +0 -573
  63. package/src/builders/update/create-update-builder.ts +0 -375
  64. package/src/builders/update/index.ts +0 -2
  65. package/src/builders/update/types.ts +0 -63
  66. package/src/core/types.test.ts +0 -641
  67. package/src/core/types.ts +0 -366
  68. package/src/entity/create-entity-api.ts +0 -224
  69. package/src/entity/index.ts +0 -19
  70. package/src/entity/middleware/factories.ts +0 -15
  71. package/src/entity/middleware/types.ts +0 -7
  72. package/src/entity/middleware/with-middleware.ts +0 -37
  73. package/src/entity/types.ts +0 -79
  74. package/src/entity/validation/key-validation.ts +0 -34
  75. package/src/index.ts +0 -23
  76. package/src/table.ts +0 -116
  77. package/src/utils/dynamodb-logger.test.ts +0 -246
  78. package/src/utils/dynamodb-logger.ts +0 -175
  79. package/src/utils/model-utils.test.ts +0 -452
  80. package/src/utils/model-utils.ts +0 -188
  81. package/src/utils/zod-utils.test.ts +0 -363
  82. package/src/utils/zod-utils.ts +0 -56
  83. package/tests/integration/instagram-clone.integration.test.ts +0 -1019
  84. package/tests/integration/pagination-timestamps.integration.test.ts +0 -374
  85. package/tests/integration/transactions.integration.test.ts +0 -528
  86. package/tsconfig.json +0 -12
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## @ftschopp/dynatable-core [1.4.4](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.4.3...@ftschopp/dynatable-core@1.4.4) (2026-05-09)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **core:** detect SET-collisions on auto-recomputed index keys; stripInternalKeys recurses ([#38](https://github.com/ftschopp/dynatable/issues/38)) ([d609c5b](https://github.com/ftschopp/dynatable/commit/d609c5bbeb566145ec034ec9883246a6d77d7cf6)), closes [#17](https://github.com/ftschopp/dynatable/issues/17) [#GSI1](https://github.com/ftschopp/dynatable/issues/GSI1) [#GSI1](https://github.com/ftschopp/dynatable/issues/GSI1)
7
+
8
+ ## @ftschopp/dynatable-core [1.4.3](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.4.2...@ftschopp/dynatable-core@1.4.3) (2026-05-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **query:** resolve index keys exactly, not by prefix match ([#34](https://github.com/ftschopp/dynatable/issues/34)) ([5ca8654](https://github.com/ftschopp/dynatable/commit/5ca865465454e84bee6b5e3e1510f5905a7027d9)), closes [#11](https://github.com/ftschopp/dynatable/issues/11)
14
+
1
15
  ## @ftschopp/dynatable-core [1.4.2](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.4.1...@ftschopp/dynatable-core@1.4.2) (2026-05-08)
2
16
 
3
17
 
@@ -1 +1 @@
1
- {"version":3,"file":"create-query-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/query/create-query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAsZ7D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,KAAK,CAAC,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,YAAY,CAAC,KAAK,CAAC,CA6BrB"}
1
+ {"version":3,"file":"create-query-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/query/create-query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAAiB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AA8a7D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,KAAK,CAAC,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,YAAY,CAAC,KAAK,CAAC,CA6BrB"}
@@ -6,6 +6,23 @@ const operators_1 = require("../shared/operators");
6
6
  const conditions_1 = require("../shared/conditions");
7
7
  const projection_1 = require("../shared/projection");
8
8
  const model_utils_1 = require("../../utils/model-utils");
9
+ /**
10
+ * Decide whether an entry in `model.index` belongs to the given index.
11
+ *
12
+ * 1. If the key declaration carries an explicit `indexName`, that wins —
13
+ * consumers with non-conventional names (e.g. index `BySpotifyId` with
14
+ * keys `lookupPK`/`lookupSK`) opt in by setting it.
15
+ * 2. Otherwise we fall back to the historical convention but with an EXACT
16
+ * `<indexName>PK` / `<indexName>SK` suffix check (not `startsWith`), so
17
+ * sibling indexes whose names share a prefix — `GSI1` vs `GSI10` — don't
18
+ * cross-pollute key resolution.
19
+ */
20
+ function keyBelongsToIndex(keyName, keyDef, indexName) {
21
+ if (keyDef.indexName !== undefined) {
22
+ return keyDef.indexName === indexName;
23
+ }
24
+ return keyName === `${indexName}PK` || keyName === `${indexName}SK`;
25
+ }
9
26
  /**
10
27
  * Maps a model attribute name to its corresponding DynamoDB key name (PK/SK)
11
28
  * Also returns the key template for value transformation
@@ -16,7 +33,7 @@ function getKeyNameForAttribute(fieldName, model, indexName) {
16
33
  // When an index is specified, check model.index first for key templates
17
34
  if (indexName && model.index) {
18
35
  for (const [keyName, keyDef] of Object.entries(model.index)) {
19
- if (!keyName.startsWith(indexName)) {
36
+ if (!keyBelongsToIndex(keyName, keyDef, indexName)) {
20
37
  continue;
21
38
  }
22
39
  const templateVars = (0, model_utils_1.extractTemplateVars)(keyDef.value);
@@ -198,7 +215,7 @@ function createQueryExecutor(state) {
198
215
  if (keyConditions.length === 0) {
199
216
  const keyTemplates = state.indexName
200
217
  ? Object.entries(state.model?.index ?? {})
201
- .filter(([keyName]) => keyName.startsWith(state.indexName))
218
+ .filter(([keyName, def]) => keyBelongsToIndex(keyName, def, state.indexName))
202
219
  .map(([, def]) => def.value)
203
220
  : Object.values(state.model?.key ?? {}).map((def) => def.value);
204
221
  const templateVars = Array.from(new Set(keyTemplates.flatMap((tpl) => (0, model_utils_1.extractTemplateVars)(tpl))));
@@ -1 +1 @@
1
- {"version":3,"file":"create-update-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/update/create-update-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAA4B,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,aAAa,GAAE;IACb,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;CACuB,EAChD,UAAU,GAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAsB,EACnF,YAAY,SAAI,EAChB,gBAAgB,UAAQ,EACxB,MAAM,CAAC,EAAE,cAAc,EACvB,YAAY,CAAC,EAAE,YAAY,EAC3B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,aAAa,CAAC,KAAK,CAAC,CAoVtB"}
1
+ {"version":3,"file":"create-update-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/update/create-update-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAA4B,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAa7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,aAAa,GAAE;IACb,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;CACuB,EAChD,UAAU,GAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAsB,EACnF,YAAY,SAAI,EAChB,gBAAgB,UAAQ,EACxB,MAAM,CAAC,EAAE,cAAc,EACvB,YAAY,CAAC,EAAE,YAAY,EAC3B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,aAAa,CAAC,KAAK,CAAC,CAsWtB"}
@@ -4,6 +4,15 @@ exports.createUpdateBuilder = createUpdateBuilder;
4
4
  const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
5
  const shared_1 = require("../shared");
6
6
  const model_utils_1 = require("../../utils/model-utils");
7
+ /**
8
+ * Pull the LHS attribute name out of a SET-action expression like
9
+ * `#GSI1PK = :v_0` → `'GSI1PK'`. Returns `undefined` for shapes the
10
+ * builder doesn't emit so callers can ignore them safely.
11
+ */
12
+ function extractAttrName(action) {
13
+ const m = action.expression.match(/^\s*#([A-Za-z0-9_]+)\s*=/);
14
+ return m?.[1];
15
+ }
7
16
  /**
8
17
  * Creates an UpdateBuilder for an item key and table.
9
18
  *
@@ -120,6 +129,22 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
120
129
  `but the templates cannot be fully resolved from the update payload. ` +
121
130
  `Include the missing fields in .set():\n${details}`);
122
131
  }
132
+ // If the user's `.set()` already targets the same index-key
133
+ // attribute (e.g. `.set('GSI1PK', 'foo')`), refuse to silently
134
+ // emit a second SET against the same path. DynamoDB rejects
135
+ // `SET #GSI1PK = :a, #GSI1PK = :b` outright, and namespacing the
136
+ // placeholders only hides which one wins. Force the caller to
137
+ // resolve the conflict explicitly.
138
+ const userSetKeys = new Set(actionsToProcess.set.map(extractAttrName));
139
+ userSetKeys.delete(undefined);
140
+ const conflicts = Object.keys(idxActions).filter((k) => userSetKeys.has(k));
141
+ if (conflicts.length > 0) {
142
+ throw new Error(`Update would write the same secondary-index key twice: ` +
143
+ `[${conflicts.join(', ')}] is recomputed from the index template AND ` +
144
+ `set explicitly via .set(). Either remove the explicit .set() and let ` +
145
+ `the recomputation handle it, or include all template variables in ` +
146
+ `.set() so you take full control.`);
147
+ }
123
148
  for (const [indexName, resolved] of Object.entries(idxActions)) {
124
149
  const valueName = getUniqueValueName(indexName);
125
150
  actionsToProcess.set.push({
@@ -83,10 +83,15 @@ export type AttributeDefinition = ScalarAttributeDefinition | ObjectAttributeDef
83
83
  *
84
84
  * @property type - Always String for DynamoDB keys
85
85
  * @property value - Template string for key generation
86
+ * @property indexName - Optional explicit association of this key to a secondary
87
+ * index. Use this when index keys are not named with the conventional
88
+ * `<indexName>PK` / `<indexName>SK` pattern, or to disambiguate indexes
89
+ * whose names share a prefix (e.g. `GSI1` and `GSI10`).
86
90
  */
87
91
  export type KeyDefinition = {
88
92
  type: StringConstructor;
89
93
  value: string;
94
+ indexName?: string;
90
95
  };
91
96
  /**
92
97
  * Primary key definition - requires both PK and SK (uppercase)
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -50,9 +50,15 @@ export declare const applyPostDefaults: <M extends ModelDefinition>(model: M, va
50
50
  timestamps?: boolean;
51
51
  }) => InferModel<M>;
52
52
  /**
53
- * Removes internal DynamoDB keys from an item or array of items
54
- * @param data - Single item or array of items from DynamoDB
55
- * @returns Data with internal keys removed
53
+ * Removes internal DynamoDB keys from an item or array of items.
54
+ *
55
+ * Recurses into nested plain objects and arrays so an `_type` / `PK` / `SK`
56
+ * field embedded inside an attribute value (e.g. a denormalized snapshot
57
+ * of another entity) is also stripped. Class instances such as `Date` are
58
+ * passed through untouched — recursing into them would lose their type.
59
+ *
60
+ * @param data - Single item, array of items, or any nested value from DynamoDB
61
+ * @returns Data with internal keys removed at every level
56
62
  */
57
63
  export declare const stripInternalKeys: <T>(data: T | T[] | undefined) => T | T[] | undefined;
58
64
  //# sourceMappingURL=model-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-utils.d.ts","sourceRoot":"","sources":["../../src/utils/model-utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,KAAG,MAAM,EAG5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAoB7E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,eAAe,EACnD,OAAO,CAAC,EACR,OAAO,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAM,KAAK,GAAG,OAAO,GAAG,MAAc,KACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAWvB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;CACnE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,eAAe,EAC3D,OAAO,CAAC,EACR,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC3B,mBAwBF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,eAAe,EACzD,OAAO,CAAC,EACR,eAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,UAAU;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KACrD,UAAU,CAAC,CAAC,CAiCd,CAAC;AAOF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,KAAG,CAAC,GAAG,CAAC,EAAE,GAAG,SAoB1E,CAAC"}
1
+ {"version":3,"file":"model-utils.d.ts","sourceRoot":"","sources":["../../src/utils/model-utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAiB,eAAe,EAAE,MAAM,cAAc,CAAC;AAG1E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,KAAG,MAAM,EAG5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,MAoB7E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,eAAe,EACnD,OAAO,CAAC,EACR,OAAO,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAM,KAAK,GAAG,OAAO,GAAG,MAAc,KACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAWvB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;CACnE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,eAAe,EAC3D,OAAO,CAAC,EACR,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC3B,mBAwBF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,eAAe,EACzD,OAAO,CAAC,EACR,eAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,UAAU;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,KACrD,UAAU,CAAC,CAAC,CAiCd,CAAC;AAOF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,KAAG,CAAC,GAAG,CAAC,EAAE,GAAG,SAqB1E,CAAC"}
@@ -125,9 +125,15 @@ exports.applyPostDefaults = applyPostDefaults;
125
125
  */
126
126
  const INTERNAL_KEYS = ['PK', 'SK', '_type'];
127
127
  /**
128
- * Removes internal DynamoDB keys from an item or array of items
129
- * @param data - Single item or array of items from DynamoDB
130
- * @returns Data with internal keys removed
128
+ * Removes internal DynamoDB keys from an item or array of items.
129
+ *
130
+ * Recurses into nested plain objects and arrays so an `_type` / `PK` / `SK`
131
+ * field embedded inside an attribute value (e.g. a denormalized snapshot
132
+ * of another entity) is also stripped. Class instances such as `Date` are
133
+ * passed through untouched — recursing into them would lose their type.
134
+ *
135
+ * @param data - Single item, array of items, or any nested value from DynamoDB
136
+ * @returns Data with internal keys removed at every level
131
137
  */
132
138
  const stripInternalKeys = (data) => {
133
139
  if (data === undefined || data === null) {
@@ -136,12 +142,14 @@ const stripInternalKeys = (data) => {
136
142
  if (Array.isArray(data)) {
137
143
  return data.map((item) => (0, exports.stripInternalKeys)(item));
138
144
  }
139
- if (typeof data === 'object') {
145
+ // Only recurse into plain objects; preserve Date, Buffer, Set, Map,
146
+ // and anything else with a non-Object prototype.
147
+ if (typeof data === 'object' && Object.getPrototypeOf(data) === Object.prototype) {
140
148
  const cleaned = {};
141
149
  for (const [key, value] of Object.entries(data)) {
142
- if (!INTERNAL_KEYS.includes(key)) {
143
- cleaned[key] = value;
144
- }
150
+ if (INTERNAL_KEYS.includes(key))
151
+ continue;
152
+ cleaned[key] = (0, exports.stripInternalKeys)(value);
145
153
  }
146
154
  return cleaned;
147
155
  }
package/package.json CHANGED
@@ -1,16 +1,30 @@
1
1
  {
2
2
  "name": "@ftschopp/dynatable-core",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "Core library for DynamoDB single table design",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./package.json": "./package.json"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "CHANGELOG.md"
18
+ ],
7
19
  "publishConfig": {
8
20
  "access": "public"
9
21
  },
10
22
  "scripts": {
11
23
  "build": "tsc && tsc-alias",
12
24
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
13
- "test": "jest"
25
+ "lint": "eslint src",
26
+ "test": "jest",
27
+ "prepublishOnly": "yarn build"
14
28
  },
15
29
  "devDependencies": {
16
30
  "@repo/eslint-config": "*",
@@ -33,5 +47,8 @@
33
47
  "ramda": "^0.32.0",
34
48
  "ulid": "^3.0.2",
35
49
  "zod": "^4.3.5"
50
+ },
51
+ "engines": {
52
+ "node": ">=22"
36
53
  }
37
54
  }
package/eslint.config.mjs DELETED
@@ -1,4 +0,0 @@
1
- import { config } from "@repo/eslint-config/react-internal";
2
-
3
- /** @type {import("eslint").Linter.Config} */
4
- export default config;
package/jest.config.js DELETED
@@ -1,11 +0,0 @@
1
- /** @type {import('jest').Config} */
2
- module.exports = {
3
- preset: 'ts-jest',
4
- testEnvironment: 'node',
5
- testMatch: ['**/?(*.)+(test).[tj]s'],
6
- testPathIgnorePatterns: ['/node_modules/', '/dist/'],
7
- roots: ['<rootDir>/src', '<rootDir>/tests'],
8
- moduleNameMapper: {
9
- '^@/(.*)$': '<rootDir>/src/$1',
10
- },
11
- };
@@ -1,339 +0,0 @@
1
- # Builders Architecture
2
-
3
- This directory contains the builder pattern implementation for DynamoDB operations.
4
-
5
- ## Structure
6
-
7
- ```
8
- builders/
9
- ├── shared/ # Shared utilities and types
10
- │ ├── types.ts # Base types (Condition, OpBuilder, etc.)
11
- │ ├── operators.ts # Condition operators (eq, ne, lt, etc.)
12
- │ └── conditions.ts # Condition expression builders
13
- ├── get/ # GET operation builder
14
- │ ├── types.ts
15
- │ ├── create-get-builder.ts
16
- │ └── index.ts
17
- ├── put/ # PUT operation builder
18
- │ ├── types.ts
19
- │ ├── create-put-builder.ts
20
- │ └── index.ts
21
- └── query/ # QUERY operation builder
22
- ├── types.ts
23
- ├── create-query-builder.ts
24
- └── index.ts
25
- ```
26
-
27
- ## Design Principles
28
-
29
- 1. **Modularity**: Each operation has its own directory with dedicated types and implementation
30
- 2. **Reusability**: Common utilities are centralized in `shared/`
31
- 3. **Scalability**: Easy to add new operations (query, scan, delete, etc.) by following the same pattern
32
- 4. **Type Safety**: Full TypeScript support with proper type inference
33
-
34
- ## Adding a New Builder
35
-
36
- To add a new operation (e.g., `query`):
37
-
38
- 1. Create a new directory: `builders/query/`
39
- 2. Add three files:
40
- - `types.ts` - Interface definition extending `OperationBuilder` or `ExecutableBuilder`
41
- - `create-query-builder.ts` - Implementation with immutable builder pattern
42
- - `index.ts` - Export all public APIs
43
- 3. Import shared utilities from `../shared`
44
- 4. Export from main `builders/index.ts`
45
-
46
- ## Usage Examples
47
-
48
- ### GET Operation
49
-
50
- ```typescript
51
- import { createGetBuilder } from './builders';
52
-
53
- const getBuilder = createGetBuilder(tableName, key, client)
54
- .select(['name', 'email'])
55
- .consistentRead();
56
-
57
- const item = await getBuilder.execute();
58
- ```
59
-
60
- ### PUT Operation
61
-
62
- ```typescript
63
- import { createPutBuilder } from './builders';
64
-
65
- const putBuilder = createPutBuilder(tableName, item, client).ifNotExists().returning('ALL_NEW');
66
-
67
- const result = await putBuilder.execute();
68
- ```
69
-
70
- ### QUERY Operation
71
-
72
- ```typescript
73
- import { createQueryBuilder } from './builders';
74
-
75
- // Basic query with partition key
76
- const query1 = createQueryBuilder(tableName, client, model)
77
- .where((attr, op) => op.eq(attr.username, 'juanca'))
78
- .execute();
79
-
80
- // Query with AND filter
81
- const query2 = createQueryBuilder(tableName, client, model)
82
- .where((attr, op) => op.and(op.eq(attr.username, 'juanca'), op.gt(attr.likesCount, 10)))
83
- .limit(10)
84
- .scanIndexForward(false)
85
- .select(['id', 'title', 'createdAt'])
86
- .execute();
87
-
88
- // Query with OR filter
89
- const query3 = createQueryBuilder(tableName, client, model)
90
- .where((attr, op) =>
91
- op.and(
92
- op.eq(attr.username, 'juanca'),
93
- op.or(op.gt(attr.likesCount, 100), op.gt(attr.commentCount, 50))
94
- )
95
- )
96
- .execute();
97
-
98
- // Complex nested conditions
99
- const query4 = createQueryBuilder(tableName, client, model)
100
- .where((attr, op) =>
101
- op.and(
102
- op.eq(attr.username, 'juanca'),
103
- op.or(
104
- op.and(op.gt(attr.likesCount, 100), op.lt(attr.commentCount, 10)),
105
- op.gt(attr.likesCount, 500)
106
- )
107
- )
108
- )
109
- .execute();
110
-
111
- // Query using a secondary index
112
- const query5 = createQueryBuilder(tableName, client, model)
113
- .where((attr, op) => op.eq(attr.status, 'active'))
114
- .useIndex('GSI1')
115
- .execute();
116
- ```
117
-
118
- ## Type-Safe Queries
119
-
120
- The Query Builder provides full TypeScript type safety with an intuitive API:
121
-
122
- ```typescript
123
- // Your model type
124
- type Photo = {
125
- username: string; // Used in partition key template
126
- photoId: string; // Used in sort key template
127
- url: string;
128
- likesCount: number;
129
- commentCount: number;
130
- };
131
-
132
- // Type-safe query - TypeScript knows all fields and their types!
133
- const photos = await createQueryBuilder<Photo>(tableName, client, model)
134
- .where((attr, op) =>
135
- op.and(
136
- op.eq(attr.username, 'juanca'), // ✓ Key field - goes to KeyConditionExpression
137
- op.gt(attr.likesCount, 10) // ✓ Non-key field - goes to FilterExpression
138
- )
139
- )
140
- .select(['username', 'url', 'likesCount']) // ✓ Only Photo keys allowed
141
- .execute();
142
-
143
- // TypeScript will catch errors at compile time:
144
- // .where((attr, op) => op.eq(attr.invalid, 'x')) // ✗ Property 'invalid' does not exist
145
- // .where((attr, op) => op.eq(attr.username, 123)) // ✗ Argument of type 'number' not assignable
146
- // .select(['invalidField']) // ✗ Type error!
147
- ```
148
-
149
- ### Important: Automatic Separation of Key Conditions vs Filters
150
-
151
- The query builder **automatically separates** your conditions:
152
-
153
- **KeyConditionExpression** (efficient, uses indexes):
154
-
155
- - Fields used in partition key (pk) or sort key (sk) templates
156
- - Evaluated during the query at the index level
157
- - Very efficient - only reads matching items
158
-
159
- **FilterExpression** (less efficient, post-processing):
160
-
161
- - All other fields not in key templates
162
- - Applied AFTER items are retrieved
163
- - OR operators automatically go here (DynamoDB requirement)
164
-
165
- ```typescript
166
- // ✓ The builder handles this automatically!
167
- .where((attr, op) => op.and(
168
- op.eq(attr.username, 'juanca'), // → KeyConditionExpression (username is in pk template)
169
- op.gt(attr.likesCount, 10) // → FilterExpression (likesCount is not a key)
170
- ))
171
-
172
- // Generates:
173
- // KeyConditionExpression: "#username = :username_0"
174
- // FilterExpression: "#likesCount > :likesCount_1"
175
- ```
176
-
177
- ## Important: Operator Isolation
178
-
179
- Each builder creates its own isolated instance of operators with independent counters. This prevents naming conflicts when building multiple queries concurrently or reusing builder code.
180
-
181
- ```typescript
182
- // ✓ Each builder has isolated state
183
- const query1 = createQueryBuilder(table, client).where((attr, op) => op.eq(attr.id, '1')); // Uses :id_0
184
-
185
- const query2 = createQueryBuilder(table, client).where((attr, op) => op.eq(attr.id, '2')); // Also uses :id_0 (isolated counter)
186
-
187
- // No conflicts! Each builder has its own counter starting at 0
188
- ```
189
-
190
- For advanced use cases where you need to manually create operators, use `createOpBuilder()`:
191
-
192
- ```typescript
193
- import { createOpBuilder } from './builders/shared';
194
-
195
- const op = createOpBuilder(); // Creates isolated operator instance
196
- const condition = op.eq(attr, value);
197
- ```
198
-
199
- ## Available Operators
200
-
201
- The `op` parameter in `.where()` provides these operators:
202
-
203
- **Comparison Operators:**
204
-
205
- - `op.eq(attr, value)` - Equals (=)
206
- - `op.ne(attr, value)` - Not equals (<>)
207
- - `op.lt(attr, value)` - Less than (<)
208
- - `op.lte(attr, value)` - Less than or equal (<=)
209
- - `op.gt(attr, value)` - Greater than (>)
210
- - `op.gte(attr, value)` - Greater than or equal (>=)
211
- - `op.between(attr, low, high)` - Between two values
212
-
213
- **String Operators:**
214
-
215
- - `op.beginsWith(attr, prefix)` - Begins with a string prefix (for string/binary fields)
216
- - `op.contains(attr, value)` - Contains a substring or value (works with strings, sets, and lists)
217
-
218
- **Existence Operators:**
219
-
220
- - `op.exists(attr)` - Attribute exists
221
- - `op.notExists(attr)` - Attribute does not exist
222
-
223
- **Type Checking:**
224
-
225
- - `op.attributeType(attr, type)` - Check the attribute's type
226
- - Valid types: `'S'` (String), `'N'` (Number), `'B'` (Binary), `'SS'` (String Set), `'NS'` (Number Set), `'BS'` (Binary Set), `'M'` (Map), `'L'` (List), `'NULL'`, `'BOOL'`
227
-
228
- **Advanced Operators:**
229
-
230
- - `op.in(attr, values[])` - Attribute value is in the provided array
231
- - `op.size(attr)` - Get the size of an attribute (string length, number of elements in set/list, etc.)
232
- - Returns a `SizeRef` object with comparison methods:
233
- - `.eq(n)` - Size equals n
234
- - `.ne(n)` - Size not equals n
235
- - `.lt(n)` - Size less than n
236
- - `.lte(n)` - Size less than or equal to n
237
- - `.gt(n)` - Size greater than n
238
- - `.gte(n)` - Size greater than or equal to n
239
-
240
- **Logical Operators:**
241
-
242
- - `op.and(...conditions)` - Combines conditions with AND
243
- - `op.or(...conditions)` - Combines conditions with OR
244
- - `op.not(condition)` - Negates a condition
245
-
246
- ### Example Usage
247
-
248
- ```typescript
249
- // Basic equality
250
- .where((attr, op) => op.eq(attr.username, 'juanca'))
251
-
252
- // Comparison operators
253
- .where((attr, op) => op.and(
254
- op.eq(attr.username, 'juanca'),
255
- op.gt(attr.age, 18),
256
- op.lt(attr.score, 100)
257
- ))
258
-
259
- // String operations
260
- .where((attr, op) => op.beginsWith(attr.email, 'admin@'))
261
-
262
- // Between operator
263
- .where((attr, op) => op.between(attr.createdAt, '2024-01-01', '2024-12-31'))
264
-
265
- // OR conditions
266
- .where((attr, op) => op.or(
267
- op.eq(attr.status, 'active'),
268
- op.eq(attr.status, 'pending')
269
- ))
270
-
271
- // Complex nested conditions
272
- .where((attr, op) => op.and(
273
- op.eq(attr.org, 'acme'),
274
- op.or(
275
- op.and(
276
- op.gt(attr.score, 80),
277
- op.eq(attr.verified, true)
278
- ),
279
- op.eq(attr.role, 'admin')
280
- )
281
- ))
282
-
283
- // NOT operator
284
- .where((attr, op) => op.not(op.eq(attr.status, 'deleted')))
285
-
286
- // Existence operators
287
- .where((attr, op) => op.and(
288
- op.eq(attr.username, 'alice'),
289
- op.exists(attr.email) // Has email field
290
- ))
291
-
292
- .where((attr, op) => op.notExists(attr.deletedAt)) // Not deleted
293
-
294
- // Contains operator (for strings, sets, lists)
295
- .where((attr, op) => op.and(
296
- op.eq(attr.username, 'alice'),
297
- op.contains(attr.bio, 'developer') // Bio contains "developer"
298
- ))
299
-
300
- .where((attr, op) => op.contains(attr.tags, 'premium')) // Has "premium" in tags set/list
301
-
302
- // IN operator
303
- .where((attr, op) => op.in(attr.status, ['active', 'pending', 'verified']))
304
-
305
- // Size operator
306
- .where((attr, op) => op.size(attr.tags).gte(3)) // At least 3 tags
307
- .where((attr, op) => op.size(attr.username).lt(20)) // Username shorter than 20 chars
308
- .where((attr, op) => op.size(attr.comments).eq(0)) // No comments
309
-
310
- // Attribute type checking
311
- .where((attr, op) => op.attributeType(attr.metadata, 'M')) // Is a Map
312
- .where((attr, op) => op.attributeType(attr.items, 'L')) // Is a List
313
-
314
- // Complex example with new operators
315
- await table.entities.User.query()
316
- .where((attr, op) => op.and(
317
- op.eq(attr.status, 'active'),
318
- op.exists(attr.email),
319
- op.size(attr.followers).gte(10),
320
- op.or(
321
- op.contains(attr.tags, 'premium'),
322
- op.contains(attr.tags, 'verified')
323
- )
324
- ))
325
- .execute();
326
-
327
- // Complete example with all features
328
- await table.entities.Photo.query()
329
- .where((attr, op) => op.and(
330
- op.eq(attr.username, 'juanca'), // Key field
331
- op.or(
332
- op.gt(attr.likesCount, 100), // Filter field
333
- op.gt(attr.commentCount, 50) // Filter field
334
- )
335
- ))
336
- .limit(50)
337
- .scanIndexForward(false)
338
- .execute();
339
- ```