electrodb 2.8.0 → 2.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/package.json +1 -1
- package/src/entity.js +21 -9
- package/src/schema.js +15 -14
package/package.json
CHANGED
package/src/entity.js
CHANGED
|
@@ -1886,12 +1886,20 @@ class Entity {
|
|
|
1886
1886
|
// should only happen when an attribute is changed.
|
|
1887
1887
|
const { indexKey, updatedKeys, deletedKeys = [] } = this._getUpdatedKeys(pk, sk, preparedUpdateValues, removed);
|
|
1888
1888
|
const accessPattern = this.model.translations.indexes.fromIndexToAccessPattern[TableIndex];
|
|
1889
|
-
|
|
1890
1889
|
for (const path of Object.keys(preparedUpdateValues)) {
|
|
1891
1890
|
if (modifiedAttributeNames[path] !== undefined && preparedUpdateValues[path] !== undefined) {
|
|
1892
1891
|
update.updateValue(modifiedAttributeNames[path], preparedUpdateValues[path]);
|
|
1893
1892
|
} else if (preparedUpdateValues[path] !== undefined) {
|
|
1894
|
-
|
|
1893
|
+
const attr = this.model.schema.getAttribute(path);
|
|
1894
|
+
if (attr) {
|
|
1895
|
+
// attributes might enter into this flow because they were triggered via a `watch` event and were
|
|
1896
|
+
// not supplied directly by the user. In this case we should set the field name.
|
|
1897
|
+
// TODO: This will only work with root attributes and should be refactored for nested attributes.
|
|
1898
|
+
update.set(attr.field, preparedUpdateValues[path]);
|
|
1899
|
+
} else {
|
|
1900
|
+
// this could be fields added by electro that don't apeear in the schema
|
|
1901
|
+
update.set(path, preparedUpdateValues[path]);
|
|
1902
|
+
}
|
|
1895
1903
|
}
|
|
1896
1904
|
}
|
|
1897
1905
|
|
|
@@ -1901,7 +1909,6 @@ class Entity {
|
|
|
1901
1909
|
const wasNotAlreadyModified = modifiedAttributeNames[indexKey] === undefined;
|
|
1902
1910
|
if (isNotTablePK && isNotTableSK && wasNotAlreadyModified) {
|
|
1903
1911
|
update.set(indexKey, updatedKeys[indexKey]);
|
|
1904
|
-
|
|
1905
1912
|
}
|
|
1906
1913
|
}
|
|
1907
1914
|
|
|
@@ -1948,7 +1955,6 @@ class Entity {
|
|
|
1948
1955
|
_makePutParams({ data } = {}, pk, sk) {
|
|
1949
1956
|
let { updatedKeys, setAttributes } = this._getPutKeys(pk, sk && sk.facets, data);
|
|
1950
1957
|
let translatedFields = this.model.schema.translateToFields(setAttributes);
|
|
1951
|
-
|
|
1952
1958
|
return {
|
|
1953
1959
|
Item: {
|
|
1954
1960
|
...translatedFields,
|
|
@@ -2406,8 +2412,10 @@ class Entity {
|
|
|
2406
2412
|
indexKey[sk] = keys.sk[0];
|
|
2407
2413
|
}
|
|
2408
2414
|
}
|
|
2409
|
-
|
|
2410
|
-
|
|
2415
|
+
if (keys.pk !== undefined && keys.pk !== '') {
|
|
2416
|
+
updatedKeys[pk] = keys.pk;
|
|
2417
|
+
}
|
|
2418
|
+
if (sk && keys.sk[0] !== undefined && keys.sk[0] !== '') {
|
|
2411
2419
|
updatedKeys[sk] = keys.sk[0];
|
|
2412
2420
|
}
|
|
2413
2421
|
}
|
|
@@ -3298,7 +3306,9 @@ class Entity {
|
|
|
3298
3306
|
if (Array.isArray(sk.facets)) {
|
|
3299
3307
|
let duplicates = pk.facets.filter(facet => sk.facets.includes(facet));
|
|
3300
3308
|
if (duplicates.length !== 0) {
|
|
3301
|
-
|
|
3309
|
+
if (sk.facets.length > 1) {
|
|
3310
|
+
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexCompositeAttributes, `The Access Pattern '${accessPattern}' contains duplicate references the composite attribute(s): ${u.commaSeparatedString(duplicates)}. Composite attributes can only be used more than once in an index if your sort key is limitted to a single attribute. This is to prevent unexpected runtime errors related to the inability to generate keys.`);
|
|
3311
|
+
}
|
|
3302
3312
|
}
|
|
3303
3313
|
}
|
|
3304
3314
|
|
|
@@ -3595,7 +3605,6 @@ class Entity {
|
|
|
3595
3605
|
|
|
3596
3606
|
_parseModel(model, config = {}) {
|
|
3597
3607
|
/** start beta/v1 condition **/
|
|
3598
|
-
const {client} = config;
|
|
3599
3608
|
let modelVersion = u.getModelVersion(model);
|
|
3600
3609
|
let service, entity, version, table, name;
|
|
3601
3610
|
switch(modelVersion) {
|
|
@@ -3635,7 +3644,10 @@ class Entity {
|
|
|
3635
3644
|
indexAccessPattern,
|
|
3636
3645
|
indexHasSubCollections,
|
|
3637
3646
|
} = this._normalizeIndexes(model.indexes);
|
|
3638
|
-
let schema = new Schema(model.attributes, facets, {
|
|
3647
|
+
let schema = new Schema(model.attributes, facets, {
|
|
3648
|
+
getClient: () => this.client,
|
|
3649
|
+
isRoot: true,
|
|
3650
|
+
});
|
|
3639
3651
|
let filters = this._normalizeFilters(model.filters);
|
|
3640
3652
|
// todo: consider a rename
|
|
3641
3653
|
let prefixes = this._normalizeKeyFixings({service, entity, version, indexes, modelVersion, clusteredIndexes, schema});
|
package/src/schema.js
CHANGED
|
@@ -127,7 +127,7 @@ class Attribute {
|
|
|
127
127
|
this.parent = { parentType: this.type, parentPath: this.path };
|
|
128
128
|
this.get = this._makeGet(definition.get);
|
|
129
129
|
this.set = this._makeSet(definition.set);
|
|
130
|
-
this.
|
|
130
|
+
this.getClient = definition.getClient;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
static buildChildAttributes(type, definition, parent) {
|
|
@@ -145,25 +145,25 @@ class Attribute {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
static buildChildListItems(definition, parent) {
|
|
148
|
-
const {items,
|
|
148
|
+
const {items, getClient} = definition;
|
|
149
149
|
const prop = {...items, ...parent};
|
|
150
150
|
// The use of "*" is to ensure the child's name is "*" when added to the traverser and searching for the children of a list
|
|
151
|
-
return Schema.normalizeAttributes({ '*': prop }, {}, {
|
|
151
|
+
return Schema.normalizeAttributes({ '*': prop }, {}, {getClient, traverser: parent.traverser, parent}).attributes["*"];
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
static buildChildSetItems(definition, parent) {
|
|
155
|
-
const {items,
|
|
155
|
+
const {items, getClient} = definition;
|
|
156
156
|
|
|
157
157
|
const allowedTypes = [AttributeTypes.string, AttributeTypes.boolean, AttributeTypes.number, AttributeTypes.enum];
|
|
158
158
|
if (!Array.isArray(items) && !allowedTypes.includes(items)) {
|
|
159
159
|
throw new e.ElectroError(e.ErrorCodes.InvalidAttributeDefinition, `Invalid "items" definition for Set attribute: "${definition.path}". Acceptable item types include ${u.commaSeparatedString(allowedTypes)}`);
|
|
160
160
|
}
|
|
161
161
|
const prop = {type: items, ...parent};
|
|
162
|
-
return Schema.normalizeAttributes({ prop }, {}, {
|
|
162
|
+
return Schema.normalizeAttributes({ prop }, {}, {getClient, traverser: parent.traverser, parent}).attributes.prop;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
static buildChildMapProperties(definition, parent) {
|
|
166
|
-
const {properties,
|
|
166
|
+
const {properties, getClient} = definition;
|
|
167
167
|
if (!properties || typeof properties !== "object") {
|
|
168
168
|
throw new e.ElectroError(e.ErrorCodes.InvalidAttributeDefinition, `Invalid "properties" definition for Map attribute: "${definition.path}". The "properties" definition must describe the attributes that the Map will accept`);
|
|
169
169
|
}
|
|
@@ -171,7 +171,7 @@ class Attribute {
|
|
|
171
171
|
for (let name of Object.keys(properties)) {
|
|
172
172
|
attributes[name] = {...properties[name], ...parent};
|
|
173
173
|
}
|
|
174
|
-
return Schema.normalizeAttributes(attributes, {}, {
|
|
174
|
+
return Schema.normalizeAttributes(attributes, {}, {getClient, traverser: parent.traverser, parent});
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
static buildPath(name, type, parentPath) {
|
|
@@ -886,11 +886,12 @@ class SetAttribute extends Attribute {
|
|
|
886
886
|
}
|
|
887
887
|
|
|
888
888
|
_createDDBSet(value) {
|
|
889
|
-
|
|
889
|
+
const client = this.getClient();
|
|
890
|
+
if (client && typeof client.createSet === "function") {
|
|
890
891
|
value = Array.isArray(value)
|
|
891
892
|
? Array.from(new Set(value))
|
|
892
893
|
: value;
|
|
893
|
-
return
|
|
894
|
+
return client.createSet(value, { validate: true });
|
|
894
895
|
} else {
|
|
895
896
|
return new DynamoDBSet(value, this.items.type);
|
|
896
897
|
}
|
|
@@ -1005,10 +1006,10 @@ class SetAttribute extends Attribute {
|
|
|
1005
1006
|
}
|
|
1006
1007
|
|
|
1007
1008
|
class Schema {
|
|
1008
|
-
constructor(properties = {}, facets = {}, {traverser = new AttributeTraverser(),
|
|
1009
|
+
constructor(properties = {}, facets = {}, {traverser = new AttributeTraverser(), getClient, parent, isRoot} = {}) {
|
|
1009
1010
|
this._validateProperties(properties, parent);
|
|
1010
|
-
let schema = Schema.normalizeAttributes(properties, facets, {traverser,
|
|
1011
|
-
this.
|
|
1011
|
+
let schema = Schema.normalizeAttributes(properties, facets, {traverser, getClient, parent, isRoot});
|
|
1012
|
+
this.getClient = getClient;
|
|
1012
1013
|
this.attributes = schema.attributes;
|
|
1013
1014
|
this.enums = schema.enums;
|
|
1014
1015
|
this.translationForTable = schema.translationForTable;
|
|
@@ -1021,7 +1022,7 @@ class Schema {
|
|
|
1021
1022
|
this.isRoot = !!isRoot;
|
|
1022
1023
|
}
|
|
1023
1024
|
|
|
1024
|
-
static normalizeAttributes(attributes = {}, facets = {}, {traverser,
|
|
1025
|
+
static normalizeAttributes(attributes = {}, facets = {}, {traverser, getClient, parent, isRoot} = {}) {
|
|
1025
1026
|
const attributeHasParent = !!parent;
|
|
1026
1027
|
let invalidProperties = [];
|
|
1027
1028
|
let normalized = {};
|
|
@@ -1114,7 +1115,7 @@ class Schema {
|
|
|
1114
1115
|
let definition = {
|
|
1115
1116
|
name,
|
|
1116
1117
|
field,
|
|
1117
|
-
|
|
1118
|
+
getClient,
|
|
1118
1119
|
casing,
|
|
1119
1120
|
prefix,
|
|
1120
1121
|
postfix,
|