electrodb 1.9.0 → 1.10.0
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/index.d.ts +3 -1561
- package/package.json +7 -7
- package/src/entity.d.ts +94 -0
- package/src/entity.test-d.ts +110 -0
- package/src/service.d.ts +17 -0
- package/src/types/client.ts +15 -0
- package/src/types/collections.ts +243 -0
- package/src/types/events.ts +47 -0
- package/src/types/index.ts +67 -0
- package/src/types/model.ts +132 -0
- package/src/types/options.ts +81 -0
- package/src/types/schema.test-d.ts +2507 -0
- package/src/types/schema.ts +1016 -0
- package/src/types/tests.test-d.ts +3 -0
- package/src/types/types.test-d.ts +142 -0
- package/src/types/where.test-d.ts +1939 -0
- package/src/types/where.ts +94 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electrodb",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
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": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"test-ts": "mocha -r ts-node/register ./test/**.spec.ts",
|
|
9
9
|
"test-all": "mocha ./test/**.spec.js",
|
|
10
10
|
"test-all-local": "LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 node ./test/init.js && LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 mocha ./test/**.spec.js && npm run test-types && LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 npm run test-ts",
|
|
11
|
-
"test-types": "
|
|
11
|
+
"test-types": "tsd",
|
|
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
14
|
"coverage-html-local": "nyc npm run test-all-local && nyc report --reporter=html",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"moment": "2.24.0",
|
|
44
44
|
"nyc": "^15.1.0",
|
|
45
45
|
"source-map-support": "^0.5.19",
|
|
46
|
-
"ts-node": "^
|
|
47
|
-
"tsd": "^0.
|
|
48
|
-
"typescript": "^4.
|
|
46
|
+
"ts-node": "^10.8.1",
|
|
47
|
+
"tsd": "^0.21.0",
|
|
48
|
+
"typescript": "^4.7.4",
|
|
49
49
|
"uuid": "7.0.1"
|
|
50
50
|
},
|
|
51
51
|
"keywords": [
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"directory": "test"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"
|
|
65
|
-
"
|
|
64
|
+
"@aws-sdk/lib-dynamodb": "^3.54.1",
|
|
65
|
+
"jsonschema": "1.2.7"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/entity.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ParseOptions
|
|
3
|
+
} from './types/options';
|
|
4
|
+
import {
|
|
5
|
+
TableIndexCompositeAttributes,
|
|
6
|
+
AllTableIndexCompositeAttributes,
|
|
7
|
+
ResponseItem,
|
|
8
|
+
Item,
|
|
9
|
+
Schema,
|
|
10
|
+
SetItem,
|
|
11
|
+
AddItem,
|
|
12
|
+
SubtractItem,
|
|
13
|
+
AppendItem,
|
|
14
|
+
DeleteItem,
|
|
15
|
+
RemoveItem,
|
|
16
|
+
PutItem,
|
|
17
|
+
} from './types/schema';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
Queries,
|
|
21
|
+
SetRecord,
|
|
22
|
+
RemoveRecord,
|
|
23
|
+
DataUpdateMethodRecord,
|
|
24
|
+
RecordsActionOptions,
|
|
25
|
+
SingleRecordOperationOptions,
|
|
26
|
+
BulkRecordOperationOptions,
|
|
27
|
+
DeleteRecordOperationOptions,
|
|
28
|
+
PutRecordOperationOptions,
|
|
29
|
+
ParseSingleInput,
|
|
30
|
+
ParseMultiInput
|
|
31
|
+
} from './types/model';
|
|
32
|
+
|
|
33
|
+
import { ElectroEventListener } from './types/events';
|
|
34
|
+
import { DocumentClient } from './types/client';
|
|
35
|
+
|
|
36
|
+
export type Resolve<T> = T extends Function | string | number | boolean
|
|
37
|
+
? T : {[Key in keyof T]: Resolve<T[Key]>}
|
|
38
|
+
|
|
39
|
+
export type EntityConfiguration = {
|
|
40
|
+
table?: string;
|
|
41
|
+
client?: DocumentClient;
|
|
42
|
+
listeners?: Array<ElectroEventListener>;
|
|
43
|
+
logger?: ElectroEventListener;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export class Entity<A extends string, F extends string, C extends string, S extends Schema<A,F,C>> {
|
|
47
|
+
readonly schema: S;
|
|
48
|
+
private config?: EntityConfiguration;
|
|
49
|
+
constructor(schema: S, config?: EntityConfiguration);
|
|
50
|
+
|
|
51
|
+
get(key: AllTableIndexCompositeAttributes<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S> | null>;
|
|
52
|
+
get(key: AllTableIndexCompositeAttributes<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, [Array<Resolve<ResponseItem<A,F,C,S>>>, Array<Resolve<AllTableIndexCompositeAttributes<A,F,C,S>>>], [Array<Resolve<ResponseItem<A,F,C,S>> | null>, Array<Resolve<AllTableIndexCompositeAttributes<A,F,C,S>>>]>;
|
|
53
|
+
|
|
54
|
+
delete(key: AllTableIndexCompositeAttributes<A,F,C,S>): DeleteRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
|
|
55
|
+
delete(key: AllTableIndexCompositeAttributes<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, AllTableIndexCompositeAttributes<A,F,C,S>[], AllTableIndexCompositeAttributes<A,F,C,S>[]>;
|
|
56
|
+
|
|
57
|
+
put(record: PutItem<A,F,C,S>): PutRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
|
|
58
|
+
put(record: PutItem<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, AllTableIndexCompositeAttributes<A,F,C,S>[], AllTableIndexCompositeAttributes<A,F,C,S>[]>;
|
|
59
|
+
|
|
60
|
+
remove(key: AllTableIndexCompositeAttributes<A,F,C,S>): DeleteRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>
|
|
61
|
+
update(key: AllTableIndexCompositeAttributes<A,F,C,S>): {
|
|
62
|
+
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
63
|
+
remove: RemoveRecord<A,F,C,S, RemoveItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
64
|
+
add: SetRecord<A,F,C,S, AddItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
65
|
+
subtract: SetRecord<A,F,C,S, SubtractItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
66
|
+
append: SetRecord<A,F,C,S, AppendItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
67
|
+
delete: SetRecord<A,F,C,S, DeleteItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
68
|
+
data: DataUpdateMethodRecord<A,F,C,S, Item<A,F,C,S,S["attributes"]>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
patch(key: AllTableIndexCompositeAttributes<A,F,C,S>): {
|
|
72
|
+
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
73
|
+
remove: RemoveRecord<A,F,C,S, RemoveItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
74
|
+
add: SetRecord<A,F,C,S, AddItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
75
|
+
subtract: SetRecord<A,F,C,S, SubtractItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
76
|
+
append: SetRecord<A,F,C,S, AppendItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
77
|
+
delete: SetRecord<A,F,C,S, DeleteItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
78
|
+
data: DataUpdateMethodRecord<A,F,C,S, Item<A,F,C,S,S["attributes"]>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
create(record: PutItem<A,F,C,S>): PutRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>
|
|
82
|
+
|
|
83
|
+
find(record: Partial<Item<A,F,C,S,S["attributes"]>>): RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], AllTableIndexCompositeAttributes<A,F,C,S>>;
|
|
84
|
+
|
|
85
|
+
match(record: Partial<Item<A,F,C,S,S["attributes"]>>): RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], AllTableIndexCompositeAttributes<A,F,C,S>>;
|
|
86
|
+
|
|
87
|
+
scan: RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], TableIndexCompositeAttributes<A,F,C,S>>;
|
|
88
|
+
query: Queries<A,F,C,S>;
|
|
89
|
+
|
|
90
|
+
parse(item: ParseSingleInput, options?: ParseOptions): ResponseItem<A,F,C,S> | null;
|
|
91
|
+
parse(item: ParseMultiInput, options?: ParseOptions): ResponseItem<A,F,C,S>[];
|
|
92
|
+
setIdentifier(type: "entity" | "version", value: string): void;
|
|
93
|
+
client: any;
|
|
94
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Entity } from './entity';
|
|
2
|
+
|
|
3
|
+
const entityWithSK = new Entity({
|
|
4
|
+
model: {
|
|
5
|
+
entity: "abc",
|
|
6
|
+
service: "myservice",
|
|
7
|
+
version: "myversion"
|
|
8
|
+
},
|
|
9
|
+
attributes: {
|
|
10
|
+
attr1: {
|
|
11
|
+
type: "string",
|
|
12
|
+
default: "abc",
|
|
13
|
+
get: (val) => val + 123,
|
|
14
|
+
set: (val) => (val ?? "") + 456,
|
|
15
|
+
validate: (val) => !!val,
|
|
16
|
+
},
|
|
17
|
+
attr2: {
|
|
18
|
+
type: "string",
|
|
19
|
+
// default: () => "sfg",
|
|
20
|
+
// required: false,
|
|
21
|
+
validate: (val) => val.length > 0
|
|
22
|
+
},
|
|
23
|
+
attr3: {
|
|
24
|
+
type: ["123", "def", "ghi"] as const,
|
|
25
|
+
default: "def"
|
|
26
|
+
},
|
|
27
|
+
attr4: {
|
|
28
|
+
type: ["abc", "ghi"] as const,
|
|
29
|
+
required: true
|
|
30
|
+
},
|
|
31
|
+
attr5: {
|
|
32
|
+
type: "string"
|
|
33
|
+
},
|
|
34
|
+
attr6: {
|
|
35
|
+
type: "number",
|
|
36
|
+
default: () => 100,
|
|
37
|
+
get: (val) => val + 5,
|
|
38
|
+
set: (val) => (val ?? 0) + 5,
|
|
39
|
+
validate: (val) => true,
|
|
40
|
+
},
|
|
41
|
+
attr7: {
|
|
42
|
+
type: "any",
|
|
43
|
+
default: () => false,
|
|
44
|
+
get: (val) => ({key: "value"}),
|
|
45
|
+
set: (val) => (val ?? 0) + 5,
|
|
46
|
+
validate: (val) => true,
|
|
47
|
+
},
|
|
48
|
+
attr8: {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
required: true,
|
|
51
|
+
get: (val) => !!val,
|
|
52
|
+
set: (val) => !!val,
|
|
53
|
+
validate: (val) => !!val,
|
|
54
|
+
},
|
|
55
|
+
attr9: {
|
|
56
|
+
type: "number"
|
|
57
|
+
},
|
|
58
|
+
attr10: {
|
|
59
|
+
type: "boolean"
|
|
60
|
+
},
|
|
61
|
+
attr11: {
|
|
62
|
+
type: 'list',
|
|
63
|
+
items: {
|
|
64
|
+
type: 'string'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
indexes: {
|
|
69
|
+
myIndex: {
|
|
70
|
+
collection: "mycollection2",
|
|
71
|
+
pk: {
|
|
72
|
+
field: "pk",
|
|
73
|
+
composite: ["attr1"]
|
|
74
|
+
},
|
|
75
|
+
sk: {
|
|
76
|
+
field: "sk",
|
|
77
|
+
composite: ["attr2"]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
myIndex2: {
|
|
81
|
+
collection: "mycollection1",
|
|
82
|
+
index: "gsi1",
|
|
83
|
+
pk: {
|
|
84
|
+
field: "gsipk1",
|
|
85
|
+
composite: ["attr6", "attr9"]
|
|
86
|
+
},
|
|
87
|
+
sk: {
|
|
88
|
+
field: "gsisk1",
|
|
89
|
+
composite: ["attr4", "attr5"]
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
myIndex3: {
|
|
93
|
+
collection: "mycollection",
|
|
94
|
+
index: "gsi2",
|
|
95
|
+
pk: {
|
|
96
|
+
field: "gsipk2",
|
|
97
|
+
composite: ["attr5"]
|
|
98
|
+
},
|
|
99
|
+
sk: {
|
|
100
|
+
field: "gsisk2",
|
|
101
|
+
composite: ["attr4", "attr3", "attr9"]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
entityWithSK.update({
|
|
108
|
+
attr1: 'abc',
|
|
109
|
+
attr2: 'def'
|
|
110
|
+
}).append({})
|
package/src/service.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Entity } from './entity';
|
|
2
|
+
import { DocumentClient } from './types/client';
|
|
3
|
+
import { ElectroEventListener } from './types/events';
|
|
4
|
+
import { CollectionQueries, CollectionAssociations } from './types/collections';
|
|
5
|
+
|
|
6
|
+
export type ServiceConfiguration = {
|
|
7
|
+
table?: string;
|
|
8
|
+
client?: DocumentClient;
|
|
9
|
+
listeners?: Array<ElectroEventListener>;
|
|
10
|
+
logger?: ElectroEventListener;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class Service<E extends {[name: string]: Entity<any, any, any, any>}> {
|
|
14
|
+
entities: E;
|
|
15
|
+
collections: CollectionQueries<E, CollectionAssociations<E>>
|
|
16
|
+
constructor(entities: E, config?: ServiceConfiguration);
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type DocumentClientMethod = (parameters: any) => {promise: () => Promise<any>};
|
|
2
|
+
|
|
3
|
+
export type DocumentClient = {
|
|
4
|
+
get: DocumentClientMethod;
|
|
5
|
+
put: DocumentClientMethod;
|
|
6
|
+
delete: DocumentClientMethod;
|
|
7
|
+
update: DocumentClientMethod;
|
|
8
|
+
batchWrite: DocumentClientMethod;
|
|
9
|
+
batchGet: DocumentClientMethod;
|
|
10
|
+
scan: DocumentClientMethod;
|
|
11
|
+
transactGet: DocumentClientMethod;
|
|
12
|
+
transactWrite: DocumentClientMethod;
|
|
13
|
+
} | {
|
|
14
|
+
send: (command: any) => Promise<any>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { Entity } from '../entity';
|
|
2
|
+
import {
|
|
3
|
+
GoRecord,
|
|
4
|
+
ParamRecord,
|
|
5
|
+
PageRecord,
|
|
6
|
+
} from './options';
|
|
7
|
+
import {
|
|
8
|
+
EntityCollections,
|
|
9
|
+
ItemAttribute,
|
|
10
|
+
ResponseItem,
|
|
11
|
+
Schema,
|
|
12
|
+
TableIndexCompositeAttributes,
|
|
13
|
+
} from './schema';
|
|
14
|
+
import {
|
|
15
|
+
WhereAttributeSymbol
|
|
16
|
+
} from './where';
|
|
17
|
+
|
|
18
|
+
type AllCollectionNames<E extends {[name: string]: Entity<any, any, any, any>}> = {
|
|
19
|
+
[Name in keyof E]:
|
|
20
|
+
E[Name] extends Entity<infer A, infer F, infer C, infer S>
|
|
21
|
+
? {
|
|
22
|
+
[Collection in keyof EntityCollections<A,F,C,S>]: Collection
|
|
23
|
+
}[keyof EntityCollections<A,F,C,S>]
|
|
24
|
+
: never
|
|
25
|
+
}[keyof E];
|
|
26
|
+
|
|
27
|
+
type AllEntityAttributeNames<E extends {[name: string]: Entity<any, any, any, any>}> = {
|
|
28
|
+
[Name in keyof E]: {
|
|
29
|
+
[A in keyof E[Name]["schema"]["attributes"]]: A
|
|
30
|
+
}[keyof E[Name]["schema"]["attributes"]]
|
|
31
|
+
}[keyof E];
|
|
32
|
+
|
|
33
|
+
type AllEntityAttributes<E extends {[name: string]: Entity<any, any, any, any>}> = {
|
|
34
|
+
[Attr in AllEntityAttributeNames<E>]: {
|
|
35
|
+
[Name in keyof E]: Attr extends keyof E[Name]["schema"]["attributes"]
|
|
36
|
+
? ItemAttribute<E[Name]["schema"]["attributes"][Attr]>
|
|
37
|
+
: never
|
|
38
|
+
}[keyof E];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type CollectionAssociations<E extends {[name: string]: Entity<any, any, any, any>}> = {
|
|
42
|
+
[Collection in AllCollectionNames<E>]: {
|
|
43
|
+
[Name in keyof E]: E[Name] extends Entity<infer A, infer F, infer C, infer S>
|
|
44
|
+
? Collection extends keyof EntityCollections<A,F,C,S>
|
|
45
|
+
? Name
|
|
46
|
+
: never
|
|
47
|
+
: never
|
|
48
|
+
}[keyof E];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type CollectionAttributes<E extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<E>> = {
|
|
52
|
+
[Collection in keyof Collections]: {
|
|
53
|
+
[EntityName in keyof E]: E[EntityName] extends Entity<infer A, infer F, infer C, infer S>
|
|
54
|
+
? EntityName extends Collections[Collection]
|
|
55
|
+
? keyof S["attributes"]
|
|
56
|
+
: never
|
|
57
|
+
: never
|
|
58
|
+
}[keyof E]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface CollectionWhereOperations {
|
|
62
|
+
eq: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
63
|
+
ne: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
64
|
+
gt: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
65
|
+
lt: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
66
|
+
gte: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
67
|
+
lte: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
68
|
+
between: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T, value2: T) => string;
|
|
69
|
+
begins: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
70
|
+
exists: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
71
|
+
notExists: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
72
|
+
contains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
73
|
+
notContains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
74
|
+
value: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
75
|
+
name: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type CollectionWhereCallback<E extends {[name: string]: Entity<any, any, any, any>}, I extends Partial<AllEntityAttributes<E>>> =
|
|
79
|
+
<W extends {[A in keyof I]: WhereAttributeSymbol<I[A]>}>(attributes: W, operations: CollectionWhereOperations) => string;
|
|
80
|
+
|
|
81
|
+
type CollectionWhereClause<E extends {[name: string]: Entity<any, any, any, any>}, A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends Partial<AllEntityAttributes<E>>, T> = (where: CollectionWhereCallback<E, I>) => T;
|
|
82
|
+
|
|
83
|
+
interface WhereRecordsActionOptions<E extends {[name: string]: Entity<any, any, any, any>}, A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends Partial<AllEntityAttributes<E>>, Items, IndexCompositeAttributes> {
|
|
84
|
+
go: GoRecord<Items>;
|
|
85
|
+
params: ParamRecord;
|
|
86
|
+
page: PageRecord<Items,IndexCompositeAttributes>;
|
|
87
|
+
where: CollectionWhereClause<E,A,F,C,S,I, WhereRecordsActionOptions<E,A,F,C,S,I,Items,IndexCompositeAttributes>>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type CollectionIndexKeys<Entities extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<Entities>> = {
|
|
91
|
+
[Collection in keyof Collections]: {
|
|
92
|
+
[EntityResultName in Collections[Collection]]:
|
|
93
|
+
EntityResultName extends keyof Entities
|
|
94
|
+
? Entities[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
95
|
+
? keyof TableIndexCompositeAttributes<A, F, C, S>
|
|
96
|
+
: never
|
|
97
|
+
: never
|
|
98
|
+
}[Collections[Collection]]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
type CollectionPageKeys<Entities extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<Entities>> = {
|
|
102
|
+
[Collection in keyof Collections]: {
|
|
103
|
+
[EntityResultName in Collections[Collection]]:
|
|
104
|
+
EntityResultName extends keyof Entities
|
|
105
|
+
? Entities[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
106
|
+
? keyof Parameters<Entities[EntityResultName]["query"][
|
|
107
|
+
Collection extends keyof EntityCollections<A,F,C,S>
|
|
108
|
+
? EntityCollections<A,F,C,S>[Collection]
|
|
109
|
+
: never
|
|
110
|
+
]>[0]
|
|
111
|
+
: never
|
|
112
|
+
: never
|
|
113
|
+
}[Collections[Collection]]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
type CollectionIndexAttributes<Entities extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<Entities>> = {
|
|
117
|
+
[Collection in keyof CollectionIndexKeys<Entities, Collections>]: {
|
|
118
|
+
[key in CollectionIndexKeys<Entities, Collections>[Collection]]:
|
|
119
|
+
key extends keyof AllEntityAttributes<Entities>
|
|
120
|
+
? AllEntityAttributes<Entities>[key]
|
|
121
|
+
: never
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
type CollectionPageAttributes<Entities extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<Entities>> = {
|
|
126
|
+
[Collection in keyof CollectionPageKeys<Entities, Collections>]: {
|
|
127
|
+
[key in CollectionPageKeys<Entities, Collections>[Collection]]:
|
|
128
|
+
key extends keyof AllEntityAttributes<Entities>
|
|
129
|
+
? AllEntityAttributes<Entities>[key]
|
|
130
|
+
: never
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
type OptionalPropertyNames<T> =
|
|
135
|
+
{ [K in keyof T]: undefined extends T[K] ? K : never }[keyof T];
|
|
136
|
+
|
|
137
|
+
// Common properties from L and R with undefined in R[K] replaced by type in L[K]
|
|
138
|
+
type SpreadProperties<L, R, K extends keyof L & keyof R> =
|
|
139
|
+
{ [P in K]: L[P] | Exclude<R[P], undefined> };
|
|
140
|
+
|
|
141
|
+
type Id<T> = {[K in keyof T]: T[K]} // see note at bottom*
|
|
142
|
+
|
|
143
|
+
// Type of { ...L, ...R }
|
|
144
|
+
type Spread<L, R> = Id<
|
|
145
|
+
// Properties in L that don't exist in R
|
|
146
|
+
& Pick<L, Exclude<keyof L, keyof R>>
|
|
147
|
+
// Properties in R with types that exclude undefined
|
|
148
|
+
& Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>
|
|
149
|
+
// Properties in R, with types that include undefined, that don't exist in L
|
|
150
|
+
& Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>
|
|
151
|
+
// Properties in R, with types that include undefined, that exist in L
|
|
152
|
+
& SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
|
|
153
|
+
>;
|
|
154
|
+
|
|
155
|
+
type RequiredProperties<T> = Pick<T, {[K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T]>
|
|
156
|
+
|
|
157
|
+
export type CollectionQueries<E extends {[name: string]: Entity<any, any, any, any>}, Collections extends CollectionAssociations<E>> = {
|
|
158
|
+
[Collection in keyof Collections]: {
|
|
159
|
+
[EntityName in keyof E]:
|
|
160
|
+
EntityName extends Collections[Collection]
|
|
161
|
+
? (params:
|
|
162
|
+
RequiredProperties<
|
|
163
|
+
Parameters<
|
|
164
|
+
E[EntityName]["query"][
|
|
165
|
+
E[EntityName] extends Entity<infer A, infer F, infer C, infer S>
|
|
166
|
+
? Collection extends keyof EntityCollections<A,F,C,S>
|
|
167
|
+
? EntityCollections<A,F,C,S>[Collection]
|
|
168
|
+
: never
|
|
169
|
+
: never
|
|
170
|
+
]
|
|
171
|
+
>[0]
|
|
172
|
+
>) => {
|
|
173
|
+
go: GoRecord<{
|
|
174
|
+
[EntityResultName in Collections[Collection]]:
|
|
175
|
+
EntityResultName extends keyof E
|
|
176
|
+
? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
177
|
+
? ResponseItem<A,F,C,S>[]
|
|
178
|
+
: never
|
|
179
|
+
: never
|
|
180
|
+
}>;
|
|
181
|
+
params: ParamRecord;
|
|
182
|
+
page: {
|
|
183
|
+
[EntityResultName in Collections[Collection]]: EntityResultName extends keyof E
|
|
184
|
+
? Pick<AllEntityAttributes<E>, Extract<AllEntityAttributeNames<E>, CollectionAttributes<E,Collections>[Collection]>> extends Partial<AllEntityAttributes<E>>
|
|
185
|
+
?
|
|
186
|
+
PageRecord<
|
|
187
|
+
{
|
|
188
|
+
[EntityResultName in Collections[Collection]]:
|
|
189
|
+
EntityResultName extends keyof E
|
|
190
|
+
? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
191
|
+
? ResponseItem<A,F,C,S>[]
|
|
192
|
+
: never
|
|
193
|
+
: never
|
|
194
|
+
},
|
|
195
|
+
Partial<
|
|
196
|
+
Spread<
|
|
197
|
+
Collection extends keyof CollectionPageAttributes<E, Collections>
|
|
198
|
+
? CollectionPageAttributes<E, Collections>[Collection]
|
|
199
|
+
: {},
|
|
200
|
+
Collection extends keyof CollectionIndexAttributes<E, Collections>
|
|
201
|
+
? CollectionIndexAttributes<E, Collections>[Collection]
|
|
202
|
+
: {}
|
|
203
|
+
>
|
|
204
|
+
>
|
|
205
|
+
>
|
|
206
|
+
: never
|
|
207
|
+
: never
|
|
208
|
+
}[Collections[Collection]];
|
|
209
|
+
where: {
|
|
210
|
+
[EntityResultName in Collections[Collection]]: EntityResultName extends keyof E
|
|
211
|
+
? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
212
|
+
? Pick<AllEntityAttributes<E>, Extract<AllEntityAttributeNames<E>, CollectionAttributes<E,Collections>[Collection]>> extends Partial<AllEntityAttributes<E>>
|
|
213
|
+
? CollectionWhereClause<E,A,F,C,S,
|
|
214
|
+
Pick<AllEntityAttributes<E>, Extract<AllEntityAttributeNames<E>, CollectionAttributes<E,Collections>[Collection]>>,
|
|
215
|
+
WhereRecordsActionOptions<E,A,F,C,S,
|
|
216
|
+
Pick<AllEntityAttributes<E>, Extract<AllEntityAttributeNames<E>, CollectionAttributes<E,Collections>[Collection]>>,
|
|
217
|
+
{
|
|
218
|
+
[EntityResultName in Collections[Collection]]:
|
|
219
|
+
EntityResultName extends keyof E
|
|
220
|
+
? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
|
|
221
|
+
? ResponseItem<A,F,C,S>[]
|
|
222
|
+
: never
|
|
223
|
+
: never
|
|
224
|
+
},
|
|
225
|
+
Partial<
|
|
226
|
+
Spread<
|
|
227
|
+
Collection extends keyof CollectionPageAttributes<E, Collections>
|
|
228
|
+
? CollectionPageAttributes<E, Collections>[Collection]
|
|
229
|
+
: {},
|
|
230
|
+
Collection extends keyof CollectionIndexAttributes<E, Collections>
|
|
231
|
+
? CollectionIndexAttributes<E, Collections>[Collection]
|
|
232
|
+
: {}
|
|
233
|
+
>
|
|
234
|
+
>
|
|
235
|
+
>>
|
|
236
|
+
: never
|
|
237
|
+
: never
|
|
238
|
+
: never
|
|
239
|
+
}[Collections[Collection]];
|
|
240
|
+
}
|
|
241
|
+
: never
|
|
242
|
+
}[keyof E];
|
|
243
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type ElectroDBMethodTypes = "put" | "get" | "query" | "scan" | "update" | "delete" | "remove" | "patch" | "create" | "batchGet" | "batchWrite";
|
|
2
|
+
|
|
3
|
+
interface ElectroQueryEvent<P extends any = any> {
|
|
4
|
+
type: 'query';
|
|
5
|
+
method: ElectroDBMethodTypes;
|
|
6
|
+
config: any;
|
|
7
|
+
params: P;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ElectroResultsEvent<R extends any = any> {
|
|
11
|
+
type: 'results';
|
|
12
|
+
method: ElectroDBMethodTypes;
|
|
13
|
+
config: any;
|
|
14
|
+
results: R;
|
|
15
|
+
success: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type ElectroEvent =
|
|
19
|
+
ElectroQueryEvent
|
|
20
|
+
| ElectroResultsEvent;
|
|
21
|
+
|
|
22
|
+
type ElectroEventType = Pick<ElectroEvent, 'type'>;
|
|
23
|
+
|
|
24
|
+
export type ElectroEventListener = (event: ElectroEvent) => void;
|
|
25
|
+
|
|
26
|
+
// todo: coming soon, more events!
|
|
27
|
+
// | {
|
|
28
|
+
// name: "error";
|
|
29
|
+
// type: "configuration_error" | "invalid_query" | "dynamodb_client";
|
|
30
|
+
// message: string;
|
|
31
|
+
// details: ElectroError;
|
|
32
|
+
// } | {
|
|
33
|
+
// name: "error";
|
|
34
|
+
// type: "user_defined";
|
|
35
|
+
// message: string;
|
|
36
|
+
// details: ElectroValidationError;
|
|
37
|
+
// } | {
|
|
38
|
+
// name: "warn";
|
|
39
|
+
// type: "deprecation_warning" | "optimization_suggestion";
|
|
40
|
+
// message: string;
|
|
41
|
+
// details: any;
|
|
42
|
+
// } | {
|
|
43
|
+
// name: "info";
|
|
44
|
+
// type: "client_updated" | "table_overwritten";
|
|
45
|
+
// message: string;
|
|
46
|
+
// details: any;
|
|
47
|
+
// };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Entity } from '../entity';
|
|
2
|
+
import { ResponseItem, PutItem, AddItem, SubtractItem, AppendItem, RemoveItem, DeleteItem, Item } from './schema';
|
|
3
|
+
import { Service } from '../service';
|
|
4
|
+
import { CollectionAssociations } from './collections';
|
|
5
|
+
|
|
6
|
+
export { WhereAttributeSymbol } from './where';
|
|
7
|
+
export { Schema } from './schema';
|
|
8
|
+
|
|
9
|
+
export type EntityItem<E extends Entity<any, any, any, any>> =
|
|
10
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
11
|
+
? ResponseItem<A, F, C, S>
|
|
12
|
+
: never;
|
|
13
|
+
|
|
14
|
+
export type CreateEntityItem<E extends Entity<any, any, any, any>> =
|
|
15
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
16
|
+
? PutItem<A, F, C, S>
|
|
17
|
+
: never;
|
|
18
|
+
|
|
19
|
+
export type UpdateEntityItem<E extends Entity<any, any, any, any>> =
|
|
20
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
21
|
+
? Partial<ResponseItem<A,F,C,S>>
|
|
22
|
+
: never;
|
|
23
|
+
|
|
24
|
+
export type UpdateAddEntityItem<E extends Entity<any, any, any, any>> =
|
|
25
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
26
|
+
? AddItem<A, F, C, S>
|
|
27
|
+
: never;
|
|
28
|
+
|
|
29
|
+
export type UpdateSubtractEntityItem<E extends Entity<any, any, any, any>> =
|
|
30
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
31
|
+
? SubtractItem<A, F, C, S>
|
|
32
|
+
: never;
|
|
33
|
+
|
|
34
|
+
export type UpdateAppendEntityItem<E extends Entity<any, any, any, any>> =
|
|
35
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
36
|
+
? AppendItem<A, F, C, S>
|
|
37
|
+
: never;
|
|
38
|
+
|
|
39
|
+
export type UpdateRemoveEntityItem<E extends Entity<any, any, any, any>> =
|
|
40
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
41
|
+
? RemoveItem<A, F, C, S>
|
|
42
|
+
: never;
|
|
43
|
+
|
|
44
|
+
export type UpdateDeleteEntityItem<E extends Entity<any, any, any, any>> =
|
|
45
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
46
|
+
? DeleteItem<A, F, C, S>
|
|
47
|
+
: never;
|
|
48
|
+
|
|
49
|
+
export type EntityRecord<E extends Entity<any, any, any, any>> =
|
|
50
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
51
|
+
? Item<A,F,C,S,S["attributes"]>
|
|
52
|
+
: never;
|
|
53
|
+
|
|
54
|
+
export type CollectionItem<SERVICE extends Service<any>, COLLECTION extends keyof SERVICE["collections"]> =
|
|
55
|
+
SERVICE extends Service<infer E>
|
|
56
|
+
? Pick<{
|
|
57
|
+
[EntityName in keyof E]: E[EntityName] extends Entity<infer A, infer F, infer C, infer S>
|
|
58
|
+
? COLLECTION extends keyof CollectionAssociations<E>
|
|
59
|
+
? EntityName extends CollectionAssociations<E>[COLLECTION]
|
|
60
|
+
? ResponseItem<A,F,C,S>[]
|
|
61
|
+
: never
|
|
62
|
+
: never
|
|
63
|
+
: never
|
|
64
|
+
}, COLLECTION extends keyof CollectionAssociations<E>
|
|
65
|
+
? CollectionAssociations<E>[COLLECTION]
|
|
66
|
+
: never>
|
|
67
|
+
: never
|