electrodb 1.7.2 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -159,4 +159,15 @@ All notable changes to this project will be documented in this file. Breaking ch
159
159
  ## [1.7.2] - 2022-03-27
160
160
  ### Fixed
161
161
  - Fixed issue#111, `update` method specific query option typing no longer lost when using a `where` method in a query chain
162
- - Fixing incorrect typing for exposed `UpdateEntityItem` type. Exported type was missing composite key attributes
162
+ - Fixing incorrect typing for exposed `UpdateEntityItem` type. Exported type was missing composite key attributes
163
+
164
+ ## [1.8.0] - 2022-03-28
165
+ ### Added
166
+ - Expected typings for the injected v2 client now include methods for `transactWrite` and `transactGet`
167
+ ### Changed
168
+ - Map attributes will now always resolve to least an empty object on a `create` and `put` methods (instead of just the root map)
169
+ - In the past, default values for property attributes on maps only resolves when a user provided an object to place the values on. Now default values within maps attributes will now always resolve onto the object on `create` and `put` methods.
170
+
171
+ ## [1.8.1] - 2022-03-29
172
+ ### Fixed
173
+ - Solidifying default application methodology: default values for nested properties will be applied up until an undefined default occurs or default callback returns undefined
package/README.md CHANGED
@@ -459,7 +459,7 @@ const EmployeesModel = {
459
459
  attributes: {
460
460
  employee: {
461
461
  type: "string",
462
- default: () => uuidv4(),
462
+ default: () => uuid(),
463
463
  },
464
464
  firstName: {
465
465
  type: "string",
@@ -686,9 +686,9 @@ attributes: {
686
686
  Property | Type | Required | Types | Description
687
687
  ------------ | :--------------------------------------------------------: | :------: | :-------: | -----------
688
688
  `type` | `string`, `ReadonlyArray<string>`, `string[]` | yes | all | Accepts the values: `"string"`, `"number"` `"boolean"`, `"map"`, `"list"`, `"set"`, an array of strings representing a finite list of acceptable values: `["option1", "option2", "option3"]`, or `"any"` which disables value type checking on that attribute.
689
- `required` | `boolean` | no | all | Flag an attribute as required to be present when creating a record. This attribute also acts as a type of `NOT NULL` flag, preventing it from being removed directly.
689
+ `required` | `boolean` | no | all | Flag an attribute as required to be present when creating a record. This attribute also acts as a type of `NOT NULL` flag, preventing it from being removed directly. When applied to nested properties, be mindful that default map values can cause required child attributes to fail validation.
690
690
  `hidden` | `boolean` | no | all | Flag an attribute as hidden to remove the property from results before they are returned.
691
- `default` | `value`, `() => value` | no | all | Either the default value itself or a synchronous function that returns the desired value. Applied before `set` and before `required` check.
691
+ `default` | `value`, `() => value` | no | all | Either the default value itself or a synchronous function that returns the desired value. Applied before `set` and before `required` check. In the case of nested attributes, default values will apply defaults to children attributes until an undefined value is reached
692
692
  `validate` | `RegExp`, `(value: any) => void`, `(value: any) => string` | no | all | Either regex or a synchronous callback to return an error string (will result in exception using the string as the error's message), or thrown exception in the event of an error.
693
693
  `field` | `string` | no | all | The name of the attribute as it exists in DynamoDB, if named differently in the schema attributes. Defaults to the `AttributeName` as defined in the schema.
694
694
  `readOnly` | `boolean` | no | all | Prevents an attribute from being updated after the record has been created. Attributes used in the composition of the table's primary Partition Key and Sort Key are read-only by default. The one exception to `readOnly` is for properties that also use the `watch` property, read [attribute watching](#attribute-watching) for more detail.
package/index.d.ts CHANGED
@@ -1139,6 +1139,8 @@ type DocumentClient = {
1139
1139
  batchWrite: DocumentClientMethod;
1140
1140
  batchGet: DocumentClientMethod;
1141
1141
  scan: DocumentClientMethod;
1142
+ transactGet: DocumentClientMethod;
1143
+ transactWrite: DocumentClientMethod;
1142
1144
  } | {
1143
1145
  send: (command: any) => Promise<any>;
1144
1146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electrodb",
3
- "version": "1.7.2",
3
+ "version": "1.8.2",
4
4
  "description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/client.js CHANGED
@@ -9,7 +9,7 @@ const DocumentClientVersions = {
9
9
  };
10
10
 
11
11
  const v3Methods = ['send'];
12
- const v2Methods = ['get', 'put', 'update', 'delete', 'batchWrite', 'batchGet', 'scan', 'query', 'createSet'];
12
+ const v2Methods = ['get', 'put', 'update', 'delete', 'batchWrite', 'batchGet', 'scan', 'query', 'createSet', 'transactWrite', 'transactGet'];
13
13
  const supportedClientVersions = {
14
14
  [DocumentClientVersions.v2]: v2Methods,
15
15
  [DocumentClientVersions.v3]: v3Methods,
@@ -81,6 +81,18 @@ class DocumentClientV3Wrapper {
81
81
  return this.client.send(command);
82
82
  });
83
83
  }
84
+ transactWrite(params) {
85
+ return this.promiseWrap(async () => {
86
+ const command = new this.lib.TransactWriteCommand(params);
87
+ return this.client.send(command);
88
+ });
89
+ }
90
+ transactGet(params) {
91
+ return this.promiseWrap(async () => {
92
+ const command = new this.lib.TransactGetCommand(params);
93
+ return this.client.send(command);
94
+ });
95
+ }
84
96
  createSet(value) {
85
97
  if (Array.isArray(value)) {
86
98
  return new Set(value);
package/src/entity.js CHANGED
@@ -899,6 +899,18 @@ class Entity {
899
899
  return {parameters, config};
900
900
  }
901
901
 
902
+ addListeners(logger) {
903
+ this.eventManager.add(logger);
904
+ }
905
+
906
+ _addLogger(logger) {
907
+ if (validations.isFunction(logger)) {
908
+ this.addListeners(logger);
909
+ } else {
910
+ throw new e.ElectroError(e.ErrorCodes.InvalidLoggerProvided, `Logger must be of type function`);
911
+ }
912
+ }
913
+
902
914
  _getPrimaryIndexFieldNames() {
903
915
  let hasSortKey = this.model.lookup.indexHasSortKeys[TableIndex];
904
916
  let accessPattern = this.model.translations.indexes.fromIndexToAccessPattern[TableIndex];
package/src/schema.js CHANGED
@@ -575,30 +575,30 @@ class MapAttribute extends Attribute {
575
575
  }
576
576
  return v;
577
577
  }
578
- const valueType = getValueType(value);
579
- if (value === undefined) {
580
- return getValue(value);
581
- } else if (value && valueType !== "object" && Object.keys(value).length === 0) {
582
- return getValue(value);
578
+
579
+ let data = value === undefined
580
+ ? getValue(value)
581
+ : value;
582
+
583
+ const valueType = getValueType(data);
584
+
585
+ if (data === undefined) {
586
+ return data;
583
587
  } else if (valueType !== "object") {
584
588
  throw new e.ElectroAttributeValidationError(this.path, `Invalid value type at entity path: "${this.path}". Expected value to be an object to fulfill attribute type "${this.type}"`);
585
589
  }
586
590
 
587
- const data = {};
591
+ const response = {};
588
592
 
589
593
  for (const name of Object.keys(this.properties.attributes)) {
590
594
  const attribute = this.properties.attributes[name];
591
- const results = attribute.val(value[attribute.name]);
595
+ const results = attribute.val(data[attribute.name]);
592
596
  if (results !== undefined) {
593
- data[name] = results;
597
+ response[name] = results;
594
598
  }
595
599
  }
596
600
 
597
- if (Object.keys(data).length > 0) {
598
- return getValue(data);
599
- } else {
600
- return getValue();
601
- }
601
+ return response;
602
602
  }
603
603
  }
604
604
 
@@ -726,28 +726,25 @@ class ListAttribute extends Attribute {
726
726
  return v;
727
727
  }
728
728
 
729
- if (value === undefined) {
730
- return this.default();
731
- } else if (Array.isArray(value) && value.length === 0) {
732
- return value;
733
- } else if (!Array.isArray(value)) {
729
+ const data = value === undefined
730
+ ? getValue(value)
731
+ : value;
732
+
733
+ if (data === undefined) {
734
+ return data;
735
+ } else if (!Array.isArray(data)) {
734
736
  throw new e.ElectroAttributeValidationError(this.path, `Invalid value type at entity path "${this.path}. Received value of type "${getValueType(value)}", expected value of type "array"`);
735
737
  }
736
738
 
737
- const data = [];
738
-
739
- for (const v of value) {
740
- const results = this.items.val(v);
739
+ const response = [];
740
+ for (const d of data) {
741
+ const results = this.items.val(d);
741
742
  if (results !== undefined) {
742
- data.push(results);
743
+ response.push(results);
743
744
  }
744
745
  }
745
746
 
746
- if (data.filter(value => value !== undefined).length > 0) {
747
- return getValue(data);
748
- } else {
749
- return getValue();
750
- }
747
+ return response;
751
748
  }
752
749
  }
753
750
 
package/src/service.js CHANGED
@@ -191,6 +191,14 @@ class Service {
191
191
  entity._setClient(options.client);
192
192
  }
193
193
 
194
+ if (options.logger) {
195
+ entity._addLogger(options.logger);
196
+ }
197
+
198
+ if (options.listeners) {
199
+ entity.addListeners(options.listeners);
200
+ }
201
+
194
202
  if (this._modelVersion === ModelVersions.beta && this.service.version) {
195
203
  entity.model.version = this.service.version;
196
204
  }