electrodb 1.4.3 → 1.4.7
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 +24 -1
- package/README.md +94 -0
- package/package.json +4 -2
- package/src/entity.js +24 -1
- package/src/filters.js +1 -1
- package/src/operations.js +38 -31
- package/src/update.js +1 -1
- package/.idea/aws.xml +0 -17
- package/.idea/electrodb.iml +0 -12
- package/.idea/google-java-format.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/browser.js +0 -53
- package/bundle.js +0 -9962
- package/localtestgrep.sh +0 -3
- package/notes +0 -937
- package/tslocaltestgrep.sh +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -88,4 +88,27 @@ All notable changes to this project will be documented in this file. Breaking ch
|
|
|
88
88
|
|
|
89
89
|
## [1.4.3] - 2021-10-03
|
|
90
90
|
### Fixed
|
|
91
|
-
- ElectroDB would throw when an `undefined` property was passed to query. This has been changed to not throw if a partial query on that index can be accomplished with the data provided.
|
|
91
|
+
- ElectroDB would throw when an `undefined` property was passed to query. This has been changed to not throw if a partial query on that index can be accomplished with the data provided.
|
|
92
|
+
|
|
93
|
+
## [1.4.4] - 2021-10-16
|
|
94
|
+
### Added
|
|
95
|
+
- Updates did not include composite attributes involved in primary index. Though these values cannot be changed, they should be `set` on update method calls in case the update results in an item insert. [[read more]](./README.md#updates-to-composite-attributes)
|
|
96
|
+
|
|
97
|
+
## [0.11.1] - 2021-10-17
|
|
98
|
+
### Patched
|
|
99
|
+
- Updates did not include composite attributes involved in primary index. Though these values cannot be changed, they should be `set` on update method calls in case the update results in an item insert. [[read more]](./README.md#updates-to-composite-attributes)
|
|
100
|
+
|
|
101
|
+
## [1.4.5] = 2021-10-17
|
|
102
|
+
### Fixed
|
|
103
|
+
- Improved .npmignore to remove playground oriented files, and created official directory to keep playground in sync with library changes.
|
|
104
|
+
|
|
105
|
+
## [1.4.6] = 2021-10-20
|
|
106
|
+
### Added, Fixed
|
|
107
|
+
- Adding Entity identifiers to all update operations. When primary index composite attributes were added in 1.4.4, entities were written properly but did not include the identifiers. This resulted in entities being written but not being readable without the query option `ignoreOwnership` being used.
|
|
108
|
+
|
|
109
|
+
## [1.4.7] = 2021-10-20
|
|
110
|
+
### Changed
|
|
111
|
+
- Using `add()` update mutation now resolves to `ADD #prop :prop` update expression instead of a `SET #prop = #prop + :prop`
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
- Fixed param naming conflict during updates, when map attribute shares a name with another (separate) attribute.
|
package/README.md
CHANGED
|
@@ -176,6 +176,7 @@ tasks
|
|
|
176
176
|
+ [Put Record](#put-record)
|
|
177
177
|
+ [Batch Write Put Records](#batch-write-put-records)
|
|
178
178
|
+ [Update Record](#update-record)
|
|
179
|
+
- [Updates to Composite Attributes](#updates-to-composite-attributes)
|
|
179
180
|
- [Update Method: Set](#update-method-set)
|
|
180
181
|
- [Update Method: Remove](#update-method-remove)
|
|
181
182
|
- [Update Method: Add](#update-method-add)
|
|
@@ -3129,6 +3130,99 @@ Update Method | Attribute Types
|
|
|
3129
3130
|
[delete](#update-method-delete) | `any` `set` | `object`
|
|
3130
3131
|
[data](#update-method-data) | `*` | `callback`
|
|
3131
3132
|
|
|
3133
|
+
#### Updates to Composite Attributes
|
|
3134
|
+
|
|
3135
|
+
ElectroDB adds some constraints to update calls to prevent the accidental loss of data. If an access pattern is defined with multiple composite attributes, then ElectroDB ensure the attributes cannot be updated individually. If an attribute involved in an index composite is updated, then the index key also must be updated, and if the whole key cannot be formed by the attributes supplied to the update, then it cannot create a composite key without overwriting the old data.
|
|
3136
|
+
|
|
3137
|
+
This example shows why a partial update to a composite key is prevented by ElectroDB:
|
|
3138
|
+
|
|
3139
|
+
```json
|
|
3140
|
+
{
|
|
3141
|
+
"index": "my-gsi",
|
|
3142
|
+
"pk": {
|
|
3143
|
+
"field": "gsi1pk",
|
|
3144
|
+
"composite": ["attr1"]
|
|
3145
|
+
},
|
|
3146
|
+
"sk": {
|
|
3147
|
+
"field": "gsi1sk",
|
|
3148
|
+
"composite": ["attr2", "attr3"]
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
```
|
|
3152
|
+
|
|
3153
|
+
The above secondary index definition would generate the following index keys:
|
|
3154
|
+
|
|
3155
|
+
```json
|
|
3156
|
+
{
|
|
3157
|
+
"gsi1pk": "$service#attr1_value1",
|
|
3158
|
+
"gsi1sk": "$entity_version#attr2_value2#attr3_value6"
|
|
3159
|
+
}
|
|
3160
|
+
```
|
|
3161
|
+
|
|
3162
|
+
If a user attempts to update the attribute `attr2`, then ElectroDB has no way of knowing value of the attribute `attr3` or if forming the composite key without it would overwrite its value. The same problem exists if a user were to update `attr3`, ElectroDB cannot update the key without knowing each composite attribute's value.
|
|
3163
|
+
|
|
3164
|
+
In the event that a secondary index includes composite values from the table's primary index, ElectroDB will draw from the values supplied for the update key to address index gaps in the secondary index. For example:
|
|
3165
|
+
|
|
3166
|
+
For the defined indexes:
|
|
3167
|
+
|
|
3168
|
+
```json
|
|
3169
|
+
{
|
|
3170
|
+
"accessPattern1": {
|
|
3171
|
+
"pk": {
|
|
3172
|
+
"field": "pk",
|
|
3173
|
+
"composite": ["attr1"]
|
|
3174
|
+
},
|
|
3175
|
+
"sk": {
|
|
3176
|
+
"field": "sk",
|
|
3177
|
+
"composite": ["attr2"]
|
|
3178
|
+
}
|
|
3179
|
+
},
|
|
3180
|
+
"accessPattern2": {
|
|
3181
|
+
"index": "my-gsi",
|
|
3182
|
+
"pk": {
|
|
3183
|
+
"field": "gsi1pk",
|
|
3184
|
+
"composite": ["attr3"]
|
|
3185
|
+
},
|
|
3186
|
+
"sk": {
|
|
3187
|
+
"field": "gsi1sk",
|
|
3188
|
+
"composite": ["attr2", "attr4"]
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
```
|
|
3193
|
+
|
|
3194
|
+
A user could update `attr4` alone because ElectroDB is able to leverage the value for `attr2` from values supplied to the `update()` method:
|
|
3195
|
+
|
|
3196
|
+
```typescript
|
|
3197
|
+
entity.update({ attr1: "value1", attr2: "value2" })
|
|
3198
|
+
.set({ attr4: "value4" })
|
|
3199
|
+
.go();
|
|
3200
|
+
|
|
3201
|
+
{
|
|
3202
|
+
"UpdateExpression": "SET #attr4 = :attr4_u0, #gsi1sk = :gsi1sk_u0, #attr1 = :attr1_u0, #attr2 = :attr2_u0",
|
|
3203
|
+
"ExpressionAttributeNames": {
|
|
3204
|
+
"#attr4": "attr4",
|
|
3205
|
+
"#gsi1sk": "gsi1sk",
|
|
3206
|
+
"#attr1": "attr1",
|
|
3207
|
+
"#attr2": "attr2"
|
|
3208
|
+
},
|
|
3209
|
+
"ExpressionAttributeValues": {
|
|
3210
|
+
":attr4_u0": "value6",
|
|
3211
|
+
// This index was successfully built
|
|
3212
|
+
":gsi1sk_u0": "$update-edgecases_1#attr2_value2#attr4_value6",
|
|
3213
|
+
":attr1_u0": "value1",
|
|
3214
|
+
":attr2_u0": "value2"
|
|
3215
|
+
},
|
|
3216
|
+
"TableName": "test_table",
|
|
3217
|
+
"Key": {
|
|
3218
|
+
"pk": "$service#attr1_value1",
|
|
3219
|
+
"sk": "$entity_version#attr2_value2"
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
```
|
|
3223
|
+
|
|
3224
|
+
> Note: Included in the update are all attributes from the table's primary index. These values are automatically included on all updates in the event an update results in an insert.
|
|
3225
|
+
|
|
3132
3226
|
#### Update Method: Set
|
|
3133
3227
|
|
|
3134
3228
|
The `set()` method will accept all attributes defined on the model. Provide a value to apply or replace onto the item.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electrodb",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
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": {
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"test-types": "node ./node_modules/tsd/dist/cli.js",
|
|
12
12
|
"coverage": "nyc npm run test-all && nyc report --reporter=text-lcov | coveralls",
|
|
13
13
|
"coverage-coveralls-local": "nyc npm run test-all-local && nyc report --reporter=text-lcov | coveralls",
|
|
14
|
-
"coverage-html-local": "nyc npm run test-all-local && nyc report --reporter=html"
|
|
14
|
+
"coverage-html-local": "nyc npm run test-all-local && nyc report --reporter=html",
|
|
15
|
+
"build:browser": "browserify playground/browser.js -o playground/bundle.js"
|
|
15
16
|
},
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"@types/node": "^15.6.0",
|
|
31
32
|
"@types/uuid": "^8.3.0",
|
|
32
33
|
"aws-sdk": "2.630.0",
|
|
34
|
+
"browserify": "^17.0.0",
|
|
33
35
|
"chai": "4.2.0",
|
|
34
36
|
"coveralls": "^3.1.0",
|
|
35
37
|
"istanbul": "0.4.5",
|
package/src/entity.js
CHANGED
|
@@ -1003,6 +1003,7 @@ class Entity {
|
|
|
1003
1003
|
}
|
|
1004
1004
|
|
|
1005
1005
|
_makeUpdateParams(update = {}, pk = {}, sk = {}) {
|
|
1006
|
+
let primaryIndexAttributes = {...pk, ...sk};
|
|
1006
1007
|
let modifiedAttributeValues = {};
|
|
1007
1008
|
let modifiedAttributeNames = {};
|
|
1008
1009
|
for (const path of Object.keys(update.paths)) {
|
|
@@ -1038,6 +1039,7 @@ class Entity {
|
|
|
1038
1039
|
const wasNotAlreadyModified = modifiedAttributeNames[indexKey] === undefined;
|
|
1039
1040
|
if (isNotTablePK && isNotTableSK && wasNotAlreadyModified) {
|
|
1040
1041
|
update.set(indexKey, updatedKeys[indexKey]);
|
|
1042
|
+
|
|
1041
1043
|
}
|
|
1042
1044
|
}
|
|
1043
1045
|
|
|
@@ -1050,6 +1052,27 @@ class Entity {
|
|
|
1050
1052
|
}
|
|
1051
1053
|
}
|
|
1052
1054
|
|
|
1055
|
+
// This loop adds the composite attributes to the Primary Index. This is important
|
|
1056
|
+
// in the case an update results in an "upsert". We want to add the Primary Index
|
|
1057
|
+
// composite attributes to the update so they will be included on the item when it
|
|
1058
|
+
// is created. It is done after all of the above because it is not a true "update"
|
|
1059
|
+
// so it should not be subject to the above "rules".
|
|
1060
|
+
for (const primaryIndexAttribute of Object.keys(primaryIndexAttributes)) {
|
|
1061
|
+
// isNotTablePK and isNotTableSK is important to check in case these properties
|
|
1062
|
+
// are not also the name of the index (you cannot modify the PK or SK of an item
|
|
1063
|
+
// after its creation)
|
|
1064
|
+
const attribute = this.model.schema.attributes[primaryIndexAttribute];
|
|
1065
|
+
const isNotTablePK = !!(attribute && attribute.field !== this.model.indexes[accessPattern].pk.field);
|
|
1066
|
+
const isNotTableSK = !!(attribute && attribute.field !== this.model.indexes[accessPattern].sk.field);
|
|
1067
|
+
const wasNotAlreadyModified = modifiedAttributeNames[primaryIndexAttribute] === undefined;
|
|
1068
|
+
if (isNotTablePK && isNotTableSK && wasNotAlreadyModified) {
|
|
1069
|
+
update.set(primaryIndexAttribute, primaryIndexAttributes[primaryIndexAttribute]);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
update.set(this.identifiers.entity, this.getName());
|
|
1074
|
+
update.set(this.identifiers.version, this.getVersion());
|
|
1075
|
+
|
|
1053
1076
|
return {
|
|
1054
1077
|
UpdateExpression: update.build(),
|
|
1055
1078
|
ExpressionAttributeNames: update.getNames(),
|
|
@@ -1429,7 +1452,7 @@ class Entity {
|
|
|
1429
1452
|
{ ...keyAttributes },
|
|
1430
1453
|
);
|
|
1431
1454
|
const removedKeyImpact = this._expectIndexFacets(
|
|
1432
|
-
{...removed},
|
|
1455
|
+
{ ...removed },
|
|
1433
1456
|
{...keyAttributes}
|
|
1434
1457
|
)
|
|
1435
1458
|
|
package/src/filters.js
CHANGED
package/src/operations.js
CHANGED
|
@@ -4,7 +4,7 @@ const v = require("./util");
|
|
|
4
4
|
|
|
5
5
|
const deleteOperations = {
|
|
6
6
|
canNest: false,
|
|
7
|
-
template: function del(attr, path, value) {
|
|
7
|
+
template: function del(options, attr, path, value) {
|
|
8
8
|
let operation = "";
|
|
9
9
|
let expression = "";
|
|
10
10
|
switch(attr.type) {
|
|
@@ -23,19 +23,19 @@ const deleteOperations = {
|
|
|
23
23
|
const UpdateOperations = {
|
|
24
24
|
name: {
|
|
25
25
|
canNest: true,
|
|
26
|
-
template: function name(attr, path) {
|
|
26
|
+
template: function name(options, attr, path) {
|
|
27
27
|
return path;
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
value: {
|
|
31
31
|
canNest: true,
|
|
32
|
-
template: function value(attr, path, value) {
|
|
32
|
+
template: function value(options, attr, path, value) {
|
|
33
33
|
return value;
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
append: {
|
|
37
37
|
canNest: false,
|
|
38
|
-
template: function append(attr, path, value) {
|
|
38
|
+
template: function append(options, attr, path, value) {
|
|
39
39
|
let operation = "";
|
|
40
40
|
let expression = "";
|
|
41
41
|
switch(attr.type) {
|
|
@@ -52,7 +52,7 @@ const UpdateOperations = {
|
|
|
52
52
|
},
|
|
53
53
|
add: {
|
|
54
54
|
canNest: false,
|
|
55
|
-
template: function add(attr, path, value) {
|
|
55
|
+
template: function add(options, attr, path, value) {
|
|
56
56
|
let operation = "";
|
|
57
57
|
let expression = "";
|
|
58
58
|
switch(attr.type) {
|
|
@@ -62,8 +62,13 @@ const UpdateOperations = {
|
|
|
62
62
|
expression = `${path} ${value}`;
|
|
63
63
|
break;
|
|
64
64
|
case AttributeTypes.number:
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if (options.nestedValue) {
|
|
66
|
+
operation = ItemOperations.set;
|
|
67
|
+
expression = `${path} = ${path} + ${value}`;
|
|
68
|
+
} else {
|
|
69
|
+
operation = ItemOperations.add;
|
|
70
|
+
expression = `${path} ${value}`;
|
|
71
|
+
}
|
|
67
72
|
break;
|
|
68
73
|
default:
|
|
69
74
|
throw new Error(`Invalid Update Attribute Operation: "ADD" Operation can only be performed on attributes with type "number", "set", or "any".`);
|
|
@@ -73,7 +78,7 @@ const UpdateOperations = {
|
|
|
73
78
|
},
|
|
74
79
|
subtract: {
|
|
75
80
|
canNest: false,
|
|
76
|
-
template: function subtract(attr, path, value) {
|
|
81
|
+
template: function subtract(options, attr, path, value) {
|
|
77
82
|
let operation = "";
|
|
78
83
|
let expression = "";
|
|
79
84
|
switch(attr.type) {
|
|
@@ -91,7 +96,7 @@ const UpdateOperations = {
|
|
|
91
96
|
},
|
|
92
97
|
set: {
|
|
93
98
|
canNest: false,
|
|
94
|
-
template: function set(attr, path, value) {
|
|
99
|
+
template: function set(options, attr, path, value) {
|
|
95
100
|
let operation = "";
|
|
96
101
|
let expression = "";
|
|
97
102
|
switch(attr.type) {
|
|
@@ -114,7 +119,7 @@ const UpdateOperations = {
|
|
|
114
119
|
},
|
|
115
120
|
remove: {
|
|
116
121
|
canNest: false,
|
|
117
|
-
template: function remove(attr, ...paths) {
|
|
122
|
+
template: function remove(options, attr, ...paths) {
|
|
118
123
|
let operation = "";
|
|
119
124
|
let expression = "";
|
|
120
125
|
switch(attr.type) {
|
|
@@ -142,86 +147,86 @@ const UpdateOperations = {
|
|
|
142
147
|
|
|
143
148
|
const FilterOperations = {
|
|
144
149
|
ne: {
|
|
145
|
-
template: function eq(attr, name, value) {
|
|
150
|
+
template: function eq(options, attr, name, value) {
|
|
146
151
|
return `${name} <> ${value}`;
|
|
147
152
|
},
|
|
148
153
|
strict: false,
|
|
149
154
|
},
|
|
150
155
|
eq: {
|
|
151
|
-
template: function eq(attr, name, value) {
|
|
156
|
+
template: function eq(options, attr, name, value) {
|
|
152
157
|
return `${name} = ${value}`;
|
|
153
158
|
},
|
|
154
159
|
strict: false,
|
|
155
160
|
},
|
|
156
161
|
gt: {
|
|
157
|
-
template: function gt(attr, name, value) {
|
|
162
|
+
template: function gt(options, attr, name, value) {
|
|
158
163
|
return `${name} > ${value}`;
|
|
159
164
|
},
|
|
160
165
|
strict: false
|
|
161
166
|
},
|
|
162
167
|
lt: {
|
|
163
|
-
template: function lt(attr, name, value) {
|
|
168
|
+
template: function lt(options, attr, name, value) {
|
|
164
169
|
return `${name} < ${value}`;
|
|
165
170
|
},
|
|
166
171
|
strict: false
|
|
167
172
|
},
|
|
168
173
|
gte: {
|
|
169
|
-
template: function gte(attr, name, value) {
|
|
174
|
+
template: function gte(options, attr, name, value) {
|
|
170
175
|
return `${name} >= ${value}`;
|
|
171
176
|
},
|
|
172
177
|
strict: false
|
|
173
178
|
},
|
|
174
179
|
lte: {
|
|
175
|
-
template: function lte(attr, name, value) {
|
|
180
|
+
template: function lte(options, attr, name, value) {
|
|
176
181
|
return `${name} <= ${value}`;
|
|
177
182
|
},
|
|
178
183
|
strict: false
|
|
179
184
|
},
|
|
180
185
|
between: {
|
|
181
|
-
template: function between(attr, name, value1, value2) {
|
|
186
|
+
template: function between(options, attr, name, value1, value2) {
|
|
182
187
|
return `(${name} between ${value1} and ${value2})`;
|
|
183
188
|
},
|
|
184
189
|
strict: false
|
|
185
190
|
},
|
|
186
191
|
begins: {
|
|
187
|
-
template: function begins(attr, name, value) {
|
|
192
|
+
template: function begins(options, attr, name, value) {
|
|
188
193
|
return `begins_with(${name}, ${value})`;
|
|
189
194
|
},
|
|
190
195
|
strict: false
|
|
191
196
|
},
|
|
192
197
|
exists: {
|
|
193
|
-
template: function exists(attr, name) {
|
|
198
|
+
template: function exists(options, attr, name) {
|
|
194
199
|
return `attribute_exists(${name})`;
|
|
195
200
|
},
|
|
196
201
|
strict: false
|
|
197
202
|
},
|
|
198
203
|
notExists: {
|
|
199
|
-
template: function notExists(attr, name) {
|
|
204
|
+
template: function notExists(options, attr, name) {
|
|
200
205
|
return `attribute_not_exists(${name})`;
|
|
201
206
|
},
|
|
202
207
|
strict: false
|
|
203
208
|
},
|
|
204
209
|
contains: {
|
|
205
|
-
template: function contains(attr, name, value) {
|
|
210
|
+
template: function contains(options, attr, name, value) {
|
|
206
211
|
return `contains(${name}, ${value})`;
|
|
207
212
|
},
|
|
208
213
|
strict: false
|
|
209
214
|
},
|
|
210
215
|
notContains: {
|
|
211
|
-
template: function notContains(attr, name, value) {
|
|
216
|
+
template: function notContains(options, attr, name, value) {
|
|
212
217
|
return `not contains(${name}, ${value})`;
|
|
213
218
|
},
|
|
214
219
|
strict: false
|
|
215
220
|
},
|
|
216
221
|
value: {
|
|
217
|
-
template: function(attr, name, value) {
|
|
222
|
+
template: function(options, attr, name, value) {
|
|
218
223
|
return value;
|
|
219
224
|
},
|
|
220
225
|
strict: false,
|
|
221
226
|
canNest: true,
|
|
222
227
|
},
|
|
223
228
|
name: {
|
|
224
|
-
template: function(attr, name) {
|
|
229
|
+
template: function(options, attr, name) {
|
|
225
230
|
return name;
|
|
226
231
|
},
|
|
227
232
|
strict: false,
|
|
@@ -230,7 +235,7 @@ const FilterOperations = {
|
|
|
230
235
|
};
|
|
231
236
|
|
|
232
237
|
class ExpressionState {
|
|
233
|
-
constructor({prefix
|
|
238
|
+
constructor({prefix} = {}) {
|
|
234
239
|
this.names = {};
|
|
235
240
|
this.values = {};
|
|
236
241
|
this.paths = {};
|
|
@@ -238,13 +243,9 @@ class ExpressionState {
|
|
|
238
243
|
this.impacted = {};
|
|
239
244
|
this.expression = "";
|
|
240
245
|
this.prefix = prefix || "";
|
|
241
|
-
this.singleOccurrence = singleOccurrence;
|
|
242
246
|
}
|
|
243
247
|
|
|
244
248
|
incrementName(name) {
|
|
245
|
-
if (this.singleOccurrence) {
|
|
246
|
-
return `${this.prefix}${0}`
|
|
247
|
-
}
|
|
248
249
|
if (this.counts[name] === undefined) {
|
|
249
250
|
this.counts[name] = 0;
|
|
250
251
|
}
|
|
@@ -372,12 +373,14 @@ class AttributeOperationProxy {
|
|
|
372
373
|
if (property.__is_clause__ === AttributeProxySymbol) {
|
|
373
374
|
const {paths, root, target} = property();
|
|
374
375
|
const attributeValues = [];
|
|
376
|
+
let hasNestedValue = false;
|
|
375
377
|
for (let value of values) {
|
|
376
378
|
value = target.format(value);
|
|
377
379
|
// template.length is to see if function takes value argument
|
|
378
|
-
if (template.length >
|
|
380
|
+
if (template.length > 3) {
|
|
379
381
|
if (seen.has(value)) {
|
|
380
382
|
attributeValues.push(value);
|
|
383
|
+
hasNestedValue = true;
|
|
381
384
|
} else {
|
|
382
385
|
let attributeValueName = builder.setValue(target.name, value);
|
|
383
386
|
builder.setPath(paths.json, {value, name: attributeValueName});
|
|
@@ -386,7 +389,11 @@ class AttributeOperationProxy {
|
|
|
386
389
|
}
|
|
387
390
|
}
|
|
388
391
|
|
|
389
|
-
const
|
|
392
|
+
const options = {
|
|
393
|
+
nestedValue: hasNestedValue
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const formatted = template(options, target, paths.expression, ...attributeValues);
|
|
390
397
|
builder.setImpacted(operation, paths.json);
|
|
391
398
|
if (canNest) {
|
|
392
399
|
seen.add(paths.expression);
|
package/src/update.js
CHANGED
package/.idea/aws.xml
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="accountSettings">
|
|
4
|
-
<option name="activeProfile" value="profile:default" />
|
|
5
|
-
<option name="activeRegion" value="us-east-1" />
|
|
6
|
-
<option name="recentlyUsedProfiles">
|
|
7
|
-
<list>
|
|
8
|
-
<option value="profile:default" />
|
|
9
|
-
</list>
|
|
10
|
-
</option>
|
|
11
|
-
<option name="recentlyUsedRegions">
|
|
12
|
-
<list>
|
|
13
|
-
<option value="us-east-1" />
|
|
14
|
-
</list>
|
|
15
|
-
</option>
|
|
16
|
-
</component>
|
|
17
|
-
</project>
|
package/.idea/electrodb.iml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
-
</content>
|
|
9
|
-
<orderEntry type="inheritedJdk" />
|
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
-
</component>
|
|
12
|
-
</module>
|
package/.idea/misc.xml
DELETED
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/electrodb.iml" filepath="$PROJECT_DIR$/.idea/electrodb.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/vcs.xml
DELETED
package/browser.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
const ElectroDB = require("./index");
|
|
2
|
-
window.Prism = window.Prism || {};
|
|
3
|
-
const appDiv = document.getElementById('param-container');
|
|
4
|
-
|
|
5
|
-
function printToScreen(val) {
|
|
6
|
-
const innerHtml = appDiv.innerHTML;
|
|
7
|
-
// if (window.Prism) {
|
|
8
|
-
// console.log("fn", window.Prism.highlight, window.Prism.highlight.toString());
|
|
9
|
-
// console.log("window.Prism.languages.json", Object.keys(window.Prism.languages), window.Prism.languages.JSON);
|
|
10
|
-
// // appDiv.innerHTML = innerHtml + window.Prism.highlight(val, window.Prism.languages.json, 'json');
|
|
11
|
-
// } else {
|
|
12
|
-
// console.log("FUUUU", window, window.Prism);
|
|
13
|
-
// }
|
|
14
|
-
// appDiv.innerHTML = innerHtml + Prism.highlight(val, Prism.languages.json, 'json');
|
|
15
|
-
appDiv.innerHTML = innerHtml + `<hr><pre><code class="language-json">${val}</code></pre>`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function clearScreen() {
|
|
19
|
-
appDiv.innerHTML = '';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class Entity extends ElectroDB.Entity {
|
|
23
|
-
constructor(...params) {
|
|
24
|
-
super(...params);
|
|
25
|
-
this.client = {};
|
|
26
|
-
}
|
|
27
|
-
_queryParams(state, config) {
|
|
28
|
-
const params = super._queryParams(state, config);
|
|
29
|
-
printToScreen(JSON.stringify(params, null, 4));
|
|
30
|
-
return params;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
_params(state, config) {
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
const params = super._params(state, config);
|
|
36
|
-
printToScreen(JSON.stringify(params, null, 4));
|
|
37
|
-
return params;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
go(type, params) {
|
|
41
|
-
printToScreen(JSON.stringify(params, null, 4));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
class Service extends ElectroDB.Service {}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
window.ElectroDB = {
|
|
49
|
-
Entity,
|
|
50
|
-
Service,
|
|
51
|
-
printToScreen,
|
|
52
|
-
clearScreen
|
|
53
|
-
};
|