bosia 0.6.22 → 0.6.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosia",
3
- "version": "0.6.22",
3
+ "version": "0.6.23",
4
4
  "type": "module",
5
5
  "description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
6
6
  "keywords": [
@@ -366,7 +366,7 @@ async function resolve(event: RequestEvent): Promise<Response> {
366
366
  }
367
367
  }
368
368
 
369
- const response = await handler({
369
+ const handlerResult = await handler({
370
370
  request,
371
371
  params: apiMatch.params,
372
372
  url,
@@ -374,6 +374,15 @@ async function resolve(event: RequestEvent): Promise<Response> {
374
374
  cookies,
375
375
  });
376
376
 
377
+ // Redirect returned (not thrown) — convert to a 303 Response.
378
+ if (handlerResult instanceof Redirect) {
379
+ return new Response(null, {
380
+ status: handlerResult.status,
381
+ headers: { Location: handlerResult.location },
382
+ });
383
+ }
384
+
385
+ const response = handlerResult as Response;
377
386
  const responseContentType = response.headers.get("content-type") ?? "";
378
387
  // SSE responses are long-lived pub/sub streams — caching the buffered
379
388
  // bytes would serve a stale finite snapshot to future subscribers and
@@ -423,6 +432,17 @@ async function resolve(event: RequestEvent): Promise<Response> {
423
432
 
424
433
  return response;
425
434
  } catch (err) {
435
+ // `throw redirect(303, "/")` from a +server.ts handler — turn it into
436
+ // a real 303 instead of a 500. Mirrors the page-action handler below.
437
+ if (err instanceof Redirect) {
438
+ return new Response(null, {
439
+ status: err.status,
440
+ headers: { Location: err.location },
441
+ });
442
+ }
443
+ if (err instanceof HttpError) {
444
+ return Response.json({ error: err.message }, { status: err.status });
445
+ }
426
446
  if (isDev) console.error("API route error:", err);
427
447
  else console.error("API route error:", (err as Error).message ?? err);
428
448
  if (isDev) reportDevErrorFromCatch(err);
@@ -1,6 +1,8 @@
1
1
  @import "tailwindcss";
2
2
  @source "../src";
3
3
 
4
+ @custom-variant dark (&:where(.dark, .dark *));
5
+
4
6
  /*
5
7
  * ─── shadcn-inspired Design Tokens ──────────────────────
6
8
  * CSS custom properties for light & dark themes.
@@ -1,6 +1,8 @@
1
1
  @import "tailwindcss";
2
2
  @source "../src";
3
3
 
4
+ @custom-variant dark (&:where(.dark, .dark *));
5
+
4
6
  /*
5
7
  * ─── shadcn-inspired Design Tokens ──────────────────────
6
8
  * CSS custom properties for light & dark themes.
@@ -14,8 +14,7 @@
14
14
  "bosia": "^{{BOSIA_VERSION}}",
15
15
  "svelte": "^5.20.0",
16
16
  "tailwind-merge": "^3.5.0",
17
- "drizzle-orm": "^0.44.0",
18
- "postgres": "^3.4.0"
17
+ "drizzle-orm": "^0.44.0"
19
18
  },
20
19
  "devDependencies": {
21
20
  "@types/bun": "latest",
@@ -1,6 +1,8 @@
1
1
  @import "tailwindcss";
2
2
  @source "../src";
3
3
 
4
+ @custom-variant dark (&:where(.dark, .dark *));
5
+
4
6
  /*
5
7
  * ─── shadcn-inspired Design Tokens ──────────────────────
6
8
  * CSS custom properties for light & dark themes.
@@ -1,14 +1,44 @@
1
1
  <script lang="ts">
2
2
  import { page } from "bosia/client";
3
3
  import AdminSidebar from "$lib/components/AdminSidebar.svelte";
4
+ import {
5
+ Breadcrumb,
6
+ BreadcrumbList,
7
+ BreadcrumbItem,
8
+ BreadcrumbLink,
9
+ BreadcrumbPage,
10
+ BreadcrumbSeparator,
11
+ } from "$lib/components/ui/breadcrumb";
4
12
 
5
13
  let { data, children }: { data: { user: { id: string; email: string } }; children: any } =
6
14
  $props();
15
+
16
+ const segments = $derived(page.url.pathname.split("/").filter(Boolean));
17
+ const label = (s: string) => s[0].toUpperCase() + s.slice(1);
18
+ const hrefAt = (i: number) => "/" + segments.slice(0, i + 1).join("/");
7
19
  </script>
8
20
 
9
21
  <div class="flex min-h-screen">
10
22
  <AdminSidebar currentPath={page.url.pathname} user={data.user} />
11
23
  <main class="flex-1 overflow-x-hidden p-6">
24
+ {#if segments.length > 0}
25
+ <Breadcrumb class="mb-4">
26
+ <BreadcrumbList>
27
+ {#each segments as segment, i}
28
+ <BreadcrumbItem>
29
+ {#if i === segments.length - 1}
30
+ <BreadcrumbPage>{label(segment)}</BreadcrumbPage>
31
+ {:else}
32
+ <BreadcrumbLink href={hrefAt(i)}>{label(segment)}</BreadcrumbLink>
33
+ {/if}
34
+ </BreadcrumbItem>
35
+ {#if i < segments.length - 1}
36
+ <BreadcrumbSeparator />
37
+ {/if}
38
+ {/each}
39
+ </BreadcrumbList>
40
+ </Breadcrumb>
41
+ {/if}
12
42
  {@render children()}
13
43
  </main>
14
44
  </div>
@@ -1,3 +1,11 @@
1
+ <svelte:head>
2
+ <title>Welcome to your shop</title>
3
+ <meta
4
+ name="description"
5
+ content="A Bosia shop starter — auth, RBAC, S3 uploads, products & cart."
6
+ />
7
+ </svelte:head>
8
+
1
9
  <main class="flex min-h-[80vh] flex-col items-center justify-center gap-6 p-8">
2
10
  <div class="flex flex-col items-center gap-3 text-center">
3
11
  <img src="/favicon.svg" alt="" class="size-16" />
@@ -1,6 +1,8 @@
1
1
  @import "tailwindcss";
2
2
  @source "../src";
3
3
 
4
+ @custom-variant dark (&:where(.dark, .dark *));
5
+
4
6
  /*
5
7
  * ─── shadcn-inspired Design Tokens ──────────────────────
6
8
  * CSS custom properties for light & dark themes.