dyna-record 0.4.10 → 0.5.0

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 (41) hide show
  1. package/README.md +56 -8
  2. package/dist/src/DynaRecord.d.ts +17 -1
  3. package/dist/src/DynaRecord.d.ts.map +1 -1
  4. package/dist/src/DynaRecord.js +24 -6
  5. package/dist/src/decorators/attributes/ObjectAttribute.d.ts +40 -17
  6. package/dist/src/decorators/attributes/ObjectAttribute.d.ts.map +1 -1
  7. package/dist/src/decorators/attributes/ObjectAttribute.js +77 -17
  8. package/dist/src/decorators/attributes/index.d.ts +1 -1
  9. package/dist/src/decorators/attributes/index.d.ts.map +1 -1
  10. package/dist/src/decorators/attributes/serializers.d.ts +49 -0
  11. package/dist/src/decorators/attributes/serializers.d.ts.map +1 -1
  12. package/dist/src/decorators/attributes/serializers.js +99 -0
  13. package/dist/src/decorators/attributes/types.d.ts +51 -14
  14. package/dist/src/decorators/attributes/types.d.ts.map +1 -1
  15. package/dist/src/metadata/AttributeMetadata.d.ts +3 -0
  16. package/dist/src/metadata/AttributeMetadata.d.ts.map +1 -1
  17. package/dist/src/metadata/AttributeMetadata.js +5 -0
  18. package/dist/src/metadata/EntityMetadata.d.ts.map +1 -1
  19. package/dist/src/metadata/EntityMetadata.js +8 -1
  20. package/dist/src/metadata/types.d.ts +11 -0
  21. package/dist/src/metadata/types.d.ts.map +1 -1
  22. package/dist/src/operations/Update/Update.d.ts +6 -1
  23. package/dist/src/operations/Update/Update.d.ts.map +1 -1
  24. package/dist/src/operations/Update/Update.js +25 -3
  25. package/dist/src/operations/Update/types.d.ts +26 -2
  26. package/dist/src/operations/Update/types.d.ts.map +1 -1
  27. package/dist/src/operations/utils/expressionBuilder.d.ts +4 -3
  28. package/dist/src/operations/utils/expressionBuilder.d.ts.map +1 -1
  29. package/dist/src/operations/utils/expressionBuilder.js +63 -2
  30. package/dist/src/operations/utils/flattenObjectForUpdate.d.ts +19 -0
  31. package/dist/src/operations/utils/flattenObjectForUpdate.d.ts.map +1 -0
  32. package/dist/src/operations/utils/flattenObjectForUpdate.js +45 -0
  33. package/dist/src/operations/utils/index.d.ts +2 -0
  34. package/dist/src/operations/utils/index.d.ts.map +1 -1
  35. package/dist/src/operations/utils/index.js +2 -0
  36. package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts +8 -0
  37. package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts.map +1 -0
  38. package/dist/src/operations/utils/mergePartialObjectAttributes.js +52 -0
  39. package/dist/src/operations/utils/types.d.ts +16 -0
  40. package/dist/src/operations/utils/types.d.ts.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,19 @@
1
+ import type { ObjectSchema } from "../../decorators/attributes/types";
2
+ import type { DocumentPathOperation } from "./types";
3
+ /**
4
+ * Flattens a partial object value into document path operations for DynamoDB
5
+ * update expressions.
6
+ *
7
+ * For each field in the partial value:
8
+ * - `undefined` → skip (not being updated)
9
+ * - `null` → REMOVE operation
10
+ * - Nested object (`fieldDef.type === "object"`) → recurse, prepending parent path
11
+ * - Everything else (primitives, arrays, dates, enums) → serialize and SET
12
+ *
13
+ * @param parentPath Path segments leading to this object (e.g. ["address"] or ["address", "geo"])
14
+ * @param schema The ObjectSchema describing the object shape
15
+ * @param partialValue The partial object value to flatten
16
+ * @returns Array of DocumentPathOperation for use in expressionBuilder
17
+ */
18
+ export declare function flattenObjectForUpdate(parentPath: string[], schema: ObjectSchema, partialValue: Record<string, unknown>): DocumentPathOperation[];
19
+ //# sourceMappingURL=flattenObjectForUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flattenObjectForUpdate.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/flattenObjectForUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,mCAAmC,CAAC;AAEhF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,qBAAqB,EAAE,CAmCzB"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flattenObjectForUpdate = flattenObjectForUpdate;
4
+ const serializers_1 = require("../../decorators/attributes/serializers");
5
+ /**
6
+ * Flattens a partial object value into document path operations for DynamoDB
7
+ * update expressions.
8
+ *
9
+ * For each field in the partial value:
10
+ * - `undefined` → skip (not being updated)
11
+ * - `null` → REMOVE operation
12
+ * - Nested object (`fieldDef.type === "object"`) → recurse, prepending parent path
13
+ * - Everything else (primitives, arrays, dates, enums) → serialize and SET
14
+ *
15
+ * @param parentPath Path segments leading to this object (e.g. ["address"] or ["address", "geo"])
16
+ * @param schema The ObjectSchema describing the object shape
17
+ * @param partialValue The partial object value to flatten
18
+ * @returns Array of DocumentPathOperation for use in expressionBuilder
19
+ */
20
+ function flattenObjectForUpdate(parentPath, schema, partialValue) {
21
+ const ops = [];
22
+ for (const [key, val] of Object.entries(partialValue)) {
23
+ const fieldDef = schema[key];
24
+ if (fieldDef === undefined)
25
+ continue;
26
+ const fieldPath = [...parentPath, key];
27
+ if (val === undefined) {
28
+ continue;
29
+ }
30
+ if (val === null) {
31
+ ops.push({ type: "remove", path: fieldPath });
32
+ continue;
33
+ }
34
+ if (fieldDef.type === "object") {
35
+ // Recurse into nested objects
36
+ const nestedOps = flattenObjectForUpdate(fieldPath, fieldDef.fields, val);
37
+ ops.push(...nestedOps);
38
+ continue;
39
+ }
40
+ // Primitives, arrays, dates, enums → serialize and SET
41
+ const serialized = (0, serializers_1.convertFieldToTableItem)(fieldDef, val);
42
+ ops.push({ type: "set", path: fieldPath, value: serialized });
43
+ }
44
+ return ops;
45
+ }
@@ -1,4 +1,6 @@
1
1
  export * from "./expressionBuilder";
2
+ export * from "./flattenObjectForUpdate";
3
+ export * from "./mergePartialObjectAttributes";
2
4
  export * from "./types";
3
5
  export * from "./utils";
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
@@ -15,5 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./expressionBuilder"), exports);
18
+ __exportStar(require("./flattenObjectForUpdate"), exports);
19
+ __exportStar(require("./mergePartialObjectAttributes"), exports);
18
20
  __exportStar(require("./types"), exports);
19
21
  __exportStar(require("./utils"), exports);
@@ -0,0 +1,8 @@
1
+ import type { AttributeMetadataStorage } from "../../metadata";
2
+ /**
3
+ * Deep merges partial ObjectAttribute updates into the target object.
4
+ * For ObjectAttribute fields: recursively merges using the schema, removing null fields.
5
+ * For regular fields: shallow assigns (existing behavior).
6
+ */
7
+ export declare function mergePartialObjectAttributes(target: Record<string, unknown>, partial: Record<string, unknown>, entityAttrs: AttributeMetadataStorage): void;
8
+ //# sourceMappingURL=mergePartialObjectAttributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mergePartialObjectAttributes.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/mergePartialObjectAttributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAG/D;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,WAAW,EAAE,wBAAwB,GACpC,IAAI,CAiBN"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergePartialObjectAttributes = mergePartialObjectAttributes;
4
+ /**
5
+ * Deep merges partial ObjectAttribute updates into the target object.
6
+ * For ObjectAttribute fields: recursively merges using the schema, removing null fields.
7
+ * For regular fields: shallow assigns (existing behavior).
8
+ */
9
+ function mergePartialObjectAttributes(target, partial, entityAttrs) {
10
+ for (const [key, val] of Object.entries(partial)) {
11
+ const attrMeta = entityAttrs[key];
12
+ if (attrMeta?.objectSchema !== undefined) {
13
+ // Deep merge for ObjectAttribute (objects are never nullable)
14
+ const existing = target[key] ?? {};
15
+ target[key] = deepMergeObject(existing, val, attrMeta.objectSchema);
16
+ }
17
+ else {
18
+ target[key] = val;
19
+ }
20
+ }
21
+ }
22
+ /**
23
+ * Recursively deep merges a partial object into an existing object using the schema
24
+ * to determine which fields are nested objects (and should be recursed) vs leaf values
25
+ * (which should be overwritten).
26
+ * - null values cause the key to be deleted
27
+ * - object-type fields per the schema are recursed
28
+ * - everything else (primitives, arrays, dates, enums) is overwritten
29
+ */
30
+ function deepMergeObject(existing, partial, schema) {
31
+ const result = {};
32
+ // Copy existing keys, skipping those being nulled
33
+ for (const [key, val] of Object.entries(existing)) {
34
+ if (partial[key] !== null) {
35
+ result[key] = val;
36
+ }
37
+ }
38
+ // Apply updates in a single pass
39
+ for (const [key, val] of Object.entries(partial)) {
40
+ if (val === null || val === undefined) {
41
+ continue;
42
+ }
43
+ const fieldDef = schema[key];
44
+ if (fieldDef?.type === "object" && typeof existing[key] === "object") {
45
+ result[key] = deepMergeObject(existing[key] ?? {}, val, fieldDef.fields);
46
+ }
47
+ else {
48
+ result[key] = val;
49
+ }
50
+ }
51
+ return result;
52
+ }
@@ -18,4 +18,20 @@ export interface UpdateRemoveExpression {
18
18
  * Represents either an update expression for setting new or modifying existing attributes of an item (UpdateSetExpression) or an update expression for removing attributes from an item (UpdateRemoveExpression) in DynamoDB.
19
19
  */
20
20
  export type UpdateExpression = UpdateSetExpression | UpdateRemoveExpression;
21
+ /**
22
+ * Represents a single document path operation for partial ObjectAttribute updates.
23
+ * Used to build DynamoDB document path expressions like `SET #addr.#street = :addr_street`
24
+ * or `REMOVE #addr.#zip`.
25
+ */
26
+ export type DocumentPathOperation = {
27
+ type: "set";
28
+ /** Path segments, e.g. ["address", "street"] or ["address", "geo", "lat"] */
29
+ path: string[];
30
+ /** The serialized value */
31
+ value: unknown;
32
+ } | {
33
+ type: "remove";
34
+ /** Path segments, e.g. ["address", "zip"] */
35
+ path: string[];
36
+ };
21
37
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACtE,wBAAwB,EAAE,WAAW,CACnC,kBAAkB,CAAC,0BAA0B,CAAC,CAC/C,CAAC;IACF,yBAAyB,EAAE,WAAW,CACpC,kBAAkB,CAAC,2BAA2B,CAAC,CAChD,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACtE,wBAAwB,EAAE,WAAW,CACnC,kBAAkB,CAAC,0BAA0B,CAAC,CAC/C,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,sBAAsB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/operations/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACtE,wBAAwB,EAAE,WAAW,CACnC,kBAAkB,CAAC,0BAA0B,CAAC,CAC/C,CAAC;IACF,yBAAyB,EAAE,WAAW,CACpC,kBAAkB,CAAC,2BAA2B,CAAC,CAChD,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACtE,wBAAwB,EAAE,WAAW,CACnC,kBAAkB,CAAC,0BAA0B,CAAC,CAC/C,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,sBAAsB,CAAC;AAE5E;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,6EAA6E;IAC7E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dyna-record",
3
- "version": "0.4.10",
3
+ "version": "0.5.0",
4
4
  "description": "Typescript Data Modeler and ORM for Dynamo",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",