duto 0.260808.0 → 0.260915.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 +35 -13
- package/package.json +54 -13
- package/src/cli.ts +45 -0
- package/src/commands/new.ts +147 -0
- package/src/commands/templates/base/.editorconfig +21 -0
- package/src/commands/templates/base/.env.dev.example +2 -0
- package/src/commands/templates/base/.env.prod.example +2 -0
- package/src/commands/templates/base/README.md +29 -0
- package/src/commands/templates/base/_gitignore +100 -0
- package/src/commands/templates/base/actions/blog/index.get.ts +9 -0
- package/src/commands/templates/base/actions/blog/post/[id].get.ts +9 -0
- package/src/commands/templates/base/actions/index.get.ts +5 -0
- package/src/commands/templates/base/configs/duto.ts +11 -0
- package/src/commands/templates/base/configs/roles.ts +5 -0
- package/src/commands/templates/base/package.json +24 -0
- package/src/commands/templates/base/tsconfig.json +42 -0
- package/src/commands/templates/workerd/wrangler.toml +47 -0
- package/src/commands/upgrade.ts +30 -0
- package/src/enum.ts +2 -0
- package/src/index.d.ts +61 -0
- package/src/index.ts +19 -23
- package/src/middleware.ts +2 -0
- package/src/{cli → pages/cli}/commands/build.ts +13 -7
- package/src/{cli → pages/cli}/commands/dev.ts +11 -4
- package/src/{cli → pages/cli}/commands/preview.ts +6 -4
- package/src/pages/cli/index.ts +10 -0
- package/src/{cli → pages/cli}/utils.ts +4 -5
- package/src/{client → pages/client}/app.tsx +1 -1
- package/src/{client → pages/client}/router.ts +1 -1
- package/src/{compiler → pages/compiler}/file.ts +1 -1
- package/src/{compiler → pages/compiler}/index.ts +2 -4
- package/src/{compiler → pages/compiler}/meta.ts +2 -2
- package/src/{compiler → pages/compiler}/routes.ts +1 -1
- package/src/{compiler → pages/compiler}/types.ts +10 -0
- package/src/{compiler → pages/compiler}/vite-plugin.ts +20 -45
- package/src/{i18n → pages/i18n}/client.ts +2 -2
- package/src/{i18n → pages/i18n}/element.ts +1 -1
- package/src/{i18n → pages/i18n}/server.ts +1 -1
- package/src/pages/index.ts +28 -0
- package/src/{preact → pages/preact}/server.ts +1 -1
- package/src/server/adapter/aws.ts +4 -0
- package/src/server/adapter/workerd.ts +4 -0
- package/src/server/app.ts +91 -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 +81 -0
- package/src/server/cli/commands/dev.ts +279 -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 +78 -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 +437 -0
- package/src/server/config.ts +19 -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/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 +114 -0
- package/src/server/request.ts +265 -0
- package/src/server/response.ts +142 -0
- package/src/server/routes.ts +473 -0
- package/src/server/types.ts +142 -0
- package/src/server/utils/environment.ts +17 -0
- package/src/server/utils.ts +71 -0
- package/src/server/validator.ts +70 -0
- package/src/utils.ts +15 -0
- package/src/cli/commands/dev-old.ts +0 -213
- package/src/cli/index.ts +0 -28
- package/src/compiler/utils.ts +0 -5
- /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}/storage.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}/island.ts +0 -0
- /package/src/{components → pages/components}/link.tsx +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}/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,47 @@
|
|
|
1
|
+
name = "duto-api"
|
|
2
|
+
main = ".duto/index.js"
|
|
3
|
+
compatibility_date = "2026-08-06"
|
|
4
|
+
|
|
5
|
+
# workers_dev = false
|
|
6
|
+
# preview_urls = false
|
|
7
|
+
no_bundle = true
|
|
8
|
+
send_metrics = false
|
|
9
|
+
compatibility_flags = [ "no_nodejs_compat", "no_nodejs_compat_v2" ]
|
|
10
|
+
|
|
11
|
+
# route = "example.com"
|
|
12
|
+
# route = { pattern = "api.example.com", custom_domain = true }
|
|
13
|
+
|
|
14
|
+
# [[routes]]
|
|
15
|
+
# pattern = "api.example.com/*"
|
|
16
|
+
# zone_name = "example.com"
|
|
17
|
+
# [[routes]]
|
|
18
|
+
# pattern = "api.example.com"
|
|
19
|
+
# custom_domain = true
|
|
20
|
+
|
|
21
|
+
# [observability]
|
|
22
|
+
# enabled = true
|
|
23
|
+
# head_sampling_rate = 0.1 # 10% of requests are logged
|
|
24
|
+
|
|
25
|
+
# PAID
|
|
26
|
+
# [limits]
|
|
27
|
+
# # The maximum CPU time allowed per invocation, in milliseconds
|
|
28
|
+
# cpu_ms = 100
|
|
29
|
+
|
|
30
|
+
# Bindings (KV, D1, R2..)
|
|
31
|
+
# kv_namespaces = []
|
|
32
|
+
# d1_databases = []
|
|
33
|
+
|
|
34
|
+
# [[d1_databases]]
|
|
35
|
+
# binding = "SCRIPT_NAME"
|
|
36
|
+
# database_name = "DB_NAME"
|
|
37
|
+
# database_id = "DB_UUID"
|
|
38
|
+
# preview_database_id = "PREVIEW_UUID"
|
|
39
|
+
# migrations_table = "MIGRATION_TABLE_NAME"
|
|
40
|
+
# migrations_dir = "migrations/sql"
|
|
41
|
+
# persist_to = "./.wrangler/state"
|
|
42
|
+
|
|
43
|
+
# [env.production]
|
|
44
|
+
# name = "rajt-api-prod"
|
|
45
|
+
|
|
46
|
+
# [vars]
|
|
47
|
+
# API_HOST = "api.example.com"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { command } from 't0n/cli'
|
|
2
|
+
import { dim, green } from 't0n/color'
|
|
3
|
+
import { event, error, step, log, rn } from 't0n/log'
|
|
4
|
+
import { _root } from '@/utils'
|
|
5
|
+
import { version } from '!/package.json'
|
|
6
|
+
|
|
7
|
+
import { createSpinner } from 'nanospinner'
|
|
8
|
+
|
|
9
|
+
export default command({
|
|
10
|
+
meta: {
|
|
11
|
+
name: 'upgrade',
|
|
12
|
+
description: '📄 Upgrade to latest version of Duto\n',
|
|
13
|
+
},
|
|
14
|
+
async run({ args }) { // @ts-ignore
|
|
15
|
+
const spinner = createSpinner('Upgrading...').start()
|
|
16
|
+
|
|
17
|
+
const proc = Bun.spawn(['bun', 'update', '-g', 'duto'], { stdout: 'ignore', stderr: 'ignore' })
|
|
18
|
+
const exitCode = await proc.exited
|
|
19
|
+
|
|
20
|
+
if (exitCode === 0) {
|
|
21
|
+
spinner.success({ text: 'Upgraded' })
|
|
22
|
+
} else {
|
|
23
|
+
spinner.error({ text: `Falha ao atualizar duto (exit ${exitCode})` })
|
|
24
|
+
process.exit(exitCode)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
event(green('Congrats!') + ` You're already on the latest version of Duto.`)
|
|
28
|
+
// event(green('Congrats!') + ` You're already on the latest version of Duto ${dim(`(which is v${version})`)}`)
|
|
29
|
+
},
|
|
30
|
+
})
|
package/src/enum.ts
ADDED
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/// <reference types='bun-types' />
|
|
2
|
+
/// <reference types='node' />
|
|
3
|
+
|
|
4
|
+
// export { }
|
|
5
|
+
|
|
6
|
+
import * as Duto from './'
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
// Duto
|
|
10
|
+
var __st: number
|
|
11
|
+
var __hmr: boolean
|
|
12
|
+
|
|
13
|
+
type Req = Duto.Req
|
|
14
|
+
type Res = Duto.Res
|
|
15
|
+
type $v = Duto.$v
|
|
16
|
+
type IRequest = Duto.IRequest
|
|
17
|
+
type IResponse = Duto.IResponse
|
|
18
|
+
type IValidator = Duto.IValidator
|
|
19
|
+
|
|
20
|
+
type Context = Duto.Context
|
|
21
|
+
type Next = Duto.Next
|
|
22
|
+
|
|
23
|
+
type Abilities = Duto.Abilities
|
|
24
|
+
type Roles = Duto.Roles
|
|
25
|
+
|
|
26
|
+
type EnumStatic = Duto.EnumStatic
|
|
27
|
+
type EnumValue = Duto.EnumValue
|
|
28
|
+
type EnumType = Duto.EnumType
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// Bun:test
|
|
32
|
+
var test: typeof import('bun:test').test
|
|
33
|
+
var describe: typeof import('bun:test').describe
|
|
34
|
+
var it: typeof import('bun:test').it
|
|
35
|
+
var expect: typeof import('bun:test').expect
|
|
36
|
+
// Hooks
|
|
37
|
+
var beforeAll: typeof import('bun:test').beforeAll
|
|
38
|
+
var afterAll: typeof import('bun:test').afterAll
|
|
39
|
+
var beforeEach: typeof import('bun:test').beforeEach
|
|
40
|
+
var afterEach: typeof import('bun:test').afterEach
|
|
41
|
+
// Mocking
|
|
42
|
+
var mock: typeof import('bun:test').mock
|
|
43
|
+
var vi: typeof import('bun:test').vi
|
|
44
|
+
var jest: typeof import('bun:test').jest
|
|
45
|
+
var spyOn: typeof import('bun:test').spyOn
|
|
46
|
+
// Utils
|
|
47
|
+
var setSystemTime: typeof import('bun:test').setSystemTime
|
|
48
|
+
var setDefaultTimeout: typeof import('bun:test').setDefaultTimeout
|
|
49
|
+
// Types
|
|
50
|
+
var Test: typeof import('bun:test').Test
|
|
51
|
+
var Describe: typeof import('bun:test').Describe
|
|
52
|
+
var Expect: typeof import('bun:test').Expect
|
|
53
|
+
var Mock: typeof import('bun:test').Mock
|
|
54
|
+
var TestOptions: typeof import('bun:test').TestOptions
|
|
55
|
+
var Matchers: typeof import('bun:test').Matchers
|
|
56
|
+
// Namespace
|
|
57
|
+
namespace jest {
|
|
58
|
+
var fn: typeof import('bun:test').vi.fn
|
|
59
|
+
var mock: typeof import('bun:test').vi.mock
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
export
|
|
2
|
-
Redirect,
|
|
3
|
-
useLocation, useParams, useSearch, useSearchParams,
|
|
4
|
-
matchRoute,
|
|
5
|
-
} from 'wouter-preact'
|
|
1
|
+
export * from './pages'
|
|
6
2
|
|
|
7
|
-
export {
|
|
8
|
-
|
|
9
|
-
getLocale, setLocale,
|
|
10
|
-
isPrefixed,
|
|
11
|
-
} from './i18n/client'
|
|
3
|
+
export { default as Response } from './server/response'
|
|
4
|
+
export * from './server/config'
|
|
12
5
|
|
|
13
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
Enum,
|
|
8
|
+
Envir, hasEnv, getEnv, setEnv, addEnv, removeEnv
|
|
9
|
+
} from 't0n'
|
|
10
|
+
export type { EnumStatic, EnumValue, EnumType } from 't0n'
|
|
14
11
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return
|
|
22
|
-
}
|
|
12
|
+
export type {
|
|
13
|
+
IRequest, IRequest as Req, IRequest as $req,
|
|
14
|
+
IResponse, IResponse as Res, IResponse as $res,
|
|
15
|
+
IValidator, IValidator as $v,
|
|
16
|
+
Context, Next,
|
|
17
|
+
} from './server/types'
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
19
|
+
// Auth
|
|
20
|
+
export { Ability } from './server/auth/ability'
|
|
21
|
+
export { Authnz } from './server/auth/authnz'
|
|
22
|
+
export { Token } from './server/auth/token'
|
|
27
23
|
|
|
28
|
-
export {
|
|
24
|
+
export type { Abilities, Roles } from './server/auth/types'
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import { build } from 'vite'
|
|
2
|
-
import {
|
|
2
|
+
import { setEnv } from 't0n'
|
|
3
3
|
import { command } from 't0n/cli'
|
|
4
4
|
import { dim, underline } from 't0n/color'
|
|
5
5
|
import { wait, error, rn, event } from 't0n/log'
|
|
6
|
-
import { meta } from '
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
6
|
+
import { meta } from '#/compiler/vite-plugin'
|
|
7
|
+
import type { SummaryMetadata } from '#/compiler/types'
|
|
8
|
+
import { getConfig } from '../utils'
|
|
9
|
+
import { filesize } from '@/utils'
|
|
9
10
|
|
|
10
11
|
export default command({
|
|
11
12
|
meta: {
|
|
12
13
|
name: 'build',
|
|
13
14
|
description: '🗂️ Perform the build for production\n',
|
|
14
15
|
},
|
|
15
|
-
|
|
16
|
+
args: {
|
|
17
|
+
minify: {
|
|
18
|
+
description: 'Minify the result',
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
default: true,
|
|
21
|
+
},
|
|
16
22
|
},
|
|
17
23
|
async run({ args }) {
|
|
18
|
-
global.__hmr = !!args?.hmr
|
|
19
24
|
wait('Building..')
|
|
25
|
+
setEnv('duto.hmr', !!args?.hmr)
|
|
26
|
+
setEnv('duto.minify', args.minify ?? true)
|
|
20
27
|
|
|
21
28
|
try {
|
|
22
29
|
await build(await getConfig())
|
|
@@ -65,7 +72,6 @@ export default command({
|
|
|
65
72
|
event(`Builded successfully${st ? dim(` in ${st} ms`) : ''}`)
|
|
66
73
|
} catch (e: any) {
|
|
67
74
|
error(e)
|
|
68
|
-
// error('Build failed:', e?.message || e)
|
|
69
75
|
process.exit(0)
|
|
70
76
|
} finally {
|
|
71
77
|
rn()
|
|
@@ -2,9 +2,10 @@ import { command, watch, killProcess } from 't0n/cli'
|
|
|
2
2
|
import { dim } from 't0n/color'
|
|
3
3
|
import { error, log, rn } from 't0n/log'
|
|
4
4
|
import { withPort } from 't0n/port'
|
|
5
|
-
import { getMetadata } from '
|
|
5
|
+
import { getMetadata } from '#/compiler/meta'
|
|
6
6
|
import { _root } from '@/utils'
|
|
7
|
-
import { getConfig, preview, reload } from '
|
|
7
|
+
import { getConfig, preview, reload } from '../utils'
|
|
8
|
+
import { getEnv, setEnv } from 't0n'
|
|
8
9
|
|
|
9
10
|
export const args = {
|
|
10
11
|
port: {
|
|
@@ -28,8 +29,11 @@ export default command({
|
|
|
28
29
|
args,
|
|
29
30
|
async run({ args }) {
|
|
30
31
|
const config = await getConfig()
|
|
31
|
-
|
|
32
|
-
const
|
|
32
|
+
const duto = getEnv('duto', {})
|
|
33
|
+
const desiredPort = Number(args.port || duto?.dev?.port || 3000)
|
|
34
|
+
const host = String(args.host || duto?.dev?.host || 'localhost')
|
|
35
|
+
// const desiredPort = args.port ? Number(args.port) : (config?.preview?.port ? Number(config.preview.port) : 3000)
|
|
36
|
+
// const host = args.host ? String(args.host) : (config?.preview?.host ? String(config.preview.host) : 'localhost')
|
|
33
37
|
|
|
34
38
|
let buildProcess: Bun.Subprocess | null = null
|
|
35
39
|
|
|
@@ -48,6 +52,9 @@ export default command({
|
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
withPort(desiredPort, async (port) => {
|
|
55
|
+
setEnv('duto.dev.port', port)
|
|
56
|
+
setEnv('duto.dev.host', host)
|
|
57
|
+
|
|
51
58
|
const ignore = [
|
|
52
59
|
/(^|[\/\\])\.(duto|git|cache|vscode|idea|next|nuxt|nyc_output)([\/\\]|$)/,
|
|
53
60
|
/(^|[\/\\])(node_modules|tmp|dist|build|out|coverage)([\/\\]|$)/,
|
|
@@ -2,10 +2,11 @@ import { command } from 't0n/cli'
|
|
|
2
2
|
import { dim } from 't0n/color'
|
|
3
3
|
import { error, log, rn } from 't0n/log'
|
|
4
4
|
import { withPort } from 't0n/port'
|
|
5
|
-
import { getMetadata } from '
|
|
5
|
+
import { getMetadata } from '#/compiler/meta'
|
|
6
6
|
import { _root } from '@/utils'
|
|
7
7
|
import { args } from './dev'
|
|
8
|
-
import { getConfig, preview } from '
|
|
8
|
+
import { getConfig, preview } from '../utils'
|
|
9
|
+
import { getEnv } from 't0n'
|
|
9
10
|
|
|
10
11
|
export default command({
|
|
11
12
|
meta: {
|
|
@@ -15,8 +16,9 @@ export default command({
|
|
|
15
16
|
args,
|
|
16
17
|
async run({ args }) {
|
|
17
18
|
const config = await getConfig()
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const duto = getEnv('duto', {})
|
|
20
|
+
const desiredPort = Number(args.port || duto?.dev?.port || 3000)
|
|
21
|
+
const host = String(args.host || duto?.dev?.host || 'localhost')
|
|
20
22
|
|
|
21
23
|
withPort(desiredPort, async (port) => {
|
|
22
24
|
try {
|
|
@@ -3,12 +3,11 @@ import { join } from 'pathe'
|
|
|
3
3
|
import { gray, green, yellow, red, cyan } from 't0n/color'
|
|
4
4
|
import type { UserConfig } from 'vite'
|
|
5
5
|
|
|
6
|
-
import { resolveExtension } from '
|
|
7
|
-
import config from '
|
|
6
|
+
import { resolveExtension } from '#/compiler/file'
|
|
7
|
+
import config from '#/compiler/vite-plugin'
|
|
8
8
|
import { _root } from '@/utils'
|
|
9
|
-
import { match, match404 } from '
|
|
10
|
-
import type { Metadata, PluginOptions } from '
|
|
11
|
-
import { getMetadata } from '@/meta'
|
|
9
|
+
import { match, match404 } from '#/compiler/routes'
|
|
10
|
+
import type { Metadata, PluginOptions } from '#/compiler/types'
|
|
12
11
|
|
|
13
12
|
export async function getConfig(name = 'config'): Promise<UserConfig & PluginOptions> {
|
|
14
13
|
let opts = {} as UserConfig
|
|
@@ -3,7 +3,7 @@ import { render, h } from 'preact'
|
|
|
3
3
|
// import { useLocation, Switch, Route, Router } from 'wouter-preact'
|
|
4
4
|
// import { matchRoute } from 'wouter-preact'
|
|
5
5
|
// import type { Routes, IRoute } from '../types'
|
|
6
|
-
import type { Page, GetProps, IRoute } from '
|
|
6
|
+
import type { Page, GetProps, IRoute } from '#/compiler/types'
|
|
7
7
|
// import { updatePickers } from '../i18n/client'
|
|
8
8
|
|
|
9
9
|
// type Route = [string, Page, IRoute['params'], GetProps]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extname, join } from 'node:path'
|
|
2
2
|
import { existsSync } from 'node:fs'
|
|
3
3
|
import { EXTENSIONS, FILE_EXTENSIONS } from './constants'
|
|
4
|
-
import type { Metadata } from '
|
|
4
|
+
import type { Metadata } from './types'
|
|
5
5
|
|
|
6
6
|
const extensionCache = new Map<string, string | null>()
|
|
7
7
|
export function resolveExtension(filePath: string): string | null {
|
|
@@ -15,7 +15,6 @@ import type { IRoute, Metadata, RouteParams, StaticProps, SummaryMetadata } from
|
|
|
15
15
|
|
|
16
16
|
// import i18n from '../client/i18n'
|
|
17
17
|
import { setLocale } from '../i18n/client'
|
|
18
|
-
import { log, substep } from 't0n/log'
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
|
|
@@ -162,13 +161,12 @@ export async function renderPage(
|
|
|
162
161
|
config.build.outDir,
|
|
163
162
|
pathname +'.html'
|
|
164
163
|
)
|
|
165
|
-
const outHTML = minify.minify(
|
|
164
|
+
const outHTML = meta.minify ? minify.minify(
|
|
166
165
|
Buffer.from(html),
|
|
167
166
|
{}
|
|
168
167
|
// options != null ? options : {},
|
|
169
|
-
)
|
|
168
|
+
) : html
|
|
170
169
|
await mkdir(dirname(outFile), {recursive: true})
|
|
171
|
-
// await writeFile(outFile, outHTML, 'utf-8')
|
|
172
170
|
await Bun.write(outFile, outHTML)
|
|
173
171
|
|
|
174
172
|
const key = '/'+ pathname
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { dirname, extname, join } from 'node:path'
|
|
8
8
|
import { readdirSync } from 'node:fs'
|
|
9
9
|
|
|
10
|
-
import { IMPORT, JSJSON, newID } from 't0n'
|
|
10
|
+
import { getEnv, IMPORT, JSJSON, newID } from 't0n'
|
|
11
11
|
|
|
12
12
|
import { getAliases } from './aliases'
|
|
13
13
|
import { EXT_RE, DYNAMIC_RE, INTERNAL_RE, LAYOUT_RE, NF_NAMES } from './constants'
|
|
@@ -257,7 +257,7 @@ export async function getLayouts(meta: Metadata, path: string) {
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
export async function getMetadata(root: string, dir: string) {
|
|
260
|
-
const meta = { root, dir } as Metadata
|
|
260
|
+
const meta = { root, dir, ...getEnv('duto', {}) } as Metadata
|
|
261
261
|
meta.summary = new Map<string, SummaryMetadata>()
|
|
262
262
|
|
|
263
263
|
meta.i18n = await getI18n(meta)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// import type { ComponentType, FunctionComponent, VNode } from 'preact'
|
|
2
|
+
import type { Platform } from '$/cli/types'
|
|
2
3
|
import type { FunctionComponent, VNode } from 'preact'
|
|
3
4
|
|
|
4
5
|
export type PluginOptions = {
|
|
@@ -41,6 +42,15 @@ export type SummaryMetadata = {
|
|
|
41
42
|
export type Metadata = {
|
|
42
43
|
root: string,
|
|
43
44
|
dir: string,
|
|
45
|
+
type: 'pages' | 'server',
|
|
46
|
+
platform: Platform,
|
|
47
|
+
dev: {
|
|
48
|
+
host: string,
|
|
49
|
+
port: number,
|
|
50
|
+
},
|
|
51
|
+
hmr: boolean,
|
|
52
|
+
minify: boolean,
|
|
53
|
+
|
|
44
54
|
aliases: Record<string, string>,
|
|
45
55
|
map: Map<string, FileMetadata>,
|
|
46
56
|
violations: Map<string, DepMetadata[]>,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// REF: https://github.com/tailwindlabs/tailwindcss/blob/main/packages/%40tailwindcss-vite/src/index.ts
|
|
2
2
|
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, rmSync } from 'node:fs'
|
|
4
4
|
import { join } from 'node:path'
|
|
5
5
|
import { defineConfig } from 'vite'
|
|
6
6
|
|
|
@@ -9,11 +9,10 @@ import tailwind from '@tailwindcss/vite'
|
|
|
9
9
|
|
|
10
10
|
import { EXT_RE } from './constants'
|
|
11
11
|
import { setAsset, setChunk, setEntry } from './assets'
|
|
12
|
-
import { renderPage } from '
|
|
12
|
+
import { renderPage } from '.'
|
|
13
13
|
import { removeExports, resolveImport } from './ast'
|
|
14
14
|
import { getMetadata } from './meta'
|
|
15
15
|
|
|
16
|
-
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
17
16
|
import type {
|
|
18
17
|
// Plugin,
|
|
19
18
|
UserConfig, ConfigEnv, ResolvedConfig,
|
|
@@ -23,12 +22,12 @@ import type {
|
|
|
23
22
|
PluginOption,
|
|
24
23
|
} from 'vite'
|
|
25
24
|
import type { Metadata, PluginOptions } from './types'
|
|
26
|
-
import {
|
|
25
|
+
import { _pages, _root } from '@/utils'
|
|
27
26
|
|
|
28
27
|
const VIRTUAL_ID = ':duto'
|
|
29
28
|
const RESOLVED_ID = '\0'+ VIRTUAL_ID
|
|
30
29
|
|
|
31
|
-
export const config = (opts: UserConfig & PluginOptions) => {
|
|
30
|
+
export const config = (opts: UserConfig & PluginOptions) => { // @ts-ignore
|
|
32
31
|
if (!opts.root) opts.root = _root
|
|
33
32
|
if (!opts.pagesDir) opts.pagesDir = 'pages',
|
|
34
33
|
|
|
@@ -57,7 +56,6 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
57
56
|
root = _root, // process.env.npm_config_local_prefix || process.env.PWD || process.cwd() || __dirname,
|
|
58
57
|
pagesDir = 'pages',
|
|
59
58
|
} = options
|
|
60
|
-
|
|
61
59
|
// let metadata: Metadata
|
|
62
60
|
|
|
63
61
|
const PAGES_RE = new RegExp(`\/${pagesDir}\/.*\.(tsx?|jsx?)$`, 'i')
|
|
@@ -101,26 +99,6 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
101
99
|
|
|
102
100
|
return opts
|
|
103
101
|
},
|
|
104
|
-
|
|
105
|
-
// configurePreviewServer(server: PreviewServer) {
|
|
106
|
-
// const distDir = join(server.config.root, 'dist')
|
|
107
|
-
|
|
108
|
-
// server.middlewares.use((req: IncomingMessage, res: ServerResponse, next: (err?: any) => void) => {
|
|
109
|
-
// if (req.url && !existsSync(join(distDir, req.url.split('?')[0]))) {
|
|
110
|
-
// const notFound = join(distDir, '404.html')
|
|
111
|
-
|
|
112
|
-
// if (existsSync(notFound)) {
|
|
113
|
-
// res.statusCode = 404
|
|
114
|
-
// res.setHeader('Content-Type', 'text/html')
|
|
115
|
-
// .end(readFileSync(notFound, 'utf-8'))
|
|
116
|
-
// return
|
|
117
|
-
// }
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
|
-
// next()
|
|
121
|
-
// })
|
|
122
|
-
// },
|
|
123
|
-
|
|
124
102
|
},
|
|
125
103
|
|
|
126
104
|
{
|
|
@@ -133,8 +111,7 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
133
111
|
// },
|
|
134
112
|
|
|
135
113
|
async config(conf: UserConfig, env: ConfigEnv) {
|
|
136
|
-
|
|
137
|
-
metadata = await getMetadata(root, pagesDir)
|
|
114
|
+
metadata = await getMetadata(root as string, pagesDir)
|
|
138
115
|
|
|
139
116
|
// console.log(metadata.map)
|
|
140
117
|
// console.log(metadata.violations)
|
|
@@ -146,8 +123,8 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
146
123
|
conf.build.manifest = false
|
|
147
124
|
conf.build.modulePreload = { polyfill: false }
|
|
148
125
|
|
|
149
|
-
conf.build.minify =
|
|
150
|
-
conf.build.cssMinify =
|
|
126
|
+
conf.build.minify = metadata.minify
|
|
127
|
+
conf.build.cssMinify = metadata.minify
|
|
151
128
|
|
|
152
129
|
conf.build.rolldownOptions = conf.build.rolldownOptions || {}
|
|
153
130
|
conf.build.rolldownOptions.preserveEntrySignatures = 'exports-only' ///
|
|
@@ -157,20 +134,22 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
157
134
|
...Object.keys(metadata.pages),
|
|
158
135
|
...metadata.assets,
|
|
159
136
|
]
|
|
137
|
+
|
|
138
|
+
const filePrefix = metadata.minify ? '' : '[name].'
|
|
160
139
|
// conf.build.rolldownOptions.input = ':duto/client/app.tsx'
|
|
161
140
|
conf.build.rolldownOptions.output = {
|
|
162
141
|
hoistTransitiveImports: false,
|
|
163
142
|
format: 'esm',
|
|
164
|
-
minifyInternalExports:
|
|
143
|
+
minifyInternalExports: metadata.minify,
|
|
165
144
|
|
|
166
145
|
// manualChunks: {
|
|
167
146
|
// vendor: ['preact', '@preact/signals', 'wouter-preact'],
|
|
168
147
|
// },
|
|
169
148
|
// preserveModules: true,
|
|
170
149
|
preserveModulesRoot: '/',
|
|
171
|
-
assetFileNames: '[hash][extname]',
|
|
172
|
-
entryFileNames: '[hash].js',
|
|
173
|
-
chunkFileNames: '[hash].js',
|
|
150
|
+
assetFileNames: filePrefix +'[hash][extname]',
|
|
151
|
+
entryFileNames: filePrefix +'[hash].js',
|
|
152
|
+
chunkFileNames: filePrefix +'[hash].js',
|
|
174
153
|
|
|
175
154
|
// chunkFileNames: '[name].[hash].js',
|
|
176
155
|
// entryFileNames: 'assets/[name].js',
|
|
@@ -213,13 +192,13 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
213
192
|
if (!id.startsWith(VIRTUAL_ID)) return null
|
|
214
193
|
|
|
215
194
|
if (EXT_RE.test(id) && id.includes('/')) {
|
|
216
|
-
const path = join(
|
|
195
|
+
const path = join(_pages, id.replace(VIRTUAL_ID, ''))
|
|
217
196
|
setEntry(id, path)
|
|
218
197
|
return path
|
|
219
198
|
}
|
|
220
199
|
|
|
221
|
-
if (id.endsWith('/hmr') &&
|
|
222
|
-
return join(
|
|
200
|
+
if (id.endsWith('/hmr') && metadata.hmr)
|
|
201
|
+
return join(_pages, 'client', id.replace(VIRTUAL_ID, '') + '.ts')
|
|
223
202
|
|
|
224
203
|
return id.replace(VIRTUAL_ID, RESOLVED_ID)
|
|
225
204
|
},
|
|
@@ -245,7 +224,7 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
245
224
|
continue
|
|
246
225
|
}
|
|
247
226
|
|
|
248
|
-
if (file.type === 'asset' && file?.originalFileName?.endsWith('duto/client/app.tsx'))
|
|
227
|
+
if (file.type === 'asset' && file?.originalFileName?.endsWith('duto/pages/client/app.tsx'))
|
|
249
228
|
file.source += 'd-b,d-p,i-d,i-s,i-i{display:contents}'
|
|
250
229
|
|
|
251
230
|
if (file.type === 'asset' && file.fileName.endsWith('.css')) {
|
|
@@ -296,10 +275,10 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
296
275
|
},
|
|
297
276
|
|
|
298
277
|
async closeBundle() {
|
|
299
|
-
for (const [_filePath, page] of metadata.pages) {
|
|
278
|
+
for (const [_filePath, page] of metadata.pages) // {
|
|
300
279
|
await renderPage(metadata, config, page)
|
|
301
280
|
// const mod = await server.ssrLoadModule(_filePath)
|
|
302
|
-
}
|
|
281
|
+
// }
|
|
303
282
|
|
|
304
283
|
rmSync(join(metadata.root, 'tmp'), {recursive: true, force: true})
|
|
305
284
|
// await server.close()
|
|
@@ -311,12 +290,8 @@ export function plugin(options: PluginOptions = {}): PluginOption[] {
|
|
|
311
290
|
// console.log(this.getModuleInfo(id))
|
|
312
291
|
|
|
313
292
|
const stripped = removeExports(id, code, stripTarget)
|
|
314
|
-
if (!stripped || stripped === code) return null
|
|
315
293
|
|
|
316
|
-
return {
|
|
317
|
-
code: stripped,
|
|
318
|
-
map: null, // source maps omitted for brevity, add if needed
|
|
319
|
-
}
|
|
294
|
+
return (!stripped || stripped === code) ? null : { code: stripped, map: null }
|
|
320
295
|
},
|
|
321
296
|
|
|
322
297
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { h, type JSX } from 'preact'
|
|
2
|
-
import { local } from '#/storage'
|
|
3
|
-
import { navigate } from '
|
|
2
|
+
import { local } from '#/client/storage'
|
|
3
|
+
import { navigate } from '..'
|
|
4
4
|
|
|
5
5
|
const accepted = (lang: string | undefined, locales: string[] = [], fallback: string) => lang && locales.includes(lang) ? lang : fallback
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
2
|
import { IMPORT, JSJSON } from 't0n'
|
|
3
3
|
|
|
4
|
-
import type { Metadata, I18nMetadata } from '
|
|
4
|
+
import type { Metadata, I18nMetadata } from '#/compiler/types'
|
|
5
5
|
import { existsSync } from 'node:fs'
|
|
6
6
|
|
|
7
7
|
export default async function getI18n(meta: Metadata) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Redirect,
|
|
3
|
+
useLocation, useParams, useSearch, useSearchParams,
|
|
4
|
+
matchRoute,
|
|
5
|
+
} from 'wouter-preact'
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
t, r, d,
|
|
9
|
+
getLocale, setLocale,
|
|
10
|
+
isPrefixed,
|
|
11
|
+
} from './i18n/client'
|
|
12
|
+
|
|
13
|
+
export { local } from './client/storage'
|
|
14
|
+
|
|
15
|
+
export const navigate = <S = any>(
|
|
16
|
+
to: string | URL,
|
|
17
|
+
options?: { replace?: boolean; state?: S; transition?: boolean }
|
|
18
|
+
) => {
|
|
19
|
+
if (window?.$duto?.sroutes?.has(to)) {
|
|
20
|
+
location.pathname = to
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const n = window?.$duto?.navigate || useLocation()[1]
|
|
25
|
+
n(to, options)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Link } from './components/link'
|