davaux 0.8.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/BASELINE.md +169 -0
- package/CLAUDE.md +518 -0
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/ROADMAP.md +198 -0
- package/build.mjs +101 -0
- package/client/control.ts +247 -0
- package/client/hydrate.ts +37 -0
- package/client/index.ts +19 -0
- package/client/jsx-runtime.ts +209 -0
- package/client/resource.ts +122 -0
- package/client/signal.ts +211 -0
- package/client/store.ts +110 -0
- package/client/useHead.ts +63 -0
- package/dist/build/config.d.ts +3 -0
- package/dist/build/config.d.ts.map +1 -0
- package/dist/build/config.js +38 -0
- package/dist/build/config.js.map +7 -0
- package/dist/build/index.d.ts +2 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +13 -0
- package/dist/build/index.js.map +7 -0
- package/dist/build/plugins.d.ts +7 -0
- package/dist/build/plugins.d.ts.map +1 -0
- package/dist/build/plugins.js +85 -0
- package/dist/build/plugins.js.map +7 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +427 -0
- package/dist/cli.js.map +7 -0
- package/dist/client/control.d.ts +49 -0
- package/dist/client/control.d.ts.map +1 -0
- package/dist/client/control.js +154 -0
- package/dist/client/control.js.map +7 -0
- package/dist/client/hydrate.d.ts +7 -0
- package/dist/client/hydrate.d.ts.map +1 -0
- package/dist/client/hydrate.js +23 -0
- package/dist/client/hydrate.js.map +7 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +32 -0
- package/dist/client/index.js.map +7 -0
- package/dist/client/jsx-runtime.d.ts +40 -0
- package/dist/client/jsx-runtime.d.ts.map +1 -0
- package/dist/client/jsx-runtime.js +139 -0
- package/dist/client/jsx-runtime.js.map +7 -0
- package/dist/client/resource.d.ts +31 -0
- package/dist/client/resource.d.ts.map +1 -0
- package/dist/client/resource.js +64 -0
- package/dist/client/resource.js.map +7 -0
- package/dist/client/signal.d.ts +90 -0
- package/dist/client/signal.d.ts.map +1 -0
- package/dist/client/signal.js +115 -0
- package/dist/client/signal.js.map +7 -0
- package/dist/client/store.d.ts +26 -0
- package/dist/client/store.d.ts.map +1 -0
- package/dist/client/store.js +63 -0
- package/dist/client/store.js.map +7 -0
- package/dist/client/useHead.d.ts +28 -0
- package/dist/client/useHead.d.ts.map +1 -0
- package/dist/client/useHead.js +33 -0
- package/dist/client/useHead.js.map +7 -0
- package/dist/config.d.ts +182 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +21 -0
- package/dist/config.js.map +7 -0
- package/dist/create-multisite.d.ts +2 -0
- package/dist/create-multisite.d.ts.map +1 -0
- package/dist/create-multisite.js +291 -0
- package/dist/create-multisite.js.map +7 -0
- package/dist/create.d.ts +2 -0
- package/dist/create.d.ts.map +1 -0
- package/dist/create.js +179 -0
- package/dist/create.js.map +7 -0
- package/dist/dev/blueprints.d.ts +11 -0
- package/dist/dev/blueprints.d.ts.map +1 -0
- package/dist/dev/blueprints.js +65 -0
- package/dist/dev/blueprints.js.map +7 -0
- package/dist/dev/components.d.ts +19 -0
- package/dist/dev/components.d.ts.map +1 -0
- package/dist/dev/components.js +87 -0
- package/dist/dev/components.js.map +7 -0
- package/dist/dev/insert.d.ts +11 -0
- package/dist/dev/insert.d.ts.map +1 -0
- package/dist/dev/insert.js +160 -0
- package/dist/dev/insert.js.map +7 -0
- package/dist/dev/remove.d.ts +53 -0
- package/dist/dev/remove.d.ts.map +1 -0
- package/dist/dev/remove.js +518 -0
- package/dist/dev/remove.js.map +7 -0
- package/dist/dev/watch.d.ts +26 -0
- package/dist/dev/watch.d.ts.map +1 -0
- package/dist/dev/watch.js +2905 -0
- package/dist/dev/watch.js.map +7 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +63 -0
- package/dist/errors.js.map +7 -0
- package/dist/generate.d.ts +2 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +191 -0
- package/dist/generate.js.map +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +7 -0
- package/dist/island.d.ts +24 -0
- package/dist/island.d.ts.map +1 -0
- package/dist/island.js +15 -0
- package/dist/island.js.map +7 -0
- package/dist/jsx-runtime.d.ts +406 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +90 -0
- package/dist/jsx-runtime.js.map +7 -0
- package/dist/link.d.ts +27 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +29 -0
- package/dist/link.js.map +7 -0
- package/dist/oml/fragment.d.ts +16 -0
- package/dist/oml/fragment.d.ts.map +1 -0
- package/dist/oml/fragment.js +26 -0
- package/dist/oml/fragment.js.map +7 -0
- package/dist/oml/index.d.ts +11 -0
- package/dist/oml/index.d.ts.map +1 -0
- package/dist/oml/index.js +21 -0
- package/dist/oml/index.js.map +7 -0
- package/dist/oml/jsx-runtime.d.ts +34 -0
- package/dist/oml/jsx-runtime.d.ts.map +1 -0
- package/dist/oml/jsx-runtime.js +59 -0
- package/dist/oml/jsx-runtime.js.map +7 -0
- package/dist/oml/jsx.d.ts +14 -0
- package/dist/oml/jsx.d.ts.map +1 -0
- package/dist/oml/jsx.js +96 -0
- package/dist/oml/jsx.js.map +7 -0
- package/dist/oml/page.d.ts +7 -0
- package/dist/oml/page.d.ts.map +1 -0
- package/dist/oml/page.js +6 -0
- package/dist/oml/page.js.map +7 -0
- package/dist/oml/render.d.ts +13 -0
- package/dist/oml/render.d.ts.map +1 -0
- package/dist/oml/render.js +117 -0
- package/dist/oml/render.js.map +7 -0
- package/dist/oml/types.d.ts +79 -0
- package/dist/oml/types.d.ts.map +1 -0
- package/dist/oml/types.js +64 -0
- package/dist/oml/types.js.map +7 -0
- package/dist/router/handler.d.ts +53 -0
- package/dist/router/handler.d.ts.map +1 -0
- package/dist/router/handler.js +342 -0
- package/dist/router/handler.js.map +7 -0
- package/dist/router/matcher.d.ts +21 -0
- package/dist/router/matcher.d.ts.map +1 -0
- package/dist/router/matcher.js +28 -0
- package/dist/router/matcher.js.map +7 -0
- package/dist/router/scanner.d.ts +17 -0
- package/dist/router/scanner.d.ts.map +1 -0
- package/dist/router/scanner.js +197 -0
- package/dist/router/scanner.js.map +7 -0
- package/dist/server/index.d.ts +23 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +29 -0
- package/dist/server/index.js.map +7 -0
- package/dist/signal.d.ts +15 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +29 -0
- package/dist/signal.js.map +7 -0
- package/dist/ssg.d.ts +45 -0
- package/dist/ssg.d.ts.map +1 -0
- package/dist/ssg.js +175 -0
- package/dist/ssg.js.map +7 -0
- package/dist/test/actions.test.d.ts +2 -0
- package/dist/test/actions.test.d.ts.map +1 -0
- package/dist/test/body-limits.test.d.ts +2 -0
- package/dist/test/body-limits.test.d.ts.map +1 -0
- package/dist/test/errors.test.d.ts +2 -0
- package/dist/test/errors.test.d.ts.map +1 -0
- package/dist/test/fixtures/routes/[id].page.d.ts +4 -0
- package/dist/test/fixtures/routes/[id].page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_error.d.ts +3 -0
- package/dist/test/fixtures/routes/_error.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_global.d.ts +3 -0
- package/dist/test/fixtures/routes/_global.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout-template.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout-template.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout_scripts.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout_scripts.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_middleware.d.ts +3 -0
- package/dist/test/fixtures/routes/_middleware.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_redirect301_mw.d.ts +3 -0
- package/dist/test/fixtures/routes/_redirect301_mw.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_redirect_mw.d.ts +3 -0
- package/dist/test/fixtures/routes/_redirect_mw.d.ts.map +1 -0
- package/dist/test/fixtures/routes/about.page.d.ts +3 -0
- package/dist/test/fixtures/routes/about.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/action.page.d.ts +6 -0
- package/dist/test/fixtures/routes/action.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/form-all.post.d.ts +3 -0
- package/dist/test/fixtures/routes/api/form-all.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/form-limited.post.d.ts +6 -0
- package/dist/test/fixtures/routes/api/form-limited.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/response-obj.get.d.ts +3 -0
- package/dist/test/fixtures/routes/api/response-obj.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/upload.post.d.ts +12 -0
- package/dist/test/fixtures/routes/api/upload.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/users.get.d.ts +6 -0
- package/dist/test/fixtures/routes/api/users.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/xml.get.d.ts +3 -0
- package/dist/test/fixtures/routes/api/xml.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/auth/_middleware.d.ts +3 -0
- package/dist/test/fixtures/routes/auth/_middleware.d.ts.map +1 -0
- package/dist/test/fixtures/routes/auth/protected.page.d.ts +3 -0
- package/dist/test/fixtures/routes/auth/protected.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/index.page.d.ts +3 -0
- package/dist/test/fixtures/routes/index.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/oml.page.d.ts +3 -0
- package/dist/test/fixtures/routes/oml.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/redirect.page.d.ts +3 -0
- package/dist/test/fixtures/routes/redirect.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/ssg/[slug].page.d.ts +5 -0
- package/dist/test/fixtures/routes/ssg/[slug].page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/ssg/server.page.d.ts +4 -0
- package/dist/test/fixtures/routes/ssg/server.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/state.page.d.ts +3 -0
- package/dist/test/fixtures/routes/state.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/throw.page.d.ts +3 -0
- package/dist/test/fixtures/routes/throw.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts +3 -0
- package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts.map +1 -0
- package/dist/test/helpers.d.ts +37 -0
- package/dist/test/helpers.d.ts.map +1 -0
- package/dist/test/layouts.test.d.ts +2 -0
- package/dist/test/layouts.test.d.ts.map +1 -0
- package/dist/test/middleware.test.d.ts +2 -0
- package/dist/test/middleware.test.d.ts.map +1 -0
- package/dist/test/multipart.test.d.ts +2 -0
- package/dist/test/multipart.test.d.ts.map +1 -0
- package/dist/test/oml-routing.test.d.ts +2 -0
- package/dist/test/oml-routing.test.d.ts.map +1 -0
- package/dist/test/oml.test.d.ts +2 -0
- package/dist/test/oml.test.d.ts.map +1 -0
- package/dist/test/redirects.test.d.ts +2 -0
- package/dist/test/redirects.test.d.ts.map +1 -0
- package/dist/test/routing.test.d.ts +2 -0
- package/dist/test/routing.test.d.ts.map +1 -0
- package/dist/test/ssg.test.d.ts +2 -0
- package/dist/test/ssg.test.d.ts.map +1 -0
- package/dist/test/web-response.test.d.ts +2 -0
- package/dist/test/web-response.test.d.ts.map +1 -0
- package/dist/types.d.ts +314 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +292 -0
- package/dist/types.js.map +7 -0
- package/package.json +103 -0
- package/pka.config.json +32 -0
- package/src/build/config.ts +42 -0
- package/src/build/index.ts +6 -0
- package/src/build/plugins.ts +118 -0
- package/src/cli.ts +502 -0
- package/src/config.ts +197 -0
- package/src/create-multisite.ts +310 -0
- package/src/create.ts +194 -0
- package/src/dev/blueprints.ts +75 -0
- package/src/dev/components.ts +108 -0
- package/src/dev/insert.ts +221 -0
- package/src/dev/remove.ts +677 -0
- package/src/dev/watch.ts +3098 -0
- package/src/env.d.ts +5 -0
- package/src/errors.ts +64 -0
- package/src/generate.ts +228 -0
- package/src/index.ts +67 -0
- package/src/island.ts +47 -0
- package/src/jsx-runtime.d.ts +408 -0
- package/src/jsx-runtime.d.ts.map +1 -0
- package/src/jsx-runtime.ts +536 -0
- package/src/link.ts +49 -0
- package/src/oml/fragment.ts +54 -0
- package/src/oml/index.ts +21 -0
- package/src/oml/jsx-runtime.ts +121 -0
- package/src/oml/jsx.ts +151 -0
- package/src/oml/page.ts +13 -0
- package/src/oml/render.ts +181 -0
- package/src/oml/types.ts +159 -0
- package/src/router/handler.ts +515 -0
- package/src/router/matcher.ts +52 -0
- package/src/router/scanner.ts +272 -0
- package/src/server/index.ts +49 -0
- package/src/signal.ts +39 -0
- package/src/ssg.ts +253 -0
- package/src/test/actions.test.ts +40 -0
- package/src/test/body-limits.test.ts +83 -0
- package/src/test/errors.test.ts +53 -0
- package/src/test/fixtures/routes/[id].page.ts +3 -0
- package/src/test/fixtures/routes/_error.ts +6 -0
- package/src/test/fixtures/routes/_global.ts +8 -0
- package/src/test/fixtures/routes/_layout-template.ts +7 -0
- package/src/test/fixtures/routes/_layout.ts +7 -0
- package/src/test/fixtures/routes/_layout_scripts.ts +8 -0
- package/src/test/fixtures/routes/_middleware.ts +8 -0
- package/src/test/fixtures/routes/_redirect301_mw.ts +5 -0
- package/src/test/fixtures/routes/_redirect_mw.ts +5 -0
- package/src/test/fixtures/routes/about.page.ts +6 -0
- package/src/test/fixtures/routes/action.page.ts +11 -0
- package/src/test/fixtures/routes/api/form-all.post.ts +5 -0
- package/src/test/fixtures/routes/api/form-limited.post.ts +6 -0
- package/src/test/fixtures/routes/api/response-obj.get.ts +17 -0
- package/src/test/fixtures/routes/api/upload.post.ts +14 -0
- package/src/test/fixtures/routes/api/users.get.ts +3 -0
- package/src/test/fixtures/routes/api/xml.get.ts +5 -0
- package/src/test/fixtures/routes/auth/_middleware.ts +11 -0
- package/src/test/fixtures/routes/auth/protected.page.ts +3 -0
- package/src/test/fixtures/routes/index.page.ts +3 -0
- package/src/test/fixtures/routes/oml.page.ts +7 -0
- package/src/test/fixtures/routes/redirect.page.ts +3 -0
- package/src/test/fixtures/routes/ssg/[slug].page.ts +8 -0
- package/src/test/fixtures/routes/ssg/server.page.ts +5 -0
- package/src/test/fixtures/routes/state.page.ts +4 -0
- package/src/test/fixtures/routes/throw.page.ts +5 -0
- package/src/test/fixtures/routes/wiki/[...slug].page.ts +3 -0
- package/src/test/helpers.ts +132 -0
- package/src/test/layouts.test.ts +76 -0
- package/src/test/middleware.test.ts +69 -0
- package/src/test/multipart.test.ts +91 -0
- package/src/test/oml-routing.test.ts +59 -0
- package/src/test/oml.test.ts +429 -0
- package/src/test/redirects.test.ts +32 -0
- package/src/test/routing.test.ts +118 -0
- package/src/test/ssg.test.ts +273 -0
- package/src/test/web-response.test.ts +33 -0
- package/src/types.ts +670 -0
- package/tsconfig.client.json +17 -0
- package/tsconfig.json +20 -0
package/src/env.d.ts
ADDED
package/src/errors.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Message } from 'esbuild'
|
|
2
|
+
|
|
3
|
+
export function formatBuildErrors(errors: Message[]): string {
|
|
4
|
+
return errors
|
|
5
|
+
.map((e) => {
|
|
6
|
+
const lines: string[] = [` ${e.text}`]
|
|
7
|
+
if (e.location) {
|
|
8
|
+
lines.push(` at ${e.location.file}:${e.location.line}:${e.location.column}`)
|
|
9
|
+
if (e.location.lineText.trim()) lines.push(` > ${e.location.lineText.trim()}`)
|
|
10
|
+
}
|
|
11
|
+
return lines.join('\n')
|
|
12
|
+
})
|
|
13
|
+
.join('\n\n')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function frameworkWarn(message: string, hint?: string): void {
|
|
17
|
+
console.warn(`[davaux] ${message}`)
|
|
18
|
+
if (hint) console.warn(` hint: ${hint}`)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function frameworkError(message: string, hint?: string): never {
|
|
22
|
+
console.error(`\n[davaux] ${message}`)
|
|
23
|
+
if (hint) console.error(` hint: ${hint}`)
|
|
24
|
+
process.exit(1)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function handleBuildError(label: string, err: unknown): never {
|
|
28
|
+
if (
|
|
29
|
+
err != null &&
|
|
30
|
+
typeof err === 'object' &&
|
|
31
|
+
Array.isArray((err as { errors?: unknown }).errors)
|
|
32
|
+
) {
|
|
33
|
+
const msgs = (err as { errors: Message[] }).errors
|
|
34
|
+
if (msgs.length > 0) {
|
|
35
|
+
console.error(`\n[davaux] ${label} failed:\n${formatBuildErrors(msgs)}`)
|
|
36
|
+
const cjsPkg = detectCjsPackage(msgs)
|
|
37
|
+
if (cjsPkg) {
|
|
38
|
+
console.error(
|
|
39
|
+
`\n Hint: "${cjsPkg}" uses CommonJS require() and cannot be bundled by esbuild.\n` +
|
|
40
|
+
` Add it to the external list in davaux.config.ts:\n\n` +
|
|
41
|
+
` export default defineConfig({\n` +
|
|
42
|
+
` external: ['${cjsPkg}'],\n` +
|
|
43
|
+
` })\n`,
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
process.exit(1)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.error(`\n[davaux] ${label} failed:`, err)
|
|
50
|
+
process.exit(1)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Detects "Dynamic require of X is not supported" errors and extracts the
|
|
54
|
+
// originating package name from the error location, so we can suggest adding
|
|
55
|
+
// it to `external`.
|
|
56
|
+
function detectCjsPackage(errors: Message[]): string | null {
|
|
57
|
+
for (const e of errors) {
|
|
58
|
+
if (!/[Dd]ynamic require/.test(e.text)) continue
|
|
59
|
+
const file = e.location?.file ?? ''
|
|
60
|
+
const m = file.match(/node_modules\/((?:@[^/]+\/)?[^/]+)/)
|
|
61
|
+
if (m) return m[1]
|
|
62
|
+
}
|
|
63
|
+
return null
|
|
64
|
+
}
|
package/src/generate.ts
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path'
|
|
3
|
+
|
|
4
|
+
const VALID_TYPES = ['page', 'api', 'layout', 'island', 'middleware'] as const
|
|
5
|
+
type GenerateType = (typeof VALID_TYPES)[number]
|
|
6
|
+
|
|
7
|
+
const VALID_METHODS = ['get', 'post', 'put', 'patch', 'delete'] as const
|
|
8
|
+
type HttpMethod = (typeof VALID_METHODS)[number]
|
|
9
|
+
|
|
10
|
+
export function generate(args: string[], cwd: string): void {
|
|
11
|
+
const [type, pathArg, ...rest] = args
|
|
12
|
+
|
|
13
|
+
if (!type || !VALID_TYPES.includes(type as GenerateType)) {
|
|
14
|
+
if (type) console.error(`[davaux] Unknown generator "${type}"`)
|
|
15
|
+
printUsage()
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const routesDir = resolve(cwd, 'src', 'routes')
|
|
20
|
+
const islandsDir = resolve(cwd, 'src', 'islands')
|
|
21
|
+
|
|
22
|
+
switch (type as GenerateType) {
|
|
23
|
+
case 'page':
|
|
24
|
+
genPage(pathArg, routesDir, cwd)
|
|
25
|
+
break
|
|
26
|
+
case 'api': {
|
|
27
|
+
const methodArg = getFlag('--method', rest) ?? 'get'
|
|
28
|
+
if (!VALID_METHODS.includes(methodArg as HttpMethod)) {
|
|
29
|
+
console.error(`[davaux] Invalid method "${methodArg}". Valid: ${VALID_METHODS.join(', ')}`)
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
genApi(pathArg, routesDir, methodArg as HttpMethod, cwd)
|
|
33
|
+
break
|
|
34
|
+
}
|
|
35
|
+
case 'layout':
|
|
36
|
+
genLayout(pathArg, routesDir, cwd)
|
|
37
|
+
break
|
|
38
|
+
case 'island':
|
|
39
|
+
genIsland(pathArg, islandsDir, cwd)
|
|
40
|
+
break
|
|
41
|
+
case 'middleware':
|
|
42
|
+
genMiddleware(pathArg, routesDir, cwd)
|
|
43
|
+
break
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ─── Generators ───────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
function genPage(pathArg: string | undefined, routesDir: string, cwd: string) {
|
|
50
|
+
if (!pathArg) {
|
|
51
|
+
console.error('[davaux] Usage: davaux generate page <path>')
|
|
52
|
+
console.error(' Example: davaux generate page about')
|
|
53
|
+
console.error(' Example: davaux generate page blog/[slug]')
|
|
54
|
+
process.exit(1)
|
|
55
|
+
}
|
|
56
|
+
const filePath = join(routesDir, `${pathArg}.page.tsx`)
|
|
57
|
+
writeGenerated(filePath, cwd, pageTemplate(pathArg))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function genApi(pathArg: string | undefined, routesDir: string, method: HttpMethod, cwd: string) {
|
|
61
|
+
if (!pathArg) {
|
|
62
|
+
console.error('[davaux] Usage: davaux generate api <path> [--method get|post|put|patch|delete]')
|
|
63
|
+
process.exit(1)
|
|
64
|
+
}
|
|
65
|
+
const filePath = join(routesDir, `${pathArg}.${method}.ts`)
|
|
66
|
+
writeGenerated(filePath, cwd, apiTemplate(pathArg))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function genLayout(pathArg: string | undefined, routesDir: string, cwd: string) {
|
|
70
|
+
const filePath = pathArg
|
|
71
|
+
? join(routesDir, pathArg, '_layout.tsx')
|
|
72
|
+
: join(routesDir, '_layout.tsx')
|
|
73
|
+
writeGenerated(filePath, cwd, layoutTemplate())
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function genIsland(nameArg: string | undefined, islandsDir: string, cwd: string) {
|
|
77
|
+
if (!nameArg) {
|
|
78
|
+
console.error('[davaux] Usage: davaux generate island <Name>')
|
|
79
|
+
console.error(' Example: davaux generate island Counter')
|
|
80
|
+
process.exit(1)
|
|
81
|
+
}
|
|
82
|
+
const filePath = join(islandsDir, `${nameArg}.tsx`)
|
|
83
|
+
writeGenerated(filePath, cwd, islandTemplate(nameArg))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function genMiddleware(pathArg: string | undefined, routesDir: string, cwd: string) {
|
|
87
|
+
const filePath = pathArg
|
|
88
|
+
? join(routesDir, pathArg, '_middleware.ts')
|
|
89
|
+
: join(routesDir, '_middleware.ts')
|
|
90
|
+
writeGenerated(filePath, cwd, middlewareTemplate())
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ─── Templates ────────────────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
function pageTemplate(routePath: string): string {
|
|
96
|
+
const title = toTitle(lastSegment(routePath))
|
|
97
|
+
const hasParams = routePath.includes('[')
|
|
98
|
+
|
|
99
|
+
if (hasParams) {
|
|
100
|
+
return `import { definePage, defineStaticPaths, type ExtractParams } from 'davaux'
|
|
101
|
+
|
|
102
|
+
export const getStaticPaths = defineStaticPaths(async () => [
|
|
103
|
+
// Return one entry per URL to pre-render with \`davaux static\`
|
|
104
|
+
{ params: { ${firstParam(routePath)}: 'example' } },
|
|
105
|
+
])
|
|
106
|
+
|
|
107
|
+
export default definePage<ExtractParams<'${routePath}'>>((ctx) => {
|
|
108
|
+
return <h1>${title}: {ctx.params.${firstParam(routePath)}}</h1>
|
|
109
|
+
})
|
|
110
|
+
`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return `import { definePage } from 'davaux'
|
|
114
|
+
|
|
115
|
+
export default definePage((ctx) => {
|
|
116
|
+
ctx.head.title = '${title}'
|
|
117
|
+
return <h1>${title}</h1>
|
|
118
|
+
})
|
|
119
|
+
`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function apiTemplate(routePath: string): string {
|
|
123
|
+
const hasParams = routePath.includes('[')
|
|
124
|
+
|
|
125
|
+
if (hasParams) {
|
|
126
|
+
return `import { defineHandler, type ExtractParams } from 'davaux'
|
|
127
|
+
|
|
128
|
+
export default defineHandler<unknown, ExtractParams<'${routePath}'>>(async (_ctx) => {
|
|
129
|
+
return { ok: true }
|
|
130
|
+
})
|
|
131
|
+
`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return `import { defineHandler } from 'davaux'
|
|
135
|
+
|
|
136
|
+
export default defineHandler(async (_ctx) => {
|
|
137
|
+
return { ok: true }
|
|
138
|
+
})
|
|
139
|
+
`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function layoutTemplate(): string {
|
|
143
|
+
return `import { defineLayout } from 'davaux'
|
|
144
|
+
|
|
145
|
+
export default defineLayout(({ children }) => (
|
|
146
|
+
<div>
|
|
147
|
+
{children as unknown as string}
|
|
148
|
+
</div>
|
|
149
|
+
))
|
|
150
|
+
`
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function islandTemplate(name: string): string {
|
|
154
|
+
return `import { createSignal } from 'davaux/client'
|
|
155
|
+
|
|
156
|
+
export default function ${name}() {
|
|
157
|
+
const [count, setCount] = createSignal(0)
|
|
158
|
+
return (
|
|
159
|
+
<button type="button" onClick={() => setCount(count() + 1)}>
|
|
160
|
+
{() => count()}
|
|
161
|
+
</button>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
`
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function middlewareTemplate(): string {
|
|
168
|
+
return `import { defineMiddleware } from 'davaux'
|
|
169
|
+
|
|
170
|
+
export default defineMiddleware(async (_ctx, next) => {
|
|
171
|
+
await next()
|
|
172
|
+
})
|
|
173
|
+
`
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
function writeGenerated(filePath: string, cwd: string, content: string) {
|
|
179
|
+
if (existsSync(filePath)) {
|
|
180
|
+
console.error(`[davaux] File already exists: ${relative(cwd, filePath)}`)
|
|
181
|
+
process.exit(1)
|
|
182
|
+
}
|
|
183
|
+
mkdirSync(dirname(filePath), { recursive: true })
|
|
184
|
+
writeFileSync(filePath, content, 'utf8')
|
|
185
|
+
console.log(`[davaux] Created ${relative(cwd, filePath)}`)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function lastSegment(routePath: string): string {
|
|
189
|
+
const segments = routePath.split('/')
|
|
190
|
+
return segments[segments.length - 1]
|
|
191
|
+
.replace(/\[.*?\]/g, '')
|
|
192
|
+
.replace(/[-_]/g, ' ')
|
|
193
|
+
.trim()
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function toTitle(segment: string): string {
|
|
197
|
+
return segment.replace(/\b\w/g, (c) => c.toUpperCase()).trim() || 'Page'
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function firstParam(routePath: string): string {
|
|
201
|
+
const match = routePath.match(/\[(\w+)\]/)
|
|
202
|
+
return match ? match[1] : 'id'
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function getFlag(name: string, argv: string[]): string | undefined {
|
|
206
|
+
const idx = argv.indexOf(name)
|
|
207
|
+
return idx !== -1 ? argv[idx + 1] : undefined
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function printUsage() {
|
|
211
|
+
console.error('Usage: davaux generate <type> [path]')
|
|
212
|
+
console.error('')
|
|
213
|
+
console.error('Types:')
|
|
214
|
+
console.error(' page <path> Page route')
|
|
215
|
+
console.error(' api <path> [--method <method>] API route (default: get)')
|
|
216
|
+
console.error(' layout [path] Layout (root if no path given)')
|
|
217
|
+
console.error(' island <Name> Client island component')
|
|
218
|
+
console.error(' middleware [path] Middleware (root if no path given)')
|
|
219
|
+
console.error('')
|
|
220
|
+
console.error('Examples:')
|
|
221
|
+
console.error(' davaux generate page about')
|
|
222
|
+
console.error(' davaux generate page blog/[slug]')
|
|
223
|
+
console.error(' davaux generate api users')
|
|
224
|
+
console.error(' davaux generate api users --method post')
|
|
225
|
+
console.error(' davaux generate layout admin')
|
|
226
|
+
console.error(' davaux generate island Counter')
|
|
227
|
+
console.error(' davaux generate middleware admin')
|
|
228
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export { island } from './island.js'
|
|
2
|
+
export type { JSX } from './jsx-runtime.js'
|
|
3
|
+
export { createLink } from './link.js'
|
|
4
|
+
export type {
|
|
5
|
+
OmlBlueprint,
|
|
6
|
+
OmlComponent,
|
|
7
|
+
OmlElement,
|
|
8
|
+
OmlFragment,
|
|
9
|
+
OmlFragmentOptions,
|
|
10
|
+
OmlNode,
|
|
11
|
+
OmlPageHandler,
|
|
12
|
+
OmlPropSchema,
|
|
13
|
+
OmlProps,
|
|
14
|
+
OmlPropType,
|
|
15
|
+
OmlRaw,
|
|
16
|
+
OmlText,
|
|
17
|
+
} from './oml/index.js'
|
|
18
|
+
export {
|
|
19
|
+
blueprintToFile,
|
|
20
|
+
clearAllFragments,
|
|
21
|
+
defineFragment,
|
|
22
|
+
defineOmlPage,
|
|
23
|
+
parseOml,
|
|
24
|
+
parseOmlBlueprint,
|
|
25
|
+
renderToHtml,
|
|
26
|
+
renderToJsx,
|
|
27
|
+
} from './oml/index.js'
|
|
28
|
+
export { batch, createEffect, createMemo, createSignal, untrack } from './signal.js'
|
|
29
|
+
export type {
|
|
30
|
+
ActionFn,
|
|
31
|
+
ApiHandler,
|
|
32
|
+
CookieOptions,
|
|
33
|
+
ErrorPageHandler,
|
|
34
|
+
ErrorPageProps,
|
|
35
|
+
ExtractParams,
|
|
36
|
+
GetStaticPathsFn,
|
|
37
|
+
IslandFile,
|
|
38
|
+
LayoutFile,
|
|
39
|
+
LayoutHandler,
|
|
40
|
+
LayoutProps,
|
|
41
|
+
MiddlewareFile,
|
|
42
|
+
MiddlewareFn,
|
|
43
|
+
MultipartFile,
|
|
44
|
+
MultipartResult,
|
|
45
|
+
PageHandler,
|
|
46
|
+
RequestContext,
|
|
47
|
+
RouteFile,
|
|
48
|
+
RouteType,
|
|
49
|
+
ScanResult,
|
|
50
|
+
State,
|
|
51
|
+
StaticPath,
|
|
52
|
+
Validator,
|
|
53
|
+
} from './types.js'
|
|
54
|
+
export {
|
|
55
|
+
CookieJar,
|
|
56
|
+
defineAction,
|
|
57
|
+
defineError,
|
|
58
|
+
defineHandler,
|
|
59
|
+
defineLayout,
|
|
60
|
+
defineMiddleware,
|
|
61
|
+
definePage,
|
|
62
|
+
defineStaticPaths,
|
|
63
|
+
PayloadTooLargeError,
|
|
64
|
+
RedirectError,
|
|
65
|
+
redirect,
|
|
66
|
+
ValidationError,
|
|
67
|
+
} from './types.js'
|
package/src/island.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { JSX } from './jsx-runtime.js'
|
|
2
|
+
|
|
3
|
+
/** A component intended to run on both server and client. */
|
|
4
|
+
export type IslandComponent<P extends Record<string, unknown> = Record<string, unknown>> = (
|
|
5
|
+
props: P,
|
|
6
|
+
) => JSX.Element
|
|
7
|
+
|
|
8
|
+
let counter = 0
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Mark a component as a client island. Write the component once — the framework
|
|
12
|
+
* compiles it for both server and client automatically.
|
|
13
|
+
*
|
|
14
|
+
* On the server: renders initial HTML and embeds serialized props in `data-props`.
|
|
15
|
+
* On the client: `hydrate()` picks up `[data-island]` elements and remounts the
|
|
16
|
+
* component with full signal reactivity.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // src/islands/Counter.tsx
|
|
20
|
+
* import { island } from 'davaux'
|
|
21
|
+
* import { createSignal } from 'davaux/client'
|
|
22
|
+
*
|
|
23
|
+
* function Counter({ initial = 0 }: { initial?: number }) {
|
|
24
|
+
* const [count, setCount] = createSignal(initial)
|
|
25
|
+
* return <button onClick={() => setCount(c => c + 1)}>{() => count()}</button>
|
|
26
|
+
* }
|
|
27
|
+
* export default island(Counter)
|
|
28
|
+
*/
|
|
29
|
+
export function island<P extends Record<string, unknown>>(
|
|
30
|
+
Component: IslandComponent<P>,
|
|
31
|
+
islandId?: string,
|
|
32
|
+
): (props: P) => Promise<string> {
|
|
33
|
+
const id = islandId ?? Component.name ?? `island-${counter++}`
|
|
34
|
+
|
|
35
|
+
const wrapper = async (props: P): Promise<string> => {
|
|
36
|
+
const rendered = await (Component(props) as unknown as Promise<string> | string)
|
|
37
|
+
const serialized = JSON.stringify(props)
|
|
38
|
+
.replace(/&/g, '\\u0026')
|
|
39
|
+
.replace(/</g, '\\u003c')
|
|
40
|
+
.replace(/>/g, '\\u003e')
|
|
41
|
+
.replace(/'/g, '\\u0027')
|
|
42
|
+
|
|
43
|
+
return `<div data-island="${id}" data-props='${serialized}'>${rendered}</div>`
|
|
44
|
+
}
|
|
45
|
+
Object.defineProperty(wrapper, 'name', { value: id, configurable: true })
|
|
46
|
+
return wrapper
|
|
47
|
+
}
|