@gigamusic/admin 0.3.0 → 2.0.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 CHANGED
@@ -1,18 +1,36 @@
1
1
  # @gigamusic/admin
2
2
 
3
- Source-shipped React admin for the gigamusic platform: releases CRUD,
4
- settings, links, link-pages, and orders view — plus per-route handler
5
- factories the consumer wires into `/api/admin/*`.
3
+ Server-only admin API handler factories for the gigamusic platform: releases CRUD, track uploads, settings, links, and orders. **Auth is the consumer's responsibility** — these handlers trust that the request has been gated upstream (typically via the consumer's `proxy.ts` or middleware).
6
4
 
7
5
  ```ts
8
- // app/admin/page.tsx (consumer)
9
- export { AdminHomePage as default } from "@gigamusic/admin";
6
+ // app/api/admin/releases/route.ts (consumer)
7
+ import { createAdminReleasesHandlers } from "@gigamusic/admin/server";
8
+ import { queries, storage, audio } from "@/lib/server";
10
9
 
11
- // app/api/admin/auth/route.ts (consumer)
12
- import { createAdminLoginHandler } from "@gigamusic/admin/server";
13
- export const POST = createAdminLoginHandler({ adminPasswordHash, adminSessionSecret });
10
+ const handlers = createAdminReleasesHandlers({ queries, storage, audio });
11
+ export const GET = handlers.GET;
12
+ export const POST = handlers.POST;
14
13
  ```
15
14
 
16
- Every page is auth-gated by the shared admin session cookie. Override a slot
17
- via the standard `<GigamusicProvider components={{ Button: MyButton }}>` from
18
- `@gigamusic/ui`, or replace a page wholesale by simply not mounting it.
15
+ Each factory takes a slice of `AdminDeps`:
16
+
17
+ ```ts
18
+ import type { AdminDeps } from "@gigamusic/admin/server";
19
+
20
+ const deps: AdminDeps = {
21
+ queries, // from createQueries(prisma)
22
+ storage, // from createR2Provider(...)
23
+ audio, // import * as audio from "@gigamusic/audio"
24
+ logger, // optional — defaults to no-op
25
+ };
26
+ ```
27
+
28
+ Available factories:
29
+
30
+ - `createAdminReleasesHandlers`, `createAdminReleaseByIdHandlers`
31
+ - `createAdminUploadPresignHandler`, `createAdminUploadProcessHandler`
32
+ - `createAdminSettingsHandlers`
33
+ - `createAdminLinksHandlers`
34
+ - `createAdminOrdersHandler`
35
+
36
+ The admin UI is the consumer's responsibility — write whatever pages you want and wire them to these handlers.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gigamusic/admin",
3
- "version": "0.3.0",
4
- "description": "Admin UI (releases CRUD, tracks, settings, links, link-pages, orders) and admin API handler factories for the gigamusic platform. Fully replaceable by the consumer mount the pages directly or override individual slots.",
3
+ "version": "2.0.0",
4
+ "description": "Server-only admin API handler factories for the gigamusic platform (releases CRUD, tracks, uploads, settings, links, orders).",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -9,17 +9,7 @@
9
9
  "directory": "packages/admin"
10
10
  },
11
11
  "type": "module",
12
- "main": "./src/index.ts",
13
- "types": "./src/index.ts",
14
12
  "exports": {
15
- ".": {
16
- "types": "./src/index.ts",
17
- "default": "./src/index.ts"
18
- },
19
- "./client": {
20
- "types": "./src/client.ts",
21
- "default": "./src/client.ts"
22
- },
23
13
  "./server": {
24
14
  "types": "./src/server.ts",
25
15
  "default": "./src/server.ts"
@@ -34,29 +24,13 @@
34
24
  },
35
25
  "dependencies": {
36
26
  "zod": "^3.24.1",
37
- "@gigamusic/audio": "0.3.0",
38
- "@gigamusic/config": "0.3.0",
39
- "@gigamusic/email": "0.3.0",
40
- "@gigamusic/core": "0.3.0",
41
- "@gigamusic/storage": "0.3.0",
42
- "@gigamusic/ui": "0.3.0",
43
- "@gigamusic/db": "0.3.0"
44
- },
45
- "peerDependencies": {
46
- "next": ">=15",
47
- "react": ">=18 <20",
48
- "react-dom": ">=18 <20"
27
+ "@gigamusic/audio": "1.0.0",
28
+ "@gigamusic/core": "1.0.0",
29
+ "@gigamusic/db": "2.0.0",
30
+ "@gigamusic/storage": "1.0.0"
49
31
  },
50
32
  "devDependencies": {
51
- "@testing-library/dom": "^10.4.0",
52
- "@testing-library/react": "^16.1.0",
53
33
  "@types/node": "^22.10.5",
54
- "@types/react": "^19.0.0",
55
- "@types/react-dom": "^19.0.0",
56
- "jsdom": "^25.0.1",
57
- "next": "^16.0.0",
58
- "react": "^19.0.0",
59
- "react-dom": "^19.0.0",
60
34
  "typescript": "^5.7.3",
61
35
  "vitest": "^2.1.8"
62
36
  },
package/src/lib/types.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { Queries } from "@gigamusic/db";
2
2
  import type { StorageProvider } from "@gigamusic/storage";
3
3
  import type * as Audio from "@gigamusic/audio";
4
- import type { EmailBranding } from "@gigamusic/email";
5
4
 
6
5
  /**
7
6
  * The Next.js App Router route-handler signature. Defined locally so the admin
@@ -27,7 +26,6 @@ export interface AdminDeps {
27
26
  queries: Queries;
28
27
  storage: StorageProvider;
29
28
  audio: typeof Audio;
30
- branding: EmailBranding;
31
29
  /**
32
30
  * Optional logger. Defaults to a no-op so the package never writes to
33
31
  * console on the consumer's behalf.
package/src/client.ts DELETED
@@ -1,16 +0,0 @@
1
- "use client";
2
-
3
- // Client-only re-exports — every consumer-side page component lives here so
4
- // importing them from a server-component context never accidentally pulls in
5
- // server-only modules.
6
-
7
- export { AdminHomePage } from "./pages/AdminHomePage";
8
- export { AdminReleasesPage } from "./pages/AdminReleasesPage";
9
- export { AdminNewReleasePage } from "./pages/AdminNewReleasePage";
10
- export { AdminEditReleasePage } from "./pages/AdminEditReleasePage";
11
- export { AdminLinksPage } from "./pages/AdminLinksPage";
12
- export { AdminSettingsPage } from "./pages/AdminSettingsPage";
13
- export { AdminOrdersPage } from "./pages/AdminOrdersPage";
14
- export { ReleaseForm } from "./components/ReleaseForm";
15
- export type { ReleaseFormProps } from "./components/ReleaseForm";
16
- export { AdminNav } from "./components/AdminNav";
@@ -1,50 +0,0 @@
1
- "use client";
2
-
3
- import Link from "next/link";
4
- import { usePathname } from "next/navigation";
5
-
6
- interface NavLink {
7
- href: string;
8
- label: string;
9
- exact?: boolean;
10
- }
11
-
12
- const DEFAULT_LINKS: NavLink[] = [
13
- { href: "/admin", label: "Releases", exact: true },
14
- { href: "/admin/orders", label: "Orders" },
15
- { href: "/admin/links", label: "Links" },
16
- { href: "/admin/settings", label: "Settings" },
17
- ];
18
-
19
- /**
20
- * Horizontal admin nav. Consumers can extend the link set by overriding the
21
- * `Navigation` slot if they need additional sections; the default set covers
22
- * everything this package ships.
23
- */
24
- export function AdminNav({ extraLinks }: { extraLinks?: NavLink[] }) {
25
- const pathname = usePathname();
26
- const links = [...DEFAULT_LINKS, ...(extraLinks ?? [])];
27
-
28
- return (
29
- <nav className="gm-admin-nav flex items-center gap-4 overflow-x-auto border-b border-border pb-4 mb-6">
30
- {links.map(({ href, label, exact }) => {
31
- const active = exact
32
- ? pathname === href
33
- : pathname === href || pathname.startsWith(`${href}/`);
34
- return (
35
- <Link
36
- key={href}
37
- href={href}
38
- className={
39
- active
40
- ? "text-sm font-semibold whitespace-nowrap"
41
- : "text-sm text-muted-foreground hover:underline whitespace-nowrap"
42
- }
43
- >
44
- {label}
45
- </Link>
46
- );
47
- })}
48
- </nav>
49
- );
50
- }