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/response.ts
CHANGED
|
@@ -1,37 +1,88 @@
|
|
|
1
|
-
import type { ContentfulStatusCode, StatusCode } from 'hono/utils/http-status'
|
|
1
|
+
import type { ContentfulStatusCode, RedirectStatusCode, StatusCode } from 'hono/utils/http-status'
|
|
2
|
+
import type { BaseMime } from 'hono/utils/mime'
|
|
3
|
+
import type { ResponseHeader } from 'hono/utils/headers'
|
|
2
4
|
import type { ErrorResponse, Errors } from './types'
|
|
3
|
-
import
|
|
5
|
+
import { HtmlEscapedCallbackPhase, resolveCallback } from 'hono/utils/html'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
type HeaderRecord =
|
|
8
|
+
| Record<'Content-Type', BaseMime>
|
|
9
|
+
| Record<ResponseHeader, string | string[]>
|
|
10
|
+
| Record<string, string | string[]>
|
|
11
|
+
|
|
12
|
+
type RBag = {
|
|
13
|
+
status?: StatusCode,
|
|
14
|
+
headers?: HeaderRecord,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default class $Response {
|
|
18
|
+
static raw(
|
|
19
|
+
status?: StatusCode,
|
|
20
|
+
body?: any,
|
|
21
|
+
cType?: BaseMime,
|
|
22
|
+
headers?: HeaderRecord
|
|
23
|
+
) {
|
|
24
|
+
const b: RBag = { status: status || 200 }
|
|
25
|
+
|
|
26
|
+
if (cType || headers) {
|
|
27
|
+
headers ??= {}
|
|
28
|
+
if (cType) headers['Content-Type'] = cType
|
|
29
|
+
b.headers = headers
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return new Response(body ?? null, b)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static text(data?: string, status?: StatusCode) {
|
|
36
|
+
return this.raw(status, data, 'text/plain; charset=UTF-8' as BaseMime)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static json<T>(data?: T, status?: StatusCode, headers?: HeaderRecord) {
|
|
40
|
+
if (data == null)
|
|
41
|
+
return this.raw(status)
|
|
42
|
+
|
|
43
|
+
return this.raw(status, JSON.stringify(data), 'application/json', headers)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static redirect(
|
|
47
|
+
location: string | URL,
|
|
48
|
+
status?: RedirectStatusCode,
|
|
49
|
+
headers?: HeaderRecord
|
|
50
|
+
) {
|
|
51
|
+
const loc = String(location)
|
|
52
|
+
|
|
53
|
+
return new Response(null, {
|
|
54
|
+
status: status || 302,
|
|
55
|
+
headers: { ...headers, 'Location': /[^\x00-\xFF]/.test(loc) ? encodeURI(loc) : loc }
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static html(
|
|
60
|
+
html: string | Promise<string>,
|
|
61
|
+
status?: ContentfulStatusCode,
|
|
62
|
+
headers?: HeaderRecord
|
|
63
|
+
): Response | Promise<Response> {
|
|
64
|
+
const res = (html: string) => this.raw(status, html, 'text/html; charset=UTF-8' as BaseMime, headers)
|
|
65
|
+
return typeof html == 'string'
|
|
66
|
+
? res(html)
|
|
67
|
+
: resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
|
|
8
68
|
}
|
|
9
69
|
|
|
10
70
|
static ok(): Response
|
|
11
71
|
static ok<T>(data: T): Response
|
|
12
72
|
static ok<T>(data?: T) {
|
|
13
|
-
|
|
14
|
-
return this.raw(200)
|
|
15
|
-
|
|
16
|
-
return c.cx.json(data, 200)
|
|
73
|
+
return this.json(data, 200)
|
|
17
74
|
}
|
|
18
75
|
|
|
19
76
|
static created(): Response
|
|
20
77
|
static created<T>(data: T): Response
|
|
21
78
|
static created<T>(data?: T) {
|
|
22
|
-
|
|
23
|
-
return this.raw(201)
|
|
24
|
-
|
|
25
|
-
return c.cx.json(data, 201)
|
|
79
|
+
return this.json(data, 201)
|
|
26
80
|
}
|
|
27
81
|
|
|
28
82
|
static accepted(): Response
|
|
29
83
|
static accepted<T>(data: T): Response
|
|
30
84
|
static accepted<T>(data?: T) {
|
|
31
|
-
|
|
32
|
-
return this.raw(202)
|
|
33
|
-
|
|
34
|
-
return c.cx.json(data, 202)
|
|
85
|
+
return this.json(data, 202)
|
|
35
86
|
}
|
|
36
87
|
|
|
37
88
|
static deleted() {
|
|
@@ -50,19 +101,13 @@ export default class Response {
|
|
|
50
101
|
static unauthorized(): Response
|
|
51
102
|
static unauthorized<T>(data: T): Response
|
|
52
103
|
static unauthorized<T>(data?: T) {
|
|
53
|
-
|
|
54
|
-
return this.raw(401)
|
|
55
|
-
|
|
56
|
-
return c.cx.json(data, 401)
|
|
104
|
+
return this.json(data, 401)
|
|
57
105
|
}
|
|
58
106
|
|
|
59
107
|
static forbidden(): Response
|
|
60
108
|
static forbidden<T>(data: T): Response
|
|
61
109
|
static forbidden<T>(data?: T) {
|
|
62
|
-
|
|
63
|
-
return this.raw(403)
|
|
64
|
-
|
|
65
|
-
return c.cx.json(data, 403)
|
|
110
|
+
return this.json(data, 403)
|
|
66
111
|
}
|
|
67
112
|
|
|
68
113
|
static notFound(): Response
|
|
@@ -95,6 +140,6 @@ export default class Response {
|
|
|
95
140
|
if (msg) resp.m = msg
|
|
96
141
|
if (errors) resp.e = errors
|
|
97
142
|
|
|
98
|
-
return
|
|
143
|
+
return this.json(resp, status)
|
|
99
144
|
}
|
|
100
145
|
}
|
package/src/routes.ts
CHANGED
|
@@ -4,6 +4,11 @@ import { fileURLToPath } from 'node:url'
|
|
|
4
4
|
import { Route } from './types'
|
|
5
5
|
import { isAnonFn } from './utils/func'
|
|
6
6
|
|
|
7
|
+
import { writeFileSync } from 'node:fs'
|
|
8
|
+
import { config } from 'dotenv'
|
|
9
|
+
import ensureDir from './utils/ensuredir'
|
|
10
|
+
import versionSHA from './utils/version-sha'
|
|
11
|
+
|
|
7
12
|
const __filename = fileURLToPath(import.meta.url)
|
|
8
13
|
const __dirname = dirname(__filename)
|
|
9
14
|
|
|
@@ -29,7 +34,7 @@ const walk = async (dir: string, baseDir: string, fn: Function, parentMw: string
|
|
|
29
34
|
|
|
30
35
|
if (stat.isDirectory()) {
|
|
31
36
|
await walk(fullPath, baseDir, fn, currentMw)
|
|
32
|
-
} else if (file
|
|
37
|
+
} else if (file != 'index.ts' && file.endsWith('.ts') && !file.endsWith('.d.ts')) {
|
|
33
38
|
const mod = await import(fullPath)
|
|
34
39
|
fn(fullPath, baseDir, mod.default, currentMw)
|
|
35
40
|
}
|
|
@@ -65,7 +70,7 @@ export async function getRoutes(
|
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
function sortRoutes(routes: Route[]) {
|
|
68
|
-
const metas = new Map<string, { score: number
|
|
73
|
+
const metas = new Map<string, { score: number, segmentsCount: number }>()
|
|
69
74
|
|
|
70
75
|
for (const route of routes)
|
|
71
76
|
metas.set(route.path, computeRouteMeta(route.path))
|
|
@@ -118,3 +123,62 @@ export async function getMiddlewares(
|
|
|
118
123
|
|
|
119
124
|
return mw
|
|
120
125
|
}
|
|
126
|
+
|
|
127
|
+
const env = Object.entries(
|
|
128
|
+
config({ path: '../../.env.prod' })?.parsed || {}
|
|
129
|
+
).filter(([key, val]) => key?.toLowerCase().indexOf('aws') != 0) // prevent AWS credentials
|
|
130
|
+
|
|
131
|
+
const version = versionSHA('../../.git') // @ts-ignore
|
|
132
|
+
env.push(['VERSION_SHA', process.env['VERSION_SHA'] = version]) // @ts-ignore
|
|
133
|
+
env.push(['VERSION_HASH', process.env['VERSION_HASH'] = version?.substring(0, 7)])
|
|
134
|
+
|
|
135
|
+
export async function cacheRoutes() {
|
|
136
|
+
const rolePath = join(__dirname, '../../../roles.json')
|
|
137
|
+
if (!existsSync(rolePath))
|
|
138
|
+
writeFileSync(rolePath, '{}')
|
|
139
|
+
|
|
140
|
+
const routes = await getRoutes()
|
|
141
|
+
const middlewares = await getMiddlewares()
|
|
142
|
+
|
|
143
|
+
const iPath = join(__dirname, '../../../tmp/import-routes.mjs')
|
|
144
|
+
ensureDir(iPath)
|
|
145
|
+
writeFileSync(iPath, `// AUTO-GENERATED FILE - DO NOT EDIT
|
|
146
|
+
${env?.length ? `import { Envir } from '../node_modules/t0n/dist/index'\nEnvir.add({${env.map(([key, val]) => key + ':' + JSON.stringify(val)).join(',')}})` : ''}
|
|
147
|
+
|
|
148
|
+
import { registerHandler, registerMiddleware } from '../node_modules/rajt/src/register'
|
|
149
|
+
|
|
150
|
+
${routes.map(r => `import ${r.name} from '../${normalizePath(r.file)}'`).join('\n')}
|
|
151
|
+
${middlewares.map(r => `import ${r.name} from '../${normalizePath(r.file)}'`).join('\n')}
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const handlers = {${routes.map(r => r.name).join()}}
|
|
155
|
+
|
|
156
|
+
for (const [name, handler] of Object.entries(handlers)) {
|
|
157
|
+
if (typeof handler == 'function' || handler.prototype?.handle) {
|
|
158
|
+
registerHandler(name, handler)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const middlewares = {${middlewares.map(r => r.name).join()}}
|
|
163
|
+
|
|
164
|
+
for (const [name, mw] of Object.entries(middlewares)) {
|
|
165
|
+
registerMiddleware(mw)
|
|
166
|
+
}
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.error('Failed to register handlers:', e)
|
|
169
|
+
}
|
|
170
|
+
`)
|
|
171
|
+
|
|
172
|
+
const rPath = join(__dirname, '../../../tmp/routes.json')
|
|
173
|
+
ensureDir(rPath)
|
|
174
|
+
writeFileSync(rPath, JSON.stringify(routes.filter(r => r.method && r.path).map(route => [
|
|
175
|
+
route.method,
|
|
176
|
+
route.path,
|
|
177
|
+
route.middlewares,
|
|
178
|
+
route.name,
|
|
179
|
+
])))
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function normalizePath(file: string) {
|
|
183
|
+
return file.replace(/\.tsx?$/i, '').replace(/(\/index)+$/i, '').replace(/\/+$/g, '')
|
|
184
|
+
}
|
|
@@ -1,67 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { config } from 'dotenv'
|
|
3
|
-
import { getRoutes, getMiddlewares } from '../routes'
|
|
4
|
-
import ensureDir from '../utils/ensuredir'
|
|
5
|
-
import versionSHA from '../utils/version-sha'
|
|
6
|
-
|
|
7
|
-
const env = Object.entries(
|
|
8
|
-
config({ path: '../../.env.prod' })?.parsed || {}
|
|
9
|
-
).filter(([key, val]) => key?.toLowerCase().indexOf('aws') != 0) // prevent AWS credentials
|
|
10
|
-
|
|
11
|
-
const version = versionSHA('../../.git')
|
|
12
|
-
env.push(['VERSION_SHA', process.env['VERSION_SHA'] = version])
|
|
13
|
-
env.push(['VERSION_HASH', process.env['VERSION_HASH'] = version?.substring(0, 7)])
|
|
14
|
-
|
|
15
|
-
async function cacheRoutes() {
|
|
16
|
-
const rolePath = '../../roles.json'
|
|
17
|
-
if (!existsSync(rolePath))
|
|
18
|
-
writeFileSync(rolePath, '{}')
|
|
19
|
-
|
|
20
|
-
const routes = await getRoutes()
|
|
21
|
-
const middlewares = await getMiddlewares()
|
|
22
|
-
|
|
23
|
-
const iPath = '../../tmp/import-routes.mjs'
|
|
24
|
-
ensureDir(iPath)
|
|
25
|
-
writeFileSync(iPath, `// AUTO-GENERATED FILE - DO NOT EDIT
|
|
26
|
-
${env?.length ? `import { Envir } from '../node_modules/t0n/dist/index'\nEnvir.add({${env.map(([key, val]) => key + ':' + JSON.stringify(val)).join(',')}})` : ''}
|
|
27
|
-
|
|
28
|
-
import { registerHandler, registerMiddleware } from '../node_modules/rajt/src/register'
|
|
29
|
-
|
|
30
|
-
${routes.map(r => `import ${r.name} from '../${normalizePath(r.file)}'`).join('\n')}
|
|
31
|
-
${middlewares.map(r => `import ${r.name} from '../${normalizePath(r.file)}'`).join('\n')}
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
const handlers = {${routes.map(r => r.name).join()}}
|
|
35
|
-
|
|
36
|
-
for (const [name, handler] of Object.entries(handlers)) {
|
|
37
|
-
if (typeof handler === 'function' || handler.prototype?.handle) {
|
|
38
|
-
registerHandler(name, handler)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const middlewares = {${middlewares.map(r => r.name).join()}}
|
|
43
|
-
|
|
44
|
-
for (const [name, mw] of Object.entries(middlewares)) {
|
|
45
|
-
registerMiddleware(mw)
|
|
46
|
-
}
|
|
47
|
-
} catch (e) {
|
|
48
|
-
console.error('Failed to register handlers:', e)
|
|
49
|
-
}
|
|
50
|
-
`)
|
|
51
|
-
|
|
52
|
-
const rPath = '../../tmp/routes.json'
|
|
53
|
-
ensureDir(rPath)
|
|
54
|
-
writeFileSync(rPath, JSON.stringify(routes.filter(r => r.method && r.path).map(route => [
|
|
55
|
-
route.method,
|
|
56
|
-
route.path,
|
|
57
|
-
route.middlewares,
|
|
58
|
-
route.name,
|
|
59
|
-
])))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function normalizePath(file: string) {
|
|
63
|
-
return file.replace(/\.tsx?$/i, '').replace(/(\/index)+$/i, '').replace(/\/+$/g, '')
|
|
64
|
-
}
|
|
1
|
+
import { cacheRoutes } from '../routes'
|
|
65
2
|
|
|
66
3
|
cacheRoutes()
|
|
67
4
|
.then(() => {
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import { Handler } from 'hono'
|
|
1
|
+
import type { Handler, ValidationTargets } from 'hono'
|
|
2
2
|
import { ResponseHeader } from 'hono/utils/headers'
|
|
3
3
|
import { StatusCode } from 'hono/utils/http-status'
|
|
4
4
|
import { BaseMime } from 'hono/utils/mime'
|
|
5
|
+
import z from 'zod'
|
|
5
6
|
import Action from './action'
|
|
7
|
+
import request from './request'
|
|
8
|
+
import response from './response'
|
|
9
|
+
import validator from './validator'
|
|
10
|
+
|
|
11
|
+
export type { Context, Next } from 'hono'
|
|
12
|
+
|
|
13
|
+
type PublicMethods<T> = {
|
|
14
|
+
[K in keyof T]: K extends `#${string}` | `$${string}` | symbol | 'prototype' ? never : K
|
|
15
|
+
}[keyof T]
|
|
16
|
+
|
|
17
|
+
export type IRequest = Pick<request, PublicMethods<request>>
|
|
18
|
+
export type IResponse = Pick<typeof response, PublicMethods<typeof response>>
|
|
19
|
+
|
|
20
|
+
export type IValidator = Pick<typeof validator, PublicMethods<typeof validator>>
|
|
21
|
+
export type Rule = {
|
|
22
|
+
schema: z.ZodObject<any>
|
|
23
|
+
target: keyof ValidationTargets
|
|
24
|
+
eTarget?: 'fieldErrors' | 'formErrors'
|
|
25
|
+
}
|
|
26
|
+
export type Rules = Rule[] | Rule | null
|
|
6
27
|
|
|
7
28
|
export type Route = {
|
|
8
29
|
method: string,
|
|
@@ -13,6 +34,8 @@ export type Route = {
|
|
|
13
34
|
handle: Handlers,
|
|
14
35
|
}
|
|
15
36
|
|
|
37
|
+
export type ActionType = Function | Handler | Action | (new () => Action)
|
|
38
|
+
|
|
16
39
|
export type Handlers = (Function | Handler | (new () => Action))[]
|
|
17
40
|
|
|
18
41
|
export type Routes = Route[]
|
|
@@ -45,6 +68,3 @@ export type ResponseOrInit<T extends StatusCode = StatusCode> = ResponseInit<T>
|
|
|
45
68
|
// | null
|
|
46
69
|
// | { [key: string]: JSONValue }
|
|
47
70
|
// | JSONValue[]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export type { Context, Next } from 'hono'
|
package/src/utils/environment.ts
CHANGED
|
@@ -10,15 +10,16 @@ export function detectEnvironment() {
|
|
|
10
10
|
try {
|
|
11
11
|
if (
|
|
12
12
|
process.env?.npm_lifecycle_event == 'dev'
|
|
13
|
+
|| process.env?.npm_lifecycle_script == 'rajt'
|
|
13
14
|
|| process.env?.AWS_SAM_LOCAL
|
|
14
15
|
// || process?.argv?.includes('--dev')
|
|
15
|
-
|| process?.argv?.some(arg => ['--dev', '--development', '--watch'].includes(arg))
|
|
16
|
+
|| process?.argv?.some(arg => ['-port', '-platform', '--dev', '--development', '--watch'].includes(arg))
|
|
16
17
|
|| process?.execArgv?.includes('--watch')
|
|
17
18
|
|| import.meta.url?.includes('localhost')
|
|
18
19
|
) {
|
|
19
20
|
return dev
|
|
20
21
|
}
|
|
21
|
-
} catch (e) {
|
|
22
|
+
} catch (e) {}
|
|
22
23
|
|
|
23
24
|
return prd
|
|
24
25
|
}
|
package/src/utils/func.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const isAsyncFn = (fn: any) => {
|
|
2
|
-
return fn?.constructor?.name
|
|
2
|
+
return fn?.constructor?.name == 'AsyncFunction'
|
|
3
3
|
|| fn.toString().toLowerCase().trim().startsWith('async')
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export const isAnonFn = (fn: any) => {
|
|
7
|
-
return fn?.name
|
|
7
|
+
return fn?.name == '' || fn?.name == 'anonymous'
|
|
8
8
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const getFullYear = Date.prototype.getFullYear
|
|
2
|
+
const getMonth = Date.prototype.getMonth
|
|
3
|
+
const getDate = Date.prototype.getDate
|
|
4
|
+
const getHours = Date.prototype.getHours
|
|
5
|
+
const getMinutes = Date.prototype.getMinutes
|
|
6
|
+
const getSeconds = Date.prototype.getSeconds
|
|
7
|
+
const pad = (n: number) => n > 9 ? n : '0' + n
|
|
8
|
+
|
|
9
|
+
export const getLocalDateTime = (date = new Date()) =>
|
|
10
|
+
getFullYear.call(date) + '-' + pad(getMonth.call(date) + 1) + '-' + pad(getDate.call(date))
|
|
11
|
+
+ ' ' + pad(getHours.call(date)) + ':' + pad(getMinutes.call(date)) + ':' + pad(getSeconds.call(date))
|
|
12
|
+
|
|
13
|
+
export default getLocalDateTime
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import colors from 'picocolors'
|
|
2
|
+
|
|
3
|
+
const _console = { ...console }
|
|
4
|
+
|
|
5
|
+
export interface ILogger {
|
|
6
|
+
write(...data: Array<string | ArrayBufferView | ArrayBuffer>): number;
|
|
7
|
+
error(...data: any[]): void;
|
|
8
|
+
info(...data: any[]): void;
|
|
9
|
+
log(...data: any[]): void;
|
|
10
|
+
// TODO: table(tabularData?: any, properties?: string[]): void;
|
|
11
|
+
trace(...data: any[]): void;
|
|
12
|
+
warn(...data: any[]): void;
|
|
13
|
+
// custom
|
|
14
|
+
step(...data: any[]): void;
|
|
15
|
+
substep(...data: any[]): void;
|
|
16
|
+
ln(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const logger = {
|
|
20
|
+
step(...args: any[]) {
|
|
21
|
+
if (args?.length && args.length < 2) return _console.log(colors.blue('⁕') +` ${args[0]}\n`)
|
|
22
|
+
const length = args.length - 1
|
|
23
|
+
args.forEach((arg, index) => {
|
|
24
|
+
switch (index) {
|
|
25
|
+
case 0:
|
|
26
|
+
return _console.log(colors.blue('⁕') + ' ' + arg)
|
|
27
|
+
// return _console.log(colors.blue('⁕') +` ${arg} \n`)
|
|
28
|
+
case length:
|
|
29
|
+
return _console.log(` ${colors.gray('⁕')} ${arg}\n`)
|
|
30
|
+
default:
|
|
31
|
+
return _console.log(` ${colors.gray('⁕')} ` + arg)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
},
|
|
35
|
+
substep(...args: any[]) {
|
|
36
|
+
args.forEach(arg => _console.log(` ${colors.gray('⁕')} ` + arg))
|
|
37
|
+
},
|
|
38
|
+
ln() {
|
|
39
|
+
_console.log('\n')
|
|
40
|
+
},
|
|
41
|
+
log(...args: any[]) {
|
|
42
|
+
_console.log(...args)
|
|
43
|
+
},
|
|
44
|
+
info(...args: any[]) {
|
|
45
|
+
_console.info(...args)
|
|
46
|
+
},
|
|
47
|
+
warn(...args: any[]) {
|
|
48
|
+
_console.warn(...args)
|
|
49
|
+
},
|
|
50
|
+
error(...args: any[]) {
|
|
51
|
+
_console.error(...args)
|
|
52
|
+
},
|
|
53
|
+
trace(...args: any[]) {
|
|
54
|
+
_console.trace(...args)
|
|
55
|
+
},
|
|
56
|
+
write(...args: any[]) {
|
|
57
|
+
_console.write(...args)
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default logger
|
package/src/utils/port.ts
CHANGED
package/src/utils/resolve.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import Action
|
|
1
|
+
import Action from '../action'
|
|
2
2
|
import { MiddlewareType } from '../middleware'
|
|
3
|
+
import type { ActionType } from '../types'
|
|
3
4
|
|
|
4
5
|
export function resolve(obj: ActionType, id: string) {
|
|
5
|
-
if (typeof obj
|
|
6
|
+
if (typeof obj == 'function' && obj?.length == 2)
|
|
6
7
|
return [obj]
|
|
7
8
|
|
|
8
9
|
if (obj?.run)
|
|
@@ -22,7 +23,7 @@ export function resolve(obj: ActionType, id: string) {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export function resolveMiddleware(obj: MiddlewareType) {
|
|
25
|
-
if (typeof obj
|
|
26
|
+
if (typeof obj == 'function' && obj.length == 2)
|
|
26
27
|
return obj
|
|
27
28
|
|
|
28
29
|
if (obj?.factory)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default function shutdown(cb: (signal: string, e: unknown) => void | Promise<void>) {
|
|
2
|
+
if (!process) return
|
|
3
|
+
const down = (signal: string) => (e?: unknown) => {
|
|
4
|
+
try {
|
|
5
|
+
cb(signal, e)
|
|
6
|
+
setTimeout(() => process.exit(0), 100)
|
|
7
|
+
} catch (e) {
|
|
8
|
+
process.exit(1)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
process.on('SIGINT', down('SIGINT'))
|
|
13
|
+
process.on('SIGTERM', down('SIGTERM'))
|
|
14
|
+
process.on('SIGHUP', down('SIGHUP'))
|
|
15
|
+
process.on('unhandledRejection', down('UNCAUGHT_REJECTION'))
|
|
16
|
+
process.on('uncaughtException', down('UNCAUGHT_EXCEPTION'))
|
|
17
|
+
// process.on('beforeExit', down('BEFORE_EXIT'))
|
|
18
|
+
// process.on('exit', down('EXIT'))
|
|
19
|
+
}
|
package/src/validator.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ZodObject } from 'zod'
|
|
2
|
+
import { zValidator } from '@hono/zod-validator'
|
|
3
|
+
import type { ValidationTargets } from 'hono'
|
|
4
|
+
import type { Rule, Rules } from './types'
|
|
5
|
+
import response from './response'
|
|
6
|
+
|
|
7
|
+
export default class $Validator {
|
|
8
|
+
private static cache = new Map<string, any>()
|
|
9
|
+
|
|
10
|
+
private static createRule<T extends keyof ValidationTargets>(
|
|
11
|
+
target: T,
|
|
12
|
+
schema?: ZodObject<any>
|
|
13
|
+
):
|
|
14
|
+
| { schema: (schema: ZodObject<any>) => Rule }
|
|
15
|
+
| Rule
|
|
16
|
+
{
|
|
17
|
+
if (schema != null) {
|
|
18
|
+
return {
|
|
19
|
+
target,
|
|
20
|
+
schema,
|
|
21
|
+
eTarget: 'fieldErrors'
|
|
22
|
+
} satisfies Rule
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
schema: (schema: ZodObject<any>) => ({
|
|
27
|
+
target,
|
|
28
|
+
schema,
|
|
29
|
+
eTarget: 'fieldErrors'
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private static getOrCreateAlias<T extends keyof ValidationTargets>(target: T) {
|
|
35
|
+
if (this.cache.has(target))
|
|
36
|
+
return this.cache.get(target)
|
|
37
|
+
|
|
38
|
+
const aliasFunc = (schema?: ZodObject<any>) => {
|
|
39
|
+
if (schema != null)
|
|
40
|
+
return this.createRule(target, schema)
|
|
41
|
+
|
|
42
|
+
return this.createRule(target)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const typedAlias = aliasFunc as {
|
|
46
|
+
(): { schema: (schema: ZodObject<any>) => Rule },
|
|
47
|
+
(schema: ZodObject<any>): Rule,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.cache.set(target, typedAlias)
|
|
51
|
+
return typedAlias
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static readonly json = $Validator.getOrCreateAlias('json')
|
|
55
|
+
static readonly form = $Validator.getOrCreateAlias('form')
|
|
56
|
+
static readonly query = $Validator.getOrCreateAlias('query')
|
|
57
|
+
static readonly param = $Validator.getOrCreateAlias('param')
|
|
58
|
+
static readonly header = $Validator.getOrCreateAlias('header')
|
|
59
|
+
static readonly cookie = $Validator.getOrCreateAlias('cookie')
|
|
60
|
+
|
|
61
|
+
static parse(rules: Rules): Function[] {
|
|
62
|
+
return (Array.isArray(rules) ? rules : [rules]) // @ts-ignore
|
|
63
|
+
.flatMap(rule => zValidator(rule.target, rule.schema, (result, c) => {
|
|
64
|
+
if (!result.success) // @ts-ignore
|
|
65
|
+
return response.badRequest({ ...result.error.flatten()[rule.eTarget] })
|
|
66
|
+
}))
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/auth/auth.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Authnz } from './authnz'
|
|
2
|
-
import { Token } from './token'
|
|
3
|
-
|
|
4
|
-
export class Auth {
|
|
5
|
-
static #u: Authnz<any> | null = null
|
|
6
|
-
|
|
7
|
-
static resolve() {
|
|
8
|
-
this.#u = Authnz.fromToken(Token.fromRequest())
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
static get user() {
|
|
12
|
-
return this.#u ? this.#u?.data : null
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
static can(...abilities: string[]): boolean {
|
|
16
|
-
return this.#u ? this.#u.can(...abilities) : false
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static cant(...abilities: string[]): boolean {
|
|
20
|
-
return !this.can(...abilities)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static hasRole(...roles: string[]): boolean {
|
|
24
|
-
return this.#u ? this.#u.hasRole(...roles) : false
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
static has(prop: string, value: any = null): boolean {
|
|
28
|
-
return this.#u ? this.#u.has(prop, value) : false
|
|
29
|
-
}
|
|
30
|
-
static hasValue(prop: string, value: any = null): boolean {
|
|
31
|
-
return this.has(prop, value)
|
|
32
|
-
}
|
|
33
|
-
}
|