dyna-record 0.4.11 → 0.5.1

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 (106) hide show
  1. package/README.md +53 -6
  2. package/dist/src/DynaRecord.d.ts +28 -19
  3. package/dist/src/DynaRecord.d.ts.map +1 -1
  4. package/dist/src/DynaRecord.js +24 -6
  5. package/dist/src/Logger.d.ts.map +1 -1
  6. package/dist/src/Logger.js +0 -1
  7. package/dist/src/decorators/Entity.d.ts +1 -1
  8. package/dist/src/decorators/Entity.d.ts.map +1 -1
  9. package/dist/src/decorators/Entity.js +3 -5
  10. package/dist/src/decorators/Table.d.ts +1 -1
  11. package/dist/src/decorators/Table.d.ts.map +1 -1
  12. package/dist/src/decorators/Table.js +2 -4
  13. package/dist/src/decorators/attributes/BooleanAttribute.d.ts.map +1 -1
  14. package/dist/src/decorators/attributes/BooleanAttribute.js +7 -9
  15. package/dist/src/decorators/attributes/DateAttribute.d.ts.map +1 -1
  16. package/dist/src/decorators/attributes/DateAttribute.js +8 -10
  17. package/dist/src/decorators/attributes/EnumAttribute.d.ts.map +1 -1
  18. package/dist/src/decorators/attributes/EnumAttribute.js +7 -9
  19. package/dist/src/decorators/attributes/ForeignKeyAttribute.d.ts.map +1 -1
  20. package/dist/src/decorators/attributes/ForeignKeyAttribute.js +9 -11
  21. package/dist/src/decorators/attributes/NumberAttribute.d.ts.map +1 -1
  22. package/dist/src/decorators/attributes/NumberAttribute.js +7 -9
  23. package/dist/src/decorators/attributes/ObjectAttribute.d.ts +40 -17
  24. package/dist/src/decorators/attributes/ObjectAttribute.d.ts.map +1 -1
  25. package/dist/src/decorators/attributes/ObjectAttribute.js +80 -29
  26. package/dist/src/decorators/attributes/PartitionKeyAttribute.d.ts.map +1 -1
  27. package/dist/src/decorators/attributes/PartitionKeyAttribute.js +6 -8
  28. package/dist/src/decorators/attributes/SortKeyAttribute.d.ts.map +1 -1
  29. package/dist/src/decorators/attributes/SortKeyAttribute.js +6 -8
  30. package/dist/src/decorators/attributes/StringAttribute.d.ts.map +1 -1
  31. package/dist/src/decorators/attributes/StringAttribute.js +7 -9
  32. package/dist/src/decorators/attributes/serializers.d.ts +4 -3
  33. package/dist/src/decorators/attributes/serializers.d.ts.map +1 -1
  34. package/dist/src/decorators/attributes/serializers.js +2 -1
  35. package/dist/src/decorators/attributes/types.d.ts +20 -6
  36. package/dist/src/decorators/attributes/types.d.ts.map +1 -1
  37. package/dist/src/decorators/relationships/BelongsTo.d.ts.map +1 -1
  38. package/dist/src/decorators/relationships/BelongsTo.js +7 -9
  39. package/dist/src/decorators/relationships/HasAndBelongsToMany.d.ts.map +1 -1
  40. package/dist/src/decorators/relationships/HasAndBelongsToMany.js +13 -15
  41. package/dist/src/decorators/relationships/HasMany.d.ts.map +1 -1
  42. package/dist/src/decorators/relationships/HasMany.js +15 -17
  43. package/dist/src/decorators/relationships/HasOne.d.ts.map +1 -1
  44. package/dist/src/decorators/relationships/HasOne.js +7 -9
  45. package/dist/src/metadata/AttributeMetadata.d.ts +3 -0
  46. package/dist/src/metadata/AttributeMetadata.d.ts.map +1 -1
  47. package/dist/src/metadata/AttributeMetadata.js +5 -0
  48. package/dist/src/metadata/EntityMetadata.d.ts +2 -2
  49. package/dist/src/metadata/EntityMetadata.d.ts.map +1 -1
  50. package/dist/src/metadata/EntityMetadata.js +8 -1
  51. package/dist/src/metadata/MetadataStorage.d.ts.map +1 -1
  52. package/dist/src/metadata/MetadataStorage.js +6 -6
  53. package/dist/src/metadata/TableMetadata.d.ts.map +1 -1
  54. package/dist/src/metadata/TableMetadata.js +7 -1
  55. package/dist/src/metadata/relationship-metadata/BelongsToRelationship.d.ts.map +1 -1
  56. package/dist/src/metadata/relationship-metadata/BelongsToRelationship.js +1 -3
  57. package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.d.ts.map +1 -1
  58. package/dist/src/metadata/relationship-metadata/HasAndBelongsToManyRelationship.js +1 -3
  59. package/dist/src/metadata/relationship-metadata/HasManyRelationship.d.ts.map +1 -1
  60. package/dist/src/metadata/relationship-metadata/HasManyRelationship.js +1 -3
  61. package/dist/src/metadata/relationship-metadata/HasOneRelationship.d.ts.map +1 -1
  62. package/dist/src/metadata/relationship-metadata/HasOneRelationship.js +1 -3
  63. package/dist/src/metadata/relationship-metadata/OwnedByRelationship.d.ts.map +1 -1
  64. package/dist/src/metadata/relationship-metadata/OwnedByRelationship.js +1 -3
  65. package/dist/src/metadata/types.d.ts +14 -3
  66. package/dist/src/metadata/types.d.ts.map +1 -1
  67. package/dist/src/metadata/utils.js +4 -4
  68. package/dist/src/operations/Create/Create.js +3 -5
  69. package/dist/src/operations/Delete/Delete.d.ts.map +1 -1
  70. package/dist/src/operations/Delete/Delete.js +3 -2
  71. package/dist/src/operations/FindById/FindById.d.ts.map +1 -1
  72. package/dist/src/operations/FindById/FindById.js +4 -4
  73. package/dist/src/operations/Query/Query.d.ts.map +1 -1
  74. package/dist/src/operations/Query/Query.js +2 -1
  75. package/dist/src/operations/Update/Update.d.ts +6 -1
  76. package/dist/src/operations/Update/Update.d.ts.map +1 -1
  77. package/dist/src/operations/Update/Update.js +41 -17
  78. package/dist/src/operations/Update/types.d.ts +14 -4
  79. package/dist/src/operations/Update/types.d.ts.map +1 -1
  80. package/dist/src/operations/types.d.ts +1 -1
  81. package/dist/src/operations/types.d.ts.map +1 -1
  82. package/dist/src/operations/utils/expressionBuilder.d.ts +4 -3
  83. package/dist/src/operations/utils/expressionBuilder.d.ts.map +1 -1
  84. package/dist/src/operations/utils/expressionBuilder.js +66 -2
  85. package/dist/src/operations/utils/flattenObjectForUpdate.d.ts +19 -0
  86. package/dist/src/operations/utils/flattenObjectForUpdate.d.ts.map +1 -0
  87. package/dist/src/operations/utils/flattenObjectForUpdate.js +45 -0
  88. package/dist/src/operations/utils/index.d.ts +2 -0
  89. package/dist/src/operations/utils/index.d.ts.map +1 -1
  90. package/dist/src/operations/utils/index.js +2 -0
  91. package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts +8 -0
  92. package/dist/src/operations/utils/mergePartialObjectAttributes.d.ts.map +1 -0
  93. package/dist/src/operations/utils/mergePartialObjectAttributes.js +60 -0
  94. package/dist/src/operations/utils/types.d.ts +16 -0
  95. package/dist/src/operations/utils/types.d.ts.map +1 -1
  96. package/dist/src/operations/utils/utils.d.ts +2 -2
  97. package/dist/src/operations/utils/utils.d.ts.map +1 -1
  98. package/dist/src/query-utils/QueryBuilder.d.ts.map +1 -1
  99. package/dist/src/query-utils/QueryBuilder.js +11 -7
  100. package/dist/src/query-utils/types.d.ts.map +1 -1
  101. package/dist/src/relationships/JoinTable.d.ts.map +1 -1
  102. package/dist/src/relationships/JoinTable.js +4 -3
  103. package/dist/src/utils.d.ts +4 -4
  104. package/dist/src/utils.d.ts.map +1 -1
  105. package/dist/src/utils.js +13 -11
  106. package/package.json +10 -12
@@ -1,11 +1,17 @@
1
1
  import type DynaRecord from "../../DynaRecord";
2
- import type { AttributeDecoratorContext, AttributeOptions } from "../types";
2
+ import type { AttributeDecoratorContext, NonNullAttributeOptions } from "../types";
3
3
  import type { ObjectSchema, InferObjectSchema } from "./types";
4
4
  /**
5
5
  * Options for the `@ObjectAttribute` decorator.
6
- * Extends {@link AttributeOptions} with a required `schema` field describing the object shape.
6
+ * Extends {@link NonNullAttributeOptions} with a required `schema` field describing the object shape.
7
+ *
8
+ * **Object attributes are never nullable.** DynamoDB cannot update nested document paths
9
+ * (e.g. `address.geo.lat`) if the parent object does not exist, which causes:
10
+ * `ValidationException: The document path provided in the update expression is invalid for update`.
11
+ * To avoid this, `@ObjectAttribute` fields always exist as at least an empty object `{}`.
7
12
  *
8
13
  * The schema supports all {@link FieldDef} types: primitives, enums, nested objects, and arrays.
14
+ * Non-object fields within the schema may still be nullable.
9
15
  *
10
16
  * @template S The specific ObjectSchema type used for type inference
11
17
  *
@@ -13,12 +19,9 @@ import type { ObjectSchema, InferObjectSchema } from "./types";
13
19
  * ```typescript
14
20
  * @ObjectAttribute({ alias: "Address", schema: addressSchema })
15
21
  * public readonly address: InferObjectSchema<typeof addressSchema>;
16
- *
17
- * @ObjectAttribute({ alias: "Meta", schema: metaSchema, nullable: true })
18
- * public readonly meta?: InferObjectSchema<typeof metaSchema>;
19
22
  * ```
20
23
  */
21
- export interface ObjectAttributeOptions<S extends ObjectSchema> extends AttributeOptions {
24
+ export interface ObjectAttributeOptions<S extends ObjectSchema> extends NonNullAttributeOptions {
22
25
  /**
23
26
  * The {@link ObjectSchema} defining the structure of the object attribute.
24
27
  *
@@ -32,21 +35,28 @@ export interface ObjectAttributeOptions<S extends ObjectSchema> extends Attribut
32
35
  * Objects are stored as native DynamoDB Map types and validated at runtime against the provided schema.
33
36
  * The TypeScript type is inferred from the schema using {@link InferObjectSchema}.
34
37
  *
35
- * Can be set to nullable via decorator props.
38
+ * **Object attributes are never nullable.** DynamoDB cannot update nested document paths
39
+ * (e.g. `address.geo.lat`) if the parent object does not exist, which causes:
40
+ * `ValidationException: The document path provided in the update expression is invalid for update`.
41
+ * To prevent this, `@ObjectAttribute` fields must always exist as at least an empty object `{}`.
42
+ * Similarly, nested object fields within the schema cannot be nullable.
36
43
  *
37
44
  * **Supported field types within the schema:**
38
- * - `"string"`, `"number"`, `"boolean"` — primitives
39
- * - `"enum"` — string literal unions, validated at runtime via `z.enum()`
40
- * - `"object"` — nested objects (arbitrarily deep)
41
- * - `"array"` — lists of any field type
45
+ * - `"string"`, `"number"`, `"boolean"` — primitives (support `nullable: true`)
46
+ * - `"enum"` — string literal unions (support `nullable: true`)
47
+ * - `"date"` — dates stored as ISO strings (support `nullable: true`)
48
+ * - `"object"` — nested objects, arbitrarily deep (**never nullable**)
49
+ * - `"array"` — lists of any field type (support `nullable: true`, full replacement on update)
42
50
  *
43
- * All field types support `nullable: true` to remove them
51
+ * Objects within arrays are not subject to the document path limitation because arrays
52
+ * use full replacement on update. Partial updates of individual objects within arrays
53
+ * are not supported.
44
54
  *
45
55
  * @template T The class type that the decorator is applied to
46
56
  * @template S The ObjectSchema type used for validation and type inference
47
57
  * @template K The inferred TypeScript type from the schema
48
58
  * @template P The decorator options type
49
- * @param props An {@link ObjectAttributeOptions} object providing the `schema` and optional `alias` and `nullable` configuration.
59
+ * @param props An {@link ObjectAttributeOptions} object providing the `schema` and optional `alias`.
50
60
  * @returns A class field decorator function
51
61
  *
52
62
  * Usage example:
@@ -69,9 +79,6 @@ export interface ObjectAttributeOptions<S extends ObjectSchema> extends Attribut
69
79
  * class MyEntity extends MyTable {
70
80
  * @ObjectAttribute({ alias: 'Address', schema: addressSchema })
71
81
  * public address: InferObjectSchema<typeof addressSchema>;
72
- *
73
- * @ObjectAttribute({ alias: 'Meta', schema: metaSchema, nullable: true })
74
- * public meta?: InferObjectSchema<typeof metaSchema>;
75
82
  * }
76
83
  *
77
84
  * // TypeScript infers:
@@ -79,6 +86,22 @@ export interface ObjectAttributeOptions<S extends ObjectSchema> extends Attribut
79
86
  * // address.geo.accuracy → "precise" | "approximate"
80
87
  * ```
81
88
  *
89
+ * **Partial updates:** When updating an entity, `@ObjectAttribute` fields support partial
90
+ * updates — only the fields you provide are modified, omitted fields are preserved. Under
91
+ * the hood, dyna-record generates DynamoDB document path expressions
92
+ * (e.g., `SET #address.#street = :address_street`) instead of replacing the entire map.
93
+ * Nested objects are recursively merged. Arrays within objects are full replacement.
94
+ * Setting a nullable field within an object to `null` generates a `REMOVE` expression
95
+ * for that specific field.
96
+ *
97
+ * ```typescript
98
+ * // Only updates street — city, zip, geo are preserved
99
+ * await MyEntity.update("id", { address: { street: "456 Oak Ave" } });
100
+ *
101
+ * // Remove a nullable field within the object
102
+ * await MyEntity.update("id", { address: { zip: null } });
103
+ * ```
104
+ *
82
105
  * Object attributes support filtering in queries using dot-path notation for nested fields
83
106
  * and the {@link ContainsFilter | $contains} operator for List membership checks.
84
107
  *
@@ -92,6 +115,6 @@ export interface ObjectAttributeOptions<S extends ObjectSchema> extends Attribut
92
115
  * });
93
116
  * ```
94
117
  */
95
- declare function ObjectAttribute<T extends DynaRecord, const S extends ObjectSchema, P extends ObjectAttributeOptions<S>>(props: P): (_value: undefined, context: AttributeDecoratorContext<T, InferObjectSchema<S>, P>) => void;
118
+ declare function ObjectAttribute<T extends DynaRecord, const S extends ObjectSchema>(props: ObjectAttributeOptions<S>): (_value: undefined, context: AttributeDecoratorContext<T, InferObjectSchema<S>, ObjectAttributeOptions<S>>) => void;
96
119
  export default ObjectAttribute;
97
120
  //# sourceMappingURL=ObjectAttribute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/ObjectAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAY,MAAM,SAAS,CAAC;AAGzE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,YAAY,CAC5D,SAAQ,gBAAgB;IACxB;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC;CACX;AAyED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,iBAAS,eAAe,CACtB,CAAC,SAAS,UAAU,EACpB,KAAK,CAAC,CAAC,SAAS,YAAY,EAC5B,CAAC,SAAS,sBAAsB,CAAC,CAAC,CAAC,EACnC,KAAK,EAAE,CAAC,YAEE,SAAS,WACR,yBAAyB,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAkBjE;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ObjectAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/ObjectAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAY,MAAM,SAAS,CAAC;AAGzE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,YAAY,CAC5D,SAAQ,uBAAuB;IAC/B;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC;CACX;AA6GD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,iBAAS,eAAe,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,CAAC,CAAC,SAAS,YAAY,EACzE,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,YAGtB,SAAS,WACR,yBAAyB,CAChC,CAAC,EACD,iBAAiB,CAAC,CAAC,CAAC,EACpB,sBAAsB,CAAC,CAAC,CAAC,CAC1B,UAmBJ;AAED,eAAe,eAAe,CAAC"}
@@ -6,6 +6,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const zod_1 = require("zod");
7
7
  const metadata_1 = __importDefault(require("../../metadata"));
8
8
  const serializers_1 = require("./serializers");
9
+ /**
10
+ * Converts an {@link ObjectSchema} to a partial Zod schema for update validation.
11
+ *
12
+ * All fields become optional (can be omitted). Nullable fields accept `null`.
13
+ * Non-nullable fields reject `null`. Nested objects are recursively partial.
14
+ * Array items validate normally (full replacement).
15
+ *
16
+ * @param schema The object schema definition
17
+ * @returns A ZodType that validates partial objects matching the schema
18
+ */
19
+ function objectSchemaToZodPartial(schema) {
20
+ const shape = {};
21
+ for (const [key, fieldDef] of Object.entries(schema)) {
22
+ shape[key] = fieldDefToZodPartial(fieldDef);
23
+ }
24
+ return zod_1.z.object(shape).partial();
25
+ }
26
+ /**
27
+ * Converts a single {@link FieldDef} to the corresponding partial Zod type.
28
+ * Nested objects use partial schemas; all other types use the standard schema.
29
+ * Object fields are never nullable — they always exist as at least `{}`.
30
+ */
31
+ function fieldDefToZodPartial(fieldDef) {
32
+ if (fieldDef.type === "object") {
33
+ return objectSchemaToZodPartial(fieldDef.fields);
34
+ }
35
+ // For non-object fields, use the standard schema (includes nullable wrapping)
36
+ return fieldDefToZod(fieldDef);
37
+ }
9
38
  /**
10
39
  * Converts an {@link ObjectSchema} to a Zod schema for runtime validation.
11
40
  *
@@ -23,24 +52,26 @@ function objectSchemaToZod(schema) {
23
52
  * Converts a single {@link FieldDef} to the corresponding Zod type for runtime validation.
24
53
  *
25
54
  * Handles all field types:
26
- * - `"object"` → recursively builds a `z.object()` via {@link objectSchemaToZod}
55
+ * - `"object"` → recursively builds a `z.object()` via {@link objectSchemaToZod}.
56
+ * Object fields are never nullable — DynamoDB requires them to exist for document path updates.
27
57
  * - `"array"` → `z.array()` wrapping a recursive call for the `items` type
28
58
  * - `"string"` → `z.string()`
29
59
  * - `"number"` → `z.number()`
30
60
  * - `"boolean"` → `z.boolean()`
31
61
  * - `"enum"` → `z.enum(values)` for string literal validation
32
62
  *
33
- * When `nullable` is `true`, wraps the type with `.optional().nullable()`.
63
+ * When `nullable` is `true` (non-object fields only), wraps the type with `.optional().nullable()`.
34
64
  *
35
65
  * @param fieldDef The field definition to convert
36
66
  * @returns A ZodType that validates values matching the field definition
37
67
  */
38
68
  function fieldDefToZod(fieldDef) {
69
+ // Object fields return early — they are never nullable
70
+ if (fieldDef.type === "object") {
71
+ return objectSchemaToZod(fieldDef.fields);
72
+ }
39
73
  let zodType;
40
74
  switch (fieldDef.type) {
41
- case "object":
42
- zodType = objectSchemaToZod(fieldDef.fields);
43
- break;
44
75
  case "array":
45
76
  zodType = zod_1.z.array(fieldDefToZod(fieldDef.items));
46
77
  break;
@@ -60,7 +91,6 @@ function fieldDefToZod(fieldDef) {
60
91
  zodType = zod_1.z.enum(fieldDef.values);
61
92
  break;
62
93
  default: {
63
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
64
94
  const _exhaustiveCheck = fieldDef;
65
95
  throw new Error("Unsupported field type");
66
96
  }
@@ -76,21 +106,28 @@ function fieldDefToZod(fieldDef) {
76
106
  * Objects are stored as native DynamoDB Map types and validated at runtime against the provided schema.
77
107
  * The TypeScript type is inferred from the schema using {@link InferObjectSchema}.
78
108
  *
79
- * Can be set to nullable via decorator props.
109
+ * **Object attributes are never nullable.** DynamoDB cannot update nested document paths
110
+ * (e.g. `address.geo.lat`) if the parent object does not exist, which causes:
111
+ * `ValidationException: The document path provided in the update expression is invalid for update`.
112
+ * To prevent this, `@ObjectAttribute` fields must always exist as at least an empty object `{}`.
113
+ * Similarly, nested object fields within the schema cannot be nullable.
80
114
  *
81
115
  * **Supported field types within the schema:**
82
- * - `"string"`, `"number"`, `"boolean"` — primitives
83
- * - `"enum"` — string literal unions, validated at runtime via `z.enum()`
84
- * - `"object"` — nested objects (arbitrarily deep)
85
- * - `"array"` — lists of any field type
116
+ * - `"string"`, `"number"`, `"boolean"` — primitives (support `nullable: true`)
117
+ * - `"enum"` — string literal unions (support `nullable: true`)
118
+ * - `"date"` — dates stored as ISO strings (support `nullable: true`)
119
+ * - `"object"` — nested objects, arbitrarily deep (**never nullable**)
120
+ * - `"array"` — lists of any field type (support `nullable: true`, full replacement on update)
86
121
  *
87
- * All field types support `nullable: true` to remove them
122
+ * Objects within arrays are not subject to the document path limitation because arrays
123
+ * use full replacement on update. Partial updates of individual objects within arrays
124
+ * are not supported.
88
125
  *
89
126
  * @template T The class type that the decorator is applied to
90
127
  * @template S The ObjectSchema type used for validation and type inference
91
128
  * @template K The inferred TypeScript type from the schema
92
129
  * @template P The decorator options type
93
- * @param props An {@link ObjectAttributeOptions} object providing the `schema` and optional `alias` and `nullable` configuration.
130
+ * @param props An {@link ObjectAttributeOptions} object providing the `schema` and optional `alias`.
94
131
  * @returns A class field decorator function
95
132
  *
96
133
  * Usage example:
@@ -113,9 +150,6 @@ function fieldDefToZod(fieldDef) {
113
150
  * class MyEntity extends MyTable {
114
151
  * @ObjectAttribute({ alias: 'Address', schema: addressSchema })
115
152
  * public address: InferObjectSchema<typeof addressSchema>;
116
- *
117
- * @ObjectAttribute({ alias: 'Meta', schema: metaSchema, nullable: true })
118
- * public meta?: InferObjectSchema<typeof metaSchema>;
119
153
  * }
120
154
  *
121
155
  * // TypeScript infers:
@@ -123,6 +157,22 @@ function fieldDefToZod(fieldDef) {
123
157
  * // address.geo.accuracy → "precise" | "approximate"
124
158
  * ```
125
159
  *
160
+ * **Partial updates:** When updating an entity, `@ObjectAttribute` fields support partial
161
+ * updates — only the fields you provide are modified, omitted fields are preserved. Under
162
+ * the hood, dyna-record generates DynamoDB document path expressions
163
+ * (e.g., `SET #address.#street = :address_street`) instead of replacing the entire map.
164
+ * Nested objects are recursively merged. Arrays within objects are full replacement.
165
+ * Setting a nullable field within an object to `null` generates a `REMOVE` expression
166
+ * for that specific field.
167
+ *
168
+ * ```typescript
169
+ * // Only updates street — city, zip, geo are preserved
170
+ * await MyEntity.update("id", { address: { street: "456 Oak Ave" } });
171
+ *
172
+ * // Remove a nullable field within the object
173
+ * await MyEntity.update("id", { address: { zip: null } });
174
+ * ```
175
+ *
126
176
  * Object attributes support filtering in queries using dot-path notation for nested fields
127
177
  * and the {@link ContainsFilter | $contains} operator for List membership checks.
128
178
  *
@@ -138,20 +188,21 @@ function fieldDefToZod(fieldDef) {
138
188
  */
139
189
  function ObjectAttribute(props) {
140
190
  return function (_value, context) {
141
- if (context.kind === "field") {
142
- context.addInitializer(function () {
143
- const { schema, ...restProps } = props;
144
- const zodSchema = objectSchemaToZod(schema);
145
- const serializers = (0, serializers_1.createObjectSerializer)(schema);
146
- metadata_1.default.addEntityAttribute(this.constructor.name, {
147
- attributeName: context.name.toString(),
148
- nullable: props?.nullable,
149
- type: zodSchema,
150
- serializers,
151
- ...restProps
152
- });
191
+ context.addInitializer(function () {
192
+ const { schema, ...restProps } = props;
193
+ const zodSchema = objectSchemaToZod(schema);
194
+ const partialZodSchema = objectSchemaToZodPartial(schema);
195
+ const serializers = (0, serializers_1.createObjectSerializer)(schema);
196
+ metadata_1.default.addEntityAttribute(this.constructor.name, {
197
+ attributeName: context.name.toString(),
198
+ type: zodSchema,
199
+ partialType: partialZodSchema,
200
+ serializers,
201
+ nullable: false,
202
+ objectSchema: schema,
203
+ ...restProps
153
204
  });
154
- }
205
+ });
155
206
  };
156
207
  }
157
208
  exports.default = ObjectAttribute;
@@ -1 +1 @@
1
- {"version":3,"file":"PartitionKeyAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/PartitionKeyAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,qBAAqB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,YAAY,EACzE,KAAK,CAAC,EAAE,uBAAuB,YAGrB,SAAS,WACR,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,UAY5C;AAED,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"PartitionKeyAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/PartitionKeyAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,qBAAqB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,YAAY,EACzE,KAAK,CAAC,EAAE,uBAAuB,YAGrB,SAAS,WACR,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,UAU5C;AAED,eAAe,qBAAqB,CAAC"}
@@ -25,15 +25,13 @@ const metadata_1 = __importDefault(require("../../metadata"));
25
25
  */
26
26
  function PartitionKeyAttribute(props) {
27
27
  return function (_value, context) {
28
- if (context.kind === "field") {
29
- context.addInitializer(function () {
30
- metadata_1.default.addPartitionKeyAttribute(this, {
31
- attributeName: context.name.toString(),
32
- type: zod_1.z.string(),
33
- ...props
34
- });
28
+ context.addInitializer(function () {
29
+ metadata_1.default.addPartitionKeyAttribute(this, {
30
+ attributeName: context.name.toString(),
31
+ type: zod_1.z.string(),
32
+ ...props
35
33
  });
36
- }
34
+ });
37
35
  };
38
36
  }
39
37
  exports.default = PartitionKeyAttribute;
@@ -1 +1 @@
1
- {"version":3,"file":"SortKeyAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/SortKeyAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,OAAO,EAC/D,KAAK,CAAC,EAAE,uBAAuB,YAGrB,SAAS,WACR,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,UAY5C;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SortKeyAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/SortKeyAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,gBAAgB,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,OAAO,EAC/D,KAAK,CAAC,EAAE,uBAAuB,YAGrB,SAAS,WACR,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,UAU5C;AAED,eAAe,gBAAgB,CAAC"}
@@ -25,15 +25,13 @@ const metadata_1 = __importDefault(require("../../metadata"));
25
25
  */
26
26
  function SortKeyAttribute(props) {
27
27
  return function (_value, context) {
28
- if (context.kind === "field") {
29
- context.addInitializer(function () {
30
- metadata_1.default.addSortKeyAttribute(this, {
31
- attributeName: context.name.toString(),
32
- type: zod_1.z.string(),
33
- ...props
34
- });
28
+ context.addInitializer(function () {
29
+ metadata_1.default.addSortKeyAttribute(this, {
30
+ attributeName: context.name.toString(),
31
+ type: zod_1.z.string(),
32
+ ...props
35
33
  });
36
- }
34
+ });
37
35
  };
38
36
  }
39
37
  exports.default = SortKeyAttribute;
@@ -1 +1 @@
1
- {"version":3,"file":"StringAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/StringAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACd,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,iBAAS,eAAe,CACtB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,gBAAgB,EAC1B,KAAK,CAAC,EAAE,CAAC,YAEC,SAAS,WACR,yBAAyB,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAa7D;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"StringAttribute.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/StringAttribute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACd,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,iBAAS,eAAe,CACtB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,gBAAgB,EAC1B,KAAK,CAAC,EAAE,CAAC,YAEC,SAAS,WACR,yBAAyB,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAW7D;AAED,eAAe,eAAe,CAAC"}
@@ -30,16 +30,14 @@ const metadata_1 = __importDefault(require("../../metadata"));
30
30
  */
31
31
  function StringAttribute(props) {
32
32
  return function (_value, context) {
33
- if (context.kind === "field") {
34
- context.addInitializer(function () {
35
- metadata_1.default.addEntityAttribute(this.constructor.name, {
36
- attributeName: context.name.toString(),
37
- nullable: props?.nullable,
38
- type: zod_1.z.string(),
39
- ...props
40
- });
33
+ context.addInitializer(function () {
34
+ metadata_1.default.addEntityAttribute(this.constructor.name, {
35
+ attributeName: context.name.toString(),
36
+ nullable: props?.nullable,
37
+ type: zod_1.z.string(),
38
+ ...props
41
39
  });
42
- }
40
+ });
43
41
  };
44
42
  }
45
43
  exports.default = StringAttribute;
@@ -1,5 +1,5 @@
1
1
  import type { NativeAttributeValue } from "@aws-sdk/util-dynamodb";
2
- import type { ObjectSchema } from "./types";
2
+ import type { ObjectSchema, FieldDef } from "./types";
3
3
  import type { Serializers } from "../../metadata/types";
4
4
  /**
5
5
  * Provides serialization and deserialization functions for date attributes when interfacing with a DynamoDB table, enabling the conversion between the table's string-based date representation and JavaScript's `Date` object. DynamoDb dos not support Date types naturally, this utility allows for Date attributes to be serialized to an entity and stored as ISO strings in Dynamo.
@@ -9,8 +9,8 @@ import type { Serializers } from "../../metadata/types";
9
9
  *
10
10
  */
11
11
  export declare const dateSerializer: {
12
- toEntityAttribute: (val: NativeAttributeValue) => any;
13
- toTableAttribute: (val?: Date) => string | undefined;
12
+ toEntityAttribute: (val: NativeAttributeValue) => unknown;
13
+ toTableAttribute: (val: unknown) => string | undefined;
14
14
  };
15
15
  /**
16
16
  * Recursively walks an {@link ObjectSchema} and converts the entity value to its
@@ -29,6 +29,7 @@ export declare const dateSerializer: {
29
29
  * @returns A new object suitable for DynamoDB storage
30
30
  */
31
31
  export declare function objectToTableItem(schema: ObjectSchema, value: Record<string, unknown>): Record<string, unknown>;
32
+ export declare function convertFieldToTableItem(fieldDef: FieldDef, val: unknown): unknown;
32
33
  /**
33
34
  * Recursively walks an {@link ObjectSchema} and converts a DynamoDB table item
34
35
  * back to its entity representation.
@@ -1 +1 @@
1
- {"version":3,"file":"serializers.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/serializers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;6BACA,oBAAoB;6BAMpB,IAAI;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAiBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAiBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CAOxE"}
1
+ {"version":3,"file":"serializers.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/serializers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;6BACA,oBAAoB,KAAG,OAAO;4BAM/B,OAAO;CAEhC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,OAAO,GACX,OAAO,CAaT;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAiBD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CAOxE"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.dateSerializer = void 0;
4
4
  exports.objectToTableItem = objectToTableItem;
5
+ exports.convertFieldToTableItem = convertFieldToTableItem;
5
6
  exports.tableItemToObject = tableItemToObject;
6
7
  exports.createObjectSerializer = createObjectSerializer;
7
8
  /**
@@ -18,7 +19,7 @@ exports.dateSerializer = {
18
19
  }
19
20
  return val;
20
21
  },
21
- toTableAttribute: (val) => val?.toISOString() ?? undefined
22
+ toTableAttribute: (val) => val instanceof Date ? val.toISOString() : undefined
22
23
  };
23
24
  /**
24
25
  * Recursively walks an {@link ObjectSchema} and converts the entity value to its
@@ -45,6 +45,15 @@ export interface PrimitiveFieldDef {
45
45
  *
46
46
  * The `fields` property is itself an {@link ObjectSchema}, enabling arbitrarily deep nesting.
47
47
  *
48
+ * **Object fields are never nullable.** DynamoDB cannot update nested document paths
49
+ * (e.g. `address.geo.lat`) if an intermediate object does not exist, which causes:
50
+ * `ValidationException: The document path provided in the update expression is invalid for update`.
51
+ * To avoid this, object-type fields always exist as at least an empty object `{}`.
52
+ * Non-object fields within the object may still be nullable.
53
+ *
54
+ * Objects within arrays are not subject to this limitation because arrays use full
55
+ * replacement on update rather than document path expressions.
56
+ *
48
57
  * @example
49
58
  * ```typescript
50
59
  * const schema = {
@@ -52,7 +61,8 @@ export interface PrimitiveFieldDef {
52
61
  * type: "object",
53
62
  * fields: {
54
63
  * lat: { type: "number" },
55
- * lng: { type: "number" }
64
+ * lng: { type: "number" },
65
+ * notes: { type: "string", nullable: true }
56
66
  * }
57
67
  * }
58
68
  * } as const satisfies ObjectSchema;
@@ -63,8 +73,6 @@ export interface ObjectFieldDef {
63
73
  type: "object";
64
74
  /** The nested {@link ObjectSchema} describing the object's shape. */
65
75
  fields: ObjectSchema;
66
- /** When `true`, the field becomes optional. */
67
- nullable?: boolean;
68
76
  }
69
77
  /**
70
78
  * A schema field definition for an array/list type.
@@ -214,9 +222,11 @@ export type InferFieldDef<F extends FieldDef> = F extends ArrayFieldDef ? Array<
214
222
  *
215
223
  * - Primitive fields map to their TS equivalents via {@link PrimitiveTypeMap}
216
224
  * - Enum fields become a union of their `values` (`values[number]`)
217
- * - Nested object fields recurse through `InferObjectSchema`
225
+ * - Nested object fields recurse through `InferObjectSchema` — always required (never nullable)
218
226
  * - Array fields become `T[]` where `T` is inferred from `items`
219
227
  * - Fields with `nullable: true` become optional (`T | undefined`)
228
+ * - Object fields are always required because DynamoDB cannot update nested document paths
229
+ * if an intermediate object does not exist
220
230
  *
221
231
  * @example
222
232
  * ```typescript
@@ -239,8 +249,12 @@ export type InferFieldDef<F extends FieldDef> = F extends ArrayFieldDef ? Array<
239
249
  * ```
240
250
  */
241
251
  export type InferObjectSchema<S extends ObjectSchema> = {
242
- [K in keyof S as S[K]["nullable"] extends true ? never : K]: InferFieldDef<S[K]>;
252
+ [K in keyof S as S[K] extends {
253
+ nullable: true;
254
+ } ? never : K]: InferFieldDef<S[K]>;
243
255
  } & {
244
- [K in keyof S as S[K]["nullable"] extends true ? K : never]?: InferFieldDef<S[K]>;
256
+ [K in keyof S as S[K] extends {
257
+ nullable: true;
258
+ } ? K : never]?: InferFieldDef<S[K]>;
245
259
  };
246
260
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,gBAAgB,CAAC;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,IAAI,EAAE,kBAAkB,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,EAAE,QAAQ,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,YAAY,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,IAAI,EAAE,OAAO,CAAC;IACd,oEAAoE;IACpE,KAAK,EAAE,QAAQ,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACvC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,QAAQ,GAChB,iBAAiB,GACjB,YAAY,GACZ,cAAc,GACd,aAAa,GACb,YAAY,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,QAAQ,IAAI,CAAC,SAAS,aAAa,GACnE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAChC,CAAC,SAAS,cAAc,GACtB,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAC9B,CAAC,SAAS,YAAY,GACpB,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GACnB,CAAC,SAAS,iBAAiB,GACzB,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAC3B,KAAK,CAAC;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,YAAY,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,aAAa,CACxE,CAAC,CAAC,CAAC,CAAC,CACL;CACF,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,aAAa,CACzE,CAAC,CAAC,CAAC,CAAC,CACL;CACF,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/decorators/attributes/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,gBAAgB,CAAC;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,IAAI,EAAE,kBAAkB,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,EAAE,QAAQ,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,IAAI,EAAE,OAAO,CAAC;IACd,oEAAoE;IACpE,KAAK,EAAE,QAAQ,CAAC;IAChB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACvC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,QAAQ,GAChB,iBAAiB,GACjB,YAAY,GACZ,cAAc,GACd,aAAa,GACb,YAAY,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,QAAQ,IAAI,CAAC,SAAS,aAAa,GACnE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAChC,CAAC,SAAS,cAAc,GACtB,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAC9B,CAAC,SAAS,YAAY,GACpB,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GACnB,CAAC,SAAS,iBAAiB,GACzB,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAC3B,KAAK,CAAC;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,YAAY,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,KAAK,GAAG,CAAC,GAAG,aAAa,CAC1E,CAAC,CAAC,CAAC,CAAC,CACL;CACF,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,aAAa,CAC3E,CAAC,CAAC,CAAC,CAAC,CACL;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BelongsTo.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/BelongsTo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,iBAAS,SAAS,CAChB,MAAM,SAAS,UAAU,EACzB,EAAE,SAAS,sBAAsB,CAAC,MAAM,CAAC,EAEzC,SAAS,EAAE,MAAM,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EACzD,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,YAGvB,SAAS,WACR,0BAA0B,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,UAa1E;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"BelongsTo.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/BelongsTo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,iBAAS,SAAS,CAChB,MAAM,SAAS,UAAU,EACzB,EAAE,SAAS,sBAAsB,CAAC,MAAM,CAAC,EAEzC,SAAS,EAAE,MAAM,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EACzD,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,YAGvB,SAAS,WACR,0BAA0B,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,UAW1E;AAED,eAAe,SAAS,CAAC"}
@@ -34,16 +34,14 @@ const metadata_1 = __importDefault(require("../../metadata"));
34
34
  */
35
35
  function BelongsTo(getTarget, props) {
36
36
  return function (_value, context) {
37
- if (context.kind === "field") {
38
- context.addInitializer(function () {
39
- metadata_1.default.addEntityRelationship(this.constructor.name, {
40
- type: "BelongsTo",
41
- propertyName: context.name,
42
- target: getTarget(),
43
- foreignKey: props.foreignKey
44
- });
37
+ context.addInitializer(function () {
38
+ metadata_1.default.addEntityRelationship(this.constructor.name, {
39
+ type: "BelongsTo",
40
+ propertyName: context.name,
41
+ target: getTarget(),
42
+ foreignKey: props.foreignKey
45
43
  });
46
- }
44
+ });
47
45
  };
48
46
  }
49
47
  exports.default = BelongsTo;
@@ -1 +1 @@
1
- {"version":3,"file":"HasAndBelongsToMany.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/HasAndBelongsToMany.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI;KACpB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK;CAC7C,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;GAGG;AACH,KAAK,eAAe,CAAC,CAAC,SAAS,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,MAAM;IACxE;;;;OAIG;IACH,SAAS,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,CAAC;CACrB,CAAC;AAEF,UAAU,wBAAwB,CAChC,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACzB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,iBAAS,mBAAmB,CAC1B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACzB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAEzB,SAAS,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,YAE3B,SAAS,WAAW,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAoBvE;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"HasAndBelongsToMany.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/HasAndBelongsToMany.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI;KACpB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK;CAC7C,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX;;;GAGG;AACH,KAAK,eAAe,CAAC,CAAC,SAAS,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,MAAM;IACxE;;;;OAIG;IAEH,SAAS,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,CAAC;CACrB,CAAC;AAEF,UAAU,wBAAwB,CAChC,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACzB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,iBAAS,mBAAmB,CAC1B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACzB,CAAC,SAAS,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAEzB,SAAS,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,YAE3B,SAAS,WAAW,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAkBvE;AAED,eAAe,mBAAmB,CAAC"}
@@ -48,22 +48,20 @@ const metadata_1 = __importDefault(require("../../metadata"));
48
48
  */
49
49
  function HasAndBelongsToMany(getTarget, props) {
50
50
  return (_value, context) => {
51
- if (context.kind === "field") {
52
- context.addInitializer(function () {
53
- const target = getTarget();
54
- const { joinTable, foreignKey } = props.through();
55
- metadata_1.default.addEntityRelationship(this.constructor.name, {
56
- type: "HasAndBelongsToMany",
57
- propertyName: context.name,
58
- target,
59
- joinTableName: joinTable.name
60
- });
61
- metadata_1.default.addJoinTable(joinTable.name, {
62
- entity: target,
63
- foreignKey: foreignKey
64
- });
51
+ context.addInitializer(function () {
52
+ const target = getTarget();
53
+ const { joinTable, foreignKey } = props.through();
54
+ metadata_1.default.addEntityRelationship(this.constructor.name, {
55
+ type: "HasAndBelongsToMany",
56
+ propertyName: context.name,
57
+ target,
58
+ joinTableName: joinTable.name
65
59
  });
66
- }
60
+ metadata_1.default.addJoinTable(joinTable.name, {
61
+ entity: target,
62
+ foreignKey: foreignKey
63
+ });
64
+ });
67
65
  };
68
66
  }
69
67
  exports.default = HasAndBelongsToMany;
@@ -1 +1 @@
1
- {"version":3,"file":"HasMany.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/HasMany.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD,UAAU,YAAY,CAAC,CAAC,SAAS,UAAU;IACzC,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,OAAO,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,UAAU,EACzD,SAAS,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,YAEN,SAAS,WAAW,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAwBvE;AAED,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"HasMany.d.ts","sourceRoot":"","sources":["../../../../src/decorators/relationships/HasMany.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD,UAAU,YAAY,CAAC,CAAC,SAAS,UAAU;IACzC,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,OAAO,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,UAAU,EACzD,SAAS,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,YAEN,SAAS,WAAW,0BAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAsBvE;AAED,eAAe,OAAO,CAAC"}