bosia 0.3.2 → 0.3.3
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/cli/add.ts +4 -4
- package/src/cli/create.ts +4 -2
- package/src/cli/feat.ts +3 -3
- package/src/cli/index.ts +17 -17
- package/src/core/plugin.ts +11 -3
- package/src/core/routeTypes.ts +11 -5
- package/src/core/server.ts +2 -2
- package/templates/default/src/routes/+error.svelte +2 -1
- package/templates/demo/src/routes/(public)/+page.svelte +1 -1
- package/templates/demo/src/routes/(public)/about/+page.svelte +1 -1
- package/templates/demo/src/routes/+error.svelte +2 -1
- package/templates/todo/src/routes/+error.svelte +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bosia",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
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/cli/add.ts
CHANGED
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
bunAdd,
|
|
12
12
|
} from "./registry.ts";
|
|
13
13
|
|
|
14
|
-
// ─── bosia add <component>
|
|
14
|
+
// ─── bun x bosia@latest add <component> ──────────────────
|
|
15
15
|
// Fetches a component from the GitHub registry (or local registry
|
|
16
16
|
// with --local) and copies it into src/lib/components/<path>/.
|
|
17
17
|
//
|
|
18
18
|
// Path-based names:
|
|
19
|
-
// bosia add button → src/lib/components/ui/button/
|
|
20
|
-
// bosia add shop/cart → src/lib/components/shop/cart/
|
|
19
|
+
// bun x bosia@latest add button → src/lib/components/ui/button/
|
|
20
|
+
// bun x bosia@latest add shop/cart → src/lib/components/shop/cart/
|
|
21
21
|
|
|
22
22
|
interface ComponentMeta {
|
|
23
23
|
name: string;
|
|
@@ -48,7 +48,7 @@ export async function initAddRegistry(root: string | null) {
|
|
|
48
48
|
export async function runAdd(name: string | undefined, flags: string[] = []) {
|
|
49
49
|
if (!name) {
|
|
50
50
|
console.error(
|
|
51
|
-
"❌ Please provide a component name.\n Usage: bosia add <component> [--local]",
|
|
51
|
+
"❌ Please provide a component name.\n Usage: bun x bosia@latest add <component> [--local]",
|
|
52
52
|
);
|
|
53
53
|
process.exit(1);
|
|
54
54
|
}
|
package/src/cli/create.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as p from "@clack/prompts";
|
|
|
5
5
|
import { installFeature, initFeatRegistry, resolveLocalRegistry } from "./feat.ts";
|
|
6
6
|
import { initAddRegistry } from "./add.ts";
|
|
7
7
|
|
|
8
|
-
// ─── bosia create <name> [--template <name>]
|
|
8
|
+
// ─── bun x bosia@latest create <name> [--template <name>] ─
|
|
9
9
|
|
|
10
10
|
const TEMPLATES_DIR = resolve(import.meta.dir, "../../templates");
|
|
11
11
|
const BOSIA_PKG = JSON.parse(readFileSync(resolve(import.meta.dir, "../../package.json"), "utf-8"));
|
|
@@ -19,7 +19,9 @@ const TEMPLATE_DESCRIPTIONS: Record<string, string> = {
|
|
|
19
19
|
|
|
20
20
|
export async function runCreate(name: string | undefined, args: string[] = []) {
|
|
21
21
|
if (!name) {
|
|
22
|
-
console.error(
|
|
22
|
+
console.error(
|
|
23
|
+
"❌ Please provide a project name.\n Usage: bun x bosia@latest create my-app",
|
|
24
|
+
);
|
|
23
25
|
process.exit(1);
|
|
24
26
|
}
|
|
25
27
|
|
package/src/cli/feat.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
bunAdd,
|
|
12
12
|
} from "./registry.ts";
|
|
13
13
|
|
|
14
|
-
// ─── bosia feat <feature> [--local]
|
|
14
|
+
// ─── bun x bosia@latest feat <feature> [--local] ─────────
|
|
15
15
|
// Fetches a feature scaffold from the GitHub registry (or local
|
|
16
16
|
// registry with --local) and copies route/lib files, installs npm deps.
|
|
17
17
|
// Supports nested feature dependencies (e.g. todo → drizzle).
|
|
@@ -34,7 +34,7 @@ interface FeatureMeta {
|
|
|
34
34
|
name: string;
|
|
35
35
|
description: string;
|
|
36
36
|
features?: string[]; // other bosia features required
|
|
37
|
-
components: string[]; // bosia components to install via `bosia add`
|
|
37
|
+
components: string[]; // bosia components to install via `bun x bosia@latest add`
|
|
38
38
|
files: FileEntry[]; // file entries with per-file strategy
|
|
39
39
|
npmDeps: Record<string, string>;
|
|
40
40
|
npmDevDeps?: Record<string, string>;
|
|
@@ -50,7 +50,7 @@ const installedFeats = new Set<string>();
|
|
|
50
50
|
export async function runFeat(name: string | undefined, flags: string[] = []) {
|
|
51
51
|
if (!name) {
|
|
52
52
|
console.error(
|
|
53
|
-
"❌ Please provide a feature name.\n Usage: bosia feat <feature> [--local]",
|
|
53
|
+
"❌ Please provide a feature name.\n Usage: bun x bosia@latest feat <feature> [--local]",
|
|
54
54
|
);
|
|
55
55
|
process.exit(1);
|
|
56
56
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// ─── Bosia CLI ────────────────────────────────────────────
|
|
3
|
-
// bosia create <name> scaffold a new project
|
|
4
|
-
// bosia dev
|
|
5
|
-
// bosia build
|
|
6
|
-
// bosia start
|
|
7
|
-
// bosia add <name>
|
|
8
|
-
// bosia feat <name>
|
|
3
|
+
// bun x bosia@latest create <name> scaffold a new project
|
|
4
|
+
// bun x bosia dev start the development server
|
|
5
|
+
// bun x bosia build build for production
|
|
6
|
+
// bun x bosia start run the production server
|
|
7
|
+
// bun x bosia@latest add <name> add a UI component from the registry
|
|
8
|
+
// bun x bosia@latest feat <name> add a feature scaffold from the registry
|
|
9
9
|
|
|
10
10
|
const [, , command, ...args] = process.argv;
|
|
11
11
|
|
|
@@ -67,17 +67,17 @@ Commands:
|
|
|
67
67
|
feat <feature> Add a feature scaffold from the registry [--local]
|
|
68
68
|
|
|
69
69
|
Examples:
|
|
70
|
-
bosia create my-app
|
|
71
|
-
bosia create my-app --template todo
|
|
72
|
-
bosia dev
|
|
73
|
-
bosia build
|
|
74
|
-
bosia start
|
|
75
|
-
bosia test
|
|
76
|
-
bosia test --watch
|
|
77
|
-
bosia test --coverage
|
|
78
|
-
bosia add button → src/lib/components/ui/button/
|
|
79
|
-
bosia add shop/cart → src/lib/components/shop/cart/
|
|
80
|
-
bosia feat login
|
|
70
|
+
bun x bosia@latest create my-app
|
|
71
|
+
bun x bosia@latest create my-app --template todo
|
|
72
|
+
bun x bosia dev
|
|
73
|
+
bun x bosia build
|
|
74
|
+
bun x bosia start
|
|
75
|
+
bun x bosia test
|
|
76
|
+
bun x bosia test --watch
|
|
77
|
+
bun x bosia test --coverage
|
|
78
|
+
bun x bosia@latest add button → src/lib/components/ui/button/
|
|
79
|
+
bun x bosia@latest add shop/cart → src/lib/components/shop/cart/
|
|
80
|
+
bun x bosia@latest feat login
|
|
81
81
|
`);
|
|
82
82
|
break;
|
|
83
83
|
}
|
package/src/core/plugin.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join, dirname } from "path";
|
|
2
|
+
import { existsSync } from "fs";
|
|
2
3
|
|
|
3
4
|
// ─── Bun Build Plugin ─────────────────────────────────────
|
|
4
5
|
// Resolves:
|
|
@@ -9,11 +10,18 @@ import { join, dirname } from "path";
|
|
|
9
10
|
let cachedTsconfigPaths: Record<string, string[]> | null = null;
|
|
10
11
|
async function getTsconfigPaths() {
|
|
11
12
|
if (cachedTsconfigPaths !== null) return cachedTsconfigPaths;
|
|
13
|
+
const tsconfigPath = join(process.cwd(), "tsconfig.json");
|
|
14
|
+
if (!existsSync(tsconfigPath)) {
|
|
15
|
+
cachedTsconfigPaths = {};
|
|
16
|
+
return cachedTsconfigPaths;
|
|
17
|
+
}
|
|
12
18
|
try {
|
|
13
|
-
const tsconfig = await Bun.file(
|
|
19
|
+
const tsconfig = await Bun.file(tsconfigPath).json();
|
|
14
20
|
cachedTsconfigPaths = tsconfig?.compilerOptions?.paths || {};
|
|
15
|
-
} catch {
|
|
16
|
-
|
|
21
|
+
} catch (err) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`tsconfig.json at ${tsconfigPath} is invalid JSON: ${(err as Error).message}. Fix the file and re-run.`,
|
|
24
|
+
);
|
|
17
25
|
}
|
|
18
26
|
return cachedTsconfigPaths!;
|
|
19
27
|
}
|
package/src/core/routeTypes.ts
CHANGED
|
@@ -50,6 +50,8 @@ export function generateRouteTypes(manifest: RouteManifest): void {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
if (manifest.errorPage && !dirs.has(".")) dirs.set(".", {});
|
|
54
|
+
|
|
53
55
|
for (const [dir, info] of dirs) {
|
|
54
56
|
// Path segments of the route dir (empty array for root ".")
|
|
55
57
|
const segments = dir === "." ? [] : dir.split("/").filter(Boolean);
|
|
@@ -96,6 +98,12 @@ export function generateRouteTypes(manifest: RouteManifest): void {
|
|
|
96
98
|
}
|
|
97
99
|
lines.push(`export type PageProps = { data: PageData };`);
|
|
98
100
|
|
|
101
|
+
if (dir === "." && manifest.errorPage) {
|
|
102
|
+
lines.push(``);
|
|
103
|
+
lines.push(`export type PageError = { status: number; message: string };`);
|
|
104
|
+
lines.push(`export type ErrorProps = { error: PageError };`);
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
// ActionData — union of all action return types, unwrapping ActionFailure
|
|
100
108
|
if (info.pageServer) {
|
|
101
109
|
lines.push(``);
|
|
@@ -144,12 +152,10 @@ export function ensureRootDirs(): void {
|
|
|
144
152
|
let tsconfig: any;
|
|
145
153
|
try {
|
|
146
154
|
tsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
147
|
-
} catch {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
' "rootDirs": [".", ".bosia/types"]',
|
|
155
|
+
} catch (err) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`tsconfig.json at ${tsconfigPath} is invalid JSON: ${(err as Error).message}. Fix the file and re-run.`,
|
|
151
158
|
);
|
|
152
|
-
return;
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
const rootDirs: string[] = tsconfig.compilerOptions?.rootDirs ?? [];
|
package/src/core/server.ts
CHANGED
|
@@ -404,7 +404,7 @@ async function resolve(event: RequestEvent): Promise<Response> {
|
|
|
404
404
|
{ status: result.status },
|
|
405
405
|
);
|
|
406
406
|
}
|
|
407
|
-
return renderPageWithFormData(
|
|
407
|
+
return await renderPageWithFormData(
|
|
408
408
|
url,
|
|
409
409
|
locals,
|
|
410
410
|
request,
|
|
@@ -422,7 +422,7 @@ async function resolve(event: RequestEvent): Promise<Response> {
|
|
|
422
422
|
data: result ?? null,
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
|
-
return renderPageWithFormData(
|
|
425
|
+
return await renderPageWithFormData(
|
|
426
426
|
url,
|
|
427
427
|
locals,
|
|
428
428
|
request,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<ul class="space-y-2 text-foreground">
|
|
12
|
-
{#each ["Bun runtime — fast builds, native TypeScript", "ElysiaJS — HTTP server with type-safe routing", "Svelte 5 Runes — fine-grained reactivity", "Isomorphic SSR with client hydration", "File-based routing (SvelteKit-compatible conventions)", "Nested layouts and route groups (public), (auth), (admin)", "Dynamic params [slug] and catch-all [...rest]", "Server loaders with parent() data threading", "Hooks — sequence() middleware for auth, logging, etc.", "Component registry — bosia add button", "Feature registry — bosia feat login"] as item}
|
|
12
|
+
{#each ["Bun runtime — fast builds, native TypeScript", "ElysiaJS — HTTP server with type-safe routing", "Svelte 5 Runes — fine-grained reactivity", "Isomorphic SSR with client hydration", "File-based routing (SvelteKit-compatible conventions)", "Nested layouts and route groups (public), (auth), (admin)", "Dynamic params [slug] and catch-all [...rest]", "Server loaders with parent() data threading", "Hooks — sequence() middleware for auth, logging, etc.", "Component registry — bun x bosia@latest add button", "Feature registry — bosia feat login"] as item}
|
|
13
13
|
<li class="flex items-start gap-2">
|
|
14
14
|
<span class="text-primary mt-0.5">✓</span>
|
|
15
15
|
<span>{item}</span>
|