rajt 0.0.57 → 0.0.59
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/README.md +10 -7
- package/package.json +35 -15
- package/src/action-old.ts +72 -0
- package/src/action.ts +12 -61
- package/src/auth/ability.ts +2 -2
- package/src/auth/authnz.ts +3 -0
- package/src/auth/index.ts +0 -1
- package/src/auth/token.ts +27 -24
- package/src/bin/rajt.js +123 -0
- package/src/cli/commands/dev/index.ts +294 -0
- package/src/cli/commands/dev/utils.ts +215 -0
- package/src/cli/index.ts +69 -0
- package/src/cli/types.ts +1 -0
- package/src/create-app.ts +15 -9
- package/src/db/d1.d.ts +1 -0
- package/src/db/d1.ts +1 -0
- package/src/dev.ts +18 -15
- package/src/enum.ts +2 -75
- package/src/esbuild.mjs +11 -9
- package/src/http.ts +9 -8
- package/src/index.ts +1 -3
- package/src/prod-aws.ts +2 -17
- package/src/prod-cf.ts +1 -18
- package/src/prod.ts +16 -0
- package/src/request-old.ts +98 -0
- package/src/request.ts +152 -71
- package/src/response.ts +71 -26
- package/src/routes.ts +66 -2
- package/src/scripts/cache-routes.ts +1 -64
- package/src/types.ts +24 -4
- package/src/utils/environment.ts +3 -2
- package/src/utils/func.ts +2 -2
- package/src/utils/local-date.ts +13 -0
- package/src/utils/logger.ts +61 -0
- package/src/utils/port.ts +1 -3
- package/src/utils/resolve.ts +4 -3
- package/src/utils/shutdown.ts +19 -0
- package/src/validator.ts +68 -0
- package/src/auth/auth.ts +0 -33
- package/src/dynamodb/client.ts +0 -125
- package/src/dynamodb/compact.ts +0 -205
- package/src/dynamodb/decorators.ts +0 -126
- package/src/dynamodb/index.ts +0 -4
- package/src/dynamodb/model.ts +0 -258
- package/src/dynamodb/query-builder.ts +0 -174
- package/src/dynamodb/repository.ts +0 -31
- package/src/dynamodb/schema.ts +0 -107
- package/src/dynamodb/types.ts +0 -32
- package/src/utils/lenght.ts +0 -32
package/src/dynamodb/model.ts
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import type { ModelMetadata, Keys, Model, Filter } from './types'
|
|
2
|
-
import { getModelMetadata } from './decorators'
|
|
3
|
-
import QueryBuilder from './query-builder'
|
|
4
|
-
import Compact from './compact'
|
|
5
|
-
import { RawClient } from './client'
|
|
6
|
-
import { isArraySchema } from './schema'
|
|
7
|
-
import getLength from '../utils/lenght'
|
|
8
|
-
|
|
9
|
-
export default class AbstractModel<T extends object> {
|
|
10
|
-
#meta: ModelMetadata
|
|
11
|
-
cls?: Model<T>
|
|
12
|
-
lastKey?: Record<string, any>
|
|
13
|
-
#queryBuilder?: QueryBuilder
|
|
14
|
-
#model?: AbstractModel<T>
|
|
15
|
-
|
|
16
|
-
constructor(
|
|
17
|
-
cls: Model<T> | ModelMetadata,
|
|
18
|
-
queryBuilder?: QueryBuilder,
|
|
19
|
-
model?: AbstractModel<T>
|
|
20
|
-
) {
|
|
21
|
-
this.#queryBuilder = queryBuilder
|
|
22
|
-
this.#model = model
|
|
23
|
-
|
|
24
|
-
if (typeof (cls as ModelMetadata).table === 'string') {
|
|
25
|
-
this.#meta = cls as ModelMetadata
|
|
26
|
-
this.cls = model?.cls
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const meta = getModelMetadata(cls)
|
|
31
|
-
if (!meta)
|
|
32
|
-
throw new Error('Missing model metadata')
|
|
33
|
-
|
|
34
|
-
this.#meta = meta
|
|
35
|
-
this.cls = cls as Model<T>
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
get table(): string {
|
|
39
|
-
return this.#meta.table
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get keySchema() {
|
|
43
|
-
return this.#meta.keys
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
set lastEvaluatedKey(val: Record<string, any> | undefined) {
|
|
47
|
-
if (this.#model) {
|
|
48
|
-
this.#model.lastKey = val
|
|
49
|
-
} else {
|
|
50
|
-
this.lastKey = val
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
get lastEvaluatedKey() {
|
|
54
|
-
return this.lastKey
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
where(builderFn: (q: QueryBuilder) => void) {
|
|
58
|
-
const qb = new QueryBuilder()
|
|
59
|
-
builderFn(qb)
|
|
60
|
-
return new AbstractModel<T>(this.#meta, qb, this)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async scan(filterFn?: Filter<T>) {
|
|
64
|
-
const result = await RawClient.scan(this.table, this.#queryBuilder?.filters)
|
|
65
|
-
|
|
66
|
-
this.lastEvaluatedKey = result.LastEvaluatedKey
|
|
67
|
-
return this.#processItems(result.Items, filterFn)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async query(filterFn?: Filter<T>) {
|
|
71
|
-
const result = await RawClient.query(this.table, this.#queryBuilder?.conditions)
|
|
72
|
-
|
|
73
|
-
this.lastEvaluatedKey = result.LastEvaluatedKey
|
|
74
|
-
return this.#processItems(result.Items, filterFn)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async get(key: Keys, sk?: string) {
|
|
78
|
-
const result = await RawClient.get(this.table, this.#key(key, sk))
|
|
79
|
-
return result.Item ? this.#processItem(result.Item) : undefined
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async put(item: Partial<T>, key: Keys) {
|
|
83
|
-
let keys
|
|
84
|
-
if (this.#meta.zip) {
|
|
85
|
-
keys = this.#getItemKey(item, key)
|
|
86
|
-
this.#validateKeys(keys)
|
|
87
|
-
// @ts-ignore
|
|
88
|
-
item = { ...keys, V: Compact.encode(this.#getItemWithoutKeys(item), this.#meta.fields) }
|
|
89
|
-
} else {
|
|
90
|
-
this.#validateKeys(item)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
await RawClient.put(this.table, item)
|
|
94
|
-
return this.#processItem(item, keys)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async update(attrs: Partial<T>, key: Keys) {
|
|
98
|
-
let keys
|
|
99
|
-
if (this.#meta.zip) {
|
|
100
|
-
keys = this.#getItemKey(attrs, key)
|
|
101
|
-
this.#validateKeys(keys)
|
|
102
|
-
// @ts-ignore
|
|
103
|
-
attrs = { V: Compact.encode(this.#getItemWithoutKeys(attrs), this.#meta.fields) }
|
|
104
|
-
} else {
|
|
105
|
-
this.#validateKeys(attrs)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const UpdateExpressionParts: string[] = []
|
|
109
|
-
const ExpressionAttributeValues: any = {}
|
|
110
|
-
for (const [k, v] of Object.entries(attrs)) {
|
|
111
|
-
UpdateExpressionParts.push(`#${k} = :${k}`)
|
|
112
|
-
ExpressionAttributeValues[`:${k}`] = v
|
|
113
|
-
}
|
|
114
|
-
const UpdateExpression = 'SET ' + UpdateExpressionParts.join(', ')
|
|
115
|
-
const ExpressionAttributeNames = Object.fromEntries(Object.keys(attrs).map(k => [`#${k}`, k]))
|
|
116
|
-
|
|
117
|
-
await RawClient.update(this.table, {
|
|
118
|
-
UpdateExpression,
|
|
119
|
-
ExpressionAttributeValues,
|
|
120
|
-
ExpressionAttributeNames,
|
|
121
|
-
}, this.#key(key))
|
|
122
|
-
|
|
123
|
-
return this.#processItem(attrs, keys)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async delete(key: Keys, sk?: string) {
|
|
127
|
-
return RawClient.delete(this.table, this.#key(key, sk))
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async batchGet(keys: Array<Keys>) {
|
|
131
|
-
const result = await RawClient.batchGet({
|
|
132
|
-
RequestItems: { [this.table]: { Keys: keys.map(key => this.#key(key)) } },
|
|
133
|
-
})
|
|
134
|
-
return (result.Responses?.[this.table] as T[] || []).map(item => this.#processItem(item))
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async batchWrite(items: Array<{ put?: Partial<T>, delete?: Keys }>) {
|
|
138
|
-
const WriteRequests = items.map(i => {
|
|
139
|
-
if (i.put) {
|
|
140
|
-
return { PutRequest: { Item: i.put } }
|
|
141
|
-
} else if (i.delete) {
|
|
142
|
-
return { DeleteRequest: { Key: this.#key(i.delete) } }
|
|
143
|
-
}
|
|
144
|
-
return null
|
|
145
|
-
}).filter(Boolean) as any[]
|
|
146
|
-
|
|
147
|
-
return RawClient.batchWrite({ RequestItems: { [this.table]: WriteRequests } })
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async deleteMany(keys: Array<Keys>) {
|
|
151
|
-
return this.batchWrite(keys.map(k => ({ delete: k })))
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
async putMany(items: Array<Partial<T>>) {
|
|
155
|
-
return this.batchWrite(items.map(item => ({ put: item })))
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
#key(key: Keys, sk?: string) {
|
|
159
|
-
if (!this.#meta.keys) return {}
|
|
160
|
-
return RawClient.key(key, sk, this.#meta.keys, this.#meta.defaultSK)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
#getItemKey(item: Partial<T>, key?: Keys): Record<string, string> {
|
|
164
|
-
if (!this.#meta.keys) return {}
|
|
165
|
-
|
|
166
|
-
const keys: Record<string, string> = {}
|
|
167
|
-
if (key)
|
|
168
|
-
this.#processExplicitKey(keys, key)
|
|
169
|
-
else if (getLength(item) > 0)
|
|
170
|
-
this.#processItemKeys(keys, item)
|
|
171
|
-
|
|
172
|
-
return keys
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
#processExplicitKey(keys: Record<string, string>, key: Keys): void {
|
|
176
|
-
if (!this.#meta.keys) return
|
|
177
|
-
if (Array.isArray(key)) {
|
|
178
|
-
keys[this.#meta.keys.PK] = key[0]
|
|
179
|
-
|
|
180
|
-
if (this.#meta.keys?.SK) {
|
|
181
|
-
if (key.length > 1)
|
|
182
|
-
// @ts-ignore
|
|
183
|
-
keys[this.#meta.keys.SK] = key[1]
|
|
184
|
-
else if (this.#meta.defaultSK)
|
|
185
|
-
keys[this.#meta.keys.SK] = this.#meta.defaultSK
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
keys[this.#meta.keys.PK] = String(key)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
#processItemKeys(keys: Record<string, string>, item: Partial<T>): void {
|
|
193
|
-
if (!this.#meta.keys) return
|
|
194
|
-
|
|
195
|
-
const pkValue = item[this.#meta.keys.PK as keyof Partial<T>]
|
|
196
|
-
if (pkValue !== undefined)
|
|
197
|
-
keys[this.#meta.keys.PK] = String(pkValue)
|
|
198
|
-
|
|
199
|
-
if (this.#meta.keys?.SK) {
|
|
200
|
-
const skValue = item[this.#meta.keys.SK as keyof Partial<T>]
|
|
201
|
-
if (skValue !== undefined)
|
|
202
|
-
keys[this.#meta.keys.SK] = String(skValue)
|
|
203
|
-
else if (this.#meta.defaultSK)
|
|
204
|
-
keys[this.#meta.keys.SK] = this.#meta.defaultSK
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
#validateKeys(keys: Record<string, any>) {
|
|
209
|
-
if (!this.#meta.keys)
|
|
210
|
-
throw new Error(`Missing keys of table "${this.table}"`)
|
|
211
|
-
|
|
212
|
-
if (!(this.#meta.keys.PK in keys))
|
|
213
|
-
throw new Error(`Missing partition key of table "${this.table}" `)
|
|
214
|
-
|
|
215
|
-
if (this.#meta.keys?.SK && !(this.#meta.keys.SK in keys))
|
|
216
|
-
throw new Error(`Missing sort key of table "${this.table}"`)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
#getItemWithoutKeys(item: Partial<T>): Partial<T> {
|
|
220
|
-
if (Array.isArray(item))
|
|
221
|
-
return item?.length ? item.map(i => this.#getItemWithoutKeys(i)) as T : [] as T
|
|
222
|
-
|
|
223
|
-
if (!this.#meta.keys || !item) return { ...item }
|
|
224
|
-
|
|
225
|
-
const { PK, SK } = this.#meta.keys
|
|
226
|
-
const { [PK as keyof T]: _, [SK as keyof T]: __, ...rest } = item
|
|
227
|
-
|
|
228
|
-
return rest as Partial<T>
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
#processItems(items: any[] | undefined, filterFn?: Filter<T>): T[] {
|
|
232
|
-
if (!items || !items.length) return []
|
|
233
|
-
items = items.map(item => this.#processItem(item))
|
|
234
|
-
return filterFn ? items.filter(filterFn) : items
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
#processItem(item: any, keys?: Record<string, string>): T {
|
|
238
|
-
if (this.#meta.zip && item?.V) {
|
|
239
|
-
const value = Compact.decode<T>(item.V, this.#meta.fields)
|
|
240
|
-
const model = isArraySchema(this.#meta.fields) && Array.isArray(value)
|
|
241
|
-
? value.map(v => new this.cls!(v))
|
|
242
|
-
: new this.cls!(value)
|
|
243
|
-
|
|
244
|
-
if (!keys) keys = this.#getItemKey(item)
|
|
245
|
-
|
|
246
|
-
return this.#withKey(model as T, keys)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return new this.cls!(item)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
#withKey(model: T, keys: Record<string, string>): T {
|
|
253
|
-
// @ts-ignore
|
|
254
|
-
if (Array.isArray(model)) return model.map(m => this.#withKey(m, keys))
|
|
255
|
-
// @ts-ignore
|
|
256
|
-
return model.withKey(keys[this.#meta.keys.PK], keys[this.#meta.keys.SK] || undefined)
|
|
257
|
-
}
|
|
258
|
-
}
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import type { Condition, Operator } from './types'
|
|
2
|
-
|
|
3
|
-
export default class QueryBuilder {
|
|
4
|
-
#filters: Condition[] = []
|
|
5
|
-
#keyConditions: Condition[] = []
|
|
6
|
-
#limit?: number
|
|
7
|
-
#startKey?: Record<string, any>
|
|
8
|
-
#index?: string
|
|
9
|
-
#attrCounter = 1
|
|
10
|
-
#valCounter = 1
|
|
11
|
-
#fieldAttrMap: Record<string, string> = {}
|
|
12
|
-
#fieldValMap: Record<string, string> = {}
|
|
13
|
-
|
|
14
|
-
filter(field: string, operator: Operator, value: any = null) {
|
|
15
|
-
this.#filters.push({ type: 'filter', field, operator, value })
|
|
16
|
-
return this
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
keyCondition(field: string, operator: Operator | any, value?: any) {
|
|
20
|
-
const noVal = value === undefined
|
|
21
|
-
this.#keyConditions.push({ type: 'keyCondition', field, operator: noVal ? '=' : operator, value: noVal ? operator : value })
|
|
22
|
-
return this
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
limit(n: number) {
|
|
26
|
-
this.#limit = n
|
|
27
|
-
return this
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
exclusiveStartKey(key: Record<string, any>) {
|
|
31
|
-
this.#startKey = key
|
|
32
|
-
return this
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
index(name: string) {
|
|
36
|
-
this.#index = name
|
|
37
|
-
return this
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private attrName(field: string) {
|
|
41
|
-
if (!this.#fieldAttrMap[field])
|
|
42
|
-
this.#fieldAttrMap[field] = '#a'+ this.#attrCounter++
|
|
43
|
-
|
|
44
|
-
return this.#fieldAttrMap[field]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private valName(val: any) {
|
|
48
|
-
val = String(val)
|
|
49
|
-
if (!this.#fieldValMap[val])
|
|
50
|
-
this.#fieldValMap[val] = ':v'+ this.#valCounter++
|
|
51
|
-
|
|
52
|
-
return this.#fieldValMap[val]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#resetCounters() {
|
|
56
|
-
this.#attrCounter = 0
|
|
57
|
-
this.#valCounter = 0
|
|
58
|
-
this.#fieldAttrMap = {}
|
|
59
|
-
this.#fieldValMap = {}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
buildExpression(conditions: Condition[]) {
|
|
63
|
-
const exprParts: string[] = []
|
|
64
|
-
const values: Record<string, any> = {}
|
|
65
|
-
const names: Record<string, string> = {}
|
|
66
|
-
|
|
67
|
-
for (const cond of conditions) {
|
|
68
|
-
const attr = this.attrName(cond.field)
|
|
69
|
-
const val = Array.isArray(cond.value) ? '' : this.valName(cond.value)
|
|
70
|
-
names[attr] = cond.field
|
|
71
|
-
|
|
72
|
-
switch (cond.operator) {
|
|
73
|
-
case 'between': {
|
|
74
|
-
const val0 = this.valName(cond.value[0])
|
|
75
|
-
const val1 = this.valName(cond.value[1])
|
|
76
|
-
exprParts.push(`${attr} BETWEEN ${val0} AND ${val1}`)
|
|
77
|
-
values[val0] = cond.value[0]
|
|
78
|
-
values[val1] = cond.value[1]
|
|
79
|
-
break
|
|
80
|
-
}
|
|
81
|
-
case 'begins_with': {
|
|
82
|
-
exprParts.push(`begins_with(${attr}, ${val})`)
|
|
83
|
-
values[val] = cond.value
|
|
84
|
-
break
|
|
85
|
-
}
|
|
86
|
-
case 'in': {
|
|
87
|
-
const inVals = cond.value.map((v: any) => {
|
|
88
|
-
const key = this.valName(v)
|
|
89
|
-
values[key] = v
|
|
90
|
-
return key
|
|
91
|
-
})
|
|
92
|
-
exprParts.push(`${attr} IN (${inVals.join(', ')})`)
|
|
93
|
-
break
|
|
94
|
-
}
|
|
95
|
-
case 'attribute_exists': {
|
|
96
|
-
exprParts.push(`attribute_exists(${attr})`)
|
|
97
|
-
break
|
|
98
|
-
}
|
|
99
|
-
case 'attribute_not_exists': {
|
|
100
|
-
exprParts.push(`attribute_not_exists(${attr})`)
|
|
101
|
-
break
|
|
102
|
-
}
|
|
103
|
-
case 'attribute_type': {
|
|
104
|
-
exprParts.push(`attribute_type(${attr}, ${val})`)
|
|
105
|
-
values[val] = cond.value
|
|
106
|
-
break
|
|
107
|
-
}
|
|
108
|
-
case 'contains': {
|
|
109
|
-
exprParts.push(`contains(${attr}, ${val})`)
|
|
110
|
-
values[val] = cond.value
|
|
111
|
-
break
|
|
112
|
-
}
|
|
113
|
-
case 'size': {
|
|
114
|
-
exprParts.push(`size(${attr}) = ${val}`)
|
|
115
|
-
values[val] = cond.value
|
|
116
|
-
break
|
|
117
|
-
}
|
|
118
|
-
default: {
|
|
119
|
-
exprParts.push(`${attr} ${cond.operator} ${val}`)
|
|
120
|
-
values[val] = cond.value
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
expression: exprParts.length ? exprParts.join(' AND ') : undefined,
|
|
127
|
-
names: Object.keys(names).length ? names : undefined,
|
|
128
|
-
values: Object.keys(values).length ? values : undefined,
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
get filters() {
|
|
133
|
-
const filter = this.buildExpression(this.#filters)
|
|
134
|
-
const params: any = {}
|
|
135
|
-
|
|
136
|
-
if (this.#limit)
|
|
137
|
-
params.Limit = this.#limit
|
|
138
|
-
|
|
139
|
-
if (this.#startKey)
|
|
140
|
-
params.ExclusiveStartKey = this.#startKey
|
|
141
|
-
|
|
142
|
-
if (filter.expression)
|
|
143
|
-
params.FilterExpression = filter.expression
|
|
144
|
-
|
|
145
|
-
if (filter.names)
|
|
146
|
-
params.ExpressionAttributeNames = filter.names
|
|
147
|
-
|
|
148
|
-
if (filter.values)
|
|
149
|
-
params.ExpressionAttributeValues = filter.values
|
|
150
|
-
|
|
151
|
-
return params
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
get conditions() {
|
|
155
|
-
const keys = this.buildExpression(this.#keyConditions)
|
|
156
|
-
const filters = this.filters
|
|
157
|
-
|
|
158
|
-
const params: any = { ...filters }
|
|
159
|
-
|
|
160
|
-
if (this.#index)
|
|
161
|
-
params.IndexName = this.#index
|
|
162
|
-
|
|
163
|
-
if (keys.expression)
|
|
164
|
-
params.KeyConditionExpression = keys.expression
|
|
165
|
-
|
|
166
|
-
if (keys.names || filters?.ExpressionAttributeNames)
|
|
167
|
-
params.ExpressionAttributeNames = { ...(keys?.names || {}), ...(filters?.ExpressionAttributeNames || {}) }
|
|
168
|
-
|
|
169
|
-
if (keys.values || filters?.ExpressionAttributeValues)
|
|
170
|
-
params.ExpressionAttributeValues = { ...(keys?.values || {}), ...(filters?.ExpressionAttributeValues || {}) }
|
|
171
|
-
|
|
172
|
-
return params
|
|
173
|
-
}
|
|
174
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { z, ZodTypeAny } from 'zod'
|
|
2
|
-
import { Dynamodb } from './client'
|
|
3
|
-
import { Schema } from './schema'
|
|
4
|
-
import { _model } from './decorators'
|
|
5
|
-
import type { ModelOpts } from './types'
|
|
6
|
-
|
|
7
|
-
export function Repository<
|
|
8
|
-
S extends ZodTypeAny,
|
|
9
|
-
B extends new (...args: any[]) => any
|
|
10
|
-
>(
|
|
11
|
-
schema: S,
|
|
12
|
-
base?: B | ModelOpts,
|
|
13
|
-
opts?: ModelOpts
|
|
14
|
-
) {
|
|
15
|
-
const isClass = typeof base === 'function'
|
|
16
|
-
type M = z.infer<S>
|
|
17
|
-
|
|
18
|
-
const Repo = Schema(schema, isClass ? base : undefined)
|
|
19
|
-
_model(Repo, isClass ? opts : base)
|
|
20
|
-
|
|
21
|
-
return class extends Repo {
|
|
22
|
-
static model = Dynamodb.model<M>(Repo as any)
|
|
23
|
-
|
|
24
|
-
static get lastKey() {
|
|
25
|
-
return this.model?.lastEvaluatedKey || null
|
|
26
|
-
}
|
|
27
|
-
} as unknown as (typeof Repo) & {
|
|
28
|
-
new (...args: any[]): InstanceType<typeof Repo>
|
|
29
|
-
model: ReturnType<typeof Dynamodb.model<M>>
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/dynamodb/schema.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { z, ZodTypeAny } from 'zod'
|
|
2
|
-
import type { SchemaStructure } from './types'
|
|
3
|
-
|
|
4
|
-
const m = Symbol('a')
|
|
5
|
-
export function isArraySchema(v: any): boolean {
|
|
6
|
-
return v[m] || false
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function arraySchema(v: any): any {
|
|
10
|
-
// @ts-ignore
|
|
11
|
-
v[m] = true
|
|
12
|
-
return v
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
|
|
16
|
-
if (schema instanceof z.ZodObject) {
|
|
17
|
-
return Object.entries(schema.shape).map(([key, value]) => {
|
|
18
|
-
const inner = unwrap(value as ZodTypeAny)
|
|
19
|
-
|
|
20
|
-
if (inner instanceof z.ZodObject)
|
|
21
|
-
return notEmpty(key, extractZodKeys(inner))
|
|
22
|
-
|
|
23
|
-
if (inner instanceof z.ZodArray) {
|
|
24
|
-
const item = unwrap(inner._def.type as ZodTypeAny)
|
|
25
|
-
return item instanceof z.ZodObject ? notEmpty(key, extractZodKeys(item)) : key
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return key
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (schema instanceof z.ZodArray) {
|
|
33
|
-
const item = unwrap(schema._def.type as ZodTypeAny)
|
|
34
|
-
if (item instanceof z.ZodObject)
|
|
35
|
-
return arraySchema(extractZodKeys(item))
|
|
36
|
-
|
|
37
|
-
return []
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return []
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function unwrap(schema: ZodTypeAny): ZodTypeAny {
|
|
44
|
-
if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable)
|
|
45
|
-
return unwrap(schema._def.innerType)
|
|
46
|
-
|
|
47
|
-
if (schema instanceof z.ZodDefault)
|
|
48
|
-
return unwrap(schema._def.innerType)
|
|
49
|
-
|
|
50
|
-
// if (schema instanceof z.ZodUnion)
|
|
51
|
-
// return unwrap(schema._def.options[0] as ZodTypeAny)
|
|
52
|
-
|
|
53
|
-
if (schema instanceof z.ZodUnion) {
|
|
54
|
-
const options = schema._def.options as ZodTypeAny[]
|
|
55
|
-
const nonEmptyOption = options.find(opt => !(opt instanceof z.ZodUndefined) && !(opt instanceof z.ZodNull))
|
|
56
|
-
return nonEmptyOption ? unwrap(nonEmptyOption) : options[0]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (schema instanceof z.ZodEffects)
|
|
60
|
-
return unwrap(schema._def.schema)
|
|
61
|
-
|
|
62
|
-
return schema
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function notEmpty(key: string, schema: SchemaStructure): string | Record<string, SchemaStructure> {
|
|
66
|
-
return schema?.length ? {[key]: schema} : key
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function Schema<
|
|
70
|
-
T extends ZodTypeAny,
|
|
71
|
-
B extends object
|
|
72
|
-
>(
|
|
73
|
-
schema: T,
|
|
74
|
-
BaseClass?: new (...args: any[]) => B
|
|
75
|
-
) {
|
|
76
|
-
const Base = (BaseClass || class {})
|
|
77
|
-
|
|
78
|
-
return class extends Base {
|
|
79
|
-
static _schema = schema
|
|
80
|
-
static defaultSortKey?: string
|
|
81
|
-
|
|
82
|
-
#PK?: string
|
|
83
|
-
#SK?: string
|
|
84
|
-
|
|
85
|
-
constructor(data: z.infer<T>) {
|
|
86
|
-
super()
|
|
87
|
-
Object.assign(this, data)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
get PK() { return this.#PK }
|
|
91
|
-
get SK() { return this.#SK }
|
|
92
|
-
|
|
93
|
-
static get schema() {
|
|
94
|
-
return extractZodKeys(this._schema)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
static get defaultSK() {
|
|
98
|
-
return this.defaultSortKey
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
withKey(key: string, sk?: string) {
|
|
102
|
-
this.#PK = key
|
|
103
|
-
if (sk) this.#SK = sk
|
|
104
|
-
return this
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
package/src/dynamodb/types.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export type Operator = '=' | '<>' | '<' | '<=' | '>' | '>=' | 'begins_with' | 'between' | 'in' | 'attribute_exists' | 'attribute_not_exists' | 'attribute_type' | 'contains' | 'size'
|
|
2
|
-
|
|
3
|
-
export type Condition = {
|
|
4
|
-
type: 'filter' | 'keyCondition',
|
|
5
|
-
field: string,
|
|
6
|
-
operator: Operator,
|
|
7
|
-
value: any
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type ISchemaStructure = string | Record<string, ISchemaStructure[]>
|
|
11
|
-
export type SchemaStructure = ISchemaStructure[]
|
|
12
|
-
|
|
13
|
-
export type KeySchema = Record<'PK' | 'SK', string>
|
|
14
|
-
export type ModelMetadata = {
|
|
15
|
-
table: string,
|
|
16
|
-
keys?: KeySchema,
|
|
17
|
-
defaultSK?: string,
|
|
18
|
-
zip: boolean,
|
|
19
|
-
fields: SchemaStructure,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type ModelOpts = string | {
|
|
23
|
-
table?: string,
|
|
24
|
-
partitionKey?: string,
|
|
25
|
-
sortKey?: string,
|
|
26
|
-
defaultSK?: string,
|
|
27
|
-
zip?: boolean,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type Keys = string | [string] | [string, string]
|
|
31
|
-
export type Model<T extends object> = new (...args: any[]) => T
|
|
32
|
-
export type Filter<T> = (item: T) => boolean
|
package/src/utils/lenght.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export default function getLength(item: any, type?: string): number {
|
|
2
|
-
if (!type) type = typeof item
|
|
3
|
-
|
|
4
|
-
switch (type) {
|
|
5
|
-
case 'string':
|
|
6
|
-
return item.length
|
|
7
|
-
|
|
8
|
-
case 'number':
|
|
9
|
-
case 'bigint':
|
|
10
|
-
// case 'function':
|
|
11
|
-
return item.toString().length
|
|
12
|
-
|
|
13
|
-
// case 'boolean':
|
|
14
|
-
// return item ? 1 : 0
|
|
15
|
-
|
|
16
|
-
// case 'symbol':
|
|
17
|
-
// return item.toString().length - 8
|
|
18
|
-
|
|
19
|
-
case 'object':
|
|
20
|
-
if (item === null)
|
|
21
|
-
return 0
|
|
22
|
-
|
|
23
|
-
if (Array.isArray(item))
|
|
24
|
-
return item.length
|
|
25
|
-
|
|
26
|
-
return Object.keys(item).length
|
|
27
|
-
|
|
28
|
-
case 'undefined':
|
|
29
|
-
default:
|
|
30
|
-
return 0
|
|
31
|
-
}
|
|
32
|
-
}
|