···11+# boombox
22+33+To install dependencies:
44+55+```bash
66+bun install
77+```
88+99+To run:
1010+1111+```bash
1212+bun run src/index.ts
1313+```
1414+1515+This project was created using `bun init` in bun v1.2.2. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
···11+CREATE TABLE `album` (
22+ `id` text PRIMARY KEY NOT NULL,
33+ `title` text NOT NULL
44+);
55+--> statement-breakpoint
66+CREATE TABLE `artist` (
77+ `id` text PRIMARY KEY NOT NULL,
88+ `name` text NOT NULL
99+);
1010+--> statement-breakpoint
1111+CREATE TABLE `artist_to_album` (
1212+ `artistId` text NOT NULL,
1313+ `albumId` text NOT NULL,
1414+ FOREIGN KEY (`artistId`) REFERENCES `artist`(`id`) ON UPDATE no action ON DELETE no action,
1515+ FOREIGN KEY (`albumId`) REFERENCES `album`(`id`) ON UPDATE no action ON DELETE no action
1616+);
1717+--> statement-breakpoint
1818+CREATE UNIQUE INDEX `artist_to_album_artistId_albumId_unique` ON `artist_to_album` (`artistId`,`albumId`);--> statement-breakpoint
1919+CREATE TABLE `file` (
2020+ `id` text PRIMARY KEY NOT NULL,
2121+ `path` text NOT NULL
2222+);
2323+--> statement-breakpoint
2424+CREATE TABLE `song` (
2525+ `id` text PRIMARY KEY NOT NULL,
2626+ `title` text NOT NULL,
2727+ `fileId` text,
2828+ FOREIGN KEY (`fileId`) REFERENCES `file`(`id`) ON UPDATE no action ON DELETE no action
2929+);
3030+--> statement-breakpoint
3131+CREATE TABLE `song_to_album` (
3232+ `songId` text NOT NULL,
3333+ `albumId` text NOT NULL,
3434+ FOREIGN KEY (`songId`) REFERENCES `song`(`id`) ON UPDATE no action ON DELETE no action,
3535+ FOREIGN KEY (`albumId`) REFERENCES `album`(`id`) ON UPDATE no action ON DELETE no action
3636+);
3737+--> statement-breakpoint
3838+CREATE UNIQUE INDEX `song_to_album_songId_albumId_unique` ON `song_to_album` (`songId`,`albumId`);--> statement-breakpoint
3939+CREATE TABLE `song_to_artist` (
4040+ `songId` text NOT NULL,
4141+ `artistId` text NOT NULL,
4242+ FOREIGN KEY (`songId`) REFERENCES `song`(`id`) ON UPDATE no action ON DELETE no action,
4343+ FOREIGN KEY (`artistId`) REFERENCES `artist`(`id`) ON UPDATE no action ON DELETE no action
4444+);
4545+--> statement-breakpoint
4646+CREATE UNIQUE INDEX `song_to_artist_songId_artistId_unique` ON `song_to_artist` (`songId`,`artistId`);
+2
backend/drizzle/0001_careful_valeria_richards.sql
···11+CREATE UNIQUE INDEX `album_title_unique` ON `album` (`title`);--> statement-breakpoint
22+CREATE UNIQUE INDEX `artist_name_unique` ON `artist` (`name`);
+1
backend/drizzle/0002_curvy_dormammu.sql
···11+CREATE UNIQUE INDEX `song_fileId_unique` ON `song` (`fileId`);
+1
backend/drizzle/0003_unique_cable.sql
···11+CREATE UNIQUE INDEX `file_path_unique` ON `file` (`path`);
+46
backend/drizzle/0004_thankful_meggan.sql
···11+PRAGMA foreign_keys=OFF;--> statement-breakpoint
22+CREATE TABLE `__new_artist_to_album` (
33+ `artistId` text NOT NULL,
44+ `albumId` text NOT NULL,
55+ FOREIGN KEY (`artistId`) REFERENCES `artist`(`id`) ON UPDATE no action ON DELETE cascade,
66+ FOREIGN KEY (`albumId`) REFERENCES `album`(`id`) ON UPDATE no action ON DELETE cascade
77+);
88+--> statement-breakpoint
99+INSERT INTO `__new_artist_to_album`("artistId", "albumId") SELECT "artistId", "albumId" FROM `artist_to_album`;--> statement-breakpoint
1010+DROP TABLE `artist_to_album`;--> statement-breakpoint
1111+ALTER TABLE `__new_artist_to_album` RENAME TO `artist_to_album`;--> statement-breakpoint
1212+PRAGMA foreign_keys=ON;--> statement-breakpoint
1313+CREATE UNIQUE INDEX `artist_to_album_artistId_albumId_unique` ON `artist_to_album` (`artistId`,`albumId`);--> statement-breakpoint
1414+CREATE TABLE `__new_song` (
1515+ `id` text PRIMARY KEY NOT NULL,
1616+ `title` text NOT NULL,
1717+ `fileId` text NOT NULL,
1818+ FOREIGN KEY (`fileId`) REFERENCES `file`(`id`) ON UPDATE no action ON DELETE cascade
1919+);
2020+--> statement-breakpoint
2121+INSERT INTO `__new_song`("id", "title", "fileId") SELECT "id", "title", "fileId" FROM `song`;--> statement-breakpoint
2222+DROP TABLE `song`;--> statement-breakpoint
2323+ALTER TABLE `__new_song` RENAME TO `song`;--> statement-breakpoint
2424+CREATE UNIQUE INDEX `song_fileId_unique` ON `song` (`fileId`);--> statement-breakpoint
2525+CREATE TABLE `__new_song_to_album` (
2626+ `songId` text NOT NULL,
2727+ `albumId` text NOT NULL,
2828+ FOREIGN KEY (`songId`) REFERENCES `song`(`id`) ON UPDATE no action ON DELETE cascade,
2929+ FOREIGN KEY (`albumId`) REFERENCES `album`(`id`) ON UPDATE no action ON DELETE cascade
3030+);
3131+--> statement-breakpoint
3232+INSERT INTO `__new_song_to_album`("songId", "albumId") SELECT "songId", "albumId" FROM `song_to_album`;--> statement-breakpoint
3333+DROP TABLE `song_to_album`;--> statement-breakpoint
3434+ALTER TABLE `__new_song_to_album` RENAME TO `song_to_album`;--> statement-breakpoint
3535+CREATE UNIQUE INDEX `song_to_album_songId_albumId_unique` ON `song_to_album` (`songId`,`albumId`);--> statement-breakpoint
3636+CREATE TABLE `__new_song_to_artist` (
3737+ `songId` text NOT NULL,
3838+ `artistId` text NOT NULL,
3939+ FOREIGN KEY (`songId`) REFERENCES `song`(`id`) ON UPDATE no action ON DELETE cascade,
4040+ FOREIGN KEY (`artistId`) REFERENCES `artist`(`id`) ON UPDATE no action ON DELETE cascade
4141+);
4242+--> statement-breakpoint
4343+INSERT INTO `__new_song_to_artist`("songId", "artistId") SELECT "songId", "artistId" FROM `song_to_artist`;--> statement-breakpoint
4444+DROP TABLE `song_to_artist`;--> statement-breakpoint
4545+ALTER TABLE `__new_song_to_artist` RENAME TO `song_to_artist`;--> statement-breakpoint
4646+CREATE UNIQUE INDEX `song_to_artist_songId_artistId_unique` ON `song_to_artist` (`songId`,`artistId`);
+2
backend/drizzle/0005_ambiguous_stryfe.sql
···11+DROP TABLE `song_to_album`;--> statement-breakpoint
22+ALTER TABLE `song` ADD `albumId` text NOT NULL REFERENCES album(id);
···11+---
22+description: Use Bun instead of Node.js, npm, pnpm, or vite.
33+globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
44+alwaysApply: false
55+---
66+77+Default to using Bun instead of Node.js.
88+99+- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
1010+- Use `bun test` instead of `jest` or `vitest`
1111+- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
1212+- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
1313+- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
1414+- Bun automatically loads .env, so don't use dotenv.
1515+1616+## APIs
1717+1818+- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
1919+- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
2020+- `Bun.redis` for Redis. Don't use `ioredis`.
2121+- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
2222+- `WebSocket` is built-in. Don't use `ws`.
2323+- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
2424+- Bun.$`ls` instead of execa.
2525+2626+## Testing
2727+2828+Use `bun test` to run tests.
2929+3030+```ts#index.test.ts
3131+import { test, expect } from "bun:test";
3232+3333+test("hello world", () => {
3434+ expect(1).toBe(1);
3535+});
3636+```
3737+3838+## Frontend
3939+4040+Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
4141+4242+Server:
4343+4444+```ts#index.ts
4545+import index from "./index.html"
4646+4747+Bun.serve({
4848+ routes: {
4949+ "/": index,
5050+ "/api/users/:id": {
5151+ GET: (req) => {
5252+ return new Response(JSON.stringify({ id: req.params.id }));
5353+ },
5454+ },
5555+ },
5656+ // optional websocket support
5757+ websocket: {
5858+ open: (ws) => {
5959+ ws.send("Hello, world!");
6060+ },
6161+ message: (ws, message) => {
6262+ ws.send(message);
6363+ },
6464+ close: (ws) => {
6565+ // handle close
6666+ }
6767+ },
6868+ development: {
6969+ hmr: true,
7070+ console: true,
7171+ }
7272+})
7373+```
7474+7575+HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
7676+7777+```html#index.html
7878+<html>
7979+ <body>
8080+ <h1>Hello, world!</h1>
8181+ <script type="module" src="./frontend.tsx"></script>
8282+ </body>
8383+</html>
8484+```
8585+8686+With the following `frontend.tsx`:
8787+8888+```tsx#frontend.tsx
8989+import React from "react";
9090+9191+// import .css files directly and it works
9292+import './index.css';
9393+9494+import { createRoot } from "react-dom/client";
9595+9696+const root = createRoot(document.body);
9797+9898+export default function Frontend() {
9999+ return <h1>Hello, world!</h1>;
100100+}
101101+102102+root.render(<Frontend />);
103103+```
104104+105105+Then, run index.ts
106106+107107+```sh
108108+bun --hot ./index.ts
109109+```
110110+111111+For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
···11+# shared
22+33+To install dependencies:
44+55+```bash
66+bun install
77+```
88+99+To run:
1010+1111+```bash
1212+bun run index.ts
1313+```
1414+1515+This project was created using `bun init` in bun v1.2.19. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.