-
Notifications
You must be signed in to change notification settings - Fork 105
/
Model.d.ts
348 lines (314 loc) · 10.5 KB
/
Model.d.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
Model.d.ts -- Hand crafted type definitions for Model
Supports dynamic definition of types based on the Schema.js
*/
import {Expression} from './Expression.js'
/*
Possible types for a schema field "type" property
*/
export type OneType =
| ArrayConstructor
| BooleanConstructor
| DateConstructor
| NumberConstructor
| ObjectConstructor
| StringConstructor
| SetConstructor
| ArrayBufferConstructor
| string
/*
Schema.indexes signature
*/
export type OneIndex = {
hash?: string
sort?: string
description?: string
project?: string | readonly string[]
follow?: boolean
type?: string
}
/*
Schema.models.Model.Field signature
*/
export type OneField = {
crypt?: boolean
default?: string | number | boolean | object | Array<any>
encode?: readonly (string | RegExp | number)[]
enum?: readonly string[]
filter?: boolean
generate?: string | boolean
hidden?: boolean
items?: OneField
map?: string
nulls?: boolean
partial?: boolean
reference?: string
required?: boolean
schema?: OneModel
scope?: string
timestamp?: boolean
ttl?: boolean
type: OneType
unique?: boolean
validate?: RegExp | string | boolean
value?: boolean | string
// DEPRECATE 2.3
uuid?: boolean | string
}
/*
Schema.models signature
*/
export type OneModel = {
[key: string]: OneField
}
/*
Schema signature
*/
export type OneSchema = {
name?: string
version: string
format?: string
params?: OneSchemaParams
models: {
[key: string]: OneModel
}
process?: object
indexes: {
[key: string]: OneIndex
}
queries?: {}
}
export type OneSchemaParams = {
createdField?: string // Name of "created" timestamp attribute. Default to 'created'.
hidden?: boolean // Hide key attributes in Javascript properties. Default false.
isoDates?: boolean // Set to true to store dates as Javascript ISO Date strings. Default false.
nulls?: boolean // Store nulls in database attributes. Default false.
timestamps?: boolean | string // Make "created" and "updated" timestamps. Set to true, 'create' or 'update'. Default true.
typeField?: string // Name of model type attribute. Default "_type".
updatedField?: string // Name of "updated" timestamp attribute. Default 'updated'.
}
/*
Entity field signature generated from the schema
*/
type EntityField<T extends OneField> = T['enum'] extends readonly EntityFieldFromType<T>[]
? T['enum'][number]
: EntityFieldFromType<T>
type EntityFieldFromType<T extends OneField> = T['type'] extends ArrayConstructor | 'array'
? ArrayItemType<T>[]
: T['type'] extends BooleanConstructor | 'boolean'
? boolean
: T['type'] extends NumberConstructor | 'number'
? number
: T['type'] extends ObjectConstructor | 'object'
? (T['schema'] extends object ? Entity<Exclude<T['schema'], undefined>> : Record<any, any>)
: T['type'] extends DateConstructor | 'date'
? Date
: T['type'] extends ArrayBufferConstructor
? ArrayBuffer
: T['type'] extends StringConstructor | 'string'
? string
: T['type'] extends SetConstructor | 'set'
? Set<any>
: T['type'] extends 'typed-array'
? EntityFieldFromType<Exclude<T['items'], undefined>>[]
: never
type ArrayItemType<T extends OneField> = T extends {items: OneField} ? EntityFieldFromType<T['items']> : any
/*
Select the required properties from a model
*/
export type Required<T extends OneModel> = {
-readonly [P in keyof T as T[P]['required'] extends true ? P : never]: EntityField<T[P]>
}
/*
Select the optional properties from a model
*/
export type Optional<T extends OneModel> = {
-readonly [P in keyof T as T[P]['required'] extends true ? never : P]?: EntityField<T[P]>
}
type OptionalOrNull<T extends OneModel> = {
-readonly [P in keyof T as T[P]['required'] extends true ? never : P]?: EntityField<T[P]> | null
}
type OptionalOrUndefined<T extends OneModel> = {
-readonly [P in keyof T as T[P]['required'] extends true ? never : P]?: EntityField<T[P]> | undefined
}
/*
Select properties with generated values
*/
export type Generated<T extends OneModel> = {
-readonly [P in keyof T as T[P]['generate'] extends string | boolean ? P : never]?: EntityField<T[P]>
}
/*
Select properties with default values
*/
type DefinedValue = string | number | bigint | boolean | symbol | object
export type Defaulted<T extends OneModel> = {
-readonly [P in keyof T as T[P]['default'] extends DefinedValue ? P : never]: EntityField<T[P]>
}
/*
Select value template properties
*/
export type ValueTemplates<T extends OneModel> = {
-readonly [P in keyof T as T[P]['value'] extends string ? P : never]: EntityField<T[P]>
}
/*
Select timestamp properties
*/
export type TimestampValue<T extends OneModel> = {
-readonly [P in keyof T as T[P]['timestamp'] extends true ? P : never]: EntityField<T[P]>
}
/*
Merge the properties of two types given preference to A.
*/
type Merge<A extends any, B extends any> = {
[P in keyof (A & B)]: P extends keyof A ? A[P] : P extends keyof B ? B[P] : never
}
/*
Create entity type which includes required and optional types
An entity type is not used by the user and is only required internally.
Merge gives better intellisense, but requires Flatten to make <infer X> work.
*/
type Flatten<T> = {[P in keyof T]: T[P]}
type Entity<T extends OneModel> = Flatten<Merge<Required<T>, OptionalOrUndefined<T>>>
/*
Entity Parameters are partial Entities.
*/
type EntityParameters<Entity> = Partial<Entity>
/*
Special case for find to allow query operators
*/
type EntityParametersForFind<T> = Partial<{
[K in keyof T]:
| T[K]
| Begins<T, K>
| BeginsWith<T, K>
| Between<T, K>
| LessThan<T, K>
| LessThanOrEqual<T, K>
| Equal<T, K>
| NotEqual<T, K>
| GreaterThanOrEqual<T, K>
| GreaterThan<T, K>
}>
type Begins<T, K extends keyof T> = {begins: T[K]}
type BeginsWith<T, K extends keyof T> = {begins_with: T[K]}
type Between<T, K extends keyof T> = {between: [T[K], T[K]]}
type LessThan<T, K extends keyof T> = {'<': T[K]}
type LessThanOrEqual<T, K extends keyof T> = {'<=': T[K]}
type Equal<T, K extends keyof T> = {'=': T[K]}
type NotEqual<T, K extends keyof T> = {'<>': T[K]}
type GreaterThanOrEqual<T, K extends keyof T> = {'>=': T[K]}
type GreaterThan<T, K extends keyof T> = {'>': T[K]}
/*
Any entity. Essentially untyped.
*/
export type AnyEntity = {
[key: string]: any
}
type ModelConstructorOptions = {
fields?: OneModel
indexes?: {
[key: string]: OneIndex
}
timestamps?: boolean | string
}
/*
Possible params options for all APIs
*/
export type OneParams = {
add?: object
batch?: object
capacity?: string
consistent?: boolean
context?: object
count?: boolean
delete?: object
execute?: boolean
exists?: boolean | null
fields?: string[]
follow?: boolean
hidden?: boolean
index?: string
limit?: number
log?: boolean
many?: boolean
maxPages?: number
next?: object
parse?: boolean
partial?: boolean
postFormat?: (model: AnyModel, cmd: {}) => {}
prev?: object
push?: object
remove?: string[]
reprocess?: boolean
return?: string | boolean
reverse?: boolean
segment?: number
segments?: number
select?: string
set?: object
stats?: object
substitutions?: object
timestamps?: boolean
throw?: boolean
transform?: (model: AnyModel, op: string, name: string, value: any, properties: OneProperties) => any
transaction?: object
type?: string
tunnel?: object
where?: string
profile?: string
}
/*
Properties for most APIs. Essentially untyped.
*/
export type OneProperties = {
[key: string]: any
}
export class Paged<T> extends Array<T> {
count?: number
next?: object
prev?: object
}
export type AnyModel = {
constructor(table: any, name: string, options?: ModelConstructorOptions): AnyModel
create(properties: OneProperties, params?: OneParams): Promise<AnyEntity>
find(properties?: OneProperties, params?: OneParams): Promise<Paged<AnyEntity>>
get(properties: OneProperties, params?: OneParams): Promise<AnyEntity | undefined>
load(properties: OneProperties, params?: OneParams): Promise<AnyEntity | undefined>
init(properties?: OneProperties, params?: OneParams): AnyEntity
remove(properties: OneProperties, params?: OneParams): Promise<AnyEntity | Array<AnyEntity> | undefined>
scan(properties?: OneProperties, params?: OneParams): Promise<Paged<AnyEntity>>
update(properties: OneProperties, params?: OneParams): Promise<AnyEntity>
upsert(properties: OneProperties, params?: OneParams): Promise<AnyEntity>
}
type ExtractModel<M> = M extends Entity<infer X> ? X : never
type GetKeys<T> = T extends T ? keyof T : never
/*
Create the type for create properties.
Allow, but not require: generated, defaulted and value templates
Require all other required properties and allow all optional properties
type EntityParametersForCreate<M extends OneModel> = Required<M> & Optional<M>
*/
type EntityParametersForCreate<T extends OneModel> = Omit<
Omit<Omit<Omit<Required<T>, GetKeys<Defaulted<T>>>, GetKeys<Generated<T>>>, GetKeys<ValueTemplates<T>>>,
GetKeys<TimestampValue<T>>
> &
Optional<T> &
Partial<Generated<T>> &
Partial<Defaulted<T>> &
Partial<ValueTemplates<T>> &
Partial<TimestampValue<T>>
type EntityParametersForUpdate<T extends OneModel> = Partial<Required<T> & OptionalOrNull<T>>
type TransactionalOneParams = OneParams & {transaction: object}
export class Model<T> {
constructor(table: any, name: string, options?: ModelConstructorOptions)
create(properties: EntityParametersForCreate<ExtractModel<T>>, params?: OneParams): Promise<T>
find(properties?: EntityParametersForFind<T>, params?: OneParams): Promise<Paged<T>>
get(properties: EntityParameters<T>, params?: OneParams): Promise<T | undefined>
load(properties: EntityParameters<T>, params?: OneParams): Promise<T | undefined>
init(properties?: EntityParameters<T>, params?: OneParams): T
remove(properties: EntityParameters<T>, params?: OneParams): Promise<T | Array<T> | undefined>
scan(properties?: EntityParameters<T>, params?: OneParams): Promise<Paged<T>>
update(properties: EntityParametersForUpdate<ExtractModel<T>>, params?: OneParams): Promise<T>
upsert(properties: EntityParameters<T>, params?: OneParams): Promise<T>
check(properties: EntityParameters<T>, params: TransactionalOneParams): void
}