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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rajt",
3
3
  "description": "A serverless bundler layer, fully typed for AWS Lambda (Node.js and LLRT) and Cloudflare Workers.",
4
- "version": "0.0.49",
4
+ "version": "0.0.51",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "exports": {
@@ -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 || "us-east-1",
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 || "DUMMYIDEXAMPLE",
31
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "DUMMYEXAMPLEKEY",
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.#key(key, sk),
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.#key(key, sk) }))
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 #key(key: Keys | Record<string, string>, sk?: string) {
91
- if (typeof key == 'object' && key != null) return key
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
- const keys = {PK: pk}
105
- // @ts-ignore
106
- if (skValue) keys.SK = skValue
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
  }
@@ -29,14 +29,28 @@ export default class Compact {
29
29
  }
30
30
 
31
31
  static {
32
- this.#reverseTypeMap = Object.fromEntries(Object.entries(this.#typeMap).map(([k, v]) => [v, k.replace(/"/g, "'")]))
33
- this.#typeRegex = this.#mapRegex(Object.keys(this.#typeMap))
34
- this.#reverseTypeRegex = this.#mapRegex(Object.keys(this.#reverseTypeMap))
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
- return this.#minify(
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.#deminify(val)
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 (!obj || [null, true, false].includes(obj)) return obj
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 ([null, true, false].includes(val) || type != 'object' && length < 2)
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 || null]
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 || null]
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 ([null, true, false].includes(val) || type != 'object' && length < 2)
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 #minify(val: string): string {
192
+ static #pack(val: string): string {
181
193
  return val.replace(this.#typeRegex, match => this.#typeMap[match])
182
194
  }
183
195
 
184
- static #deminify(val: string): string {
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
  }
@@ -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> {
@@ -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) : boolean {
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 { [key]: extractZodKeys(inner) }
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 ? { [key]: extractZodKeys(item) } : key
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
- const r = extractZodKeys(item)
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