bosbun 0.0.1

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.
Files changed (46) hide show
  1. package/README.md +163 -0
  2. package/package.json +56 -0
  3. package/src/cli/add.ts +83 -0
  4. package/src/cli/build.ts +16 -0
  5. package/src/cli/create.ts +54 -0
  6. package/src/cli/dev.ts +14 -0
  7. package/src/cli/feat.ts +80 -0
  8. package/src/cli/index.ts +75 -0
  9. package/src/cli/start.ts +28 -0
  10. package/src/core/build.ts +157 -0
  11. package/src/core/client/App.svelte +147 -0
  12. package/src/core/client/hydrate.ts +78 -0
  13. package/src/core/client/router.svelte.ts +46 -0
  14. package/src/core/cookies.ts +52 -0
  15. package/src/core/cors.ts +60 -0
  16. package/src/core/csrf.ts +65 -0
  17. package/src/core/dev.ts +193 -0
  18. package/src/core/env.ts +135 -0
  19. package/src/core/envCodegen.ts +94 -0
  20. package/src/core/errors.ts +23 -0
  21. package/src/core/hooks.ts +74 -0
  22. package/src/core/html.ts +170 -0
  23. package/src/core/matcher.ts +85 -0
  24. package/src/core/plugin.ts +59 -0
  25. package/src/core/prerender.ts +79 -0
  26. package/src/core/renderer.ts +222 -0
  27. package/src/core/routeFile.ts +88 -0
  28. package/src/core/routeTypes.ts +95 -0
  29. package/src/core/scanner.ts +99 -0
  30. package/src/core/server.ts +320 -0
  31. package/src/core/types.ts +37 -0
  32. package/src/lib/index.ts +19 -0
  33. package/src/lib/utils.ts +24 -0
  34. package/templates/default/.env.example +34 -0
  35. package/templates/default/README.md +102 -0
  36. package/templates/default/package.json +21 -0
  37. package/templates/default/public/.gitkeep +0 -0
  38. package/templates/default/src/app.css +132 -0
  39. package/templates/default/src/app.d.ts +7 -0
  40. package/templates/default/src/lib/.gitkeep +0 -0
  41. package/templates/default/src/routes/+error.svelte +18 -0
  42. package/templates/default/src/routes/+layout.svelte +6 -0
  43. package/templates/default/src/routes/+page.svelte +36 -0
  44. package/templates/default/src/routes/about/+page.server.ts +1 -0
  45. package/templates/default/src/routes/about/+page.svelte +8 -0
  46. package/templates/default/tsconfig.json +22 -0
@@ -0,0 +1,24 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export function getServerTime() {
9
+ const now = new Date();
10
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
11
+
12
+ // Get timezone offset in minutes and convert to ±HH:MM format
13
+ const offsetMinutes = -now.getTimezoneOffset();
14
+ const offsetHours = Math.floor(Math.abs(offsetMinutes) / 60);
15
+ const offsetMins = Math.abs(offsetMinutes) % 60;
16
+ const sign = offsetMinutes >= 0 ? '+' : '-';
17
+ const offsetStr = `${sign}${String(offsetHours).padStart(2, '0')}:${String(offsetMins).padStart(2, '0')}`;
18
+
19
+ // Convert UTC time to local time by adding the offset
20
+ const localTime = new Date(now.getTime() + offsetMinutes * 60 * 1000);
21
+ const timestamp = localTime.toISOString().slice(0, -1) + offsetStr;
22
+
23
+ return { timestamp, timezone: timeZone };
24
+ }
@@ -0,0 +1,34 @@
1
+ # ─── Bunia Environment Variables ───────────────────────────────────────────────
2
+ #
3
+ # Copy this file to .env and fill in your values.
4
+ # .env.local overrides .env (gitignored — for local secrets).
5
+ # .env.development / .env.production for mode-specific values.
6
+ #
7
+ # Prefix convention:
8
+ #
9
+ # PUBLIC_STATIC_* Client + server, inlined at build time (e.g. app name)
10
+ # PUBLIC_* Client + server, injected at runtime via window.__BUNIA_ENV__
11
+ # STATIC_* Server only, inlined at build time
12
+ # (no prefix) Server only, read from process.env at runtime (secrets, DB creds)
13
+ #
14
+ # Import in your code:
15
+ # import { PUBLIC_STATIC_APP_NAME, DB_PASSWORD } from 'bunia:env';
16
+ #
17
+ # Framework vars (PORT, NODE_ENV, BODY_SIZE_LIMIT, CSRF_ALLOWED_ORIGINS) are
18
+ # NOT exposed via bunia:env — access them via process.env directly.
19
+ # ────────────────────────────────────────────────────────────────────────────────
20
+
21
+ # Public build-time constant (safe to expose to client)
22
+ PUBLIC_STATIC_APP_NAME=My Bunia App
23
+
24
+ # Framework vars — access via process.env directly (not via bunia:env)
25
+ # PORT=9000
26
+
27
+ # Public runtime var (safe to expose to client, can change without rebuild)
28
+ # PUBLIC_API_URL=https://api.example.com
29
+
30
+ # Server-only build-time constant
31
+ # STATIC_DB_HOST=localhost
32
+
33
+ # Server-only runtime secret (never sent to client)
34
+ # DATABASE_URL=postgres://user:password@localhost:5432/mydb
@@ -0,0 +1,102 @@
1
+ # {{PROJECT_NAME}}
2
+
3
+ A [Bunia](https://github.com/bosapi/bunia) project — SSR · Svelte 5 · Bun · ElysiaJS.
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ bun run dev # start development server at http://localhost:9000
9
+ bun run build # build for production
10
+ bun run start # run the production server
11
+ ```
12
+
13
+ ## Project Structure
14
+
15
+ ```
16
+ src/
17
+ ├── app.css # Global styles and Tailwind design tokens
18
+ ├── hooks.server.ts # Optional request middleware (auth, logging)
19
+ ├── lib/ # Shared utilities — import via $lib
20
+ └── routes/ # Pages and API endpoints
21
+ ├── +layout.svelte # Root layout
22
+ └── +page.svelte # Home page (/)
23
+ public/ # Static assets
24
+ ```
25
+
26
+ ## Routes
27
+
28
+ Add pages by creating `+page.svelte` files under `src/routes/`:
29
+
30
+ ```
31
+ src/routes/
32
+ ├── +page.svelte # /
33
+ ├── about/
34
+ │ └── +page.svelte # /about
35
+ └── blog/
36
+ ├── +page.svelte # /blog
37
+ └── [slug]/
38
+ ├── +page.server.ts # server loader
39
+ └── +page.svelte # /blog/:slug
40
+ ```
41
+
42
+ ### Server Loaders
43
+
44
+ Fetch data on the server before rendering:
45
+
46
+ ```typescript
47
+ // src/routes/blog/[slug]/+page.server.ts
48
+ import type { LoadEvent } from "bunia";
49
+
50
+ export async function load({ params }: LoadEvent) {
51
+ return { post: await getPost(params.slug) };
52
+ }
53
+ ```
54
+
55
+ ### API Endpoints
56
+
57
+ ```typescript
58
+ // src/routes/api/hello/+server.ts
59
+ export function GET() {
60
+ return Response.json({ message: "hello" });
61
+ }
62
+ ```
63
+
64
+ ### Route Groups
65
+
66
+ Group routes under a shared layout without changing the URL:
67
+
68
+ ```
69
+ src/routes/
70
+ └── (app)/
71
+ ├── +layout.svelte # shared layout for the group
72
+ └── dashboard/
73
+ └── +page.svelte # /dashboard
74
+ ```
75
+
76
+ ## Styling
77
+
78
+ `src/app.css` imports Tailwind v4 and defines shadcn-inspired design tokens. Use the semantic color classes anywhere:
79
+
80
+ ```svelte
81
+ <div class="bg-background text-foreground">
82
+ <p class="text-muted-foreground">Muted text</p>
83
+ <button class="bg-primary text-primary-foreground">Click</button>
84
+ </div>
85
+ ```
86
+
87
+ Dark mode is supported via the `.dark` class on any parent element.
88
+
89
+ ## Utilities
90
+
91
+ ```typescript
92
+ import { cn } from "$lib/utils";
93
+
94
+ // Merges Tailwind classes safely
95
+ cn("px-4 py-2", isActive && "bg-primary")
96
+ ```
97
+
98
+ ## Learn More
99
+
100
+ - [Bunia documentation](https://github.com/bosapi/bunia)
101
+ - [Svelte 5 docs](https://svelte.dev)
102
+ - [Tailwind CSS v4](https://tailwindcss.com)
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "bunia dev",
7
+ "build": "bunia build",
8
+ "start": "bunia start",
9
+ "check": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "bunia": "*",
13
+ "svelte": "^5.20.0",
14
+ "clsx": "^2.1.1",
15
+ "tailwind-merge": "^3.5.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/bun": "latest",
19
+ "typescript": "^5"
20
+ }
21
+ }
File without changes
@@ -0,0 +1,132 @@
1
+ @import "tailwindcss";
2
+ @source "../src";
3
+
4
+ /*
5
+ * ─── shadcn-inspired Design Tokens ──────────────────────
6
+ * CSS custom properties for light & dark themes.
7
+ * Uses HSL values so Tailwind can apply opacity modifiers.
8
+ */
9
+
10
+ @theme {
11
+ --color-background: hsl(var(--background));
12
+ --color-foreground: hsl(var(--foreground));
13
+
14
+ --color-card: hsl(var(--card));
15
+ --color-card-foreground: hsl(var(--card-foreground));
16
+
17
+ --color-popover: hsl(var(--popover));
18
+ --color-popover-foreground: hsl(var(--popover-foreground));
19
+
20
+ --color-primary: hsl(var(--primary));
21
+ --color-primary-foreground: hsl(var(--primary-foreground));
22
+
23
+ --color-secondary: hsl(var(--secondary));
24
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
25
+
26
+ --color-muted: hsl(var(--muted));
27
+ --color-muted-foreground: hsl(var(--muted-foreground));
28
+
29
+ --color-accent: hsl(var(--accent));
30
+ --color-accent-foreground: hsl(var(--accent-foreground));
31
+
32
+ --color-destructive: hsl(var(--destructive));
33
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
34
+
35
+ --color-border: hsl(var(--border));
36
+ --color-input: hsl(var(--input));
37
+ --color-ring: hsl(var(--ring));
38
+
39
+ --radius-sm: calc(var(--radius) - 4px);
40
+ --radius-md: calc(var(--radius) - 2px);
41
+ --radius-lg: var(--radius);
42
+ --radius-xl: calc(var(--radius) + 4px);
43
+ }
44
+
45
+ /* ─── Light Theme (Default) ─────────────────────────────── */
46
+
47
+ :root {
48
+ --background: 0 0% 100%;
49
+ --foreground: 222.2 84% 4.9%;
50
+
51
+ --card: 0 0% 100%;
52
+ --card-foreground: 222.2 84% 4.9%;
53
+
54
+ --popover: 0 0% 100%;
55
+ --popover-foreground: 222.2 84% 4.9%;
56
+
57
+ --primary: 222.2 47.4% 11.2%;
58
+ --primary-foreground: 210 40% 98%;
59
+
60
+ --secondary: 210 40% 96.1%;
61
+ --secondary-foreground: 222.2 47.4% 11.2%;
62
+
63
+ --muted: 210 40% 96.1%;
64
+ --muted-foreground: 215.4 16.3% 46.9%;
65
+
66
+ --accent: 210 40% 96.1%;
67
+ --accent-foreground: 222.2 47.4% 11.2%;
68
+
69
+ --destructive: 0 84.2% 60.2%;
70
+ --destructive-foreground: 210 40% 98%;
71
+
72
+ --border: 214.3 31.8% 91.4%;
73
+ --input: 214.3 31.8% 91.4%;
74
+ --ring: 222.2 84% 4.9%;
75
+
76
+ --radius: 0.5rem;
77
+ }
78
+
79
+ /* ─── Dark Theme ─────────────────────────────────────────── */
80
+
81
+ .dark {
82
+ --background: 222.2 84% 4.9%;
83
+ --foreground: 210 40% 98%;
84
+
85
+ --card: 222.2 84% 4.9%;
86
+ --card-foreground: 210 40% 98%;
87
+
88
+ --popover: 222.2 84% 4.9%;
89
+ --popover-foreground: 210 40% 98%;
90
+
91
+ --primary: 210 40% 98%;
92
+ --primary-foreground: 222.2 47.4% 11.2%;
93
+
94
+ --secondary: 217.2 32.6% 17.5%;
95
+ --secondary-foreground: 210 40% 98%;
96
+
97
+ --muted: 217.2 32.6% 17.5%;
98
+ --muted-foreground: 215 20.2% 65.1%;
99
+
100
+ --accent: 217.2 32.6% 17.5%;
101
+ --accent-foreground: 210 40% 98%;
102
+
103
+ --destructive: 0 62.8% 30.6%;
104
+ --destructive-foreground: 210 40% 98%;
105
+
106
+ --border: 217.2 32.6% 17.5%;
107
+ --input: 217.2 32.6% 17.5%;
108
+ --ring: 212.7 26.8% 83.9%;
109
+ }
110
+
111
+ /* ─── Base Styles ────────────────────────────────────────── */
112
+
113
+ @layer base {
114
+ * {
115
+ border-color: theme(--color-border);
116
+ }
117
+
118
+ body {
119
+ background-color: theme(--color-background);
120
+ color: theme(--color-foreground);
121
+ font-family:
122
+ "Inter",
123
+ system-ui,
124
+ -apple-system,
125
+ BlinkMacSystemFont,
126
+ "Segoe UI",
127
+ Roboto,
128
+ "Helvetica Neue",
129
+ Arial,
130
+ sans-serif;
131
+ }
132
+ }
@@ -0,0 +1,7 @@
1
+ /// <reference types="svelte" />
2
+
3
+ declare module "*.svelte" {
4
+ import type { Component } from "svelte";
5
+ const component: Component<Record<string, any>, Record<string, any>, any>;
6
+ export default component;
7
+ }
File without changes
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ let { data }: { data: { status: number; message: string } } = $props();
3
+ </script>
4
+
5
+ <svelte:head>
6
+ <title>{data.status} — {data.message}</title>
7
+ </svelte:head>
8
+
9
+ <main class="flex min-h-screen flex-col items-center justify-center gap-4 text-center px-4">
10
+ <p class="text-8xl font-bold text-gray-200">{data.status}</p>
11
+ <p class="text-2xl font-semibold">{data.message}</p>
12
+ <a
13
+ href="/"
14
+ class="mt-4 rounded-md border px-4 py-2 text-sm hover:bg-muted transition-colors"
15
+ >
16
+ Go home
17
+ </a>
18
+ </main>
@@ -0,0 +1,6 @@
1
+ <script lang="ts">
2
+ import "../app.css";
3
+ let { children }: { children: any } = $props();
4
+ </script>
5
+
6
+ {@render children()}
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ const name = "{{PROJECT_NAME}}";
3
+ </script>
4
+
5
+ <main class="flex min-h-screen flex-col items-center justify-center gap-6 p-8">
6
+ <div class="flex flex-col items-center gap-3 text-center">
7
+ <p class="text-6xl">🐰</p>
8
+ <h1 class="text-4xl font-bold tracking-tight">{name}</h1>
9
+ <p class="text-muted-foreground text-lg">
10
+ A Bunia project — SSR + Svelte 5 + Bun + ElysiaJS
11
+ </p>
12
+ </div>
13
+
14
+ <div class="mt-4 flex gap-3">
15
+ <a
16
+ href="https://github.com/bosapi/bunia"
17
+ target="_blank"
18
+ rel="noopener noreferrer"
19
+ class="bg-primary text-primary-foreground hover:bg-primary/90 rounded-md px-4 py-2 text-sm font-medium transition-colors"
20
+ >
21
+ Docs
22
+ </a>
23
+ <a
24
+ href="https://github.com/bosapi/bunia/tree/main/registry"
25
+ target="_blank"
26
+ rel="noopener noreferrer"
27
+ class="border-border bg-secondary text-secondary-foreground hover:bg-secondary/80 rounded-md border px-4 py-2 text-sm font-medium transition-colors"
28
+ >
29
+ Components
30
+ </a>
31
+ </div>
32
+
33
+ <p class="text-muted-foreground mt-6 text-sm">
34
+ Edit <code class="bg-muted rounded px-1 py-0.5 font-mono text-xs">src/routes/+page.svelte</code> to get started
35
+ </p>
36
+ </main>
@@ -0,0 +1 @@
1
+ export const prerender = true;
@@ -0,0 +1,8 @@
1
+ <svelte:head>
2
+ <title>About | {{PROJECT_NAME}}</title>
3
+ </svelte:head>
4
+
5
+ <div>
6
+ <h1>About</h1>
7
+ <p>This page is prerendered at build time — no server work per request.</p>
8
+ </div>
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "allowJs": true,
8
+ "skipLibCheck": true,
9
+ "allowImportingTsExtensions": true,
10
+ "noEmit": true,
11
+ "verbatimModuleSyntax": true,
12
+ "types": ["bun-types"],
13
+ "lib": ["dom", "dom.iterable", "esnext"],
14
+ "rootDirs": [".", ".bunia/types"],
15
+ "paths": {
16
+ "$lib": ["./src/lib"],
17
+ "$lib/*": ["./src/lib/*"]
18
+ }
19
+ },
20
+ "include": ["src/**/*"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }