electrodb 1.7.0 → 1.7.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.
- package/CHANGELOG.md +5 -1
- package/README.md +150 -62
- package/index.d.ts +2 -0
- package/package.json +5 -2
- package/src/client.js +135 -0
- package/src/entity.js +3 -1
- package/src/errors.js +6 -0
- package/src/schema.js +20 -16
- package/src/service.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -150,4 +150,8 @@ All notable changes to this project will be documented in this file. Breaking ch
|
|
|
150
150
|
|
|
151
151
|
## [1.7.0] - 2022-03-13
|
|
152
152
|
### Added
|
|
153
|
-
- New feature: "Listeners". Listeners open the door to some really cool tooling that was not possible because of how ElectroDB augments raw DynamoDB responses and did not provide easy access to raw DyanmoDB parameters.
|
|
153
|
+
- New feature: "Listeners". Listeners open the door to some really cool tooling that was not possible because of how ElectroDB augments raw DynamoDB responses and did not provide easy access to raw DyanmoDB parameters. [[read more](./README.md#listeners)]
|
|
154
|
+
|
|
155
|
+
## [1.7.1] - 2022-03-19
|
|
156
|
+
### Added
|
|
157
|
+
- Adding support for the v3 DyanmoDBClient. This change also brings in a new ElectroDB dependency [@aws-sdk/lib-dynamodb](https://www.npmjs.com/package/@aws-sdk/client-dynamodb). [[read more](./README.md#aws-dynamodb-client)]
|
package/README.md
CHANGED
|
@@ -205,6 +205,14 @@ tasks
|
|
|
205
205
|
* [Pagination Example](#pagination-example)
|
|
206
206
|
* [Query Examples](#query-examples)
|
|
207
207
|
* [Query Options](#query-options)
|
|
208
|
+
- [AWS DynamoDB Client](#aws-dynamodb-client)
|
|
209
|
+
* [V2 Client](#v2-client)
|
|
210
|
+
* [V3 Client](#v3-client)
|
|
211
|
+
- [Events](#events)
|
|
212
|
+
* [Query Event](#query-event)
|
|
213
|
+
* [Results Event](#results-event)
|
|
214
|
+
- [Logging](#logging)
|
|
215
|
+
- [Listeners](#listeners)
|
|
208
216
|
- [Errors:](#errors-)
|
|
209
217
|
+ [No Client Defined On Model](#no-client-defined-on-model)
|
|
210
218
|
+ [Invalid Identifier](#invalid-identifier)
|
|
@@ -4309,6 +4317,146 @@ pages | ∞ | How many DynamoDB pages should a quer
|
|
|
4309
4317
|
listeners | `[]` | An array of callbacks that are invoked when [internal ElectroDB events](#events) occur.
|
|
4310
4318
|
logger | _none_ | A convenience option for a single event listener that semantically can be used for logging.
|
|
4311
4319
|
|
|
4320
|
+
# AWS DynamoDB Client
|
|
4321
|
+
ElectroDB supports both the [v2](https://www.npmjs.com/package/aws-sdk) and [v3](https://www.npmjs.com/package/@aws-sdk/client-dynamodb) aws clients. The client can be supplied creating a new Entity or Service, or added to a Entity/Service instance via the `setClient()` method.
|
|
4322
|
+
|
|
4323
|
+
*On the instantiation of an `Entity`:*
|
|
4324
|
+
```typescript
|
|
4325
|
+
import { Entity } from 'electrodb';
|
|
4326
|
+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
|
|
4327
|
+
const table = "my_table_name";
|
|
4328
|
+
const client = new DocumentClient({
|
|
4329
|
+
region: "us-east-1"
|
|
4330
|
+
});
|
|
4331
|
+
|
|
4332
|
+
const task = new Entity({
|
|
4333
|
+
// your model
|
|
4334
|
+
}, {
|
|
4335
|
+
client, // <----- client
|
|
4336
|
+
table,
|
|
4337
|
+
});
|
|
4338
|
+
```
|
|
4339
|
+
|
|
4340
|
+
*On the instantiation of an `Service`:*
|
|
4341
|
+
```typescript
|
|
4342
|
+
import { Entity } from 'electrodb';
|
|
4343
|
+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
|
|
4344
|
+
const table = "my_table_name";
|
|
4345
|
+
const client = new DocumentClient({
|
|
4346
|
+
region: "us-east-1"
|
|
4347
|
+
});
|
|
4348
|
+
|
|
4349
|
+
const task = new Entity({
|
|
4350
|
+
// your model
|
|
4351
|
+
});
|
|
4352
|
+
|
|
4353
|
+
const user = new Entity({
|
|
4354
|
+
// your model
|
|
4355
|
+
});
|
|
4356
|
+
|
|
4357
|
+
const service = new Service({ task, user }, {
|
|
4358
|
+
client, // <----- client
|
|
4359
|
+
table,
|
|
4360
|
+
});
|
|
4361
|
+
```
|
|
4362
|
+
|
|
4363
|
+
*Via the `setClient` method:*
|
|
4364
|
+
```typescript
|
|
4365
|
+
import { Entity } from 'electrodb';
|
|
4366
|
+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
|
|
4367
|
+
const table = "my_table_name";
|
|
4368
|
+
const client = new DocumentClient({
|
|
4369
|
+
region: "us-east-1"
|
|
4370
|
+
});
|
|
4371
|
+
|
|
4372
|
+
const task = new Entity({
|
|
4373
|
+
// your model
|
|
4374
|
+
});
|
|
4375
|
+
|
|
4376
|
+
task.setClient(client);
|
|
4377
|
+
```
|
|
4378
|
+
|
|
4379
|
+
## V2 Client
|
|
4380
|
+
The [v2](https://www.npmjs.com/package/aws-sdk) sdk will work out of the box with the the DynamoDB DocumentClient.
|
|
4381
|
+
|
|
4382
|
+
*Example:*
|
|
4383
|
+
```typescript
|
|
4384
|
+
import { DocumentClient } from "aws-sdk/clients/dynamodb";
|
|
4385
|
+
const client = new DocumentClient({
|
|
4386
|
+
region: "us-east-1"
|
|
4387
|
+
});
|
|
4388
|
+
```
|
|
4389
|
+
|
|
4390
|
+
## V3 Client
|
|
4391
|
+
The [v3](https://www.npmjs.com/package/@aws-sdk/client-dynamodb) client will work out of the box with the the DynamoDBClient.
|
|
4392
|
+
|
|
4393
|
+
```typescript
|
|
4394
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
4395
|
+
const client = new DynamoDBClient({
|
|
4396
|
+
region: "us-east-1"
|
|
4397
|
+
});
|
|
4398
|
+
```
|
|
4399
|
+
|
|
4400
|
+
# Logging
|
|
4401
|
+
A logger callback function can be provided both the at the instantiation of an `Entity` or `Service` instance or as a [Query Option](#query-options). The property `logger` is implemented as a convenience property; under the hood ElectroDB uses this property identically to how it uses a [Listener](#listeners).
|
|
4402
|
+
|
|
4403
|
+
*On the instantiation of an `Entity`:*
|
|
4404
|
+
```typescript
|
|
4405
|
+
import { DynamoDB } from 'aws-sdk';
|
|
4406
|
+
import { Entity, ElectroEvent } from 'electrodb';
|
|
4407
|
+
|
|
4408
|
+
const table = "my_table_name";
|
|
4409
|
+
const client = new DynamoDB.DocumentClient();
|
|
4410
|
+
const logger = (event: ElectroEvent) => {
|
|
4411
|
+
console.log(JSON.stringify(event, null, 4));
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
const task = new Entity({
|
|
4415
|
+
// your model
|
|
4416
|
+
}, {
|
|
4417
|
+
client,
|
|
4418
|
+
table,
|
|
4419
|
+
logger // <----- logger listener
|
|
4420
|
+
});
|
|
4421
|
+
```
|
|
4422
|
+
|
|
4423
|
+
*On the instantiation of an `Service`:*
|
|
4424
|
+
```typescript
|
|
4425
|
+
import { DynamoDB } from 'aws-sdk';
|
|
4426
|
+
import { Entity, ElectroEvent } from 'electrodb';
|
|
4427
|
+
|
|
4428
|
+
const table = "my_table_name";
|
|
4429
|
+
const client = new DynamoDB.DocumentClient();
|
|
4430
|
+
const logger = (event: ElectroEvent) => {
|
|
4431
|
+
console.log(JSON.stringify(event, null, 4));
|
|
4432
|
+
}
|
|
4433
|
+
|
|
4434
|
+
const task = new Entity({
|
|
4435
|
+
// your model
|
|
4436
|
+
});
|
|
4437
|
+
|
|
4438
|
+
const user = new Entity({
|
|
4439
|
+
// your model
|
|
4440
|
+
});
|
|
4441
|
+
|
|
4442
|
+
const service = new Service({ task, user }, {
|
|
4443
|
+
client,
|
|
4444
|
+
table,
|
|
4445
|
+
logger // <----- logger listener
|
|
4446
|
+
});
|
|
4447
|
+
```
|
|
4448
|
+
|
|
4449
|
+
*As a [Query Option](#query-options):*
|
|
4450
|
+
```typescript
|
|
4451
|
+
const logger = (event: ElectroEvent) => {
|
|
4452
|
+
console.log(JSON.stringify(event, null, 4));
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
task.query
|
|
4456
|
+
.assigned({ userId })
|
|
4457
|
+
.go({ logger });
|
|
4458
|
+
```
|
|
4459
|
+
|
|
4312
4460
|
# Events
|
|
4313
4461
|
ElectroDB can be supplied with callbacks (see: [logging](#logging) and [listeners](#listeners) to learn how) to be invoked after certain request lifecycles. This can be useful for logging, analytics, expanding functionality, and more. The following are events currently supported by ElectroDB -- if you would like to see additional events feel free to create a github issue to discuss your concept/need!
|
|
4314
4462
|
|
|
@@ -4413,66 +4561,6 @@ entity.get({ prop1, prop2 }).go();
|
|
|
4413
4561
|
}
|
|
4414
4562
|
```
|
|
4415
4563
|
|
|
4416
|
-
# Logging
|
|
4417
|
-
A logger callback function can be provided both the at the instantiation of an `Entity` or `Service` instance or as a [Query Option](#query-options). The property `logger` is implemented as a convenience property; under the hood ElectroDB uses this property identically to how it uses a [Listener](#listeners).
|
|
4418
|
-
|
|
4419
|
-
*On the instantiation of an `Entity`:*
|
|
4420
|
-
```typescript
|
|
4421
|
-
import { DynamoDB } from 'aws-sdk';
|
|
4422
|
-
import {Entity, ElectroEvent} from 'electrodb';
|
|
4423
|
-
|
|
4424
|
-
const table = "my_table_name";
|
|
4425
|
-
const client = new DynamoDB.DocumentClient();
|
|
4426
|
-
const logger = (event: ElectroEvent) => {
|
|
4427
|
-
console.log(JSON.stringify(event, null, 4));
|
|
4428
|
-
}
|
|
4429
|
-
|
|
4430
|
-
const task = new Entity({
|
|
4431
|
-
// your model
|
|
4432
|
-
}, {
|
|
4433
|
-
client,
|
|
4434
|
-
table,
|
|
4435
|
-
logger // <----- logger listener
|
|
4436
|
-
});
|
|
4437
|
-
```
|
|
4438
|
-
|
|
4439
|
-
*On the instantiation of an `Service`:*
|
|
4440
|
-
```typescript
|
|
4441
|
-
import { DynamoDB } from 'aws-sdk';
|
|
4442
|
-
import {Entity, ElectroEvent} from 'electrodb';
|
|
4443
|
-
|
|
4444
|
-
const table = "my_table_name";
|
|
4445
|
-
const client = new DynamoDB.DocumentClient();
|
|
4446
|
-
const logger = (event: ElectroEvent) => {
|
|
4447
|
-
console.log(JSON.stringify(event, null, 4));
|
|
4448
|
-
}
|
|
4449
|
-
|
|
4450
|
-
const task = new Entity({
|
|
4451
|
-
// your model
|
|
4452
|
-
});
|
|
4453
|
-
|
|
4454
|
-
const user = new Entity({
|
|
4455
|
-
// your model
|
|
4456
|
-
});
|
|
4457
|
-
|
|
4458
|
-
const service = new Service({ task, user }, {
|
|
4459
|
-
client,
|
|
4460
|
-
table,
|
|
4461
|
-
logger // <----- logger listener
|
|
4462
|
-
});
|
|
4463
|
-
```
|
|
4464
|
-
|
|
4465
|
-
*As a [Query Option](#query-options):*
|
|
4466
|
-
```typescript
|
|
4467
|
-
const logger = (event: ElectroEvent) => {
|
|
4468
|
-
console.log(JSON.stringify(event, null, 4));
|
|
4469
|
-
}
|
|
4470
|
-
|
|
4471
|
-
task.query
|
|
4472
|
-
.assigned({ userId })
|
|
4473
|
-
.go({ logger });
|
|
4474
|
-
```
|
|
4475
|
-
|
|
4476
4564
|
# Listeners
|
|
4477
4565
|
ElectroDB can be supplied with callbacks (called "Listeners") to be invoked after certain request lifecycles. Unlike [Attribute Getters and Setters](#attribute-getters-and-setters), Listeners are implemented to react to events passively, not to modify values during the request lifecycle. Listeners can be useful for logging, analytics, expanding functionality, and more. Listeners can be provide both the at the instantiation of an `Entity` or `Service` instance or as a [Query Option](#query-options).
|
|
4478
4566
|
|
|
@@ -4481,7 +4569,7 @@ ElectroDB can be supplied with callbacks (called "Listeners") to be invoked afte
|
|
|
4481
4569
|
*On the instantiation of an `Entity`:*
|
|
4482
4570
|
```typescript
|
|
4483
4571
|
import { DynamoDB } from 'aws-sdk';
|
|
4484
|
-
import {Entity, ElectroEvent} from 'electrodb';
|
|
4572
|
+
import { Entity, ElectroEvent } from 'electrodb';
|
|
4485
4573
|
|
|
4486
4574
|
const table = "my_table_name";
|
|
4487
4575
|
const client = new DynamoDB.DocumentClient();
|
|
@@ -4508,7 +4596,7 @@ const task = new Entity({
|
|
|
4508
4596
|
*On the instantiation of an `Service`:*
|
|
4509
4597
|
```typescript
|
|
4510
4598
|
import { DynamoDB } from 'aws-sdk';
|
|
4511
|
-
import {Entity, ElectroEvent} from 'electrodb';
|
|
4599
|
+
import { Entity, ElectroEvent } from 'electrodb';
|
|
4512
4600
|
|
|
4513
4601
|
const table = "my_table_name";
|
|
4514
4602
|
const client = new DynamoDB.DocumentClient();
|
package/index.d.ts
CHANGED
|
@@ -1120,6 +1120,8 @@ type DocumentClient = {
|
|
|
1120
1120
|
batchWrite: DocumentClientMethod;
|
|
1121
1121
|
batchGet: DocumentClientMethod;
|
|
1122
1122
|
scan: DocumentClientMethod;
|
|
1123
|
+
} | {
|
|
1124
|
+
send: (command: any) => Promise<any>;
|
|
1123
1125
|
}
|
|
1124
1126
|
|
|
1125
1127
|
type ElectroDBMethodTypes = "put" | "get" | "query" | "scan" | "update" | "delete" | "remove" | "patch" | "create" | "batchGet" | "batchWrite";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electrodb",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
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": {
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/tywalch/electrodb#readme",
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@aws-sdk/client-dynamodb": "^3.54.1",
|
|
29
|
+
"@aws-sdk/lib-dynamodb": "^3.54.1",
|
|
28
30
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
29
31
|
"@types/chai": "^4.2.12",
|
|
30
32
|
"@types/mocha": "^8.0.3",
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
"directory": "test"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"jsonschema": "1.2.7"
|
|
64
|
+
"jsonschema": "1.2.7",
|
|
65
|
+
"@aws-sdk/lib-dynamodb": "^3.54.1"
|
|
63
66
|
}
|
|
64
67
|
}
|
package/src/client.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const {isFunction} = require('./validations');
|
|
2
|
+
const {ElectroError, ErrorCodes} = require('./errors');
|
|
3
|
+
const lib = require('@aws-sdk/lib-dynamodb');
|
|
4
|
+
|
|
5
|
+
const DocumentClientVersions = {
|
|
6
|
+
v2: 'v2',
|
|
7
|
+
v3: 'v3',
|
|
8
|
+
electro: 'electro',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const v3Methods = ['send'];
|
|
12
|
+
const v2Methods = ['get', 'put', 'update', 'delete', 'batchWrite', 'batchGet', 'scan', 'query', 'createSet'];
|
|
13
|
+
const supportedClientVersions = {
|
|
14
|
+
[DocumentClientVersions.v2]: v2Methods,
|
|
15
|
+
[DocumentClientVersions.v3]: v3Methods,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class DocumentClientV3Wrapper {
|
|
19
|
+
static init(client) {
|
|
20
|
+
return new DocumentClientV3Wrapper(client, lib);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor(client, lib) {
|
|
24
|
+
this.client = client;
|
|
25
|
+
this.lib = lib;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
promiseWrap(fn) {
|
|
29
|
+
return {
|
|
30
|
+
promise: async () => {
|
|
31
|
+
return fn();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get(params) {
|
|
37
|
+
return this.promiseWrap(() => {
|
|
38
|
+
const command = new this.lib.GetCommand(params);
|
|
39
|
+
return this.client.send(command);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
put(params) {
|
|
43
|
+
return this.promiseWrap(() => {
|
|
44
|
+
const command = new this.lib.PutCommand(params);
|
|
45
|
+
return this.client.send(command);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
update(params) {
|
|
49
|
+
return this.promiseWrap(() => {
|
|
50
|
+
const command = new this.lib.UpdateCommand(params);
|
|
51
|
+
return this.client.send(command);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
delete(params) {
|
|
55
|
+
return this.promiseWrap(async () => {
|
|
56
|
+
const command = new this.lib.DeleteCommand(params);
|
|
57
|
+
return this.client.send(command);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
batchWrite(params) {
|
|
61
|
+
return this.promiseWrap(async () => {
|
|
62
|
+
const command = new this.lib.BatchWriteCommand(params);
|
|
63
|
+
return this.client.send(command);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
batchGet(params) {
|
|
67
|
+
return this.promiseWrap(async () => {
|
|
68
|
+
const command = new this.lib.BatchGetCommand(params);
|
|
69
|
+
return this.client.send(command);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
scan(params) {
|
|
73
|
+
return this.promiseWrap(async () => {
|
|
74
|
+
const command = new this.lib.ScanCommand(params);
|
|
75
|
+
return this.client.send(command);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
query(params) {
|
|
79
|
+
return this.promiseWrap(async () => {
|
|
80
|
+
const command = new this.lib.QueryCommand(params);
|
|
81
|
+
return this.client.send(command);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
createSet(value) {
|
|
85
|
+
if (Array.isArray(value)) {
|
|
86
|
+
return new Set(value);
|
|
87
|
+
} else {
|
|
88
|
+
return new Set([value]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function identifyClientVersion(client = {}) {
|
|
94
|
+
if (client instanceof DocumentClientV3Wrapper) return DocumentClientVersions.electro;
|
|
95
|
+
for (const [version, methods] of Object.entries(supportedClientVersions)) {
|
|
96
|
+
const hasMethods = methods.every(method => {
|
|
97
|
+
return method in client && isFunction(client[method]);
|
|
98
|
+
});
|
|
99
|
+
if (hasMethods) {
|
|
100
|
+
return version;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function normalizeClient(client) {
|
|
106
|
+
if (client === undefined) return client;
|
|
107
|
+
const version = identifyClientVersion(client);
|
|
108
|
+
switch(version) {
|
|
109
|
+
case DocumentClientVersions.v3:
|
|
110
|
+
return DocumentClientV3Wrapper.init(client);
|
|
111
|
+
case DocumentClientVersions.v2:
|
|
112
|
+
case DocumentClientVersions.electro:
|
|
113
|
+
return client;
|
|
114
|
+
default:
|
|
115
|
+
throw new ElectroError(ErrorCodes.InvalidClientProvided, 'Invalid DynamoDB Document Client provided. ElectroDB supports the v2 and v3 DynamoDB Document Clients from the aws-sdk');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function normalizeConfig(config = {}) {
|
|
120
|
+
return {
|
|
121
|
+
...config,
|
|
122
|
+
client: normalizeClient(config.client)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
v2Methods,
|
|
128
|
+
v3Methods,
|
|
129
|
+
normalizeClient,
|
|
130
|
+
normalizeConfig,
|
|
131
|
+
identifyClientVersion,
|
|
132
|
+
DocumentClientVersions,
|
|
133
|
+
supportedClientVersions,
|
|
134
|
+
DocumentClientV3Wrapper,
|
|
135
|
+
};
|
package/src/entity.js
CHANGED
|
@@ -7,11 +7,13 @@ const { WhereFactory } = require("./where");
|
|
|
7
7
|
const { clauses, ChainState } = require("./clauses");
|
|
8
8
|
const {EventManager} = require('./events');
|
|
9
9
|
const validations = require("./validations");
|
|
10
|
+
const c = require('./client');
|
|
10
11
|
const u = require("./util");
|
|
11
12
|
const e = require("./errors");
|
|
12
13
|
|
|
13
14
|
class Entity {
|
|
14
15
|
constructor(model, config = {}) {
|
|
16
|
+
config = c.normalizeConfig(config);
|
|
15
17
|
this.eventManager = new EventManager({
|
|
16
18
|
listeners: config.listeners
|
|
17
19
|
});
|
|
@@ -588,7 +590,7 @@ class Entity {
|
|
|
588
590
|
|
|
589
591
|
_setClient(client) {
|
|
590
592
|
if (client) {
|
|
591
|
-
this.client = client;
|
|
593
|
+
this.client = c.normalizeClient(client);
|
|
592
594
|
}
|
|
593
595
|
}
|
|
594
596
|
|
package/src/errors.js
CHANGED
|
@@ -133,6 +133,12 @@ const ErrorCodes = {
|
|
|
133
133
|
name: "InvalidListenerProvided",
|
|
134
134
|
sym: ErrorCode,
|
|
135
135
|
},
|
|
136
|
+
InvalidClientProvided: {
|
|
137
|
+
code: 1021,
|
|
138
|
+
section: "invalid-client-provided",
|
|
139
|
+
name: "InvalidClientProvided",
|
|
140
|
+
sym: ErrorCode,
|
|
141
|
+
},
|
|
136
142
|
MissingAttribute: {
|
|
137
143
|
code: 2001,
|
|
138
144
|
section: "missing-attribute",
|
package/src/schema.js
CHANGED
|
@@ -768,21 +768,28 @@ class SetAttribute extends Attribute {
|
|
|
768
768
|
_makeSetValidate(definition) {
|
|
769
769
|
const validate = this._makeValidate(definition.validate);
|
|
770
770
|
return (value) => {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
771
|
+
switch (getValueType(value)) {
|
|
772
|
+
case ValueTypes.array:
|
|
773
|
+
return validate([...value]);
|
|
774
|
+
case ValueTypes.aws_set:
|
|
775
|
+
return validate([...value.values]);
|
|
776
|
+
case ValueTypes.set:
|
|
777
|
+
return validate(Array.from(value));
|
|
778
|
+
default:
|
|
779
|
+
return validate(value);
|
|
777
780
|
}
|
|
778
781
|
}
|
|
779
782
|
}
|
|
780
783
|
|
|
781
784
|
fromDDBSet(value) {
|
|
782
|
-
|
|
783
|
-
|
|
785
|
+
switch (getValueType(value)) {
|
|
786
|
+
case ValueTypes.aws_set:
|
|
787
|
+
return [...value.values];
|
|
788
|
+
case ValueTypes.set:
|
|
789
|
+
return Array.from(value);
|
|
790
|
+
default:
|
|
791
|
+
return value;
|
|
784
792
|
}
|
|
785
|
-
return value;
|
|
786
793
|
}
|
|
787
794
|
|
|
788
795
|
_createDDBSet(value) {
|
|
@@ -820,15 +827,14 @@ class SetAttribute extends Attribute {
|
|
|
820
827
|
|
|
821
828
|
_makeGet(get, items) {
|
|
822
829
|
this._checkGetSet(get, "get");
|
|
823
|
-
|
|
824
830
|
const getter = get || ((attr) => attr);
|
|
825
|
-
|
|
826
831
|
return (values, siblings) => {
|
|
827
832
|
if (values !== undefined) {
|
|
828
833
|
const data = this.fromDDBSet(values);
|
|
829
834
|
return getter(data, siblings);
|
|
830
835
|
}
|
|
831
|
-
|
|
836
|
+
const data = this.fromDDBSet(values);
|
|
837
|
+
const results = getter(data, siblings);
|
|
832
838
|
if (results !== undefined) {
|
|
833
839
|
// if not undefined, try to convert, else no need to return
|
|
834
840
|
return this.fromDDBSet(results);
|
|
@@ -840,9 +846,7 @@ class SetAttribute extends Attribute {
|
|
|
840
846
|
this._checkGetSet(set, "set");
|
|
841
847
|
const setter = set || ((attr) => attr);
|
|
842
848
|
return (values, siblings) => {
|
|
843
|
-
const results = values
|
|
844
|
-
? setter(values.values, siblings)
|
|
845
|
-
: setter(values, siblings)
|
|
849
|
+
const results = setter(this.fromDDBSet(values), siblings);
|
|
846
850
|
if (results !== undefined) {
|
|
847
851
|
return this.toDDBSet(results);
|
|
848
852
|
}
|
|
@@ -879,7 +883,7 @@ class SetAttribute extends Attribute {
|
|
|
879
883
|
} else {
|
|
880
884
|
errors.push(
|
|
881
885
|
new e.ElectroAttributeValidationError(this.path, `Invalid value type at attribute path: "${this.path}". Expected value to be an Expected value to be an Array, native JavaScript Set objects, or DocumentClient Set objects to fulfill attribute type "${this.type}"`)
|
|
882
|
-
)
|
|
886
|
+
);
|
|
883
887
|
}
|
|
884
888
|
for (const item of arr) {
|
|
885
889
|
const [isValid, errorValues] = this.items.isValid(item);
|
package/src/service.js
CHANGED
|
@@ -6,6 +6,7 @@ const { FilterOperations } = require("./operations");
|
|
|
6
6
|
const { WhereFactory } = require("./where");
|
|
7
7
|
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util");
|
|
8
8
|
const v = require("./validations");
|
|
9
|
+
const c = require('./client');
|
|
9
10
|
const e = require("./errors");
|
|
10
11
|
const u = require("./util");
|
|
11
12
|
|
|
@@ -104,6 +105,7 @@ class Service {
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
constructor(service = "", config = {}) {
|
|
108
|
+
config = c.normalizeConfig(config);
|
|
107
109
|
this.version = ServiceVersions.v1;
|
|
108
110
|
let type = inferConstructorType(service);
|
|
109
111
|
switch(type) {
|