rajt 0.0.49 → 0.0.51
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/package.json +1 -1
- package/src/dynamodb/client.ts +31 -16
- package/src/dynamodb/compact.ts +33 -15
- package/src/dynamodb/model.ts +4 -25
- package/src/dynamodb/schema.ts +15 -9
package/package.json
CHANGED
package/src/dynamodb/client.ts
CHANGED
|
@@ -21,14 +21,14 @@ import {
|
|
|
21
21
|
} from '@aws-sdk/lib-dynamodb'
|
|
22
22
|
import type { NativeAttributeValue } from '@aws-sdk/util-dynamodb'
|
|
23
23
|
import AbstractModel from './model'
|
|
24
|
-
import { Keys } from './types'
|
|
24
|
+
import { Keys, KeySchema } from './types'
|
|
25
25
|
|
|
26
26
|
const client = new DynamoDBClient(process.env?.AWS_SAM_LOCAL ? {
|
|
27
|
-
region: process.env.AWS_REGION ||
|
|
27
|
+
region: process.env.AWS_REGION || 'us-east-1',
|
|
28
28
|
endpoint: process.env.AWS_ENDPOINT_URL || undefined,
|
|
29
29
|
credentials: {
|
|
30
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID ||
|
|
31
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY ||
|
|
30
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'DUMMYIDEXAMPLE',
|
|
31
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'DUMMYEXAMPLEKEY',
|
|
32
32
|
},
|
|
33
33
|
} : {})
|
|
34
34
|
|
|
@@ -46,10 +46,7 @@ export class Dynamodb {
|
|
|
46
46
|
|
|
47
47
|
export class RawClient {
|
|
48
48
|
static async get(TableName: string, key: Keys | Record<string, string>, sk?: string) {
|
|
49
|
-
return DocumentClient.send(new GetCommand({
|
|
50
|
-
TableName,
|
|
51
|
-
Key: this.#key(key, sk),
|
|
52
|
-
}))
|
|
49
|
+
return DocumentClient.send(new GetCommand({ TableName, Key: this.key(key, sk) }))
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
static async scan(TableName: string, filters: Omit<ScanCommandInput, 'TableName'>) {
|
|
@@ -71,12 +68,12 @@ export class RawClient {
|
|
|
71
68
|
sk?: string
|
|
72
69
|
) {
|
|
73
70
|
return DocumentClient.send(new UpdateCommand({
|
|
74
|
-
...filters, TableName, Key: this
|
|
71
|
+
...filters, TableName, Key: this.key(key, sk),
|
|
75
72
|
}))
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
static async delete(TableName: string, key: Keys | Record<string, string>, sk?: string) {
|
|
79
|
-
return DocumentClient.send(new DeleteCommand({ TableName, Key: this
|
|
76
|
+
return DocumentClient.send(new DeleteCommand({ TableName, Key: this.key(key, sk) }))
|
|
80
77
|
}
|
|
81
78
|
|
|
82
79
|
static async batchGet(batch: BatchGetCommandInput) {
|
|
@@ -87,23 +84,41 @@ export class RawClient {
|
|
|
87
84
|
return DocumentClient.send(new BatchWriteCommand(batch))
|
|
88
85
|
}
|
|
89
86
|
|
|
90
|
-
static
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
static key(
|
|
88
|
+
key: Keys | Record<string, string>,
|
|
89
|
+
sk?: string,
|
|
90
|
+
schema?: KeySchema,
|
|
91
|
+
defaultSK?: string,
|
|
92
|
+
) {
|
|
93
93
|
let pk: string
|
|
94
94
|
let skValue: string | undefined
|
|
95
95
|
|
|
96
96
|
if (Array.isArray(key)) {
|
|
97
97
|
pk = key[0]
|
|
98
98
|
skValue = key[1] ?? sk
|
|
99
|
+
} else if (typeof key == 'object' && key != null) {
|
|
100
|
+
return key
|
|
99
101
|
} else {
|
|
100
102
|
pk = key
|
|
101
103
|
skValue = sk
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
if (!schema) {
|
|
107
|
+
const keys = {PK: pk}
|
|
108
|
+
// @ts-ignore
|
|
109
|
+
if (skValue) keys.SK = skValue
|
|
110
|
+
return keys
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const keys = { [schema.PK]: pk }
|
|
114
|
+
|
|
115
|
+
if (schema?.SK) {
|
|
116
|
+
if (skValue) {
|
|
117
|
+
keys[schema.SK] = skValue
|
|
118
|
+
} else if (defaultSK) {
|
|
119
|
+
keys[schema.SK] = defaultSK
|
|
120
|
+
}
|
|
121
|
+
}
|
|
107
122
|
|
|
108
123
|
return keys
|
|
109
124
|
}
|
package/src/dynamodb/compact.ts
CHANGED
|
@@ -29,14 +29,28 @@ export default class Compact {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
static {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const keys = []
|
|
33
|
+
const values = []
|
|
34
|
+
const reverseTypeMap: Record<string, string> = {}
|
|
35
|
+
for (const key in this.#typeMap) {
|
|
36
|
+
const val = this.#typeMap[key]
|
|
37
|
+
const k = key.replace(/"/g, "'")
|
|
38
|
+
keys.push(k)
|
|
39
|
+
values.push(val)
|
|
40
|
+
|
|
41
|
+
reverseTypeMap[val] = k
|
|
42
|
+
this.#typeMap[k] = val
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.#reverseTypeMap = reverseTypeMap
|
|
46
|
+
this.#typeRegex = this.#mapRegex(keys)
|
|
47
|
+
this.#reverseTypeRegex = this.#mapRegex(values)
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
static encode(obj: any, schema: SchemaStructure): string {
|
|
38
51
|
const seen: any[] = []
|
|
39
|
-
|
|
52
|
+
|
|
53
|
+
return this.#pack(
|
|
40
54
|
JSON.stringify(this.zip(obj, schema, seen))
|
|
41
55
|
.replace(/"\^(\d+)"/g, '^$1')
|
|
42
56
|
.replace(/"/g, '~TDQ~')
|
|
@@ -49,7 +63,7 @@ export default class Compact {
|
|
|
49
63
|
static smartDecode<T = any>(val: any, schema: SchemaStructure): T {
|
|
50
64
|
if (!val) return val as T
|
|
51
65
|
|
|
52
|
-
if (Array.isArray(val))
|
|
66
|
+
if (Array.isArray(val)) // @ts-ignore
|
|
53
67
|
return val.map((i: {v: string}) => this.decode<T>(i?.V, schema)).filter(Boolean) as T
|
|
54
68
|
|
|
55
69
|
return val?.V ? this.decode<T>(val.V, schema) : val
|
|
@@ -59,7 +73,7 @@ export default class Compact {
|
|
|
59
73
|
if (!val || typeof val !== 'string') return val as T
|
|
60
74
|
|
|
61
75
|
return this.withSchema(this.unzip(JSON.parse(
|
|
62
|
-
this.#
|
|
76
|
+
this.#unpack(val)
|
|
63
77
|
.replace(/"/g, '~TSQ~')
|
|
64
78
|
.replace(/'/g, '"')
|
|
65
79
|
.replace(/~TSQ~/g, "'")
|
|
@@ -72,7 +86,7 @@ export default class Compact {
|
|
|
72
86
|
if (Array.isArray(obj))
|
|
73
87
|
return obj?.length ? obj.map(item => this.zip(item, schema, seen)) : []
|
|
74
88
|
|
|
75
|
-
if (
|
|
89
|
+
if (this.#cantZip(obj)) return obj
|
|
76
90
|
|
|
77
91
|
return schema.map(key => {
|
|
78
92
|
if (typeof key === 'string')
|
|
@@ -96,8 +110,7 @@ export default class Compact {
|
|
|
96
110
|
const type = typeof val
|
|
97
111
|
const length = getLength(val, type)
|
|
98
112
|
|
|
99
|
-
if (
|
|
100
|
-
return val
|
|
113
|
+
if (this.#cantZip(val, type, length)) return val
|
|
101
114
|
|
|
102
115
|
if (type == 'object') {
|
|
103
116
|
for (const key in val)
|
|
@@ -131,7 +144,7 @@ export default class Compact {
|
|
|
131
144
|
if (!key) return undefined
|
|
132
145
|
|
|
133
146
|
if (typeof key == 'string')
|
|
134
|
-
return [key, value
|
|
147
|
+
return [key, value === undefined ? null : value]
|
|
135
148
|
|
|
136
149
|
const mainKey = Object.keys(key)[0]
|
|
137
150
|
const subKeys = key[mainKey]
|
|
@@ -145,7 +158,7 @@ export default class Compact {
|
|
|
145
158
|
: [mainKey, this.withSchema(value, subKeys)]
|
|
146
159
|
}
|
|
147
160
|
|
|
148
|
-
return [mainKey, value
|
|
161
|
+
return [mainKey, value === undefined ? null : value]
|
|
149
162
|
}
|
|
150
163
|
|
|
151
164
|
static memo(val: any, seen: any[]): any {
|
|
@@ -161,8 +174,7 @@ export default class Compact {
|
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
const length = getLength(val, type)
|
|
164
|
-
if (
|
|
165
|
-
return val
|
|
177
|
+
if (this.#cantZip(val, type, length)) return val
|
|
166
178
|
|
|
167
179
|
const index = seen.indexOf(val)
|
|
168
180
|
if (index !== -1)
|
|
@@ -177,11 +189,17 @@ export default class Compact {
|
|
|
177
189
|
return new RegExp(`(?<![^\\s,\\[\\{:])(${keys.join('|')})(?![^\\s,\\]\\}:])`, 'g')
|
|
178
190
|
}
|
|
179
191
|
|
|
180
|
-
static #
|
|
192
|
+
static #pack(val: string): string {
|
|
181
193
|
return val.replace(this.#typeRegex, match => this.#typeMap[match])
|
|
182
194
|
}
|
|
183
195
|
|
|
184
|
-
static #
|
|
196
|
+
static #unpack(val: string): string {
|
|
185
197
|
return val.replace(this.#reverseTypeRegex, match => this.#reverseTypeMap[match])
|
|
186
198
|
}
|
|
199
|
+
|
|
200
|
+
static #cantZip(val: any, type: string = '', length: number = 0) {
|
|
201
|
+
if (!val || [null, true, false, 'true', 'false'].includes(val)) return true
|
|
202
|
+
|
|
203
|
+
return !type && !length ? false : type != 'object' && length < 2
|
|
204
|
+
}
|
|
187
205
|
}
|
package/src/dynamodb/model.ts
CHANGED
|
@@ -75,7 +75,7 @@ export default class AbstractModel<T extends object> {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
async get(key: Keys, sk?: string) {
|
|
78
|
-
const result = await RawClient.get(this.table, key, sk)
|
|
78
|
+
const result = await RawClient.get(this.table, this.#key(key, sk))
|
|
79
79
|
return result.Item ? this.#processItem(result.Item) : undefined
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -118,13 +118,13 @@ export default class AbstractModel<T extends object> {
|
|
|
118
118
|
UpdateExpression,
|
|
119
119
|
ExpressionAttributeValues,
|
|
120
120
|
ExpressionAttributeNames,
|
|
121
|
-
}, key)
|
|
121
|
+
}, this.#key(key))
|
|
122
122
|
|
|
123
123
|
return this.#processItem(attrs, keys)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
async delete(key: Keys, sk?: string) {
|
|
127
|
-
return RawClient.delete(this.table, key, sk)
|
|
127
|
+
return RawClient.delete(this.table, this.#key(key, sk))
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
async batchGet(keys: Array<Keys>) {
|
|
@@ -157,28 +157,7 @@ export default class AbstractModel<T extends object> {
|
|
|
157
157
|
|
|
158
158
|
#key(key: Keys, sk?: string) {
|
|
159
159
|
if (!this.#meta.keys) return {}
|
|
160
|
-
|
|
161
|
-
let pk: string
|
|
162
|
-
let skValue: string | undefined
|
|
163
|
-
if (Array.isArray(key)) {
|
|
164
|
-
pk = key[0]
|
|
165
|
-
skValue = key[1] ?? sk
|
|
166
|
-
} else {
|
|
167
|
-
pk = key
|
|
168
|
-
skValue = sk
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const keys = { [this.#meta.keys.PK]: pk }
|
|
172
|
-
|
|
173
|
-
if (this.#meta.keys?.SK) {
|
|
174
|
-
if (skValue) {
|
|
175
|
-
keys[this.#meta.keys.SK] = skValue
|
|
176
|
-
} else if (this.#meta.defaultSK) {
|
|
177
|
-
keys[this.#meta.keys.SK] = this.#meta.defaultSK
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return keys
|
|
160
|
+
return RawClient.key(key, sk, this.#meta.keys, this.#meta.defaultSK)
|
|
182
161
|
}
|
|
183
162
|
|
|
184
163
|
#getItemKey(item: Partial<T>, key?: Keys): Record<string, string> {
|
package/src/dynamodb/schema.ts
CHANGED
|
@@ -2,21 +2,27 @@ import { z, ZodTypeAny } from 'zod'
|
|
|
2
2
|
import type { SchemaStructure } from './types'
|
|
3
3
|
|
|
4
4
|
const m = Symbol('a')
|
|
5
|
-
export function isArraySchema(v: any)
|
|
5
|
+
export function isArraySchema(v: any): boolean {
|
|
6
6
|
return v[m] || false
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export function arraySchema(v: any): any {
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
v[m] = true
|
|
12
|
+
return v
|
|
13
|
+
}
|
|
14
|
+
|
|
9
15
|
export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
|
|
10
16
|
if (schema instanceof z.ZodObject) {
|
|
11
17
|
return Object.entries(schema.shape).map(([key, value]) => {
|
|
12
18
|
const inner = unwrap(value as ZodTypeAny)
|
|
13
19
|
|
|
14
20
|
if (inner instanceof z.ZodObject)
|
|
15
|
-
return
|
|
21
|
+
return notEmpty(key, extractZodKeys(inner))
|
|
16
22
|
|
|
17
23
|
if (inner instanceof z.ZodArray) {
|
|
18
24
|
const item = unwrap(inner._def.type as ZodTypeAny)
|
|
19
|
-
return item instanceof z.ZodObject ?
|
|
25
|
+
return item instanceof z.ZodObject ? notEmpty(key, extractZodKeys(item)) : key
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
return key
|
|
@@ -25,12 +31,8 @@ export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
|
|
|
25
31
|
|
|
26
32
|
if (schema instanceof z.ZodArray) {
|
|
27
33
|
const item = unwrap(schema._def.type as ZodTypeAny)
|
|
28
|
-
if (item instanceof z.ZodObject)
|
|
29
|
-
|
|
30
|
-
// @ts-ignore
|
|
31
|
-
r[m] = true
|
|
32
|
-
return r
|
|
33
|
-
}
|
|
34
|
+
if (item instanceof z.ZodObject)
|
|
35
|
+
return arraySchema(extractZodKeys(item))
|
|
34
36
|
|
|
35
37
|
return []
|
|
36
38
|
}
|
|
@@ -60,6 +62,10 @@ export function unwrap(schema: ZodTypeAny): ZodTypeAny {
|
|
|
60
62
|
return schema
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
function notEmpty(key: string, schema: SchemaStructure): string | Record<string, SchemaStructure> {
|
|
66
|
+
return schema?.length ? {[key]: schema} : key
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
export function Schema<
|
|
64
70
|
T extends ZodTypeAny,
|
|
65
71
|
B extends object
|