rajt 0.0.13 → 0.0.14
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 +1 -1
- package/package.json +2 -1
- package/src/dynamodb/decorators.ts +86 -9
- package/src/dynamodb/index.ts +2 -1
- package/src/dynamodb/model.ts +4 -2
- package/src/dynamodb/schema.ts +50 -0
- package/src/dynamodb/metadata-registry.ts +0 -28
package/README.md
CHANGED
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.
|
|
4
|
+
"version": "0.0.14",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"dotenv": "^16.5.0",
|
|
46
46
|
"esbuild": "^0.25.2",
|
|
47
47
|
"hono": "^4.7.6",
|
|
48
|
+
"plur": "^5.1.0",
|
|
48
49
|
"tsconfig-paths": "^4.2.0",
|
|
49
50
|
"tsx": "^4.19.3",
|
|
50
51
|
"typescript": "^5.8.3"
|
|
@@ -1,20 +1,97 @@
|
|
|
1
|
-
import
|
|
1
|
+
import plur from 'plur'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export type ModelMetadata = {
|
|
4
|
+
table: string,
|
|
5
|
+
keys?: Record<'PK' | 'SK', string>,
|
|
6
|
+
zip: boolean,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type ModelOpts = string | {
|
|
10
|
+
table?: string,
|
|
11
|
+
partitionKey?: string,
|
|
12
|
+
sortKey?: string,
|
|
13
|
+
zip?: boolean,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getModelMetadata(target: Function | any): ModelMetadata {
|
|
17
|
+
const typeKeys = typeof target.m[1]
|
|
18
|
+
return {
|
|
19
|
+
table: target.m[0],
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
keys: typeKeys !== 'undefined' ? (typeKeys === 'string' ? { PK: target.m[1] } : { PK: target.m[1][0], SK: target.m[1][1] }) : undefined,
|
|
22
|
+
zip: target.m[2] || false,
|
|
23
|
+
fields: target.m[3] || [],
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function _table(target: Function | any, opt?: ModelOpts) {
|
|
28
|
+
if (!target?.m) target.m = []
|
|
29
|
+
const table = opt ? (typeof opt === 'string' ? opt : opt?.table) : undefined
|
|
30
|
+
|
|
31
|
+
target.m[0] = table || plur(target.name.toLocaleUpperCase())
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function _zip(target: Function | any) {
|
|
35
|
+
if (!target?.m) target.m = []
|
|
36
|
+
target.m[2] = true
|
|
37
|
+
target.m[3] = Object.keys(new target)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function _key(target: Function | any, pk: string, sk?: string) {
|
|
41
|
+
if (!target?.m) target.m = []
|
|
42
|
+
target.m[1] = pk && sk? [pk, sk] : [pk]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function Entity(opt?: ModelOpts) {
|
|
46
|
+
return (target: any) => _table(target, opt)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function Model(opt?: ModelOpts) {
|
|
50
|
+
return (target: any) => {
|
|
51
|
+
_table(target, opt)
|
|
52
|
+
const notStr = typeof opt !== 'string'
|
|
53
|
+
|
|
54
|
+
if (!opt || notStr && opt?.zip)
|
|
55
|
+
_zip(target)
|
|
56
|
+
|
|
57
|
+
const pk = opt && notStr ? opt?.partitionKey : undefined
|
|
58
|
+
const sk = opt && notStr ? opt?.sortKey : undefined
|
|
59
|
+
_key(target, pk || 'PK', sk || 'SK')
|
|
7
60
|
}
|
|
8
61
|
}
|
|
9
62
|
|
|
63
|
+
export function Zip() {
|
|
64
|
+
return (target: any) => _zip(target)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function Key(pk: string, sk?: string) {
|
|
68
|
+
return (target: any) => {
|
|
69
|
+
_key(target, pk, sk)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function Keys(pk: string, sk?: string) {
|
|
73
|
+
return Key(pk, sk)
|
|
74
|
+
}
|
|
75
|
+
|
|
10
76
|
export function PartitionKey(attrName?: string) {
|
|
11
|
-
return
|
|
12
|
-
|
|
77
|
+
return (target: any, prop: string) => {
|
|
78
|
+
if (!target?.m) target.m = []
|
|
79
|
+
if (['string', 'undefined'].includes(typeof target.m[1])) {
|
|
80
|
+
target.m[1] = attrName || prop
|
|
81
|
+
} else {
|
|
82
|
+
target.m[1][0] = attrName || prop
|
|
83
|
+
}
|
|
13
84
|
}
|
|
14
85
|
}
|
|
15
86
|
|
|
16
87
|
export function SortKey(attrName?: string) {
|
|
17
|
-
return
|
|
18
|
-
|
|
88
|
+
return (target: any, prop: string) => {
|
|
89
|
+
if (!target?.m) target.m = []
|
|
90
|
+
if (['string', 'undefined'].includes(typeof target.m[1])) {
|
|
91
|
+
target.m[1] = []
|
|
92
|
+
target.m[1][1] = attrName || prop
|
|
93
|
+
} else {
|
|
94
|
+
target.m[1][0] = attrName || prop
|
|
95
|
+
}
|
|
19
96
|
}
|
|
20
97
|
}
|
package/src/dynamodb/index.ts
CHANGED
package/src/dynamodb/model.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AwsLiteDynamoDB } from '@aws-lite/dynamodb-types'
|
|
2
|
-
import { getModelMetadata } from './
|
|
3
|
-
import type { ModelMetadata } from './
|
|
2
|
+
import { getModelMetadata } from './decorators'
|
|
3
|
+
import type { ModelMetadata } from './decorators'
|
|
4
4
|
import QueryBuilder from './query-builder'
|
|
5
5
|
|
|
6
6
|
export default class AbstractModel<T extends object> {
|
|
@@ -46,6 +46,8 @@ export default class AbstractModel<T extends object> {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
schema(pk: string, sk?: string) {
|
|
49
|
+
if (!this.meta.keys) return {}
|
|
50
|
+
|
|
49
51
|
const keys = { [this.meta.keys.PK]: pk }
|
|
50
52
|
if (sk && this.meta.keys.SK)
|
|
51
53
|
keys[this.meta.keys.SK] = sk
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z, ZodTypeAny } from 'zod'
|
|
2
|
+
|
|
3
|
+
function extractZodKeys(schema: ZodTypeAny): any {
|
|
4
|
+
if (schema instanceof z.ZodObject) {
|
|
5
|
+
const shape = schema.shape
|
|
6
|
+
return Object.entries(shape).map(([key, value]) => {
|
|
7
|
+
const inner = unwrap(value as ZodTypeAny)
|
|
8
|
+
|
|
9
|
+
if (inner instanceof z.ZodObject) {
|
|
10
|
+
return { [key]: extractZodKeys(inner) }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (inner instanceof z.ZodArray) {
|
|
14
|
+
const item = unwrap(inner._def.type as ZodTypeAny)
|
|
15
|
+
if (item instanceof z.ZodObject)
|
|
16
|
+
return { [key]: extractZodKeys(item) }
|
|
17
|
+
|
|
18
|
+
return key
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return key
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return []
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function unwrap(schema: ZodTypeAny): ZodTypeAny {
|
|
29
|
+
if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable)
|
|
30
|
+
return unwrap(schema._def.innerType)
|
|
31
|
+
|
|
32
|
+
if (schema instanceof z.ZodUnion)
|
|
33
|
+
return unwrap(schema._def.options[0] as ZodTypeAny)
|
|
34
|
+
|
|
35
|
+
return schema
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default function Schema<T extends ZodTypeAny>(schema: T) {
|
|
39
|
+
return class {
|
|
40
|
+
static _schema = schema
|
|
41
|
+
|
|
42
|
+
static getSchema() {
|
|
43
|
+
return extractZodKeys(schema)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
constructor(data: z.infer<T>) {
|
|
47
|
+
Object.assign(this, data)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type ModelMetadata = {
|
|
2
|
-
table: string,
|
|
3
|
-
keys: Record<'PK' | 'SK', string>,
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
const modelRegistry = new Map<Function, ModelMetadata>()
|
|
7
|
-
|
|
8
|
-
export function registerModelMetadata(target: Function, metadata: { table: string }) {
|
|
9
|
-
const data = modelRegistry.get(target)
|
|
10
|
-
if (data)
|
|
11
|
-
data.table = metadata.table
|
|
12
|
-
else
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
modelRegistry.set(target, { table: metadata.table, keys: {} })
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function registerKeyMetadata(target: Function, keyType: 'PK' | 'SK', name: string) {
|
|
18
|
-
const data = modelRegistry.get(target)
|
|
19
|
-
if (data)
|
|
20
|
-
data.keys[keyType] = name
|
|
21
|
-
else
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
modelRegistry.set(target, { table: '', keys: { [keyType]: name } })
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getModelMetadata(target: Function) {
|
|
27
|
-
return modelRegistry.get(target)
|
|
28
|
-
}
|