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 +1 -1
- package/src/core/server.ts +21 -1
- package/templates/default/src/app.css +2 -0
- package/templates/demo/src/app.css +2 -0
- package/templates/shop/package.json +1 -2
- package/templates/shop/src/app.css +2 -0
- package/templates/shop/src/routes/(private)/+layout.svelte +30 -0
- package/templates/shop/src/routes/(public)/+page.svelte +8 -0
- package/templates/todo/src/app.css +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bosia",
|
|
3
|
-
"version": "0.6.
|
|
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": [
|
package/src/core/server.ts
CHANGED
|
@@ -366,7 +366,7 @@ async function resolve(event: RequestEvent): Promise<Response> {
|
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
-
const
|
|
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,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" />
|