duto 0.260808.0 → 0.260906.0
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/LICENSE +2 -2
- package/README.md +1 -1
- package/package.json +51 -16
- package/src/cli.ts +42 -0
- package/src/enum.ts +2 -0
- package/src/index.d.ts +61 -0
- package/src/index.ts +15 -24
- package/src/middleware.ts +2 -0
- package/src/{compiler → pages/compiler}/vite-plugin.ts +1 -1
- package/src/{i18n → pages/i18n}/client.ts +1 -1
- package/src/pages/index.ts +28 -0
- package/src/server/adapter/aws.ts +4 -0
- package/src/server/adapter/workerd.ts +4 -0
- package/src/server/app.ts +96 -0
- package/src/server/auth/ability.ts +72 -0
- package/src/server/auth/authnz.ts +86 -0
- package/src/server/auth/index.ts +5 -0
- package/src/server/auth/token.ts +147 -0
- package/src/server/auth/types.ts +2 -0
- package/src/server/cli/commands/build.ts +41 -0
- package/src/server/cli/commands/deploy.ts +82 -0
- package/src/server/cli/commands/dev.ts +277 -0
- package/src/server/cli/commands/make.ts +98 -0
- package/src/server/cli/commands/migrate.ts +93 -0
- package/src/server/cli/commands/routes.ts +79 -0
- package/src/server/cli/index.ts +27 -0
- package/src/server/cli/stubs.ts +39 -0
- package/src/server/cli/types.ts +3 -0
- package/src/server/cli/utils.ts +443 -0
- package/src/server/config.ts +4 -0
- package/src/server/db/d1.d.ts +1 -0
- package/src/server/db/d1.ts +1 -0
- package/src/server/db/dynamodb.d.ts +1 -0
- package/src/server/db/dynamodb.ts +1 -0
- package/src/server/db/index.ts +1 -0
- package/src/server/entry.ts +19 -0
- package/src/server/handle.ts +30 -0
- package/src/server/http.ts +23 -0
- package/src/server/middlewares/auth.ts +40 -0
- package/src/server/middlewares/logger.ts +30 -0
- package/src/server/open-api/register.ts +29 -0
- package/src/server/open-api/spec.ts +107 -0
- package/src/server/request.ts +233 -0
- package/src/server/response.ts +142 -0
- package/src/server/routes.ts +474 -0
- package/src/server/types.ts +142 -0
- package/src/server/utils/environment.ts +17 -0
- package/src/server/utils.ts +46 -0
- package/src/server/validator.ts +70 -0
- package/src/utils.ts +5 -0
- package/src/cli/index.ts +0 -28
- package/src/cli/utils.ts +0 -146
- /package/src/{client → pages/client}/app.tsx +0 -0
- /package/src/{client → pages/client}/hmr.ts +0 -0
- /package/src/{client → pages/client}/island.ts +0 -0
- /package/src/{client → pages/client}/link.ts +0 -0
- /package/src/{client → pages/client}/router.ts +0 -0
- /package/src/{client → pages/client}/storage.ts +0 -0
- /package/src/{cli → pages}/commands/build.ts +0 -0
- /package/src/{cli → pages}/commands/dev-old.ts +0 -0
- /package/src/{cli → pages}/commands/dev.ts +0 -0
- /package/src/{cli → pages}/commands/preview.ts +0 -0
- /package/src/{compiler → pages/compiler}/aliases.ts +0 -0
- /package/src/{compiler → pages/compiler}/assets.ts +0 -0
- /package/src/{compiler → pages/compiler}/ast.ts +0 -0
- /package/src/{compiler → pages/compiler}/constants.ts +0 -0
- /package/src/{compiler → pages/compiler}/file.ts +0 -0
- /package/src/{compiler → pages/compiler}/index.ts +0 -0
- /package/src/{compiler → pages/compiler}/island.ts +0 -0
- /package/src/{compiler → pages/compiler}/meta.ts +0 -0
- /package/src/{compiler → pages/compiler}/routes.ts +0 -0
- /package/src/{compiler → pages/compiler}/types.ts +0 -0
- /package/src/{compiler → pages/compiler}/utils.ts +0 -0
- /package/src/{components → pages/components}/link.tsx +0 -0
- /package/src/{i18n → pages/i18n}/element.ts +0 -0
- /package/src/{i18n → pages/i18n}/server.ts +0 -0
- /package/src/{preact → pages/preact}/client-dev.ts +0 -0
- /package/src/{preact → pages/preact}/client.ts +0 -0
- /package/src/{preact → pages/preact}/context.ts +0 -0
- /package/src/{preact → pages/preact}/server.ts +0 -0
- /package/src/{preact → pages/preact}/signals.ts +0 -0
- /package/src/{preact → pages/preact}/static-html.ts +0 -0
- /package/src/{preact → pages/preact}/types.ts +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator'
|
|
2
|
+
import response from './response'
|
|
3
|
+
import type * as z from 'zod'
|
|
4
|
+
import type {
|
|
5
|
+
Rule, Rules, RuleFn,
|
|
6
|
+
ValidationTargets,
|
|
7
|
+
zObject,
|
|
8
|
+
MiddlewareHandler,
|
|
9
|
+
} from './types'
|
|
10
|
+
|
|
11
|
+
export default class $Validator {
|
|
12
|
+
private static cache = new Map<string, RuleFn>()
|
|
13
|
+
|
|
14
|
+
private static createRule<T extends keyof ValidationTargets>(
|
|
15
|
+
target: T,
|
|
16
|
+
schema: zObject
|
|
17
|
+
): Rule {
|
|
18
|
+
return {
|
|
19
|
+
target,
|
|
20
|
+
schema,
|
|
21
|
+
eTarget: 'fieldErrors'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private static fn<T extends keyof ValidationTargets>(target: T) {
|
|
26
|
+
if (this.cache.has(target))
|
|
27
|
+
return this.cache.get(target)
|
|
28
|
+
|
|
29
|
+
const fn = (schema: zObject) => this.createRule(target, schema)
|
|
30
|
+
this.cache.set(target, fn)
|
|
31
|
+
return fn
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static readonly json = $Validator.fn('json')!
|
|
35
|
+
static readonly form = $Validator.fn('form')!
|
|
36
|
+
static readonly query = $Validator.fn('query')!
|
|
37
|
+
static readonly param = $Validator.fn('param')!
|
|
38
|
+
static readonly header = $Validator.fn('header')!
|
|
39
|
+
static readonly cookie = $Validator.fn('cookie')!
|
|
40
|
+
|
|
41
|
+
static #parser = (rule: Rule) => zValidator(rule.target, rule.schema, (result, c) => {
|
|
42
|
+
if (!result.success) // @ts-ignore
|
|
43
|
+
return response.badRequest(formatZodErrors(result.error.issues || []))
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
static setParser(parser: (rule: Rule) => MiddlewareHandler) {
|
|
47
|
+
this.#parser = parser
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static parse(rules: Rules): Function[] {
|
|
51
|
+
return (Array.isArray(rules) ? rules : [rules]) // @ts-ignore
|
|
52
|
+
.flatMap(this.#parser)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function formatZodErrors(issues: z.ZodIssue[]): Record<string, string[]> {
|
|
57
|
+
const result: Record<string, string[]> = {}
|
|
58
|
+
|
|
59
|
+
for (const issue of issues) {
|
|
60
|
+
const path = issue.path.join('.')
|
|
61
|
+
const key = path || 'root'
|
|
62
|
+
|
|
63
|
+
if (!result[key])
|
|
64
|
+
result[key] = []
|
|
65
|
+
|
|
66
|
+
result[key].push(issue.message)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return result
|
|
70
|
+
}
|
package/src/utils.ts
ADDED
package/src/cli/index.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
if (!process?.isBun || typeof Bun === 'undefined') {
|
|
4
|
-
console.error('Error: "Bun" is not available. Please install:')
|
|
5
|
-
console.log(' curl -fsSL https://bun.sh/install | bash')
|
|
6
|
-
process.exit(0)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
global.__st = performance.now()
|
|
10
|
-
|
|
11
|
-
import { join } from 'pathe'
|
|
12
|
-
import { cli } from 't0n/cli'
|
|
13
|
-
import { version } from '!/package.json'
|
|
14
|
-
|
|
15
|
-
if (typeof document === 'undefined' && import.meta.main) {
|
|
16
|
-
const cmd = (c: string) => join(import.meta.dirname, 'commands', c)
|
|
17
|
-
|
|
18
|
-
cli({
|
|
19
|
-
name: 'duto',
|
|
20
|
-
description: 'Duto CLI',
|
|
21
|
-
version,
|
|
22
|
-
commands: {
|
|
23
|
-
dev: cmd('dev'),
|
|
24
|
-
build: cmd('build'),
|
|
25
|
-
preview: cmd('preview'),
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
}
|
package/src/cli/utils.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { IMPORT, Datte } from 't0n'
|
|
2
|
-
import { join } from 'pathe'
|
|
3
|
-
import { gray, green, yellow, red, cyan } from 't0n/color'
|
|
4
|
-
import type { UserConfig } from 'vite'
|
|
5
|
-
|
|
6
|
-
import { resolveExtension } from '@/file'
|
|
7
|
-
import config from '@/vite-plugin'
|
|
8
|
-
import { _root } from '@/utils'
|
|
9
|
-
import { match, match404 } from '@/routes'
|
|
10
|
-
import type { Metadata, PluginOptions } from '@/types'
|
|
11
|
-
import { getMetadata } from '@/meta'
|
|
12
|
-
|
|
13
|
-
export async function getConfig(name = 'config'): Promise<UserConfig & PluginOptions> {
|
|
14
|
-
let opts = {} as UserConfig
|
|
15
|
-
const file = resolveExtension(name)
|
|
16
|
-
if (file) opts = await IMPORT(join(_root, file), 'default')
|
|
17
|
-
return config(opts)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// export const formatTime = (ms: number) => {
|
|
21
|
-
// if (ms < 1000) return `${ms}ms`
|
|
22
|
-
// return `${(ms / 1000).toFixed(2)}s`
|
|
23
|
-
// }
|
|
24
|
-
export const formatTime = (ms: number) => {
|
|
25
|
-
if (ms < 0.001) return `${(ms * 1_000_000).toFixed(2)}ns`
|
|
26
|
-
if (ms < 1) return `${(ms * 1000).toFixed(2)}µs`
|
|
27
|
-
if (ms < 1000) return `${ms.toFixed(2)}ms`
|
|
28
|
-
if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`
|
|
29
|
-
return `${Math.floor(ms / 60000)}m ${((ms % 60000) / 1000).toFixed(1)}s`
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const statusColorMap = new Map([
|
|
33
|
-
[5, red],
|
|
34
|
-
[4, yellow],
|
|
35
|
-
[3, cyan],
|
|
36
|
-
])
|
|
37
|
-
|
|
38
|
-
const getStatusColor = (status: number) => (statusColorMap.get(Math.floor(status / 100)) ?? green)(String(status))
|
|
39
|
-
|
|
40
|
-
const clients = new Set<Bun.ServerWebSocket<void>>()
|
|
41
|
-
export function reload() {
|
|
42
|
-
for (const ws of clients) {
|
|
43
|
-
if (ws.readyState === WebSocket.OPEN)
|
|
44
|
-
ws.send('reload')
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function preview(
|
|
49
|
-
meta: Metadata,
|
|
50
|
-
host: string = '0.0.0.0',
|
|
51
|
-
port: number = 4173
|
|
52
|
-
) {
|
|
53
|
-
return Bun.serve({
|
|
54
|
-
hostname: host,
|
|
55
|
-
port,
|
|
56
|
-
|
|
57
|
-
websocket: {
|
|
58
|
-
open(ws) {
|
|
59
|
-
clients.add(ws)
|
|
60
|
-
},
|
|
61
|
-
close(ws) {
|
|
62
|
-
clients.delete(ws)
|
|
63
|
-
},
|
|
64
|
-
message() {},
|
|
65
|
-
},
|
|
66
|
-
async fetch(req, server) {
|
|
67
|
-
const start = performance.now()
|
|
68
|
-
|
|
69
|
-
const url = new URL(req.url)
|
|
70
|
-
const path = decodeURIComponent(url.pathname)
|
|
71
|
-
const headers = {
|
|
72
|
-
'Access-Control-Allow-Origin': '*',
|
|
73
|
-
'Access-Control-Allow-Methods': 'GET',
|
|
74
|
-
'Access-Control-Allow-Headers': '*',
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (req.method === 'OPTIONS')
|
|
78
|
-
return new Response(null, { status: 204, headers })
|
|
79
|
-
|
|
80
|
-
if (req.headers.get('upgrade') === 'websocket'
|
|
81
|
-
&& req.headers.get('sec-websocket-protocol') === 'duto') {
|
|
82
|
-
server.upgrade(req)
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let status = 500
|
|
87
|
-
let route: string | undefined
|
|
88
|
-
let matched: Bun.MatchedRoute | null | undefined
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
let res: Response
|
|
92
|
-
const dist = 'dist' // TODO: get from configs
|
|
93
|
-
|
|
94
|
-
let file = Bun.file(join(_root, dist, path))
|
|
95
|
-
|
|
96
|
-
if (await file.exists()) {
|
|
97
|
-
// route = path
|
|
98
|
-
res = new Response(file)
|
|
99
|
-
} else {
|
|
100
|
-
matched = match(path)
|
|
101
|
-
|
|
102
|
-
// console.log(matched)
|
|
103
|
-
route = matched?.name || match404(meta, path)
|
|
104
|
-
|
|
105
|
-
res = new Response(null, { status: 404 })
|
|
106
|
-
|
|
107
|
-
// for (const asset of path !== '/' && matched && matched.kind === 'exact' ? [
|
|
108
|
-
// path,
|
|
109
|
-
// join(path, 'index'),
|
|
110
|
-
// ] : ['index']) {
|
|
111
|
-
for (const asset of [
|
|
112
|
-
path,
|
|
113
|
-
join(path, 'index'),
|
|
114
|
-
'index',
|
|
115
|
-
]) {
|
|
116
|
-
file = Bun.file(join(_root, dist, asset +'.html'))
|
|
117
|
-
|
|
118
|
-
if (await file.exists()) {
|
|
119
|
-
// if (route === '/' || !route) route = asset
|
|
120
|
-
res = new Response(file)
|
|
121
|
-
break
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
status = res.status
|
|
127
|
-
return res
|
|
128
|
-
} catch (err) {
|
|
129
|
-
status = 500
|
|
130
|
-
throw err
|
|
131
|
-
} finally {
|
|
132
|
-
if (route || matched) {
|
|
133
|
-
const elapsed = `${Math.max(1, Math.ceil(performance.now() - start))}ms`
|
|
134
|
-
|
|
135
|
-
console.log([
|
|
136
|
-
gray(Datte.dateTime()),
|
|
137
|
-
getStatusColor(status),
|
|
138
|
-
path,
|
|
139
|
-
route && route !== path ? gray(route) : '',
|
|
140
|
-
gray(elapsed),
|
|
141
|
-
].filter(Boolean).join(' '))
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
})
|
|
146
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|