rajt 0.0.68 → 0.0.70
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 -13
- package/src/action.ts +4 -1
- package/src/cli/commands/build.ts +2 -3
- package/src/cli/commands/utils.ts +1 -1
- package/src/cli/index.ts +3 -4
- package/src/create-app.ts +10 -30
- package/src/http.ts +4 -2
- package/src/index.ts +1 -1
- package/src/middleware.ts +8 -2
- package/src/response.ts +5 -9
- package/src/types.ts +62 -19
- package/src/utils/colors.ts +102 -0
- package/src/utils/log.ts +1 -1
- package/src/utils/port.ts +1 -1
- package/src/utils/resolve.ts +3 -7
- package/src/validator.ts +20 -42
- package/src/context.ts +0 -43
- package/src/esbuild.mjs +0 -124
- package/src/exceptions.ts +0 -15
- package/src/scripts/cache-routes.ts +0 -10
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.70",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -26,13 +26,6 @@
|
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
28
|
"rajt": "./src/bin/rajt.js",
|
|
29
|
-
"dev": "tsx watch src/dev.ts",
|
|
30
|
-
"aws:build": "bun run --silent cache:routes && bun run --silent aws:export && bun run --silent clean:temp",
|
|
31
|
-
"cf:build": "bun run --silent cache:routes && bun run --silent cf:export && bun run --silent clean:temp",
|
|
32
|
-
"aws:build:watch": "chokidar \"../../{actions,configs,enums,locales,middlewares,models,utils}/**/*.ts\" -c \"bun run --silent aws:build\" --initial",
|
|
33
|
-
"cf:build:watch": "chokidar \"../../{actions,configs,enums,locales,middlewares,models,utils}/**/*.ts\" -c \"bun run --silent cf:build\" --initial",
|
|
34
|
-
"aws:export": "node src/esbuild.mjs aws",
|
|
35
|
-
"cf:export": "node src/esbuild.mjs cf",
|
|
36
29
|
"aws:local": "bun run --silent aws:build && bun run --silent sam:local",
|
|
37
30
|
"aws:package": "bun run --silent aws:build && bun run --silent sam:package",
|
|
38
31
|
"aws:deploy": "bun run --silent aws:build && bun run --silent sam:package && bun run --silent sam:deploy",
|
|
@@ -41,10 +34,6 @@
|
|
|
41
34
|
"sam:package": "sam package --template-file ../../template-prod.yaml --output-template-file ../../packaged.yaml",
|
|
42
35
|
"sam:deploy": "sam deploy --template-file ../../packaged.yaml --stack-name rajt-llrt --capabilities CAPABILITY_IAM",
|
|
43
36
|
"sam:update": "source ../../.env.prod && aws lambda update-function-code --function-name $AWS_NAME --zip-file fileb://../../lambda.zip --region $AWS_REGION --no-cli-pager 2>&1 >/dev/null",
|
|
44
|
-
"cf:local-": "source ../../.env.dev && bun run --silent cf:build:watch -- cd ../../dist && bunx wrangler dev --port=$PORT --persist-to='../.wrangler/state'",
|
|
45
|
-
"cf:deploy": "bun run --silent cf:build && cd ../../dist && bunx wrangler deploy",
|
|
46
|
-
"cache:routes": "tsx src/scripts/cache-routes.ts",
|
|
47
|
-
"ensure-dirs": "rm -rf ../../dist ../../tmp && mkdir -p ../../tmp && chmod 755 ../../tmp && mkdir -p ../../dist && chmod 755 ../../dist",
|
|
48
37
|
"clean": "rm -rf ../../dist ../../tmp",
|
|
49
38
|
"clean:build": "rm -rf ../../dist",
|
|
50
39
|
"clean:temp": "rm -rf ../../tmp",
|
|
@@ -64,7 +53,6 @@
|
|
|
64
53
|
"esbuild": "^0.25.2",
|
|
65
54
|
"hono": "^4.11.7",
|
|
66
55
|
"miniflare": "^4.20251217.0",
|
|
67
|
-
"picocolors": "^1.1.1",
|
|
68
56
|
"tiny-glob": "^0.2",
|
|
69
57
|
"tsx": "^4.19.3",
|
|
70
58
|
"ua-parser-js": "^2.0.8"
|
package/src/action.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import response from './response'
|
|
2
2
|
import validator from './validator'
|
|
3
3
|
import { GET_REQUEST } from './request'
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Context,
|
|
6
|
+
IRequest, IResponse, IValidator, Rules
|
|
7
|
+
} from './types'
|
|
5
8
|
|
|
6
9
|
export default class Action {
|
|
7
10
|
static run() {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { defineCommand } from 'citty'
|
|
2
|
-
import { gray } from '
|
|
3
|
-
|
|
2
|
+
import { gray } from '../../utils/colors'
|
|
4
3
|
import { build, normalizePlatform, platformError } from './utils'
|
|
5
|
-
import { wait, error
|
|
4
|
+
import { wait, error } from '../../utils/log'
|
|
6
5
|
|
|
7
6
|
import { platforms } from './constants'
|
|
8
7
|
|
|
@@ -6,7 +6,7 @@ import { readFile, stat, writeFile } from 'node:fs/promises'
|
|
|
6
6
|
import { basename, dirname, join, relative } from 'node:path'
|
|
7
7
|
|
|
8
8
|
import chokidar from 'chokidar'
|
|
9
|
-
import { gray } from '
|
|
9
|
+
import { gray } from '../../utils/colors'
|
|
10
10
|
import type { ChokidarEventName, Platform } from './types'
|
|
11
11
|
|
|
12
12
|
import { cacheRoutes } from '../../routes'
|
package/src/cli/index.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { defineCommand, runMain, renderUsage } from 'citty'
|
|
2
2
|
import type { ArgsDef, CommandDef } from 'citty'
|
|
3
|
-
import colors from 'picocolors'
|
|
4
3
|
import { createConsola } from 'consola'
|
|
5
|
-
|
|
4
|
+
import { logo } from '../utils/log'
|
|
5
|
+
import { isColorSupported, gray } from '../utils/colors'
|
|
6
6
|
import { version as rajtVersion } from '../../package.json'
|
|
7
7
|
|
|
8
|
-
import { logo } from '../utils/log'
|
|
9
8
|
|
|
10
9
|
import dev from './commands/dev'
|
|
11
10
|
import build from './commands/build'
|
|
@@ -26,7 +25,7 @@ const directly = () => {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
const name = 'Rajt CLI'
|
|
29
|
-
const version = [name,
|
|
28
|
+
const version = [name, isColorSupported ? gray('v'+rajtVersion) : rajtVersion].join(' ')
|
|
30
29
|
|
|
31
30
|
if (directly()) {
|
|
32
31
|
const _args = process.argv.slice(2)
|
package/src/create-app.ts
CHANGED
|
@@ -1,48 +1,28 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
import { Hono } from 'hono'
|
|
3
2
|
import { logger } from 'hono/logger'
|
|
4
|
-
import type { Env, Context, ErrorHandler, NotFoundHandler, Next } from 'hono'
|
|
5
|
-
// import type { MiddlewareHandler } from 'hono'
|
|
6
|
-
// import { createMiddleware } from 'hono/factory'
|
|
7
|
-
// import type { H, Handler, HandlerResponse } from 'hono/types'
|
|
8
|
-
import type { HTTPResponseError } from 'hono/types'
|
|
9
|
-
import { createColors } from 'picocolors'
|
|
10
|
-
import { getColorEnabledAsync } from 'hono/utils/color'
|
|
11
3
|
import { Envir } from 't0n'
|
|
12
|
-
import type {
|
|
13
|
-
|
|
4
|
+
import type {
|
|
5
|
+
Env, Context, Next,
|
|
6
|
+
HTTPResponseError,
|
|
7
|
+
ServerOptions,
|
|
8
|
+
} from './types'
|
|
14
9
|
import { resolve, resolveMiddleware } from './utils/resolve'
|
|
15
10
|
import { getMiddlewares, getHandler } from './register'
|
|
16
|
-
import { isDev } from './utils/environment'
|
|
17
|
-
import localDate from './utils/local-date'
|
|
18
11
|
import request, { GET_REQUEST } from './request'
|
|
19
12
|
import response from './response'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type InitFunction<E extends Env = Env> = (app: Hono<E>) => void
|
|
24
|
-
|
|
25
|
-
export type ServerOptions<E extends Env = Env> = Partial<{
|
|
26
|
-
routes: Routes,
|
|
27
|
-
notFound: NotFoundHandler<E>,
|
|
28
|
-
onError: ErrorHandler<E>,
|
|
29
|
-
root: string,
|
|
30
|
-
app?: Hono<E>,
|
|
31
|
-
init?: InitFunction<E>,
|
|
32
|
-
}>
|
|
13
|
+
import { isDev } from './utils/environment'
|
|
14
|
+
import localDate from './utils/local-date'
|
|
15
|
+
import { gray } from './utils/colors'
|
|
33
16
|
|
|
34
17
|
const NFHandler = () => response.notFound()
|
|
35
18
|
const EHandler = async (e: Error | HTTPResponseError) => {
|
|
36
19
|
console.error(e)
|
|
37
20
|
|
|
38
21
|
switch (true) {
|
|
39
|
-
case e instanceof Unauthorized:
|
|
40
22
|
case 'status' in e && e.status == 401:
|
|
41
23
|
return response.unauthorized()
|
|
42
24
|
|
|
43
|
-
case e
|
|
44
|
-
case 'status' in e && e.status == 400:
|
|
45
|
-
// @ts-ignore
|
|
25
|
+
case 'status' in e && e.status == 400: // @ts-ignore
|
|
46
26
|
return response.badRequest(null, e?.message)
|
|
47
27
|
|
|
48
28
|
default:
|
|
@@ -85,7 +65,7 @@ export const createApp = <E extends Env>(options?: ServerOptions<E>) => {
|
|
|
85
65
|
const app = options?.app ?? new Hono<E>()
|
|
86
66
|
|
|
87
67
|
if (isDev())
|
|
88
|
-
app.use('*', logger((...args: any[]) => console.log(
|
|
68
|
+
app.use('*', logger((...args: any[]) => console.log(gray(localDate()), ...args)))
|
|
89
69
|
|
|
90
70
|
app.use(async (c: Context, next: Next) => {
|
|
91
71
|
c.set(GET_REQUEST as unknown as string, new request(c))
|
package/src/http.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type { Context, Next } from 'hono'
|
|
2
1
|
import { MiddlewareType } from './middleware'
|
|
3
2
|
import response from './response'
|
|
4
3
|
import { GET_REQUEST } from './request'
|
|
5
4
|
import { Ability } from './auth'
|
|
6
5
|
import mergeMiddleware from './utils/merge-middleware'
|
|
7
|
-
import {
|
|
6
|
+
import type {
|
|
7
|
+
Context, Next,
|
|
8
|
+
IRequest
|
|
9
|
+
} from './types'
|
|
8
10
|
|
|
9
11
|
function method(method: string, ...args: any[]): void | ClassDecorator {
|
|
10
12
|
if (args.length == 1 && typeof args[0] == 'function')
|
package/src/index.ts
CHANGED
package/src/middleware.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Context, MiddlewareHandler, Next,
|
|
3
|
+
IRequest,
|
|
4
|
+
} from './types'
|
|
2
5
|
|
|
3
6
|
export type MiddlewareType = MiddlewareHandler | Middleware | (new () => Middleware)
|
|
4
|
-
|
|
7
|
+
|
|
8
|
+
export class Middleware {
|
|
5
9
|
static factory?: Function
|
|
6
10
|
static opts?: object | any[]
|
|
7
11
|
static path: string = '*'
|
|
@@ -9,3 +13,5 @@ export default class Middleware {
|
|
|
9
13
|
await next()
|
|
10
14
|
}
|
|
11
15
|
}
|
|
16
|
+
|
|
17
|
+
export const toHonoMiddleware = (mw: MiddlewareHandler) => async (req: IRequest, next: Next) => await mw(req.cx, next)
|
package/src/response.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
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'
|
|
4
|
-
import type { ErrorResponse, Errors } from './types'
|
|
5
1
|
import { HtmlEscapedCallbackPhase, resolveCallback } from 'hono/utils/html'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
import type {
|
|
3
|
+
ContentfulStatusCode, RedirectStatusCode, StatusCode,
|
|
4
|
+
BaseMime, HeaderRecord,
|
|
5
|
+
ErrorResponse, Errors,
|
|
6
|
+
} from './types'
|
|
11
7
|
|
|
12
8
|
type RBag = {
|
|
13
9
|
status?: StatusCode,
|
package/src/types.ts
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Hono, Env, Handler,
|
|
3
|
+
ErrorHandler, NotFoundHandler,
|
|
4
|
+
ValidationTargets,
|
|
5
|
+
// MiddlewareHandler,
|
|
6
|
+
} from 'hono'
|
|
7
|
+
import type { ResponseHeader } from 'hono/utils/headers'
|
|
8
|
+
// import type { StatusCode } from 'hono/utils/http-status'
|
|
9
|
+
import type { BaseMime } from 'hono/utils/mime'
|
|
5
10
|
import z from 'zod'
|
|
6
11
|
import Action from './action'
|
|
7
12
|
import request from './request'
|
|
8
13
|
import response from './response'
|
|
9
14
|
import validator from './validator'
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
|
|
17
|
+
// export type { H, Handler, HandlerResponse } from 'hono/types'
|
|
18
|
+
export type {
|
|
19
|
+
Env, Context, Next,
|
|
20
|
+
// ErrorHandler, NotFoundHandler,
|
|
21
|
+
MiddlewareHandler, // TODO: remove..
|
|
22
|
+
ValidationTargets,
|
|
23
|
+
} from 'hono'
|
|
24
|
+
export type { HTTPResponseError } from 'hono/types'
|
|
25
|
+
|
|
26
|
+
export type {
|
|
27
|
+
ContentfulStatusCode,
|
|
28
|
+
RedirectStatusCode,
|
|
29
|
+
StatusCode,
|
|
30
|
+
} from 'hono/utils/http-status'
|
|
31
|
+
export type { BaseMime }
|
|
12
32
|
|
|
13
33
|
type PublicMethods<T> = {
|
|
14
34
|
[K in keyof T]: K extends `#${string}` | `$${string}` | symbol | 'prototype' ? never : K
|
|
@@ -34,16 +54,32 @@ export type Route = {
|
|
|
34
54
|
handle: Handlers,
|
|
35
55
|
}
|
|
36
56
|
|
|
37
|
-
export type ActionType = Function | Handler | Action | (new () => Action)
|
|
57
|
+
// export type ActionType = Function | Handler | Action | (new () => Action)
|
|
38
58
|
|
|
39
59
|
export type Handlers = (Function | Handler | (new () => Action))[]
|
|
40
60
|
|
|
41
61
|
export type Routes = Route[]
|
|
42
62
|
|
|
43
|
-
export type
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
export type HeaderRecord =
|
|
64
|
+
| Record<'Content-Type', BaseMime>
|
|
65
|
+
| Record<ResponseHeader, string | string[]>
|
|
66
|
+
| Record<string, string | string[]>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
export type InitFunction<E extends Env = Env> = (app: Hono<E>) => void
|
|
70
|
+
export type ServerOptions<E extends Env = Env> = Partial<{
|
|
71
|
+
routes: Routes,
|
|
72
|
+
notFound: NotFoundHandler<E>,
|
|
73
|
+
onError: ErrorHandler<E>,
|
|
74
|
+
root: string,
|
|
75
|
+
app?: Hono<E>,
|
|
76
|
+
init?: InitFunction<E>,
|
|
77
|
+
}>
|
|
78
|
+
|
|
79
|
+
export interface MiddlewareFactory {
|
|
80
|
+
|
|
46
81
|
}
|
|
82
|
+
// export type MiddlewareType = MiddlewareHandler | Middleware | (new () => Middleware)
|
|
47
83
|
|
|
48
84
|
export type Errors = Record<string, string | string[]>
|
|
49
85
|
export type ErrorResponse = {
|
|
@@ -51,16 +87,23 @@ export type ErrorResponse = {
|
|
|
51
87
|
e?: Errors, // error bag
|
|
52
88
|
}
|
|
53
89
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
90
|
+
// TODO: not used..
|
|
91
|
+
|
|
92
|
+
// export type LambdaResponse = {
|
|
93
|
+
// statusCode: StatusCode,
|
|
94
|
+
// body: string,
|
|
95
|
+
// }
|
|
96
|
+
|
|
97
|
+
// export type ResponseHeadersInit = [
|
|
98
|
+
// string,
|
|
99
|
+
// string
|
|
100
|
+
// ][] | Record<"Content-Type", BaseMime> | Record<ResponseHeader, string> | Record<string, string> | Headers
|
|
101
|
+
// export type ResponseInit<T extends StatusCode = StatusCode> = {
|
|
102
|
+
// headers?: ResponseHeadersInit,
|
|
103
|
+
// status?: T,
|
|
104
|
+
// statusText?: string,
|
|
105
|
+
// }
|
|
106
|
+
// export type ResponseOrInit<T extends StatusCode = StatusCode> = ResponseInit<T> | Response
|
|
64
107
|
// export type JSONValue =
|
|
65
108
|
// | string
|
|
66
109
|
// | number
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// ISC License
|
|
2
|
+
|
|
3
|
+
// Copyright (c) 2021 Alexey Raspopov, Kostiantyn Denysov, Anton Verinov
|
|
4
|
+
|
|
5
|
+
// Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
// purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
// copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
//
|
|
17
|
+
// https://github.com/alexeyraspopov/picocolors/commit/6f0a4638348ed20633d623ee973f9c9a96f65104
|
|
18
|
+
|
|
19
|
+
import { getColorEnabledAsync } from 'hono/utils/color'
|
|
20
|
+
|
|
21
|
+
export const enabled = await getColorEnabledAsync()
|
|
22
|
+
export const isColorSupported = enabled
|
|
23
|
+
|
|
24
|
+
// const { env, stdout } = globalThis?.process ?? {}
|
|
25
|
+
// const enabled =
|
|
26
|
+
// env &&
|
|
27
|
+
// !env.NO_COLOR &&
|
|
28
|
+
// (env.FORCE_COLOR || (stdout?.isTTY && !env.CI && env.TERM !== 'dumb'))
|
|
29
|
+
|
|
30
|
+
const replaceClose = (
|
|
31
|
+
str: string,
|
|
32
|
+
close: string,
|
|
33
|
+
replace: string,
|
|
34
|
+
index: number
|
|
35
|
+
): string => {
|
|
36
|
+
const start = str.substring(0, index) + replace
|
|
37
|
+
const end = str.substring(index + close.length)
|
|
38
|
+
const nextIndex = end.indexOf(close)
|
|
39
|
+
return ~nextIndex
|
|
40
|
+
? start + replaceClose(end, close, replace, nextIndex)
|
|
41
|
+
: start + end
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const formatter = (open: string, close: string, replace = open) => {
|
|
45
|
+
if (!enabled) return String
|
|
46
|
+
return (input: string) => {
|
|
47
|
+
const string = '' + input
|
|
48
|
+
const index = string.indexOf(close, open.length)
|
|
49
|
+
return ~index
|
|
50
|
+
? open + replaceClose(string, close, replace, index) + close
|
|
51
|
+
: open + string + close
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const reset = enabled ? (s: string) => `\x1b[0m${s}\x1b[0m` : String
|
|
56
|
+
export const bold = formatter('\x1b[1m', '\x1b[22m', '\x1b[22m\x1b[1m')
|
|
57
|
+
export const dim = formatter('\x1b[2m', '\x1b[22m', '\x1b[22m\x1b[2m')
|
|
58
|
+
export const italic = formatter('\x1b[3m', '\x1b[23m')
|
|
59
|
+
export const underline = formatter('\x1b[4m', '\x1b[24m')
|
|
60
|
+
export const inverse = formatter('\x1b[7m', '\x1b[27m')
|
|
61
|
+
export const hidden = formatter('\x1b[8m', '\x1b[28m')
|
|
62
|
+
export const strikethrough = formatter('\x1b[9m', '\x1b[29m')
|
|
63
|
+
|
|
64
|
+
const endText = '\x1b[39m'
|
|
65
|
+
export const black = formatter('\x1b[30m', endText)
|
|
66
|
+
export const red = formatter('\x1b[31m', endText)
|
|
67
|
+
export const green = formatter('\x1b[32m', endText)
|
|
68
|
+
export const yellow = formatter('\x1b[33m', endText)
|
|
69
|
+
export const blue = formatter('\x1b[34m', endText)
|
|
70
|
+
export const magenta = formatter('\x1b[35m', endText)
|
|
71
|
+
export const purple = formatter('\x1b[38;2;173;127;168m', endText)
|
|
72
|
+
export const cyan = formatter('\x1b[36m', endText)
|
|
73
|
+
export const white = formatter('\x1b[37m', endText)
|
|
74
|
+
export const gray = formatter('\x1b[90m', endText)
|
|
75
|
+
|
|
76
|
+
const endBg = '\x1b[49m'
|
|
77
|
+
export const bgBlack = formatter('\x1b[40m', endBg)
|
|
78
|
+
export const bgRed = formatter('\x1b[41m', endBg)
|
|
79
|
+
export const bgGreen = formatter('\x1b[42m', endBg)
|
|
80
|
+
export const bgYellow = formatter('\x1b[43m', endBg)
|
|
81
|
+
export const bgBlue = formatter('\x1b[44m', endBg)
|
|
82
|
+
export const bgMagenta = formatter('\x1b[45m', endBg)
|
|
83
|
+
export const bgCyan = formatter('\x1b[46m', endBg)
|
|
84
|
+
export const bgWhite = formatter('\x1b[47m', endBg)
|
|
85
|
+
|
|
86
|
+
export const blackBright = formatter("\x1b[90m", endText)
|
|
87
|
+
export const redBright = formatter("\x1b[91m", endText)
|
|
88
|
+
export const greenBright = formatter("\x1b[92m", endText)
|
|
89
|
+
export const yellowBright = formatter("\x1b[93m", endText)
|
|
90
|
+
export const blueBright = formatter("\x1b[94m", endText)
|
|
91
|
+
export const magentaBright = formatter("\x1b[95m", endText)
|
|
92
|
+
export const cyanBright = formatter("\x1b[96m", endText)
|
|
93
|
+
export const whiteBright = formatter("\x1b[97m", endText)
|
|
94
|
+
|
|
95
|
+
export const bgBlackBright = formatter("\x1b[100m", endBg)
|
|
96
|
+
export const bgRedBright = formatter("\x1b[101m", endBg)
|
|
97
|
+
export const bgGreenBright = formatter("\x1b[102m", endBg)
|
|
98
|
+
export const bgYellowBright = formatter("\x1b[103m", endBg)
|
|
99
|
+
export const bgBlueBright = formatter("\x1b[104m", endBg)
|
|
100
|
+
export const bgMagentaBright = formatter("\x1b[105m", endBg)
|
|
101
|
+
export const bgCyanBright = formatter("\x1b[106m", endBg)
|
|
102
|
+
export const bgWhiteBright = formatter("\x1b[107m", endBg)
|
package/src/utils/log.ts
CHANGED
package/src/utils/port.ts
CHANGED
package/src/utils/resolve.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { MiddlewareType } from '../middleware'
|
|
3
|
-
import type { ActionType } from '../types'
|
|
4
|
-
|
|
5
|
-
export function resolve(obj: ActionType, id: string) {
|
|
1
|
+
export function resolve(obj: any, id: string) {
|
|
6
2
|
if (typeof obj == 'function' && obj?.length == 2)
|
|
7
3
|
return [obj]
|
|
8
4
|
|
|
@@ -12,7 +8,7 @@ export function resolve(obj: ActionType, id: string) {
|
|
|
12
8
|
if (obj?.handle)
|
|
13
9
|
return obj.handle()
|
|
14
10
|
|
|
15
|
-
const instance = new
|
|
11
|
+
const instance = new obj()
|
|
16
12
|
if (obj?.prototype?.run)
|
|
17
13
|
return instance.run()
|
|
18
14
|
|
|
@@ -22,7 +18,7 @@ export function resolve(obj: ActionType, id: string) {
|
|
|
22
18
|
throw new Error(`Invalid action "${id}" - unsupported type`)
|
|
23
19
|
}
|
|
24
20
|
|
|
25
|
-
export function resolveMiddleware(obj:
|
|
21
|
+
export function resolveMiddleware(obj: any) {
|
|
26
22
|
if (typeof obj == 'function' && obj.length == 2)
|
|
27
23
|
return obj
|
|
28
24
|
|
package/src/validator.ts
CHANGED
|
@@ -1,62 +1,40 @@
|
|
|
1
1
|
import { ZodObject } from 'zod'
|
|
2
2
|
import { zValidator } from '@hono/zod-validator'
|
|
3
|
-
import type { ValidationTargets } from 'hono'
|
|
4
|
-
import type { Rule, Rules } from './types'
|
|
5
3
|
import response from './response'
|
|
4
|
+
import type {
|
|
5
|
+
Rule, Rules,
|
|
6
|
+
ValidationTargets,
|
|
7
|
+
} from './types'
|
|
6
8
|
|
|
7
9
|
export default class $Validator {
|
|
8
|
-
private static cache = new Map<string, any>()
|
|
10
|
+
private static cache = new Map<string, (schema: ZodObject<any>) => Rule>()
|
|
9
11
|
|
|
10
12
|
private static createRule<T extends keyof ValidationTargets>(
|
|
11
13
|
target: T,
|
|
12
|
-
schema
|
|
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
|
-
|
|
14
|
+
schema: ZodObject<any>
|
|
15
|
+
): Rule {
|
|
25
16
|
return {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
eTarget: 'fieldErrors'
|
|
30
|
-
})
|
|
17
|
+
target,
|
|
18
|
+
schema,
|
|
19
|
+
eTarget: 'fieldErrors'
|
|
31
20
|
}
|
|
32
21
|
}
|
|
33
22
|
|
|
34
|
-
private static
|
|
23
|
+
private static fn<T extends keyof ValidationTargets>(target: T) {
|
|
35
24
|
if (this.cache.has(target))
|
|
36
25
|
return this.cache.get(target)
|
|
37
26
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
27
|
+
const fn = (schema: ZodObject<any>) => this.createRule(target, schema)
|
|
28
|
+
this.cache.set(target, fn)
|
|
29
|
+
return fn
|
|
52
30
|
}
|
|
53
31
|
|
|
54
|
-
static readonly json = $Validator.
|
|
55
|
-
static readonly form = $Validator.
|
|
56
|
-
static readonly query = $Validator.
|
|
57
|
-
static readonly param = $Validator.
|
|
58
|
-
static readonly header = $Validator.
|
|
59
|
-
static readonly cookie = $Validator.
|
|
32
|
+
static readonly json = $Validator.fn('json')
|
|
33
|
+
static readonly form = $Validator.fn('form')
|
|
34
|
+
static readonly query = $Validator.fn('query')
|
|
35
|
+
static readonly param = $Validator.fn('param')
|
|
36
|
+
static readonly header = $Validator.fn('header')
|
|
37
|
+
static readonly cookie = $Validator.fn('cookie')
|
|
60
38
|
|
|
61
39
|
static parse(rules: Rules): Function[] {
|
|
62
40
|
return (Array.isArray(rules) ? rules : [rules]) // @ts-ignore
|
package/src/context.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono'
|
|
2
|
-
import { getCookie, getSignedCookie, setCookie, setSignedCookie, deleteCookie } from 'hono/cookie'
|
|
3
|
-
import type { CookieOptions, CookiePrefixOptions } from 'hono/utils/cookie'
|
|
4
|
-
|
|
5
|
-
const cookieWrapper = (c: Context) => ({
|
|
6
|
-
all: () => getCookie(c),
|
|
7
|
-
allSigned: (secret: string) => getSignedCookie(c, secret),
|
|
8
|
-
get: (name: string, prefixOptions?: CookiePrefixOptions) => prefixOptions ? getCookie(c, name, prefixOptions) : getCookie(c, name),
|
|
9
|
-
getSigned: (secret: string, name: string, prefixOptions?: CookiePrefixOptions) => prefixOptions ? getSignedCookie(c, secret, name, prefixOptions) : getSignedCookie(c, secret, name),
|
|
10
|
-
set: (name: string, value: string, opt?: CookieOptions) => setCookie(c, name, value, opt),
|
|
11
|
-
setSigned: (name: string, value: string, secret: string, opt?: CookieOptions) => setSignedCookie(c, name, value, secret, opt),
|
|
12
|
-
delete: (name: string, opt?: CookieOptions) => deleteCookie(c, name, opt)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
export default class CX {
|
|
16
|
-
static #c: Context
|
|
17
|
-
static #cookie: ReturnType<typeof cookieWrapper>
|
|
18
|
-
|
|
19
|
-
static setContext(c: Context) {
|
|
20
|
-
this.#c = c
|
|
21
|
-
this.#cookie = cookieWrapper(c)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
static get cx(): Context {
|
|
25
|
-
return this.#c
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
static get cookie() {
|
|
29
|
-
return this.#cookie
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
static get ip(): string | undefined {
|
|
33
|
-
return this.#c.req.header('cf-connecting-ip')
|
|
34
|
-
|| this.#c.req.header('x-forwarded-for')?.split(',')[0]?.trim()
|
|
35
|
-
|| this.#c.env?.aws?.lambda?.event?.requestContext?.identity?.sourceIp
|
|
36
|
-
|| this.#c.req.header('x-real-ip')
|
|
37
|
-
|| this.#c.env?.remoteAddr?.hostname
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static get userAgent(): string | undefined {
|
|
41
|
-
return this.#c.req.header('user-agent')
|
|
42
|
-
}
|
|
43
|
-
}
|
package/src/esbuild.mjs
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import esbuild from 'esbuild'
|
|
2
|
-
import { basename, dirname, join, relative } from 'node:path'
|
|
3
|
-
import { mkdirSync, existsSync, readdirSync, rmSync, copyFileSync } from 'node:fs'
|
|
4
|
-
import { readFile, stat, writeFile } from 'node:fs/promises'
|
|
5
|
-
|
|
6
|
-
const fail = (e) => {
|
|
7
|
-
console.error('❌ Build failed' + (e ? ':' : ''), e || '')
|
|
8
|
-
process.exit(1)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const args = process.argv.slice(2)
|
|
12
|
-
const platform = args[0] || ''
|
|
13
|
-
|
|
14
|
-
const platforms = ['aws', 'cf']
|
|
15
|
-
if (!platform || !platforms.includes(platform))
|
|
16
|
-
fail()
|
|
17
|
-
|
|
18
|
-
const __dirname = dirname(new URL(import.meta.url).pathname)
|
|
19
|
-
|
|
20
|
-
const formatSize = (bytes) => {
|
|
21
|
-
if (bytes < 1024) return `${bytes}b`
|
|
22
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)}kb`
|
|
23
|
-
return `${(bytes / (1024 * 1024)).toFixed(2)}mb`
|
|
24
|
-
}
|
|
25
|
-
const formatTime = (ms) => {
|
|
26
|
-
if (ms < 1000) return `${ms}ms`
|
|
27
|
-
return `${(ms / 1000).toFixed(2)}s`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const isCF = platform == 'cf'
|
|
31
|
-
const buildOptions = {
|
|
32
|
-
entryPoints: [join(__dirname, `prod-${platform}.ts`)],
|
|
33
|
-
bundle: true,
|
|
34
|
-
minify: true,
|
|
35
|
-
outfile: join(__dirname, '../../../dist/index.js'),
|
|
36
|
-
platform: isCF ? 'browser' : 'node',
|
|
37
|
-
target: isCF ? 'es2022' : 'node20',
|
|
38
|
-
conditions: isCF ? ['worker', 'browser'] : [],
|
|
39
|
-
format: 'esm',
|
|
40
|
-
treeShaking: true,
|
|
41
|
-
legalComments: 'none',
|
|
42
|
-
external: [
|
|
43
|
-
'@aws-sdk', '@smithy',
|
|
44
|
-
...(isCF ? [
|
|
45
|
-
'cloudflare:workers',
|
|
46
|
-
'node:crypto', 'crypto',
|
|
47
|
-
'node:buffer', 'buffer',
|
|
48
|
-
] : []),
|
|
49
|
-
],
|
|
50
|
-
metafile: true,
|
|
51
|
-
write: false,
|
|
52
|
-
plugins: [
|
|
53
|
-
{
|
|
54
|
-
name: 'preserve-class-names',
|
|
55
|
-
setup(build) {
|
|
56
|
-
build.onLoad(
|
|
57
|
-
{ filter: /(actions|features|routes)\/.*\.ts$/ },
|
|
58
|
-
async (args) => {
|
|
59
|
-
const contents = await readFile(args.path, 'utf8')
|
|
60
|
-
const result = await esbuild.transform(contents, {
|
|
61
|
-
loader: 'ts',
|
|
62
|
-
minify: true,
|
|
63
|
-
keepNames: true
|
|
64
|
-
})
|
|
65
|
-
return { contents: result.code, loader: 'ts' }
|
|
66
|
-
}
|
|
67
|
-
)
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'remove-use-strict',
|
|
72
|
-
setup(build) {
|
|
73
|
-
build.onEnd(async (result) => {
|
|
74
|
-
if (!result.outputFiles) return
|
|
75
|
-
|
|
76
|
-
const files = result.outputFiles.filter(file => file.path.endsWith('.js'))
|
|
77
|
-
await Promise.all(files.map(async file => {
|
|
78
|
-
if (!file.path.endsWith('.js')) return
|
|
79
|
-
|
|
80
|
-
await writeFile(
|
|
81
|
-
file.path,
|
|
82
|
-
new TextDecoder()
|
|
83
|
-
.decode(file.contents)
|
|
84
|
-
.replace(/(["'`])\s*use strict\s*\1;?|`use strict`;?/g, '')
|
|
85
|
-
)
|
|
86
|
-
}))
|
|
87
|
-
})
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
]
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const startTime = Date.now()
|
|
94
|
-
const cwd = join(__dirname, '../../..')
|
|
95
|
-
|
|
96
|
-
const distDir = join(cwd, 'dist')
|
|
97
|
-
existsSync(distDir)
|
|
98
|
-
? readdirSync(distDir).forEach(file => rmSync(join(distDir, file), { recursive: true, force: true }))
|
|
99
|
-
: mkdirSync(distDir, { recursive: true })
|
|
100
|
-
|
|
101
|
-
for (const file of await readdirSync(distDir))
|
|
102
|
-
await rmSync(join(distDir, file))
|
|
103
|
-
|
|
104
|
-
if (isCF) {
|
|
105
|
-
for (let file of [
|
|
106
|
-
'wrangler.toml',
|
|
107
|
-
]) {
|
|
108
|
-
file = join(cwd, file)
|
|
109
|
-
if (existsSync(file))
|
|
110
|
-
copyFileSync(file, join(cwd, 'dist', basename(file)))
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
esbuild.build(buildOptions)
|
|
115
|
-
.then(async result => {
|
|
116
|
-
const outputFile = buildOptions.outfile
|
|
117
|
-
const stats = await stat(outputFile)
|
|
118
|
-
const size = formatSize(stats.size)
|
|
119
|
-
|
|
120
|
-
console.log(`\n⚡️ Done in ${formatTime(Date.now() - startTime)}`)
|
|
121
|
-
console.log(` ${relative(join(cwd, 'node_modules/rajt/src'), buildOptions.entryPoints[0])} → ${relative(cwd, outputFile)}`)
|
|
122
|
-
console.log(` Size: ${size}`)
|
|
123
|
-
console.log(` Files: ${Object.keys(result.metafile.outputs).length}`)
|
|
124
|
-
}).catch(fail)
|
package/src/exceptions.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export class Unauthorized extends Error {
|
|
2
|
-
status = 401
|
|
3
|
-
constructor(message = 'Unauthorized') {
|
|
4
|
-
super(message)
|
|
5
|
-
this.name = 'UnauthorizedError'
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class BadRequest extends Error {
|
|
10
|
-
status = 400
|
|
11
|
-
constructor(message = 'Bad Request') {
|
|
12
|
-
super(message)
|
|
13
|
-
this.name = 'BadRequestError'
|
|
14
|
-
}
|
|
15
|
-
}
|