bosia 0.6.20 → 0.6.22

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 (58) hide show
  1. package/package.json +2 -2
  2. package/src/cli/add.ts +5 -5
  3. package/src/cli/addRouter.ts +53 -0
  4. package/src/cli/block.ts +19 -12
  5. package/src/cli/create.ts +6 -11
  6. package/src/cli/feat.ts +19 -22
  7. package/src/cli/index.ts +25 -23
  8. package/src/cli/manifest.ts +1 -1
  9. package/src/cli/registry.ts +40 -2
  10. package/src/core/build.ts +1 -3
  11. package/src/core/client/App.svelte +3 -8
  12. package/src/core/client/page.svelte.ts +28 -0
  13. package/src/core/client/router.svelte.ts +3 -8
  14. package/src/core/config.ts +1 -4
  15. package/src/core/cookies.ts +1 -2
  16. package/src/core/dev-500.ts +1 -1
  17. package/src/core/html.ts +1 -2
  18. package/src/core/plugin.ts +1 -3
  19. package/src/core/plugins/inspector/bun-plugin.ts +1 -4
  20. package/src/core/plugins/inspector/index.ts +45 -59
  21. package/src/core/renderer.ts +3 -10
  22. package/src/core/routeTypes.ts +3 -9
  23. package/src/core/scanner.ts +1 -3
  24. package/src/core/server.ts +9 -34
  25. package/src/core/staticManifest.ts +1 -3
  26. package/src/core/svelteAudit.ts +2 -5
  27. package/src/core/svelteCompiler.ts +2 -8
  28. package/src/lib/client.ts +1 -0
  29. package/templates/default/.prettierignore +1 -0
  30. package/templates/demo/.prettierignore +1 -0
  31. package/templates/shop/.env.example +12 -0
  32. package/templates/shop/.prettierignore +7 -0
  33. package/templates/shop/.prettierrc.json +9 -0
  34. package/templates/shop/README.md +62 -0
  35. package/templates/shop/_gitignore +12 -0
  36. package/templates/shop/bosia.config.ts +10 -0
  37. package/templates/shop/instructions.txt +8 -0
  38. package/templates/shop/package.json +27 -0
  39. package/templates/shop/public/favicon.svg +14 -0
  40. package/templates/shop/public/logo-dark.svg +14 -0
  41. package/templates/shop/public/logo-light.svg +14 -0
  42. package/templates/shop/src/app.css +132 -0
  43. package/templates/shop/src/app.d.ts +14 -0
  44. package/templates/shop/src/app.html +11 -0
  45. package/templates/shop/src/hooks.server.ts +21 -0
  46. package/templates/shop/src/lib/utils.ts +1 -0
  47. package/templates/shop/src/routes/(private)/+layout.server.ts +10 -0
  48. package/templates/shop/src/routes/(private)/+layout.svelte +14 -0
  49. package/templates/shop/src/routes/(private)/dashboard/+page.svelte +11 -0
  50. package/templates/shop/src/routes/(public)/+layout.svelte +13 -0
  51. package/templates/shop/src/routes/(public)/+page.svelte +30 -0
  52. package/templates/shop/src/routes/+error.svelte +19 -0
  53. package/templates/shop/src/routes/+layout.server.ts +9 -0
  54. package/templates/shop/src/routes/+layout.svelte +6 -0
  55. package/templates/shop/template.json +10 -0
  56. package/templates/shop/tsconfig.json +22 -0
  57. package/templates/todo/.prettierignore +1 -0
  58. package/templates/todo/template.json +4 -1
@@ -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,14 @@
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
+ }
8
+
9
+ declare namespace App {
10
+ interface Locals {
11
+ db: import("./features/drizzle").Database;
12
+ requestTime: number;
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ <!doctype html>
2
+ <html lang="%bosia.lang%">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ %bosia.head%
7
+ </head>
8
+ <body>
9
+ %bosia.body%
10
+ </body>
11
+ </html>
@@ -0,0 +1,21 @@
1
+ import { sequence } from "bosia";
2
+ import type { Handle } from "bosia";
3
+ import { db } from "./features/drizzle";
4
+ import { authHandle } from "./features/auth";
5
+
6
+ const dbHandle: Handle = async ({ event, resolve }) => {
7
+ event.locals.db = db;
8
+ return resolve(event);
9
+ };
10
+
11
+ const loggingHandle: Handle = async ({ event, resolve }) => {
12
+ const start = Date.now();
13
+ event.locals.requestTime = start;
14
+ const res = await resolve(event);
15
+ const ms = Date.now() - start;
16
+ console.log(`[${event.request.method}] ${event.url.pathname} ${res.status} (${ms}ms)`);
17
+ res.headers.set("X-Response-Time", `${ms}ms`);
18
+ return res;
19
+ };
20
+
21
+ export const handle = sequence(dbHandle, authHandle, loggingHandle);
@@ -0,0 +1 @@
1
+ export { cn } from "bosia";
@@ -0,0 +1,10 @@
1
+ import { redirect } from "bosia";
2
+ import type { LoadEvent } from "bosia";
3
+
4
+ export async function load({ locals, url }: LoadEvent) {
5
+ if (!locals.user) {
6
+ const next = encodeURIComponent(url.pathname + url.search);
7
+ throw redirect(303, `/login?next=${next}`);
8
+ }
9
+ return { user: locals.user };
10
+ }
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import { page } from "bosia/client";
3
+ import AdminSidebar from "$lib/components/AdminSidebar.svelte";
4
+
5
+ let { data, children }: { data: { user: { id: string; email: string } }; children: any } =
6
+ $props();
7
+ </script>
8
+
9
+ <div class="flex min-h-screen">
10
+ <AdminSidebar currentPath={page.url.pathname} user={data.user} />
11
+ <main class="flex-1 overflow-x-hidden p-6">
12
+ {@render children()}
13
+ </main>
14
+ </div>
@@ -0,0 +1,11 @@
1
+ <!-- EDIT THIS FILE: add cards, KPIs, recent orders, sales charts, etc. -->
2
+ <svelte:head>
3
+ <title>Dashboard</title>
4
+ </svelte:head>
5
+
6
+ <div class="flex flex-col gap-4">
7
+ <h1 class="text-2xl font-bold tracking-tight">Dashboard</h1>
8
+ <p class="text-muted-foreground text-sm">
9
+ This is your admin home. Add widgets, KPI cards, and recent activity here.
10
+ </p>
11
+ </div>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import { page } from "bosia/client";
3
+ import PublicNavbar from "$lib/components/PublicNavbar.svelte";
4
+
5
+ let { data, children }: { data: { user: any }; children: any } = $props();
6
+ </script>
7
+
8
+ <div class="flex min-h-screen flex-col">
9
+ <PublicNavbar currentPath={page.url.pathname} user={data.user} />
10
+ <div class="flex-1">
11
+ {@render children()}
12
+ </div>
13
+ </div>
@@ -0,0 +1,30 @@
1
+ <main class="flex min-h-[80vh] flex-col items-center justify-center gap-6 p-8">
2
+ <div class="flex flex-col items-center gap-3 text-center">
3
+ <img src="/favicon.svg" alt="" class="size-16" />
4
+ <h1 class="text-4xl font-bold tracking-tight">Welcome to your shop</h1>
5
+ <p class="text-muted-foreground text-lg">
6
+ A Bosia shop starter — auth, RBAC, S3 uploads, products & cart.
7
+ </p>
8
+ </div>
9
+
10
+ <div class="mt-4 flex gap-3">
11
+ <a
12
+ href="/products"
13
+ class="bg-primary text-primary-foreground hover:bg-primary/90 rounded-md px-4 py-2 text-sm font-medium transition-colors"
14
+ >
15
+ Browse products
16
+ </a>
17
+ <a
18
+ href="/login"
19
+ 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"
20
+ >
21
+ Sign in
22
+ </a>
23
+ </div>
24
+
25
+ <p class="text-muted-foreground mt-6 text-sm">
26
+ Edit <code class="bg-muted rounded px-1 py-0.5 font-mono text-xs"
27
+ >src/routes/(public)/+page.svelte</code
28
+ > to get started
29
+ </p>
30
+ </main>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import type { ErrorProps } from "./$types";
3
+ let { error }: ErrorProps = $props();
4
+ </script>
5
+
6
+ <svelte:head>
7
+ <title>{error.status} — {error.message}</title>
8
+ </svelte:head>
9
+
10
+ <div class="min-h-screen flex flex-col items-center justify-center gap-4 text-center px-4">
11
+ <p class="text-8xl font-bold text-gray-200">{error.status}</p>
12
+ <p class="text-2xl font-semibold text-gray-700">{error.message}</p>
13
+ <a
14
+ href="/"
15
+ class="mt-4 px-5 py-2 rounded-lg bg-gray-900 text-white text-sm hover:bg-gray-700 transition-colors"
16
+ >
17
+ Go home
18
+ </a>
19
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { LoadEvent } from "bosia";
2
+
3
+ export async function load({ locals }: LoadEvent) {
4
+ return {
5
+ appName: "Bosia Shop",
6
+ requestTime: (locals.requestTime as number | null) ?? null,
7
+ user: locals.user ?? null,
8
+ };
9
+ }
@@ -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,10 @@
1
+ {
2
+ "features": ["auth", "rbac", "file-upload", "shop"],
3
+ "featureOptions": {
4
+ "drizzle.dialect": "postgres",
5
+ "auth.dialect": "postgres",
6
+ "rbac.dialect": "postgres",
7
+ "file-upload.dialect": "postgres",
8
+ "shop.dialect": "postgres"
9
+ }
10
+ }
@@ -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": [".", ".bosia/types"],
15
+ "paths": {
16
+ "$lib": ["./src/lib"],
17
+ "$lib/*": ["./src/lib/*"]
18
+ }
19
+ },
20
+ "include": ["src/**/*", ".bosia/types/**/*.d.ts"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }
@@ -4,3 +4,4 @@ build
4
4
  .bosia
5
5
  bun.lock
6
6
  public/bosia-tw.css
7
+ bosia.json
@@ -1,3 +1,6 @@
1
1
  {
2
- "features": ["todo"]
2
+ "features": ["todo"],
3
+ "featureOptions": {
4
+ "drizzle.dialect": "postgres"
5
+ }
3
6
  }