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.
- package/README.md +56 -8
- package/dist/src/DynaRecord.d.ts +17 -1
- package/dist/src/DynaRecord.d.ts.map +1 -1
- package/dist/src/DynaRecord.js +24 -6
- package/dist/src/decorators/attributes/ObjectAttribute.d.ts +40 -17
- package/dist/src/decorators/attributes/ObjectAttribute.d.ts.map +1 -1
- package/dist/src/decorators/attributes/ObjectAttribute.js +77 -17
- package/dist/src/decorators/attributes/index.d.ts +1 -1
- package/dist/src/decorators/attributes/index.d.ts.map +1 -1
- package/dist/src/decorators/attributes/serializers.d.ts +49 -0
- package/dist/src/decorators/attributes/serializers.d.ts.map +1 -1
- package/dist/src/decorators/attributes/serializers.js +99 -0
- package/dist/src/decorators/attributes/types.d.ts +51 -14
- package/dist/src/decorators/attributes/types.d.ts.map +1 -1
- package/dist/src/metadata/AttributeMetadata.d.ts +3 -0
- package/dist/src/metadata/AttributeMetadata.d.ts.map +1 -1
- package/dist/src/metadata/AttributeMetadata.js +5 -0
- package/dist/src/metadata/EntityMetadata.d.ts.map +1 -1
- package/dist/src/metadata/EntityMetadata.js +8 -1
- package/dist/src/metadata/types.d.ts +11 -0
- package/dist/src/metadata/types.d.ts.map +1 -1
- package/dist/src/operations/Update/Update.d.ts +6 -1
- package/dist/src/operations/Update/Update.d.ts.map +1 -1
- package/dist/src/operations/Update/Update.js +25 -3
- package/dist/src/operations/Update/types.d.ts +26 -2
- package/dist/src/operations/Update/types.d.ts.map +1 -1
- package/dist/src/operations/utils/expressionBuilder.d.ts +4 -3
- package/dist/src/operations/utils/expressionBuilder.d.ts.map +1 -1
- package/dist/src/operations/utils/expressionBuilder.js +63 -2
- package/dist/src/operations/utils/flattenObjectForUpdate.d.ts +19 -0
- package/dist/src/operations/utils/flattenObjectForUpdate.d.ts.map +1 -0
- package/dist/src/operations/utils/flattenObjectForUpdate.js +45 -0
- package/dist/src/operations/utils/index.d.ts +2 -0
- package/dist/src/operations/utils/index.d.ts.map +1 -1
- package/dist/src/operations/utils/index.js +2 -0
- package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts +8 -0
- package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts.map +1 -0
- package/dist/src/operations/utils/mergePartialObjectAttributes.js +52 -0
- package/dist/src/operations/utils/types.d.ts +16 -0
- package/dist/src/operations/utils/types.d.ts.map +1 -1
- 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 +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"}
|