@farbenmeer/bunny 0.1.0

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/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @farbenmeer/bunny
2
+
3
+ This is a web framework based on [Bun](https://bun.sh/) and [Tapi](https://www.npmjs.com/package/@farbenmeer/tapi).
4
+
5
+ ## Start a project
6
+
7
+ To scaffold a new project run:
8
+ ```bash
9
+ bunx @farbenmeer/bunny init
10
+ ```
11
+
12
+ Then run `bun run migrate` to create the database schema. Bunny uses sqlite as the default database.
13
+
14
+ ## Other commands
15
+ * `bun run dev` to start the development server
16
+ * `bun run build` to build the project for production
17
+ * `bun run start` to start the production server
18
+ * `bun run generate` to generate a migration file based on the drizzle schema in `src/lib/schema.ts`
19
+ * `bun run migrate` to apply migrations to the database
20
+
21
+ ## Project Structure
22
+
23
+ The main entry points to the project are
24
+ * `src/index.html` for the client side application. Set up static tags for the favicon and the site title and optionally add some loading UI while the react bundle is being loaded.
25
+ * `src/index.tsx` as the react-entrypoint. This sets up the react application and renders it into the DOM. If you add a loading UI to index.html this is the place to remove it before rendering the react application. It imports the `App` component that contains the main frontend logic.
26
+ * `src/main.css` for global styles (mainly tailwindcss-setup)
27
+ * `src/api.ts` for the API entrypoint (using Tapi's `defineApi`). See [Tapi's documentation](https://www.npmjs.com/package/@farbenmeer/tapi) for more information.
28
+ * `src/auth.ts` for defining authentication providers using [bun-auth](https://www.npmjs.com/package/@farbenmeer/bun-auth)
Binary file
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const build: Command;
3
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,KAAK,SAwBd,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { Command } from "commander";
2
+ import { mkdir, rmdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { generateServer } from "./server";
5
+ import tailwindPlugin from "./tailwind-plugin";
6
+ export const build = new Command()
7
+ .name("build")
8
+ .option("--sourcemap", "Generate sourcemaps", false)
9
+ .description("Bunny Development server")
10
+ .action(async (options) => {
11
+ const distDir = path.join(process.cwd(), ".bunny", "dist");
12
+ await rmdir(distDir, { recursive: true });
13
+ await mkdir(distDir, { recursive: true });
14
+ const serverFile = await generateServer();
15
+ await Bun.build({
16
+ entrypoints: [serverFile],
17
+ outdir: distDir,
18
+ target: "bun",
19
+ format: "esm",
20
+ minify: true,
21
+ naming: {
22
+ entry: "[name].[ext]",
23
+ asset: "__bunny/assets/[name]-[hash].[ext]",
24
+ chunk: "__bunny/chunks/[name]-[hash].[ext]",
25
+ },
26
+ sourcemap: options.sourcemap,
27
+ env: "BUNNY_PUBLIC_*",
28
+ plugins: [tailwindPlugin],
29
+ });
30
+ });
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import "./tailwind-plugin";
3
+ export declare const dev: Command;
4
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,mBAAmB,CAAC;AAE3B,eAAO,MAAM,GAAG,SASZ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Command } from "commander";
2
+ import { mkdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { generateServer } from "./server";
5
+ import "./tailwind-plugin";
6
+ export const dev = new Command()
7
+ .name("dev")
8
+ .description("Bunny Development server")
9
+ .action(async () => {
10
+ const bunnyDir = path.join(process.cwd(), ".bunny");
11
+ await mkdir(bunnyDir, { recursive: true });
12
+ const serverFile = await generateServer();
13
+ process.env.NODE_ENV = "development";
14
+ await import(serverFile);
15
+ });
@@ -0,0 +1,2 @@
1
+ export declare const serverCode = "\nimport { serve } from \"bun\";\nimport { createRequestHandler } from \"@farbenmeer/bunny\";\nimport { api } from \"api\";\nimport client from \"index.html\";\n\nconst tapiHandler = createRequestHandler(api);\n\n\nserve({\n routes: {\n \"/api/*\": (req) => tapiHandler(new Request(req)),\n \"/*\": client,\n },\n port: 3000,\n development: process.env.NODE_ENV === \"development\" && {\n // Enable browser hot reloading in development\n hmr: true,\n\n // Echo console logs from the browser to the server\n console: true,\n },\n});\n";
2
+ //# sourceMappingURL=generate-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-server.d.ts","sourceRoot":"","sources":["../../src/cli/generate-server.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,ijBAuBtB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import * as path from "node:path";
2
+ export const serverCode = `
3
+ import { serve } from "bun";
4
+ import { createRequestHandler } from "@farbenmeer/bunny";
5
+ import { api } from "api";
6
+ import client from "index.html";
7
+
8
+ const tapiHandler = createRequestHandler(api);
9
+
10
+
11
+ serve({
12
+ routes: {
13
+ "/api/*": (req) => tapiHandler(new Request(req)),
14
+ "/*": client,
15
+ },
16
+ port: 3000,
17
+ development: process.env.NODE_ENV === "development" && {
18
+ // Enable browser hot reloading in development
19
+ hmr: true,
20
+
21
+ // Echo console logs from the browser to the server
22
+ console: true,
23
+ },
24
+ });
25
+ `;
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const init: Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,IAAI,SAoCb,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { Command } from "commander";
2
+ import { exists, mkdir, readdir } from "node:fs/promises";
3
+ import { $ } from "bun";
4
+ import path from "node:path";
5
+ export const init = new Command()
6
+ .name("init")
7
+ .description("Initialize a new project")
8
+ .argument("[name]", "Name of the project")
9
+ .action(async (name) => {
10
+ console.info("Initializing project...");
11
+ if (name) {
12
+ const dirPath = path.join(process.cwd(), name);
13
+ if (await exists(dirPath)) {
14
+ if ((await readdir(dirPath, { recursive: true })).length > 0) {
15
+ console.error(`Directory ${name} already exists and contains files.`);
16
+ process.exit(1);
17
+ }
18
+ }
19
+ else {
20
+ await mkdir(dirPath, { recursive: true });
21
+ }
22
+ process.chdir(dirPath);
23
+ }
24
+ else {
25
+ const pkgPath = path.join(process.cwd(), "package.json");
26
+ if (await Bun.file(pkgPath).exists()) {
27
+ console.error(`Package.json already exists.`);
28
+ process.exit(1);
29
+ }
30
+ }
31
+ const tarBall = path.join(path.dirname(path.dirname(__dirname)), "boilerplate.tar.gz");
32
+ // Extract the tarball to the current directory
33
+ await $ `tar -xzf ${tarBall} --strip-components=1`;
34
+ await $ `bun pm pkg set name=${name ?? path.basename(process.cwd())}`;
35
+ console.log("Project initialized successfully!");
36
+ });
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import "./tailwind-plugin";
3
+ export declare const migrate: Command;
4
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,mBAAmB,CAAC;AAE3B,eAAO,MAAM,OAAO,SAShB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { Command } from "commander";
2
+ import * as migrator from "drizzle-orm/bun-sqlite/migrator";
3
+ import path from "node:path";
4
+ import "./tailwind-plugin";
5
+ export const migrate = new Command()
6
+ .name("migrate")
7
+ .description("Apply Database Migrations")
8
+ .action(async () => {
9
+ const dbPath = path.join(process.cwd(), "src", "lib", "db");
10
+ const { db } = await import(dbPath);
11
+ migrator.migrate(db, {
12
+ migrationsFolder: path.join(process.cwd(), "drizzle"),
13
+ });
14
+ });
@@ -0,0 +1,3 @@
1
+ import type { BunPlugin } from "bun";
2
+ export declare const tailwindPlugin: BunPlugin;
3
+ //# sourceMappingURL=register-tailwind-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-tailwind-plugin.d.ts","sourceRoot":"","sources":["../../src/cli/register-tailwind-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAKrC,eAAO,MAAM,cAAc,EAAE,SAe5B,CAAC"}
@@ -0,0 +1,19 @@
1
+ //import postcss from "postcss";
2
+ //const processCss = postcss([postcssTailwind({})]);
3
+ export const tailwindPlugin = {
4
+ name: "Tailwind CSS",
5
+ target: "bun",
6
+ setup(build) {
7
+ //build.onLoad({ filter: /\.(css)$/ }, async ({ path }) => {
8
+ // console.log("process", path);
9
+ // const contents = await Bun.file(path).text();
10
+ // const result = await processCss.process(contents, { from: path });
11
+ // return { contents: result.css, loader: "css" };
12
+ //});
13
+ build.onLoad({ filter: /^$/ }, async ({ path }) => {
14
+ console.log("load", path);
15
+ });
16
+ },
17
+ };
18
+ console.log("register plugin");
19
+ Bun.plugin(tailwindPlugin);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server-direct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-direct.d.ts","sourceRoot":"","sources":["../../src/cli/server-direct.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import { serve } from "bun";
2
+ import { createRequestHandler } from "@farbenmeer/tapi";
3
+ // @ts-ignore
4
+ import { api } from "api";
5
+ import client from "index.html";
6
+ const tapiHandler = createRequestHandler(api);
7
+ serve({
8
+ routes: {
9
+ "/api/*": (req) => tapiHandler(new Request(req)),
10
+ "/*": client,
11
+ },
12
+ port: 3000,
13
+ development: process.env.NODE_ENV === "development" && {
14
+ // Enable browser hot reloading in development
15
+ hmr: true,
16
+ // Echo console logs from the browser to the server
17
+ console: true,
18
+ },
19
+ });
@@ -0,0 +1,2 @@
1
+ export declare function generateServer(): Promise<string>;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/cli/server.ts"],"names":[],"mappings":"AAEA,wBAAsB,cAAc,oBAqDnC"}
@@ -0,0 +1,39 @@
1
+ import * as path from "node:path";
2
+ export async function generateServer() {
3
+ const serverFile = path.join(process.cwd(), ".bunny", "server.ts");
4
+ const hasAuth = await Bun.file(path.join(process.cwd(), "src", "auth.ts")).exists();
5
+ const hasApi = await Bun.file(path.join(process.cwd(), "src", "api.ts")).exists();
6
+ await Bun.write(serverFile, `
7
+ import { serve } from "bun";
8
+ ${hasApi
9
+ ? 'import { api } from "api"; import { createRequestHandler } from "@farbenmeer/bunny";'
10
+ : ""}
11
+ ${hasAuth
12
+ ? 'import { auth } from "auth"; import { createAuthRoute } from "@farbenmeer/bun-auth";'
13
+ : ""}
14
+ import client from "index.html";
15
+
16
+ ${hasApi
17
+ ? 'const tapiHandler = createRequestHandler(api, { basePath: "/api" });'
18
+ : ""}
19
+
20
+ const server = serve({
21
+ routes: {
22
+ ${hasAuth ? '"/api/auth/*": createAuthRoute(auth),' : ""}
23
+ ${hasApi ? '"/api/*": (req) => tapiHandler(new Request(req)),' : ""}
24
+ "/*": client,
25
+ },
26
+ port: 3000,
27
+ development: process.env.NODE_ENV === "development" && {
28
+ // Enable browser hot reloading in development
29
+ hmr: true,
30
+
31
+ // Echo console logs from the browser to the server
32
+ console: true,
33
+ },
34
+ });
35
+
36
+ console.log(\`🚀 Server running at \${server.url}\`);
37
+ `);
38
+ return serverFile;
39
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const start: Command;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,KAAK,SAQd,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Command } from "commander";
2
+ import path from "node:path";
3
+ export const start = new Command()
4
+ .name("start")
5
+ .description("Bunny Production server")
6
+ .action(async () => {
7
+ const distDir = path.join(process.cwd(), ".bunny", "dist");
8
+ process.env.NODE_ENV = "production";
9
+ process.chdir(distDir);
10
+ await import(path.join(distDir, "server.js"));
11
+ });
@@ -0,0 +1,4 @@
1
+ import type { BunPlugin } from "bun";
2
+ declare const tailwindPlugin: BunPlugin;
3
+ export default tailwindPlugin;
4
+ //# sourceMappingURL=tailwind-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind-plugin.d.ts","sourceRoot":"","sources":["../../src/cli/tailwind-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAKrC,QAAA,MAAM,cAAc,EAAE,SAUrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,15 @@
1
+ import postcssTailwind from "@tailwindcss/postcss";
2
+ import postcss from "postcss";
3
+ const processCss = postcss([postcssTailwind({})]);
4
+ const tailwindPlugin = {
5
+ name: "Tailwind CSS",
6
+ setup(build) {
7
+ build.onLoad({ filter: /\.(css)$/ }, async ({ path }) => {
8
+ console.log("process", path);
9
+ const contents = await Bun.file(path).text();
10
+ const result = await processCss.process(contents, { from: path });
11
+ return { contents: result.css, loader: "css" };
12
+ });
13
+ },
14
+ };
15
+ export default tailwindPlugin;
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from "commander";
3
+ import { init } from "./cli/init";
4
+ import { dev } from "./cli/dev";
5
+ import { build } from "./cli/build";
6
+ import { start } from "./cli/start";
7
+ import { migrate } from "./cli/migrate";
8
+ const program = new Command();
9
+ program
10
+ .name("bunny")
11
+ .description("CLI for the Bunny Web-Framework")
12
+ .version("0.1.0")
13
+ .addCommand(init)
14
+ .addCommand(dev)
15
+ .addCommand(build)
16
+ .addCommand(start)
17
+ .addCommand(migrate);
18
+ await program.parseAsync(process.argv);
@@ -0,0 +1,3 @@
1
+ export * from "@farbenmeer/tapi";
2
+ export * from "@farbenmeer/react-tapi";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "@farbenmeer/tapi";
2
+ export * from "@farbenmeer/react-tapi";
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@farbenmeer/bunny",
3
+ "version": "0.1.0",
4
+ "author": {
5
+ "name": "Michel Smola",
6
+ "email": "michel.smola@farbenmeer.de"
7
+ },
8
+ "type": "module",
9
+ "module": "dist/index.js",
10
+ "main": "dist/index.js",
11
+ "private": false,
12
+ "license": "MIT",
13
+ "files": [
14
+ "dist",
15
+ "boilerplate.tar.gz"
16
+ ],
17
+ "bin": {
18
+ "bunny": "./dist/cli.js",
19
+ "@farbenmeer/bunny": "./dist/cli.js"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc --noEmit false",
23
+ "pack:boilerplate": "bun --cwd=\"../4-bunny-boilerplate\" pm pack --filename=\"packages/3-bunny/boilerplate.tar.gz\"",
24
+ "cli": "bun src/cli.ts",
25
+ "release": "bun run build && bun run pack:boilerplate && bun publish"
26
+ },
27
+ "dependencies": {
28
+ "@farbenmeer/react-tapi": "^0.1.5",
29
+ "@farbenmeer/tapi": "^0.1.7",
30
+ "@tailwindcss/postcss": "^4.1.12",
31
+ "commander": "^14.0.0",
32
+ "postcss": "^8.5.6"
33
+ },
34
+ "devDependencies": {
35
+ "@types/bun": "latest"
36
+ },
37
+ "peerDependencies": {
38
+ "typescript": "^5"
39
+ }
40
+ }