-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
schema.ts
113 lines (101 loc) · 3.19 KB
/
schema.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import type { CoreSchema } from '../schema/index.js';
import type { IfAny, UnpackList } from './utils.js';
/**
* Get all available top level Item types from a given Schema
*/
export type ItemType<Schema extends object> =
| Schema[keyof Schema]
| {
[K in keyof Schema]: Schema[K] extends any[] ? Schema[K][number] : never;
}[keyof Schema];
/**
* Return singular collection type
*/
export type CollectionType<Schema extends object, Collection> = IfAny<
Schema,
any,
Collection extends keyof Schema
? UnpackList<Schema[Collection]> extends object
? UnpackList<Schema[Collection]>
: never
: never
>;
/**
* Returns a list of singleton collections in the schema
*/
export type SingletonCollections<Schema extends object> = {
[Key in keyof Schema]: Schema[Key] extends any[] ? never : Key;
}[keyof Schema];
/**
* Returns a list of regular collections in the schema
*/
export type RegularCollections<Schema extends object> = IfAny<
Schema,
string,
Exclude<keyof Schema, SingletonCollections<Schema>>
>;
/**
* Return string keys of all Primitive fields in the given schema Item
*/
export type PrimitiveFields<Schema extends object, Item> = {
[Key in keyof Item]: Extract<Item[Key], ItemType<Schema>> extends never ? Key : never;
}[keyof Item];
/**
* Return string keys of all Relational fields in the given schema Item
*/
export type RelationalFields<Schema extends object, Item> = {
[Key in keyof Item]: Extract<Item[Key], ItemType<Schema>> extends never ? never : Key;
}[keyof Item];
/**
* Remove the related Item types from relational m2o/a2o fields
*/
export type RemoveRelationships<Schema extends object, Item> = {
[Key in keyof Item]: Exclude<Item[Key], ItemType<Schema>>;
};
/**
* Merge a core collection from the schema with the builtin schema
*/
export type MergeCoreCollection<
Schema extends object,
Collection extends keyof Schema | string,
BuiltinCollection,
> = Collection extends keyof Schema
? UnpackList<Schema[Collection]> extends infer Item
? {
[Field in Exclude<keyof Item, keyof BuiltinCollection>]: Item[Field];
} & BuiltinCollection
: never
: BuiltinCollection;
/**
* Merge custom and core schema objects
*/
export type CompleteSchema<Schema extends object> = CoreSchema<Schema> extends infer Core
? {
[Collection in keyof Schema | keyof Core]: Collection extends keyof Core
? Core[Collection]
: Collection extends keyof Schema
? Schema[Collection]
: never;
}
: never;
/**
* Merge custom schema with core schema
*/
export type AllCollections<Schema extends object> = RegularCollections<Schema> | RegularCollections<CoreSchema<Schema>>;
/**
* Helper to extract a collection with fallback to defaults
*/
export type GetCollection<
Schema extends object,
CollectionName extends AllCollections<Schema>,
> = CollectionName extends keyof CoreSchema<Schema>
? CoreSchema<Schema>[CollectionName]
: CollectionName extends keyof Schema
? Schema[CollectionName]
: never;
/**
* Helper to extract a collection name
*/
export type GetCollectionName<Schema extends object, Collection, FullSchema extends object = CompleteSchema<Schema>> = {
[K in keyof FullSchema]: UnpackList<FullSchema[K]> extends Collection ? K : never;
}[keyof FullSchema];