@cortejojicoy/admin-kit 0.1.8
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/LICENSE +21 -0
- package/README.md +347 -0
- package/dist/client.cjs +950 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +334 -0
- package/dist/client.d.ts +334 -0
- package/dist/client.js +900 -0
- package/dist/client.js.map +1 -0
- package/dist/index.cjs +47 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.cjs +117 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.cts +28 -0
- package/dist/middleware.d.ts +28 -0
- package/dist/middleware.js +115 -0
- package/dist/middleware.js.map +1 -0
- package/dist/server.cjs +128 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +56 -0
- package/dist/server.d.ts +56 -0
- package/dist/server.js +122 -0
- package/dist/server.js.map +1 -0
- package/dist/types-N0f4k4Ie.d.cts +210 -0
- package/dist/types-N0f4k4Ie.d.ts +210 -0
- package/package.json +106 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/defaults.ts","../src/auth/providers/JWTProvider.tsx","../src/auth/providers/OAuthProvider.tsx","../src/auth/providers/CustomProvider.tsx","../src/auth/AuthContext.tsx","../src/modules/registry.ts","../src/modules/ModuleContext.tsx","../src/theme/tokens.ts","../src/theme/ThemeProvider.tsx","../src/auth/useAuth.ts","../src/AdminProvider.tsx","../src/utils/cn.ts","../src/auth/components/LoginPage.tsx","../src/adapters/appRoute.ts","../src/auth/guards/AppRouterGuard.tsx","../src/adapters/pagesRoute.ts","../src/auth/guards/PagesRouterGuard.tsx","../src/navigation/SidebarContext.tsx","../src/navigation/useSidebar.ts","../src/navigation/SidebarItem.tsx","../src/navigation/SidebarSection.tsx","../src/navigation/Sidebar.tsx","../src/navigation/buildNav.ts","../src/navigation/filterNav.ts","../src/modules/useModules.ts","../src/components/layout/Topbar.tsx","../src/components/layout/AdminLayout.tsx","../src/components/layout/PageContainer.tsx","../src/components/dashboard/StatCard.tsx","../src/components/dashboard/ChartCard.tsx","../src/components/dashboard/ActivityFeed.tsx","../src/utils/withAdminLayout.tsx","../src/theme/useTheme.ts"],"names":["createContext","useMemo","useState","useEffect","useNextRouter","useNextPathname","useNextSearchParams","NextLink","useCallback","useContext"],"mappings":"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","file":"client.js","sourcesContent":["import type { ResolvedAdminConfig, AdminConfig } from './types'\n\nexport const DEFAULT_LOGIN_PATH = '/login'\nexport const DEFAULT_AFTER_LOGIN = '/'\nexport const DEFAULT_AFTER_LOGOUT = '/login'\nexport const DEFAULT_PUBLIC_ROUTES = ['/login', '/api/auth']\n\nexport function resolveConfig(config: AdminConfig): ResolvedAdminConfig {\n return {\n ...config,\n router: config.router ?? 'app',\n auth: {\n ...config.auth,\n loginPage: {\n path: DEFAULT_LOGIN_PATH,\n title: `Sign in to ${config.app.name}`,\n ...config.auth.loginPage,\n },\n afterLoginRedirect: config.auth.afterLoginRedirect ?? DEFAULT_AFTER_LOGIN,\n afterLogoutRedirect: config.auth.afterLogoutRedirect ?? DEFAULT_AFTER_LOGOUT,\n publicRoutes: config.auth.publicRoutes ?? DEFAULT_PUBLIC_ROUTES,\n },\n layout: {\n sidebarPosition: 'left',\n sidebarCollapsible: true,\n sidebarDefaultCollapsed: false,\n ...config.layout,\n },\n theme: {\n mode: 'system',\n ...config.theme,\n },\n } as ResolvedAdminConfig\n}\n","import type { AuthProvider, AuthSession, AuthUser, JWTAuthConfig } from '../types'\n\nconst DEFAULT_COOKIE = 'admin_kit_token'\nconst DEFAULT_HEADER = { name: 'Authorization', prefix: 'Bearer ' }\n\nfunction readToken(cfg: JWTAuthConfig): string | null {\n if (typeof window === 'undefined') return null\n const storage = cfg.tokenStorage ?? 'cookie'\n const cookieName = cfg.cookieName ?? DEFAULT_COOKIE\n if (storage === 'localStorage') return window.localStorage.getItem(cookieName)\n if (storage === 'memory') return memoryToken\n const match = document.cookie.match(new RegExp('(?:^|; )' + cookieName + '=([^;]*)'))\n return match ? decodeURIComponent(match[1]) : null\n}\n\nlet memoryToken: string | null = null\n\nfunction writeToken(cfg: JWTAuthConfig, token: string | null) {\n if (typeof window === 'undefined') return\n const storage = cfg.tokenStorage ?? 'cookie'\n const cookieName = cfg.cookieName ?? DEFAULT_COOKIE\n if (storage === 'localStorage') {\n if (token) window.localStorage.setItem(cookieName, token)\n else window.localStorage.removeItem(cookieName)\n return\n }\n if (storage === 'memory') {\n memoryToken = token\n return\n }\n if (token) {\n document.cookie = `${cookieName}=${encodeURIComponent(token)}; path=/; SameSite=Lax`\n } else {\n document.cookie = `${cookieName}=; path=/; Max-Age=0; SameSite=Lax`\n }\n}\n\nfunction authHeader(cfg: JWTAuthConfig, token: string | null): Record<string, string> {\n if (!token) return {}\n const h = cfg.header ?? DEFAULT_HEADER\n return { [h.name]: `${h.prefix ?? ''}${token}` }\n}\n\nexport function createJWTProvider(cfg: JWTAuthConfig): AuthProvider {\n const mapUser = cfg.mapUser ?? ((raw: unknown) => raw as AuthUser)\n const mapTokens =\n cfg.mapTokens ??\n ((raw: unknown) => {\n const r = raw as { accessToken?: string; token?: string; refreshToken?: string; expiresAt?: number }\n return {\n accessToken: r.accessToken ?? r.token,\n refreshToken: r.refreshToken,\n expiresAt: r.expiresAt,\n }\n })\n\n async function getSession(): Promise<AuthSession | null> {\n const token = readToken(cfg)\n if (!token) return null\n const res = await fetch(cfg.endpoints.me, {\n credentials: 'include',\n headers: { ...authHeader(cfg, token) },\n })\n if (!res.ok) return null\n const raw = await res.json()\n return { user: mapUser(raw), accessToken: token }\n }\n\n return {\n name: 'jwt',\n async login(credentials) {\n const res = await fetch(cfg.endpoints.login, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(credentials),\n })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(text || `Login failed (${res.status})`)\n }\n const raw = await res.json()\n const tokens = mapTokens(raw)\n if (tokens.accessToken) writeToken(cfg, tokens.accessToken)\n const session = await getSession()\n if (!session) throw new Error('Could not establish session after login')\n return { ...session, ...tokens }\n },\n async logout() {\n const token = readToken(cfg)\n if (cfg.endpoints.logout) {\n await fetch(cfg.endpoints.logout, {\n method: 'POST',\n credentials: 'include',\n headers: { ...authHeader(cfg, token) },\n }).catch(() => undefined)\n }\n writeToken(cfg, null)\n },\n getSession,\n refresh: cfg.endpoints.refresh\n ? async () => {\n const token = readToken(cfg)\n const res = await fetch(cfg.endpoints.refresh!, {\n method: 'POST',\n credentials: 'include',\n headers: { ...authHeader(cfg, token) },\n })\n if (!res.ok) return null\n const raw = await res.json()\n const tokens = mapTokens(raw)\n if (tokens.accessToken) writeToken(cfg, tokens.accessToken)\n return getSession()\n }\n : undefined,\n }\n}\n","import type { AuthProvider, AuthSession, OAuthConfig } from '../types'\n\n/**\n * Client-side OAuth provider. Performs the redirect dance; the actual\n * token exchange must happen in a server route handler that the consumer\n * mounts (see `auth/server/oauth.ts` if implemented).\n *\n * After the server completes the callback and sets a session cookie,\n * `getSession()` reads it via the consumer-provided `/api/auth/session` endpoint.\n */\nexport function createOAuthProvider(cfg: OAuthConfig): AuthProvider {\n const callbackPath = cfg.callbackPath ?? '/api/auth/callback'\n\n function startAuthorize(providerId: string) {\n if (typeof window === 'undefined') return\n const p = cfg.providers.find((x) => x.id === providerId)\n if (!p) throw new Error(`Unknown OAuth provider: ${providerId}`)\n const url = new URL(p.authorizationUrl)\n url.searchParams.set('client_id', p.clientId)\n url.searchParams.set('response_type', 'code')\n url.searchParams.set(\n 'redirect_uri',\n p.redirectUri ?? `${window.location.origin}${callbackPath}/${p.id}`,\n )\n if (p.scopes?.length) url.searchParams.set('scope', p.scopes.join(' '))\n url.searchParams.set('state', crypto.randomUUID())\n window.location.assign(url.toString())\n }\n\n async function getSession(): Promise<AuthSession | null> {\n const res = await fetch('/api/auth/session', { credentials: 'include' })\n if (!res.ok) return null\n const raw = (await res.json()) as Partial<AuthSession> | null\n if (!raw?.user) return null\n return raw as AuthSession\n }\n\n return {\n name: 'oauth',\n async login(credentials) {\n const providerId = (credentials as { provider?: string }).provider ?? cfg.providers[0]?.id\n if (!providerId) throw new Error('No OAuth provider configured')\n startAuthorize(providerId)\n // Browser navigates away — return a never-resolving promise so callers\n // don't show success/failure before the redirect happens.\n return new Promise<AuthSession>(() => undefined)\n },\n async logout() {\n await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }).catch(() => undefined)\n },\n getSession,\n }\n}\n","import type { AuthProvider } from '../types'\n\n/**\n * Pass-through factory for consumers supplying their own AuthProvider.\n * Exists so `config.auth.provider === 'custom'` resolution can stay symmetric\n * with `'jwt'` and `'oauth'`.\n */\nexport function createCustomProvider(provider: AuthProvider): AuthProvider {\n if (!provider) throw new Error('config.auth.custom is required when provider is \"custom\"')\n return provider\n}\n","'use client'\n\nimport { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { AuthConfig } from '../config/types'\nimport { createJWTProvider } from './providers/JWTProvider'\nimport { createOAuthProvider } from './providers/OAuthProvider'\nimport { createCustomProvider } from './providers/CustomProvider'\nimport type { AuthContextValue, AuthProvider, AuthSession, AuthState } from './types'\n\nexport const AuthContext = createContext<AuthContextValue | null>(null)\n\nfunction resolveProvider(auth: AuthConfig): AuthProvider {\n switch (auth.provider) {\n case 'jwt':\n if (!auth.jwt) throw new Error('config.auth.jwt is required when provider is \"jwt\"')\n return createJWTProvider(auth.jwt)\n case 'oauth':\n if (!auth.oauth) throw new Error('config.auth.oauth is required when provider is \"oauth\"')\n return createOAuthProvider(auth.oauth)\n case 'custom':\n if (!auth.custom) throw new Error('config.auth.custom is required when provider is \"custom\"')\n return createCustomProvider(auth.custom)\n default:\n throw new Error(`Unknown auth provider: ${(auth as { provider: string }).provider}`)\n }\n}\n\nexport interface AuthContextProviderProps {\n config: AuthConfig\n children: ReactNode\n initialSession?: AuthSession | null\n}\n\nexport function AuthContextProvider({ config, children, initialSession = null }: AuthContextProviderProps) {\n const providerRef = useRef<AuthProvider | null>(null)\n if (providerRef.current === null) providerRef.current = resolveProvider(config)\n const provider = providerRef.current\n\n const [state, setState] = useState<AuthState>(() => ({\n status: initialSession ? 'authenticated' : 'loading',\n user: initialSession?.user ?? null,\n session: initialSession,\n error: null,\n }))\n\n useEffect(() => {\n if (initialSession) return\n let cancelled = false\n ;(async () => {\n try {\n const session = (await provider.initialize?.()) ?? (await provider.getSession())\n if (cancelled) return\n setState({\n status: session ? 'authenticated' : 'unauthenticated',\n user: session?.user ?? null,\n session,\n error: null,\n })\n } catch (err) {\n if (cancelled) return\n setState({\n status: 'unauthenticated',\n user: null,\n session: null,\n error: err instanceof Error ? err.message : 'Failed to load session',\n })\n }\n })()\n return () => {\n cancelled = true\n }\n }, [provider, initialSession])\n\n const login = useCallback(\n async (credentials: Record<string, unknown>) => {\n setState((s) => ({ ...s, status: 'loading', error: null }))\n try {\n const session = await provider.login(credentials)\n setState({ status: 'authenticated', user: session.user, session, error: null })\n return session\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Login failed'\n setState({ status: 'unauthenticated', user: null, session: null, error: message })\n throw err\n }\n },\n [provider],\n )\n\n const logout = useCallback(async () => {\n await provider.logout()\n setState({ status: 'unauthenticated', user: null, session: null, error: null })\n }, [provider])\n\n const getSession = useCallback(() => provider.getSession(), [provider])\n const refresh = useMemo(\n () =>\n provider.refresh\n ? async () => {\n const session = await provider.refresh!()\n setState({\n status: session ? 'authenticated' : 'unauthenticated',\n user: session?.user ?? null,\n session,\n error: null,\n })\n return session\n }\n : undefined,\n [provider],\n )\n\n const value = useMemo<AuthContextValue>(\n () => ({\n ...state,\n isAuthenticated: state.status === 'authenticated',\n isLoading: state.status === 'loading',\n login,\n logout,\n getSession,\n refresh,\n }),\n [state, login, logout, getSession, refresh],\n )\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>\n}\n","import type { AdminModule } from './types'\nimport type { AuthUser } from '../auth/types'\n\nexport interface ModuleRegistry {\n readonly all: AdminModule[]\n byId: (id: string) => AdminModule | undefined\n widgets: (slot: string) => Array<{ moduleId: string; Component: AdminModule['widgets'] extends Record<string, infer V> ? V : never }>\n}\n\n/**\n * Build a typed lookup over the modules declared in config. This is a pure\n * function — no global state, no side effects, no `registerModule()` API —\n * so SSR and client see the same module set.\n */\nexport function createModuleRegistry(\n modules: AdminModule[],\n user: AuthUser | null,\n): ModuleRegistry {\n const active = modules.filter((m) => (m.enabled ? m.enabled({ user }) : true))\n const byIdMap = new Map(active.map((m) => [m.id, m]))\n\n return {\n all: active,\n byId: (id) => byIdMap.get(id),\n widgets: (slot) =>\n active\n .filter((m) => m.widgets && slot in m.widgets)\n .map((m) => ({ moduleId: m.id, Component: m.widgets![slot]! })) as ReturnType<ModuleRegistry['widgets']>,\n }\n}\n","'use client'\n\nimport { createContext, useMemo } from 'react'\nimport type { ReactNode } from 'react'\nimport type { AdminModule } from './types'\nimport type { AuthUser } from '../auth/types'\nimport { createModuleRegistry } from './registry'\nimport type { ModuleRegistry } from './registry'\n\nexport const ModuleContext = createContext<ModuleRegistry | null>(null)\n\nexport interface ModuleProviderProps {\n modules: AdminModule[]\n user: AuthUser | null\n children: ReactNode\n}\n\n/**\n * Composes each module's `Provider` in declaration order, then exposes the\n * registry via ModuleContext. Modules cannot register themselves at runtime —\n * everything is declared in config so SSR/CSR stay in sync.\n */\nexport function ModuleProvider({ modules, user, children }: ModuleProviderProps) {\n const registry = useMemo(() => createModuleRegistry(modules, user), [modules, user])\n\n let tree = <ModuleContext.Provider value={registry}>{children}</ModuleContext.Provider>\n for (let i = registry.all.length - 1; i >= 0; i--) {\n const M = registry.all[i]\n if (M.Provider) {\n const Provider = M.Provider\n tree = <Provider>{tree}</Provider>\n }\n }\n return tree\n}\n","/**\n * Default theme tokens, exposed as CSS custom properties under `[data-admin-kit]`.\n * Consumers can override any token via `config.theme.tokens`.\n */\nexport const DEFAULT_TOKENS = {\n '--admin-color-bg': '#fafafa',\n '--admin-color-surface': '#ffffff',\n '--admin-color-border': '#e5e5e5',\n '--admin-color-text': '#171717',\n '--admin-color-text-muted': '#737373',\n '--admin-color-primary': '#171717',\n '--admin-color-primary-fg': '#ffffff',\n '--admin-color-accent': '#3b82f6',\n '--admin-radius': '0.5rem',\n '--admin-sidebar-width': '16rem',\n '--admin-sidebar-collapsed-width': '4rem',\n '--admin-topbar-height': '3.5rem',\n} as const\n\nexport type ThemeTokens = Partial<Record<keyof typeof DEFAULT_TOKENS | string, string>>\n\nexport function tokensToStyle(tokens: ThemeTokens): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(tokens)) {\n if (v != null) out[k] = v\n }\n return out\n}\n","'use client'\n\nimport { createContext, useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { ThemeConfig } from '../config/types'\nimport { DEFAULT_TOKENS, tokensToStyle } from './tokens'\n\nexport type ThemeMode = 'light' | 'dark' | 'system'\n\nexport interface ThemeContextValue {\n mode: ThemeMode\n resolvedMode: 'light' | 'dark'\n setMode: (m: ThemeMode) => void\n}\n\nexport const ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport interface ThemeProviderProps {\n theme?: ThemeConfig\n children: ReactNode\n}\n\nfunction resolveSystem(): 'light' | 'dark' {\n if (typeof window === 'undefined') return 'light'\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\nexport function ThemeProvider({ theme, children }: ThemeProviderProps) {\n const [mode, setMode] = useState<ThemeMode>(theme?.mode ?? 'system')\n const [systemMode, setSystemMode] = useState<'light' | 'dark'>(resolveSystem)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mql = window.matchMedia('(prefers-color-scheme: dark)')\n const listener = () => setSystemMode(mql.matches ? 'dark' : 'light')\n mql.addEventListener('change', listener)\n return () => mql.removeEventListener('change', listener)\n }, [])\n\n const resolvedMode = mode === 'system' ? systemMode : mode\n\n const style = useMemo(\n () => tokensToStyle({ ...DEFAULT_TOKENS, ...(theme?.tokens ?? {}) }),\n [theme?.tokens],\n )\n\n const value = useMemo<ThemeContextValue>(\n () => ({ mode, resolvedMode, setMode }),\n [mode, resolvedMode],\n )\n\n return (\n <ThemeContext.Provider value={value}>\n <div data-admin-kit data-theme={resolvedMode} style={style} className={theme?.className}>\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { AuthContext } from './AuthContext'\nimport type { AuthContextValue } from './types'\n\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext)\n if (!ctx) {\n throw new Error('useAuth must be used inside <AdminProvider> / <AuthContextProvider>')\n }\n return ctx\n}\n","'use client'\n\nimport { useMemo } from 'react'\nimport type { ReactNode } from 'react'\nimport type { AdminConfig } from './config/types'\nimport { resolveConfig } from './config/defaults'\nimport { AuthContextProvider } from './auth/AuthContext'\nimport { ModuleProvider } from './modules/ModuleContext'\nimport { ThemeProvider } from './theme/ThemeProvider'\nimport { useAuth } from './auth/useAuth'\nimport type { AuthSession } from './auth/types'\n\nexport interface AdminProviderProps {\n config: AdminConfig\n initialSession?: AuthSession | null\n children: ReactNode\n}\n\n/**\n * Top-level provider. Wraps everything in:\n * ThemeProvider → AuthContextProvider → ModuleProvider → children\n *\n * The user prop is read from auth context inside ModuleBridge so modules\n * can apply `enabled({ user })` predicates without prop drilling.\n */\nexport function AdminProvider({ config, initialSession, children }: AdminProviderProps) {\n const resolved = useMemo(() => resolveConfig(config), [config])\n\n return (\n <ThemeProvider theme={resolved.theme}>\n <AuthContextProvider config={resolved.auth} initialSession={initialSession}>\n <ModuleBridge modules={resolved.modules ?? []}>{children}</ModuleBridge>\n </AuthContextProvider>\n </ThemeProvider>\n )\n}\n\nfunction ModuleBridge({\n modules,\n children,\n}: {\n modules: NonNullable<AdminConfig['modules']>\n children: ReactNode\n}) {\n const { user } = useAuth()\n return (\n <ModuleProvider modules={modules} user={user}>\n {children}\n </ModuleProvider>\n )\n}\n","/**\n * Minimal classname combiner. Filters falsy values (false/null/undefined/'')\n * and joins the rest with a space. Kept dependency-free on purpose; if the\n * consumer wants tailwind-merge semantics they can wrap this in their own.\n */\nexport type ClassValue = string | number | null | undefined | false | ClassValue[]\n\nexport function cn(...values: ClassValue[]): string {\n const out: string[] = []\n for (const v of values) {\n if (!v) continue\n if (typeof v === 'string' || typeof v === 'number') out.push(String(v))\n else if (Array.isArray(v)) {\n const inner = cn(...v)\n if (inner) out.push(inner)\n }\n }\n return out.join(' ')\n}\n","'use client'\n\nimport { useState, useId } from 'react'\nimport type { FormEvent } from 'react'\nimport { useAuth } from '../useAuth'\nimport type { LoginPageConfig, LoginPageProps } from '../../config/types'\nimport { cn } from '../../utils/cn'\n\nexport interface AdminLoginPageProps extends LoginPageProps {\n config?: LoginPageConfig\n /** OAuth provider buttons to render alongside the form. */\n oauthProviders?: Array<{ id: string; name: string; icon?: React.ReactNode }>\n /** Called when an OAuth button is clicked. */\n onOAuthClick?: (providerId: string) => void\n className?: string\n}\n\n/**\n * Default login page. Consumers can replace it entirely via\n * `config.auth.loginPage.component`, or keep this shell and just override\n * the logo/title via `config.auth.loginPage`.\n */\nexport function LoginPage({ config, oauthProviders, onOAuthClick, className }: AdminLoginPageProps) {\n const { login, isLoading, error } = useAuth()\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const emailId = useId()\n const passwordId = useId()\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault()\n try {\n await login({ email, password })\n } catch {\n // Error is already surfaced via context state.\n }\n }\n\n return (\n <div className={cn('admin-kit-login', 'min-h-screen flex items-center justify-center p-6 bg-neutral-50', className)}>\n <div className=\"w-full max-w-sm rounded-lg border border-neutral-200 bg-white p-6 shadow-sm\">\n {config?.logo ? <div className=\"mb-4 flex justify-center\">{config.logo}</div> : null}\n <h1 className=\"text-xl font-semibold text-neutral-900\">{config?.title ?? 'Sign in'}</h1>\n {config?.subtitle ? <p className=\"mt-1 text-sm text-neutral-500\">{config.subtitle}</p> : null}\n\n <form className=\"mt-6 space-y-4\" onSubmit={handleSubmit}>\n <div>\n <label htmlFor={emailId} className=\"block text-sm font-medium text-neutral-700\">Email</label>\n <input\n id={emailId}\n type=\"email\"\n autoComplete=\"email\"\n required\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-neutral-300 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-neutral-900\"\n />\n </div>\n <div>\n <label htmlFor={passwordId} className=\"block text-sm font-medium text-neutral-700\">Password</label>\n <input\n id={passwordId}\n type=\"password\"\n autoComplete=\"current-password\"\n required\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-neutral-300 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-neutral-900\"\n />\n </div>\n\n {error ? <p className=\"text-sm text-red-600\">{error}</p> : null}\n\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"w-full rounded-md bg-neutral-900 px-3 py-2 text-sm font-medium text-white hover:bg-neutral-800 disabled:opacity-60\"\n >\n {isLoading ? 'Signing in…' : 'Sign in'}\n </button>\n </form>\n\n {oauthProviders?.length ? (\n <div className=\"mt-6\">\n <div className=\"relative my-4 text-center text-xs uppercase text-neutral-400\">\n <span className=\"bg-white px-2\">or continue with</span>\n <span className=\"absolute inset-x-0 top-1/2 -z-10 h-px bg-neutral-200\" />\n </div>\n <div className=\"flex flex-col gap-2\">\n {oauthProviders.map((p) => (\n <button\n key={p.id}\n type=\"button\"\n onClick={() => onOAuthClick?.(p.id)}\n className=\"flex items-center justify-center gap-2 rounded-md border border-neutral-300 bg-white px-3 py-2 text-sm font-medium text-neutral-800 hover:bg-neutral-50\"\n >\n {p.icon}\n <span>Continue with {p.name}</span>\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n","'use client'\n\n/**\n * App Router adapter. Re-exports / wraps next/navigation primitives so the\n * rest of the package can stay router-agnostic.\n *\n * Consumers using the Pages Router should import from './pagesRoute' instead.\n */\nimport { useRouter as useNextRouter, usePathname as useNextPathname, useSearchParams as useNextSearchParams } from 'next/navigation'\nimport NextLink from 'next/link'\nimport type { ComponentType } from 'react'\nimport type { LinkProps, RouterAdapter } from './types'\n\nexport function useAppRouter() {\n const r = useNextRouter()\n return {\n push: (href: string) => r.push(href),\n replace: (href: string) => r.replace(href),\n back: () => r.back(),\n }\n}\n\nexport function useAppPathname(): string {\n return useNextPathname() ?? '/'\n}\n\nexport function useAppSearchParams(): URLSearchParams {\n const sp = useNextSearchParams()\n return new URLSearchParams(sp?.toString() ?? '')\n}\n\nexport const AppLink = NextLink as unknown as ComponentType<LinkProps>\n\nexport const appRouterAdapter: RouterAdapter = {\n useRouter: useAppRouter,\n usePathname: useAppPathname,\n useSearchParams: useAppSearchParams,\n Link: AppLink,\n}\n","'use client'\n\nimport { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { useAuth } from '../useAuth'\nimport { useAppRouter, useAppPathname } from '../../adapters/appRoute'\n\nexport interface AppRouterGuardProps {\n loginPath?: string\n publicRoutes?: string[]\n fallback?: ReactNode\n children: ReactNode\n}\n\nexport function AppRouterGuard({\n loginPath = '/login',\n publicRoutes = [],\n fallback = null,\n children,\n}: AppRouterGuardProps) {\n const { status, isAuthenticated } = useAuth()\n const router = useAppRouter()\n const pathname = useAppPathname()\n const isPublic = publicRoutes.some((p) => pathname === p || pathname.startsWith(p + '/'))\n\n useEffect(() => {\n if (status === 'loading' || status === 'idle') return\n if (!isAuthenticated && !isPublic && pathname !== loginPath) {\n const next = encodeURIComponent(pathname)\n router.replace(`${loginPath}?next=${next}`)\n }\n }, [status, isAuthenticated, isPublic, pathname, loginPath, router])\n\n if (status === 'loading' || status === 'idle') return <>{fallback}</>\n if (!isAuthenticated && !isPublic && pathname !== loginPath) return <>{fallback}</>\n return <>{children}</>\n}\n","'use client'\n\n/**\n * Pages Router adapter. Wraps next/router primitives.\n */\nimport { useRouter as useNextRouter } from 'next/router'\nimport NextLink from 'next/link'\nimport type { ComponentType } from 'react'\nimport type { LinkProps, RouterAdapter } from './types'\n\nexport function usePagesRouter() {\n const r = useNextRouter()\n return {\n push: (href: string) => {\n void r.push(href)\n },\n replace: (href: string) => {\n void r.replace(href)\n },\n back: () => r.back(),\n }\n}\n\nexport function usePagesPathname(): string {\n const r = useNextRouter()\n return r.pathname\n}\n\nexport function usePagesSearchParams(): URLSearchParams {\n const r = useNextRouter()\n const params = new URLSearchParams()\n for (const [k, v] of Object.entries(r.query)) {\n if (Array.isArray(v)) v.forEach((vv) => params.append(k, vv))\n else if (v != null) params.set(k, String(v))\n }\n return params\n}\n\nexport const PagesLink = NextLink as unknown as ComponentType<LinkProps>\n\nexport const pagesRouterAdapter: RouterAdapter = {\n useRouter: usePagesRouter,\n usePathname: usePagesPathname,\n useSearchParams: usePagesSearchParams,\n Link: PagesLink,\n}\n","'use client'\n\nimport { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { useAuth } from '../useAuth'\nimport { usePagesRouter, usePagesPathname } from '../../adapters/pagesRoute'\n\nexport interface PagesRouterGuardProps {\n loginPath?: string\n publicRoutes?: string[]\n fallback?: ReactNode\n children: ReactNode\n}\n\nexport function PagesRouterGuard({\n loginPath = '/login',\n publicRoutes = [],\n fallback = null,\n children,\n}: PagesRouterGuardProps) {\n const { status, isAuthenticated } = useAuth()\n const router = usePagesRouter()\n const pathname = usePagesPathname()\n const isPublic = publicRoutes.some((p) => pathname === p || pathname.startsWith(p + '/'))\n\n useEffect(() => {\n if (status === 'loading' || status === 'idle') return\n if (!isAuthenticated && !isPublic && pathname !== loginPath) {\n const next = encodeURIComponent(pathname)\n router.replace(`${loginPath}?next=${next}`)\n }\n }, [status, isAuthenticated, isPublic, pathname, loginPath, router])\n\n if (status === 'loading' || status === 'idle') return <>{fallback}</>\n if (!isAuthenticated && !isPublic && pathname !== loginPath) return <>{fallback}</>\n return <>{children}</>\n}\n","'use client'\n\nimport { createContext, useCallback, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { NavSection } from './types'\n\nexport interface SidebarContextValue {\n sections: NavSection[]\n collapsed: boolean\n setCollapsed: (v: boolean) => void\n toggle: () => void\n mobileOpen: boolean\n setMobileOpen: (v: boolean) => void\n}\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null)\n\nexport interface SidebarProviderProps {\n sections: NavSection[]\n defaultCollapsed?: boolean\n children: ReactNode\n}\n\nexport function SidebarProvider({ sections, defaultCollapsed = false, children }: SidebarProviderProps) {\n const [collapsed, setCollapsed] = useState(defaultCollapsed)\n const [mobileOpen, setMobileOpen] = useState(false)\n const toggle = useCallback(() => setCollapsed((c) => !c), [])\n\n const value = useMemo<SidebarContextValue>(\n () => ({ sections, collapsed, setCollapsed, toggle, mobileOpen, setMobileOpen }),\n [sections, collapsed, mobileOpen, toggle],\n )\n\n return <SidebarContext.Provider value={value}>{children}</SidebarContext.Provider>\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { SidebarContext } from './SidebarContext'\nimport type { SidebarContextValue } from './SidebarContext'\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext)\n if (!ctx) throw new Error('useSidebar must be used inside <SidebarProvider>')\n return ctx\n}\n","'use client'\n\nimport { useState } from 'react'\nimport type { ComponentType } from 'react'\nimport type { NavItem } from './types'\nimport type { LinkProps } from '../adapters/types'\nimport { cn } from '../utils/cn'\n\nexport interface SidebarItemProps {\n item: NavItem\n active?: boolean\n collapsed?: boolean\n Link: ComponentType<LinkProps>\n currentPath: string\n depth?: number\n}\n\nexport function SidebarItem({ item, collapsed, Link, currentPath, depth = 0 }: SidebarItemProps) {\n const hasChildren = (item.children?.length ?? 0) > 0\n const isActive =\n item.href != null && (currentPath === item.href || currentPath.startsWith(item.href + '/'))\n const [open, setOpen] = useState(isActive)\n\n const baseCls = cn(\n 'admin-kit-nav-item',\n 'group flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors',\n isActive ? 'bg-neutral-100 text-neutral-900' : 'text-neutral-600 hover:bg-neutral-50 hover:text-neutral-900',\n depth > 0 && 'ml-3',\n )\n\n if (hasChildren) {\n return (\n <li>\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n className={cn(baseCls, 'w-full justify-between')}\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-2 min-w-0\">\n {item.icon}\n {!collapsed && <span className=\"truncate\">{item.label}</span>}\n </span>\n {!collapsed && (\n <span aria-hidden className={cn('text-xs transition-transform', open && 'rotate-90')}>\n ›\n </span>\n )}\n </button>\n {open && !collapsed && (\n <ul className=\"mt-1 space-y-0.5 border-l border-neutral-200 pl-2\">\n {item.children!.map((child, i) => (\n <SidebarItem\n key={child.id ?? child.href ?? `${child.label}-${i}`}\n item={child}\n Link={Link}\n currentPath={currentPath}\n depth={depth + 1}\n />\n ))}\n </ul>\n )}\n </li>\n )\n }\n\n if (!item.href) {\n return (\n <li>\n <span className={baseCls}>\n {item.icon}\n {!collapsed && <span className=\"truncate\">{item.label}</span>}\n </span>\n </li>\n )\n }\n\n return (\n <li>\n <Link\n href={item.href}\n className={baseCls}\n {...(item.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n >\n {item.icon}\n {!collapsed && (\n <>\n <span className=\"truncate flex-1\">{item.label}</span>\n {item.badge != null && (\n <span className=\"ml-auto inline-flex items-center rounded-full bg-neutral-200 px-2 text-xs font-medium text-neutral-700\">\n {item.badge}\n </span>\n )}\n </>\n )}\n </Link>\n </li>\n )\n}\n","'use client'\n\nimport type { ComponentType } from 'react'\nimport type { NavSection } from './types'\nimport type { LinkProps } from '../adapters/types'\nimport { SidebarItem } from './SidebarItem'\n\nexport interface SidebarSectionProps {\n section: NavSection\n collapsed?: boolean\n currentPath: string\n Link: ComponentType<LinkProps>\n}\n\nexport function SidebarSection({ section, collapsed, currentPath, Link }: SidebarSectionProps) {\n return (\n <div className=\"admin-kit-nav-section\">\n {section.label && !collapsed && (\n <h4 className=\"px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wider text-neutral-400\">\n {section.label}\n </h4>\n )}\n <ul className=\"space-y-0.5\">\n {section.items.map((item, i) => (\n <SidebarItem\n key={item.id ?? item.href ?? `${item.label}-${i}`}\n item={item}\n collapsed={collapsed}\n currentPath={currentPath}\n Link={Link}\n />\n ))}\n </ul>\n </div>\n )\n}\n","'use client'\n\nimport type { ComponentType, ReactNode } from 'react'\nimport type { LinkProps } from '../adapters/types'\nimport { useSidebar } from './useSidebar'\nimport { SidebarSection } from './SidebarSection'\nimport { cn } from '../utils/cn'\n\nexport interface SidebarProps {\n Link: ComponentType<LinkProps>\n currentPath: string\n header?: ReactNode\n footer?: ReactNode\n className?: string\n}\n\nexport function Sidebar({ Link, currentPath, header, footer, className }: SidebarProps) {\n const { sections, collapsed, mobileOpen, setMobileOpen } = useSidebar()\n\n return (\n <>\n {mobileOpen && (\n <div\n className=\"fixed inset-0 z-30 bg-black/40 md:hidden\"\n onClick={() => setMobileOpen(false)}\n aria-hidden\n />\n )}\n <aside\n className={cn(\n 'admin-kit-sidebar',\n 'fixed inset-y-0 left-0 z-40 flex flex-col border-r border-neutral-200 bg-white transition-all',\n collapsed ? 'w-16' : 'w-64',\n mobileOpen ? 'translate-x-0' : '-translate-x-full md:translate-x-0',\n className,\n )}\n aria-label=\"Sidebar\"\n >\n {header && <div className=\"border-b border-neutral-200 p-3\">{header}</div>}\n <nav className=\"flex-1 overflow-y-auto p-2\">\n <div className=\"space-y-2\">\n {sections.map((section, i) => (\n <SidebarSection\n key={section.id ?? `section-${i}`}\n section={section}\n collapsed={collapsed}\n currentPath={currentPath}\n Link={Link}\n />\n ))}\n </div>\n </nav>\n {footer && <div className=\"border-t border-neutral-200 p-3\">{footer}</div>}\n </aside>\n </>\n )\n}\n","import type { AdminModule } from '../modules/types'\nimport type { NavItem, NavSection } from './types'\n\n/**\n * Merge nav sections declared in config with any contributed by modules.\n * Sections with the same `id` are merged: items are concatenated and sorted\n * by `order` (ascending, stable).\n */\nexport function buildNav(configSections: NavSection[], modules: AdminModule[] = []): NavSection[] {\n const map = new Map<string, NavSection>()\n let anonIdx = 0\n\n for (const s of configSections) {\n const id = s.id ?? `__anon_${anonIdx++}`\n map.set(id, { ...s, id, items: [...s.items] })\n }\n\n for (const m of modules) {\n for (const s of m.navSections ?? []) {\n const id = s.id ?? `__anon_${anonIdx++}`\n const existing = map.get(id)\n if (existing) {\n existing.items.push(...s.items)\n } else {\n map.set(id, { ...s, id, items: [...s.items] })\n }\n }\n }\n\n const sections = Array.from(map.values()).sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n for (const s of sections) {\n s.items = sortItems(s.items)\n }\n return sections\n}\n\nfunction sortItems(items: NavItem[]): NavItem[] {\n const sorted = items.slice().sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n return sorted.map((i) => (i.children ? { ...i, children: sortItems(i.children) } : i))\n}\n","import type { AuthUser } from '../auth/types'\nimport type { NavItem, NavSection } from './types'\n\nfunction userHasAny(user: AuthUser | null, required: string[] | undefined, key: 'roles' | 'permissions'): boolean {\n if (!required || required.length === 0) return true\n const have = (user?.[key] as string[] | undefined) ?? []\n return required.some((r) => have.includes(r))\n}\n\nfunction visibleItem(item: NavItem, user: AuthUser | null): NavItem | null {\n if (item.hidden) return null\n if (!userHasAny(user, item.roles, 'roles')) return null\n if (!userHasAny(user, item.permissions, 'permissions')) return null\n if (item.visible && !item.visible(user)) return null\n\n let children: NavItem[] | undefined\n if (item.children) {\n children = item.children.map((c) => visibleItem(c, user)).filter((c): c is NavItem => c !== null)\n if (children.length === 0 && !item.href) return null\n }\n return children ? { ...item, children } : item\n}\n\nexport function filterNav(sections: NavSection[], user: AuthUser | null): NavSection[] {\n const out: NavSection[] = []\n for (const section of sections) {\n if (!userHasAny(user, section.roles, 'roles')) continue\n if (!userHasAny(user, section.permissions, 'permissions')) continue\n if (section.visible && !section.visible(user)) continue\n const items = section.items.map((i) => visibleItem(i, user)).filter((i): i is NavItem => i !== null)\n if (items.length === 0) continue\n out.push({ ...section, items })\n }\n return out\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { ModuleContext } from './ModuleContext'\nimport type { ModuleRegistry } from './registry'\n\nexport function useModules(): ModuleRegistry {\n const ctx = useContext(ModuleContext)\n if (!ctx) throw new Error('useModules must be used inside <AdminProvider> / <ModuleProvider>')\n return ctx\n}\n","'use client'\n\nimport type { ReactNode } from 'react'\nimport { useAuth } from '../../auth/useAuth'\nimport { useSidebar } from '../../navigation/useSidebar'\nimport { cn } from '../../utils/cn'\n\nexport interface TopbarProps {\n title?: ReactNode\n actions?: ReactNode\n className?: string\n}\n\nexport function Topbar({ title, actions, className }: TopbarProps) {\n const { user, logout } = useAuth()\n const { toggle, setMobileOpen, collapsed } = useSidebar()\n\n return (\n <header\n className={cn(\n 'admin-kit-topbar',\n 'sticky top-0 z-20 flex h-14 items-center gap-3 border-b border-neutral-200 bg-white px-4',\n className,\n )}\n >\n <button\n type=\"button\"\n className=\"rounded p-1.5 text-neutral-600 hover:bg-neutral-100 md:hidden\"\n onClick={() => setMobileOpen(true)}\n aria-label=\"Open sidebar\"\n >\n <Bars />\n </button>\n <button\n type=\"button\"\n className=\"hidden rounded p-1.5 text-neutral-600 hover:bg-neutral-100 md:inline-flex\"\n onClick={toggle}\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n >\n <Bars />\n </button>\n <div className=\"flex-1 truncate text-sm font-medium text-neutral-800\">{title}</div>\n <div className=\"flex items-center gap-2\">{actions}</div>\n {user && (\n <div className=\"ml-2 flex items-center gap-2 border-l border-neutral-200 pl-3\">\n <span className=\"text-sm text-neutral-700\">{user.name ?? user.email ?? user.id}</span>\n <button\n type=\"button\"\n onClick={() => void logout()}\n className=\"rounded-md px-2 py-1 text-xs font-medium text-neutral-600 hover:bg-neutral-100\"\n >\n Sign out\n </button>\n </div>\n )}\n </header>\n )\n}\n\nfunction Bars() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n )\n}\n","'use client'\n\nimport type { ComponentType, ReactNode } from 'react'\nimport { useMemo } from 'react'\nimport type { ResolvedAdminConfig } from '../../config/types'\nimport { useAuth } from '../../auth/useAuth'\nimport { useModules } from '../../modules/useModules'\nimport { SidebarProvider } from '../../navigation/SidebarContext'\nimport { Sidebar } from '../../navigation/Sidebar'\nimport { Topbar } from './Topbar'\nimport { buildNav } from '../../navigation/buildNav'\nimport { filterNav } from '../../navigation/filterNav'\nimport type { LinkProps } from '../../adapters/types'\nimport { cn } from '../../utils/cn'\n\nexport interface AdminLayoutProps {\n config: ResolvedAdminConfig\n /** Router-specific bits. Pass the app or pages adapter. */\n Link: ComponentType<LinkProps>\n currentPath: string\n /** Page title shown in the topbar. */\n title?: ReactNode\n /** Extra elements rendered into the topbar (right side). */\n topbarActions?: ReactNode\n children: ReactNode\n className?: string\n}\n\nexport function AdminLayout({\n config,\n Link,\n currentPath,\n title,\n topbarActions,\n children,\n className,\n}: AdminLayoutProps) {\n const { user } = useAuth()\n const modules = useModules()\n\n const sections = useMemo(\n () => filterNav(buildNav(config.navigation.sections, modules.all), user),\n [config.navigation.sections, modules, user],\n )\n\n const sidebarPosition = config.layout.sidebarPosition\n const Topbarish = config.layout.topbar?.component ?? Topbar\n const showTopbar = config.layout.topbar?.visible !== false\n\n return (\n <SidebarProvider sections={sections} defaultCollapsed={config.layout.sidebarDefaultCollapsed}>\n <div className={cn('admin-kit-root', 'min-h-screen bg-neutral-50 text-neutral-900', className)}>\n <Sidebar\n Link={Link}\n currentPath={currentPath}\n header={\n <div className=\"flex items-center gap-2\">\n {typeof config.app.logo === 'string' ? (\n <img src={config.app.logo} alt=\"\" className=\"h-6 w-6\" />\n ) : (\n config.app.logo\n )}\n <span className=\"truncate font-semibold\">{config.app.name}</span>\n </div>\n }\n />\n <div className={cn('flex min-h-screen flex-col transition-[padding]', sidebarPosition === 'right' ? 'md:pr-64' : 'md:pl-64')}>\n {showTopbar && <Topbarish title={title} actions={topbarActions} />}\n <main className=\"flex-1\">{children}</main>\n </div>\n </div>\n </SidebarProvider>\n )\n}\n","import type { ReactNode } from 'react'\nimport { cn } from '../../utils/cn'\n\nexport interface PageContainerProps {\n title?: ReactNode\n description?: ReactNode\n actions?: ReactNode\n children?: ReactNode\n className?: string\n contentClassName?: string\n}\n\nexport function PageContainer({\n title,\n description,\n actions,\n children,\n className,\n contentClassName,\n}: PageContainerProps) {\n return (\n <div className={cn('admin-kit-page', 'p-6', className)}>\n {(title || description || actions) && (\n <div className=\"mb-6 flex items-start justify-between gap-4\">\n <div>\n {title && <h1 className=\"text-2xl font-semibold text-neutral-900\">{title}</h1>}\n {description && <p className=\"mt-1 text-sm text-neutral-500\">{description}</p>}\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n )}\n <div className={cn('admin-kit-page-content', contentClassName)}>{children}</div>\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { cn } from '../../utils/cn'\n\nexport interface StatCardProps {\n label: ReactNode\n value: ReactNode\n delta?: { value: number; label?: ReactNode; direction?: 'up' | 'down' }\n icon?: ReactNode\n className?: string\n}\n\nexport function StatCard({ label, value, delta, icon, className }: StatCardProps) {\n const isUp = delta ? (delta.direction ?? (delta.value >= 0 ? 'up' : 'down')) === 'up' : false\n\n return (\n <div className={cn('admin-kit-stat', 'rounded-lg border border-neutral-200 bg-white p-4', className)}>\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"text-sm font-medium text-neutral-500\">{label}</div>\n {icon && <div className=\"text-neutral-400\">{icon}</div>}\n </div>\n <div className=\"mt-2 text-2xl font-semibold text-neutral-900\">{value}</div>\n {delta && (\n <div\n className={cn(\n 'mt-1 inline-flex items-center gap-1 text-xs font-medium',\n isUp ? 'text-emerald-600' : 'text-red-600',\n )}\n >\n <span aria-hidden>{isUp ? '↑' : '↓'}</span>\n <span>{Math.abs(delta.value)}%</span>\n {delta.label && <span className=\"text-neutral-500\">{delta.label}</span>}\n </div>\n )}\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { cn } from '../../utils/cn'\n\nexport interface ChartCardProps {\n title?: ReactNode\n subtitle?: ReactNode\n actions?: ReactNode\n children?: ReactNode\n className?: string\n contentClassName?: string\n}\n\n/**\n * Lightweight chart card shell — does not ship a chart library. Plug in\n * recharts / chart.js / visx in `children`.\n */\nexport function ChartCard({ title, subtitle, actions, children, className, contentClassName }: ChartCardProps) {\n return (\n <div className={cn('admin-kit-chart-card', 'rounded-lg border border-neutral-200 bg-white', className)}>\n {(title || subtitle || actions) && (\n <div className=\"flex items-start justify-between gap-3 border-b border-neutral-100 p-4\">\n <div>\n {title && <h3 className=\"text-sm font-semibold text-neutral-900\">{title}</h3>}\n {subtitle && <p className=\"mt-0.5 text-xs text-neutral-500\">{subtitle}</p>}\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n )}\n <div className={cn('p-4', contentClassName)}>{children}</div>\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { cn } from '../../utils/cn'\n\nexport interface ActivityItem {\n id: string\n title: ReactNode\n description?: ReactNode\n timestamp?: string | Date\n icon?: ReactNode\n actor?: { name?: string; image?: string }\n}\n\nexport interface ActivityFeedProps {\n items: ActivityItem[]\n emptyState?: ReactNode\n className?: string\n}\n\nfunction formatRelative(timestamp: string | Date): string {\n const date = timestamp instanceof Date ? timestamp : new Date(timestamp)\n const diff = Date.now() - date.getTime()\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ago`\n const days = Math.floor(hours / 24)\n if (days < 7) return `${days}d ago`\n return date.toLocaleDateString()\n}\n\nexport function ActivityFeed({ items, emptyState, className }: ActivityFeedProps) {\n if (items.length === 0) {\n return (\n <div className={cn('admin-kit-activity-empty', 'rounded-lg border border-dashed border-neutral-200 p-6 text-center text-sm text-neutral-500', className)}>\n {emptyState ?? 'No activity yet.'}\n </div>\n )\n }\n\n return (\n <ul className={cn('admin-kit-activity', 'divide-y divide-neutral-100 rounded-lg border border-neutral-200 bg-white', className)}>\n {items.map((item) => (\n <li key={item.id} className=\"flex gap-3 p-3\">\n <div className=\"mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-100 text-neutral-600\">\n {item.icon ?? (item.actor?.image ? <img src={item.actor.image} alt=\"\" className=\"h-8 w-8 rounded-full\" /> : (item.actor?.name?.[0] ?? '•'))}\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm text-neutral-900\">{item.title}</div>\n {item.description && <div className=\"text-sm text-neutral-500\">{item.description}</div>}\n {item.timestamp && (\n <div className=\"mt-0.5 text-xs text-neutral-400\">{formatRelative(item.timestamp)}</div>\n )}\n </div>\n </li>\n ))}\n </ul>\n )\n}\n","/**\n * Pages-router compatibility HOC. Wraps a page component in AdminLayout\n * using the pages-router adapter. For App Router, use `<AdminLayout>` inside\n * `app/(admin)/layout.tsx` directly.\n *\n * Usage (pages/):\n * import { withAdminLayout } from '@cortejojicoy/admin-kit'\n * function DashboardPage() { ... }\n * export default withAdminLayout(DashboardPage, { title: 'Dashboard' })\n */\n'use client'\n\nimport type { ComponentType, ReactNode } from 'react'\nimport type { ResolvedAdminConfig } from '../config/types'\nimport { AdminLayout } from '../components/layout/AdminLayout'\nimport { PagesLink, usePagesPathname } from '../adapters/pagesRoute'\n\nexport interface WithAdminLayoutOptions {\n config: ResolvedAdminConfig\n title?: ReactNode\n topbarActions?: ReactNode\n}\n\nexport function withAdminLayout<P extends object>(\n Page: ComponentType<P>,\n opts: WithAdminLayoutOptions,\n): ComponentType<P> {\n function Wrapped(props: P) {\n const currentPath = usePagesPathname()\n return (\n <AdminLayout\n config={opts.config}\n Link={PagesLink}\n currentPath={currentPath}\n title={opts.title}\n topbarActions={opts.topbarActions}\n >\n <Page {...props} />\n </AdminLayout>\n )\n }\n Wrapped.displayName = `withAdminLayout(${Page.displayName ?? Page.name ?? 'Page'})`\n return Wrapped\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { ThemeContext } from './ThemeProvider'\nimport type { ThemeContextValue } from './ThemeProvider'\n\nexport function useTheme(): ThemeContextValue {\n const ctx = useContext(ThemeContext)\n if (!ctx) throw new Error('useTheme must be used inside <ThemeProvider> / <AdminProvider>')\n return ctx\n}\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/config/defineConfig.ts
|
|
4
|
+
function defineAdminConfig(config) {
|
|
5
|
+
return config;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/config/defaults.ts
|
|
9
|
+
var DEFAULT_LOGIN_PATH = "/login";
|
|
10
|
+
var DEFAULT_AFTER_LOGIN = "/";
|
|
11
|
+
var DEFAULT_AFTER_LOGOUT = "/login";
|
|
12
|
+
var DEFAULT_PUBLIC_ROUTES = ["/login", "/api/auth"];
|
|
13
|
+
function resolveConfig(config) {
|
|
14
|
+
return {
|
|
15
|
+
...config,
|
|
16
|
+
router: config.router ?? "app",
|
|
17
|
+
auth: {
|
|
18
|
+
...config.auth,
|
|
19
|
+
loginPage: {
|
|
20
|
+
path: DEFAULT_LOGIN_PATH,
|
|
21
|
+
title: `Sign in to ${config.app.name}`,
|
|
22
|
+
...config.auth.loginPage
|
|
23
|
+
},
|
|
24
|
+
afterLoginRedirect: config.auth.afterLoginRedirect ?? DEFAULT_AFTER_LOGIN,
|
|
25
|
+
afterLogoutRedirect: config.auth.afterLogoutRedirect ?? DEFAULT_AFTER_LOGOUT,
|
|
26
|
+
publicRoutes: config.auth.publicRoutes ?? DEFAULT_PUBLIC_ROUTES
|
|
27
|
+
},
|
|
28
|
+
layout: {
|
|
29
|
+
sidebarPosition: "left",
|
|
30
|
+
sidebarCollapsible: true,
|
|
31
|
+
sidebarDefaultCollapsed: false,
|
|
32
|
+
...config.layout
|
|
33
|
+
},
|
|
34
|
+
theme: {
|
|
35
|
+
mode: "system",
|
|
36
|
+
...config.theme
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.DEFAULT_AFTER_LOGIN = DEFAULT_AFTER_LOGIN;
|
|
42
|
+
exports.DEFAULT_AFTER_LOGOUT = DEFAULT_AFTER_LOGOUT;
|
|
43
|
+
exports.DEFAULT_LOGIN_PATH = DEFAULT_LOGIN_PATH;
|
|
44
|
+
exports.defineAdminConfig = defineAdminConfig;
|
|
45
|
+
exports.resolveConfig = resolveConfig;
|
|
46
|
+
//# sourceMappingURL=index.cjs.map
|
|
47
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/defineConfig.ts","../src/config/defaults.ts"],"names":[],"mappings":";;;AAWO,SAAS,kBAAyC,MAAA,EAAc;AACrE,EAAA,OAAO,MAAA;AACT;;;ACXO,IAAM,kBAAA,GAAqB;AAC3B,IAAM,mBAAA,GAAsB;AAC5B,IAAM,oBAAA,GAAuB;AAC7B,IAAM,qBAAA,GAAwB,CAAC,QAAA,EAAU,WAAW,CAAA;AAEpD,SAAS,cAAc,MAAA,EAA0C;AACtE,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,MAAA,EAAQ,OAAO,MAAA,IAAU,KAAA;AAAA,IACzB,IAAA,EAAM;AAAA,MACJ,GAAG,MAAA,CAAO,IAAA;AAAA,MACV,SAAA,EAAW;AAAA,QACT,IAAA,EAAM,kBAAA;AAAA,QACN,KAAA,EAAO,CAAA,WAAA,EAAc,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA,CAAA;AAAA,QACpC,GAAG,OAAO,IAAA,CAAK;AAAA,OACjB;AAAA,MACA,kBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,kBAAA,IAAsB,mBAAA;AAAA,MACtD,mBAAA,EAAqB,MAAA,CAAO,IAAA,CAAK,mBAAA,IAAuB,oBAAA;AAAA,MACxD,YAAA,EAAc,MAAA,CAAO,IAAA,CAAK,YAAA,IAAgB;AAAA,KAC5C;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,eAAA,EAAiB,MAAA;AAAA,MACjB,kBAAA,EAAoB,IAAA;AAAA,MACpB,uBAAA,EAAyB,KAAA;AAAA,MACzB,GAAG,MAAA,CAAO;AAAA,KACZ;AAAA,IACA,KAAA,EAAO;AAAA,MACL,IAAA,EAAM,QAAA;AAAA,MACN,GAAG,MAAA,CAAO;AAAA;AACZ,GACF;AACF","file":"index.cjs","sourcesContent":["import type { AdminConfig } from './types'\n\n/**\n * Identity helper that gives consumers full type-checking on their admin config.\n *\n * export const adminConfig = defineAdminConfig({\n * app: { name: 'My Admin' },\n * auth: { provider: 'jwt', jwt: { endpoints: { login: '/api/auth/login', me: '/api/auth/me' } } },\n * navigation: { sections: [...] },\n * })\n */\nexport function defineAdminConfig<T extends AdminConfig>(config: T): T {\n return config\n}\n","import type { ResolvedAdminConfig, AdminConfig } from './types'\n\nexport const DEFAULT_LOGIN_PATH = '/login'\nexport const DEFAULT_AFTER_LOGIN = '/'\nexport const DEFAULT_AFTER_LOGOUT = '/login'\nexport const DEFAULT_PUBLIC_ROUTES = ['/login', '/api/auth']\n\nexport function resolveConfig(config: AdminConfig): ResolvedAdminConfig {\n return {\n ...config,\n router: config.router ?? 'app',\n auth: {\n ...config.auth,\n loginPage: {\n path: DEFAULT_LOGIN_PATH,\n title: `Sign in to ${config.app.name}`,\n ...config.auth.loginPage,\n },\n afterLoginRedirect: config.auth.afterLoginRedirect ?? DEFAULT_AFTER_LOGIN,\n afterLogoutRedirect: config.auth.afterLogoutRedirect ?? DEFAULT_AFTER_LOGOUT,\n publicRoutes: config.auth.publicRoutes ?? DEFAULT_PUBLIC_ROUTES,\n },\n layout: {\n sidebarPosition: 'left',\n sidebarCollapsible: true,\n sidebarDefaultCollapsed: false,\n ...config.layout,\n },\n theme: {\n mode: 'system',\n ...config.theme,\n },\n } as ResolvedAdminConfig\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { A as AdminConfig, R as ResolvedAdminConfig } from './types-N0f4k4Ie.cjs';
|
|
2
|
+
export { a as AdminModule, b as AppConfig, c as AuthActions, d as AuthConfig, e as AuthContextValue, f as AuthProvider, g as AuthSession, h as AuthState, i as AuthStatus, j as AuthUser, J as JWTAuthConfig, k as JWTEndpoints, L as LayoutConfig, l as LoginPageConfig, m as LoginPageProps, N as NavItem, n as NavSection, O as OAuthConfig, o as OAuthProviderConfig, p as RouterFlavor, T as ThemeConfig } from './types-N0f4k4Ie.cjs';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Identity helper that gives consumers full type-checking on their admin config.
|
|
7
|
+
*
|
|
8
|
+
* export const adminConfig = defineAdminConfig({
|
|
9
|
+
* app: { name: 'My Admin' },
|
|
10
|
+
* auth: { provider: 'jwt', jwt: { endpoints: { login: '/api/auth/login', me: '/api/auth/me' } } },
|
|
11
|
+
* navigation: { sections: [...] },
|
|
12
|
+
* })
|
|
13
|
+
*/
|
|
14
|
+
declare function defineAdminConfig<T extends AdminConfig>(config: T): T;
|
|
15
|
+
|
|
16
|
+
declare const DEFAULT_LOGIN_PATH = "/login";
|
|
17
|
+
declare const DEFAULT_AFTER_LOGIN = "/";
|
|
18
|
+
declare const DEFAULT_AFTER_LOGOUT = "/login";
|
|
19
|
+
declare function resolveConfig(config: AdminConfig): ResolvedAdminConfig;
|
|
20
|
+
|
|
21
|
+
export { AdminConfig, DEFAULT_AFTER_LOGIN, DEFAULT_AFTER_LOGOUT, DEFAULT_LOGIN_PATH, ResolvedAdminConfig, defineAdminConfig, resolveConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { A as AdminConfig, R as ResolvedAdminConfig } from './types-N0f4k4Ie.js';
|
|
2
|
+
export { a as AdminModule, b as AppConfig, c as AuthActions, d as AuthConfig, e as AuthContextValue, f as AuthProvider, g as AuthSession, h as AuthState, i as AuthStatus, j as AuthUser, J as JWTAuthConfig, k as JWTEndpoints, L as LayoutConfig, l as LoginPageConfig, m as LoginPageProps, N as NavItem, n as NavSection, O as OAuthConfig, o as OAuthProviderConfig, p as RouterFlavor, T as ThemeConfig } from './types-N0f4k4Ie.js';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Identity helper that gives consumers full type-checking on their admin config.
|
|
7
|
+
*
|
|
8
|
+
* export const adminConfig = defineAdminConfig({
|
|
9
|
+
* app: { name: 'My Admin' },
|
|
10
|
+
* auth: { provider: 'jwt', jwt: { endpoints: { login: '/api/auth/login', me: '/api/auth/me' } } },
|
|
11
|
+
* navigation: { sections: [...] },
|
|
12
|
+
* })
|
|
13
|
+
*/
|
|
14
|
+
declare function defineAdminConfig<T extends AdminConfig>(config: T): T;
|
|
15
|
+
|
|
16
|
+
declare const DEFAULT_LOGIN_PATH = "/login";
|
|
17
|
+
declare const DEFAULT_AFTER_LOGIN = "/";
|
|
18
|
+
declare const DEFAULT_AFTER_LOGOUT = "/login";
|
|
19
|
+
declare function resolveConfig(config: AdminConfig): ResolvedAdminConfig;
|
|
20
|
+
|
|
21
|
+
export { AdminConfig, DEFAULT_AFTER_LOGIN, DEFAULT_AFTER_LOGOUT, DEFAULT_LOGIN_PATH, ResolvedAdminConfig, defineAdminConfig, resolveConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/config/defineConfig.ts
|
|
2
|
+
function defineAdminConfig(config) {
|
|
3
|
+
return config;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// src/config/defaults.ts
|
|
7
|
+
var DEFAULT_LOGIN_PATH = "/login";
|
|
8
|
+
var DEFAULT_AFTER_LOGIN = "/";
|
|
9
|
+
var DEFAULT_AFTER_LOGOUT = "/login";
|
|
10
|
+
var DEFAULT_PUBLIC_ROUTES = ["/login", "/api/auth"];
|
|
11
|
+
function resolveConfig(config) {
|
|
12
|
+
return {
|
|
13
|
+
...config,
|
|
14
|
+
router: config.router ?? "app",
|
|
15
|
+
auth: {
|
|
16
|
+
...config.auth,
|
|
17
|
+
loginPage: {
|
|
18
|
+
path: DEFAULT_LOGIN_PATH,
|
|
19
|
+
title: `Sign in to ${config.app.name}`,
|
|
20
|
+
...config.auth.loginPage
|
|
21
|
+
},
|
|
22
|
+
afterLoginRedirect: config.auth.afterLoginRedirect ?? DEFAULT_AFTER_LOGIN,
|
|
23
|
+
afterLogoutRedirect: config.auth.afterLogoutRedirect ?? DEFAULT_AFTER_LOGOUT,
|
|
24
|
+
publicRoutes: config.auth.publicRoutes ?? DEFAULT_PUBLIC_ROUTES
|
|
25
|
+
},
|
|
26
|
+
layout: {
|
|
27
|
+
sidebarPosition: "left",
|
|
28
|
+
sidebarCollapsible: true,
|
|
29
|
+
sidebarDefaultCollapsed: false,
|
|
30
|
+
...config.layout
|
|
31
|
+
},
|
|
32
|
+
theme: {
|
|
33
|
+
mode: "system",
|
|
34
|
+
...config.theme
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { DEFAULT_AFTER_LOGIN, DEFAULT_AFTER_LOGOUT, DEFAULT_LOGIN_PATH, defineAdminConfig, resolveConfig };
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/defineConfig.ts","../src/config/defaults.ts"],"names":[],"mappings":";AAWO,SAAS,kBAAyC,MAAA,EAAc;AACrE,EAAA,OAAO,MAAA;AACT;;;ACXO,IAAM,kBAAA,GAAqB;AAC3B,IAAM,mBAAA,GAAsB;AAC5B,IAAM,oBAAA,GAAuB;AAC7B,IAAM,qBAAA,GAAwB,CAAC,QAAA,EAAU,WAAW,CAAA;AAEpD,SAAS,cAAc,MAAA,EAA0C;AACtE,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,MAAA,EAAQ,OAAO,MAAA,IAAU,KAAA;AAAA,IACzB,IAAA,EAAM;AAAA,MACJ,GAAG,MAAA,CAAO,IAAA;AAAA,MACV,SAAA,EAAW;AAAA,QACT,IAAA,EAAM,kBAAA;AAAA,QACN,KAAA,EAAO,CAAA,WAAA,EAAc,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA,CAAA;AAAA,QACpC,GAAG,OAAO,IAAA,CAAK;AAAA,OACjB;AAAA,MACA,kBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,kBAAA,IAAsB,mBAAA;AAAA,MACtD,mBAAA,EAAqB,MAAA,CAAO,IAAA,CAAK,mBAAA,IAAuB,oBAAA;AAAA,MACxD,YAAA,EAAc,MAAA,CAAO,IAAA,CAAK,YAAA,IAAgB;AAAA,KAC5C;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,eAAA,EAAiB,MAAA;AAAA,MACjB,kBAAA,EAAoB,IAAA;AAAA,MACpB,uBAAA,EAAyB,KAAA;AAAA,MACzB,GAAG,MAAA,CAAO;AAAA,KACZ;AAAA,IACA,KAAA,EAAO;AAAA,MACL,IAAA,EAAM,QAAA;AAAA,MACN,GAAG,MAAA,CAAO;AAAA;AACZ,GACF;AACF","file":"index.js","sourcesContent":["import type { AdminConfig } from './types'\n\n/**\n * Identity helper that gives consumers full type-checking on their admin config.\n *\n * export const adminConfig = defineAdminConfig({\n * app: { name: 'My Admin' },\n * auth: { provider: 'jwt', jwt: { endpoints: { login: '/api/auth/login', me: '/api/auth/me' } } },\n * navigation: { sections: [...] },\n * })\n */\nexport function defineAdminConfig<T extends AdminConfig>(config: T): T {\n return config\n}\n","import type { ResolvedAdminConfig, AdminConfig } from './types'\n\nexport const DEFAULT_LOGIN_PATH = '/login'\nexport const DEFAULT_AFTER_LOGIN = '/'\nexport const DEFAULT_AFTER_LOGOUT = '/login'\nexport const DEFAULT_PUBLIC_ROUTES = ['/login', '/api/auth']\n\nexport function resolveConfig(config: AdminConfig): ResolvedAdminConfig {\n return {\n ...config,\n router: config.router ?? 'app',\n auth: {\n ...config.auth,\n loginPage: {\n path: DEFAULT_LOGIN_PATH,\n title: `Sign in to ${config.app.name}`,\n ...config.auth.loginPage,\n },\n afterLoginRedirect: config.auth.afterLoginRedirect ?? DEFAULT_AFTER_LOGIN,\n afterLogoutRedirect: config.auth.afterLogoutRedirect ?? DEFAULT_AFTER_LOGOUT,\n publicRoutes: config.auth.publicRoutes ?? DEFAULT_PUBLIC_ROUTES,\n },\n layout: {\n sidebarPosition: 'left',\n sidebarCollapsible: true,\n sidebarDefaultCollapsed: false,\n ...config.layout,\n },\n theme: {\n mode: 'system',\n ...config.theme,\n },\n } as ResolvedAdminConfig\n}\n"]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/auth/server/verifyJWT.ts
|
|
4
|
+
var enc = new TextEncoder();
|
|
5
|
+
function toAB(view) {
|
|
6
|
+
const buf = new ArrayBuffer(view.byteLength);
|
|
7
|
+
new Uint8Array(buf).set(view);
|
|
8
|
+
return buf;
|
|
9
|
+
}
|
|
10
|
+
function base64UrlDecode(input) {
|
|
11
|
+
const pad = input.length % 4 === 0 ? "" : "=".repeat(4 - input.length % 4);
|
|
12
|
+
const b64 = (input + pad).replace(/-/g, "+").replace(/_/g, "/");
|
|
13
|
+
const bin = typeof atob === "function" ? atob(b64) : Buffer.from(b64, "base64").toString("binary");
|
|
14
|
+
const out = new Uint8Array(new ArrayBuffer(bin.length));
|
|
15
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
function decodeJSON(seg) {
|
|
19
|
+
const bytes = base64UrlDecode(seg);
|
|
20
|
+
const text = new TextDecoder().decode(bytes);
|
|
21
|
+
return JSON.parse(text);
|
|
22
|
+
}
|
|
23
|
+
var ALGS = {
|
|
24
|
+
HS256: { name: "HMAC", hash: "SHA-256" },
|
|
25
|
+
HS384: { name: "HMAC", hash: "SHA-384" },
|
|
26
|
+
HS512: { name: "HMAC", hash: "SHA-512" }
|
|
27
|
+
};
|
|
28
|
+
async function verifyJWT(token, secret) {
|
|
29
|
+
const parts = token.split(".");
|
|
30
|
+
if (parts.length !== 3) return { valid: false, payload: null, reason: "malformed" };
|
|
31
|
+
const [headerSeg, payloadSeg, sigSeg] = parts;
|
|
32
|
+
let header;
|
|
33
|
+
try {
|
|
34
|
+
header = decodeJSON(headerSeg);
|
|
35
|
+
} catch {
|
|
36
|
+
return { valid: false, payload: null, reason: "bad-header" };
|
|
37
|
+
}
|
|
38
|
+
const algSpec = header.alg ? ALGS[header.alg] : void 0;
|
|
39
|
+
if (!algSpec) return { valid: false, payload: null, reason: `unsupported-alg:${header.alg}` };
|
|
40
|
+
const key = await crypto.subtle.importKey(
|
|
41
|
+
"raw",
|
|
42
|
+
toAB(enc.encode(secret)),
|
|
43
|
+
{ name: "HMAC", hash: algSpec.hash },
|
|
44
|
+
false,
|
|
45
|
+
["verify"]
|
|
46
|
+
);
|
|
47
|
+
const data = toAB(enc.encode(`${headerSeg}.${payloadSeg}`));
|
|
48
|
+
const sig = toAB(base64UrlDecode(sigSeg));
|
|
49
|
+
const ok = await crypto.subtle.verify("HMAC", key, sig, data);
|
|
50
|
+
if (!ok) return { valid: false, payload: null, reason: "bad-signature" };
|
|
51
|
+
let payload;
|
|
52
|
+
try {
|
|
53
|
+
payload = decodeJSON(payloadSeg);
|
|
54
|
+
} catch {
|
|
55
|
+
return { valid: false, payload: null, reason: "bad-payload" };
|
|
56
|
+
}
|
|
57
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
58
|
+
if (payload.exp != null && now >= payload.exp) return { valid: false, payload, reason: "expired" };
|
|
59
|
+
if (payload.nbf != null && now < payload.nbf) return { valid: false, payload, reason: "not-yet-valid" };
|
|
60
|
+
return { valid: true, payload };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/auth/server/cookies.ts
|
|
64
|
+
function parseCookies(header) {
|
|
65
|
+
if (!header) return {};
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const part of header.split(";")) {
|
|
68
|
+
const idx = part.indexOf("=");
|
|
69
|
+
if (idx === -1) continue;
|
|
70
|
+
const k = part.slice(0, idx).trim();
|
|
71
|
+
const v = part.slice(idx + 1).trim();
|
|
72
|
+
if (k) out[k] = decodeURIComponent(v);
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/middleware.ts
|
|
78
|
+
var DEFAULT_COOKIE = "admin_kit_token";
|
|
79
|
+
function createAdminMiddleware(config, opts = {}) {
|
|
80
|
+
const publicRoutes = [
|
|
81
|
+
...config.auth.publicRoutes ?? ["/login", "/api/auth"],
|
|
82
|
+
...opts.publicRoutes ?? []
|
|
83
|
+
];
|
|
84
|
+
const loginPath = config.auth.loginPage?.path ?? "/login";
|
|
85
|
+
const cookieName = config.auth.jwt?.cookieName ?? DEFAULT_COOKIE;
|
|
86
|
+
const secret = config.auth.jwt?.secret;
|
|
87
|
+
const verify = opts.verify ?? (secret ? async (token) => {
|
|
88
|
+
const r = await verifyJWT(token, secret);
|
|
89
|
+
return { valid: r.valid };
|
|
90
|
+
} : void 0);
|
|
91
|
+
return async function adminMiddleware(req) {
|
|
92
|
+
const url = new URL(req.url);
|
|
93
|
+
const pathname = url.pathname;
|
|
94
|
+
if (publicRoutes.some((p) => pathname === p || pathname.startsWith(p + "/"))) {
|
|
95
|
+
return passthrough();
|
|
96
|
+
}
|
|
97
|
+
const token = parseCookies(req.headers.get("cookie"))[cookieName];
|
|
98
|
+
if (!token) return redirectToLogin(url, pathname, loginPath);
|
|
99
|
+
if (verify) {
|
|
100
|
+
const { valid } = await verify(token);
|
|
101
|
+
if (!valid) return redirectToLogin(url, pathname, loginPath);
|
|
102
|
+
}
|
|
103
|
+
return passthrough();
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function passthrough() {
|
|
107
|
+
return new Response(null, { status: 200 });
|
|
108
|
+
}
|
|
109
|
+
function redirectToLogin(url, pathname, loginPath) {
|
|
110
|
+
const target = new URL(loginPath, url.origin);
|
|
111
|
+
target.searchParams.set("next", pathname);
|
|
112
|
+
return Response.redirect(target.toString(), 307);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.createAdminMiddleware = createAdminMiddleware;
|
|
116
|
+
//# sourceMappingURL=middleware.cjs.map
|
|
117
|
+
//# sourceMappingURL=middleware.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/server/verifyJWT.ts","../src/auth/server/cookies.ts","../src/middleware.ts"],"names":[],"mappings":"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","file":"middleware.cjs","sourcesContent":["/**\n * Edge-safe JWT verification using the Web Crypto API.\n * Supports HS256 / HS384 / HS512. For RS-family or ES-family algorithms,\n * plug in `jose` via the `verify` option on createAdminMiddleware\n * (custom verifier).\n */\n\nconst enc = new TextEncoder()\n\n/**\n * Web Crypto's `BufferSource` requires `Uint8Array<ArrayBuffer>`. Newer TS\n * lib types widen `TextEncoder.encode()` / typed arrays to `ArrayBufferLike`,\n * which leaks `SharedArrayBuffer` into the type. Copy into a fresh ArrayBuffer\n * so the call sites typecheck cleanly without `as` casts.\n */\nfunction toAB(view: Uint8Array): ArrayBuffer {\n const buf = new ArrayBuffer(view.byteLength)\n new Uint8Array(buf).set(view)\n return buf\n}\n\nfunction base64UrlDecode(input: string): Uint8Array<ArrayBuffer> {\n const pad = input.length % 4 === 0 ? '' : '='.repeat(4 - (input.length % 4))\n const b64 = (input + pad).replace(/-/g, '+').replace(/_/g, '/')\n const bin = typeof atob === 'function' ? atob(b64) : Buffer.from(b64, 'base64').toString('binary')\n const out = new Uint8Array(new ArrayBuffer(bin.length))\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\nfunction decodeJSON<T>(seg: string): T {\n const bytes = base64UrlDecode(seg)\n const text = new TextDecoder().decode(bytes)\n return JSON.parse(text) as T\n}\n\nconst ALGS: Record<string, { name: 'HMAC'; hash: string }> = {\n HS256: { name: 'HMAC', hash: 'SHA-256' },\n HS384: { name: 'HMAC', hash: 'SHA-384' },\n HS512: { name: 'HMAC', hash: 'SHA-512' },\n}\n\nexport interface JWTPayload {\n sub?: string\n exp?: number\n iat?: number\n nbf?: number\n [key: string]: unknown\n}\n\nexport interface VerifyResult {\n valid: boolean\n payload: JWTPayload | null\n reason?: string\n}\n\nexport async function verifyJWT(token: string, secret: string): Promise<VerifyResult> {\n const parts = token.split('.')\n if (parts.length !== 3) return { valid: false, payload: null, reason: 'malformed' }\n const [headerSeg, payloadSeg, sigSeg] = parts\n let header: { alg?: string; typ?: string }\n try {\n header = decodeJSON<{ alg?: string; typ?: string }>(headerSeg)\n } catch {\n return { valid: false, payload: null, reason: 'bad-header' }\n }\n const algSpec = header.alg ? ALGS[header.alg] : undefined\n if (!algSpec) return { valid: false, payload: null, reason: `unsupported-alg:${header.alg}` }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n toAB(enc.encode(secret)),\n { name: 'HMAC', hash: algSpec.hash },\n false,\n ['verify'],\n )\n const data = toAB(enc.encode(`${headerSeg}.${payloadSeg}`))\n const sig = toAB(base64UrlDecode(sigSeg))\n const ok = await crypto.subtle.verify('HMAC', key, sig, data)\n if (!ok) return { valid: false, payload: null, reason: 'bad-signature' }\n\n let payload: JWTPayload\n try {\n payload = decodeJSON<JWTPayload>(payloadSeg)\n } catch {\n return { valid: false, payload: null, reason: 'bad-payload' }\n }\n\n const now = Math.floor(Date.now() / 1000)\n if (payload.exp != null && now >= payload.exp) return { valid: false, payload, reason: 'expired' }\n if (payload.nbf != null && now < payload.nbf) return { valid: false, payload, reason: 'not-yet-valid' }\n\n return { valid: true, payload }\n}\n","/**\n * Edge-safe cookie helpers used by middleware and server helpers.\n * Avoid importing anything React/DOM here.\n */\n\nexport interface CookieOptions {\n path?: string\n maxAge?: number\n domain?: string\n secure?: boolean\n httpOnly?: boolean\n sameSite?: 'lax' | 'strict' | 'none'\n}\n\nexport function serializeCookie(name: string, value: string, opts: CookieOptions = {}): string {\n const parts = [`${name}=${encodeURIComponent(value)}`]\n parts.push(`Path=${opts.path ?? '/'}`)\n if (opts.maxAge != null) parts.push(`Max-Age=${opts.maxAge}`)\n if (opts.domain) parts.push(`Domain=${opts.domain}`)\n if (opts.secure) parts.push('Secure')\n if (opts.httpOnly) parts.push('HttpOnly')\n parts.push(`SameSite=${opts.sameSite ?? 'Lax'}`)\n return parts.join('; ')\n}\n\nexport function parseCookies(header: string | null | undefined): Record<string, string> {\n if (!header) return {}\n const out: Record<string, string> = {}\n for (const part of header.split(';')) {\n const idx = part.indexOf('=')\n if (idx === -1) continue\n const k = part.slice(0, idx).trim()\n const v = part.slice(idx + 1).trim()\n if (k) out[k] = decodeURIComponent(v)\n }\n return out\n}\n\nexport function readCookieFromRequest(req: Request, name: string): string | null {\n return parseCookies(req.headers.get('cookie'))[name] ?? null\n}\n","/**\n * Edge-safe middleware factory. Mount in the consumer's `middleware.ts`:\n *\n * // middleware.ts (consumer)\n * import { createAdminMiddleware } from '@cortejojicoy/admin-kit/middleware'\n * import { adminConfig } from './admin.config'\n *\n * export default createAdminMiddleware(adminConfig)\n * export const config = { matcher: ['/((?!_next|api/auth|favicon).*)'] }\n *\n * Keep this file free of React / DOM / Node-only deps.\n */\nimport type { AdminConfig } from './config/types'\nimport { verifyJWT } from './auth/server/verifyJWT'\nimport { parseCookies } from './auth/server/cookies'\n\nconst DEFAULT_COOKIE = 'admin_kit_token'\n\nexport interface AdminMiddlewareOptions {\n /** Override token verification (e.g., RS256 with `jose`). */\n verify?: (token: string) => Promise<{ valid: boolean }>\n /** Extra public routes that bypass auth. Merged with config.auth.publicRoutes. */\n publicRoutes?: string[]\n}\n\ntype MiddlewareHandler = (req: Request) => Response | Promise<Response>\n\nexport function createAdminMiddleware(\n config: AdminConfig,\n opts: AdminMiddlewareOptions = {},\n): MiddlewareHandler {\n const publicRoutes = [\n ...(config.auth.publicRoutes ?? ['/login', '/api/auth']),\n ...(opts.publicRoutes ?? []),\n ]\n const loginPath = config.auth.loginPage?.path ?? '/login'\n const cookieName = config.auth.jwt?.cookieName ?? DEFAULT_COOKIE\n const secret = config.auth.jwt?.secret\n const verify =\n opts.verify ??\n (secret\n ? async (token: string) => {\n const r = await verifyJWT(token, secret)\n return { valid: r.valid }\n }\n : undefined)\n\n return async function adminMiddleware(req: Request): Promise<Response> {\n const url = new URL(req.url)\n const pathname = url.pathname\n\n if (publicRoutes.some((p) => pathname === p || pathname.startsWith(p + '/'))) {\n return passthrough()\n }\n\n const token = parseCookies(req.headers.get('cookie'))[cookieName]\n if (!token) return redirectToLogin(url, pathname, loginPath)\n\n if (verify) {\n const { valid } = await verify(token)\n if (!valid) return redirectToLogin(url, pathname, loginPath)\n }\n // If no verifier is configured (oauth/custom), trust the cookie's existence\n // and let server helpers / API routes do the real check.\n return passthrough()\n }\n}\n\nfunction passthrough(): Response {\n // Returning a non-redirect Response with no body and 200 acts as a passthrough\n // in Next middleware semantics when used via NextResponse. The expected pattern\n // is for consumers to wrap this with NextResponse.next() if they need the\n // typed return. We return a plain Response that next() can interpret.\n return new Response(null, { status: 200 })\n}\n\nfunction redirectToLogin(url: URL, pathname: string, loginPath: string): Response {\n const target = new URL(loginPath, url.origin)\n target.searchParams.set('next', pathname)\n return Response.redirect(target.toString(), 307)\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { A as AdminConfig } from './types-N0f4k4Ie.cjs';
|
|
2
|
+
import 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Edge-safe middleware factory. Mount in the consumer's `middleware.ts`:
|
|
6
|
+
*
|
|
7
|
+
* // middleware.ts (consumer)
|
|
8
|
+
* import { createAdminMiddleware } from '@cortejojicoy/admin-kit/middleware'
|
|
9
|
+
* import { adminConfig } from './admin.config'
|
|
10
|
+
*
|
|
11
|
+
* export default createAdminMiddleware(adminConfig)
|
|
12
|
+
* export const config = { matcher: ['/((?!_next|api/auth|favicon).*)'] }
|
|
13
|
+
*
|
|
14
|
+
* Keep this file free of React / DOM / Node-only deps.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface AdminMiddlewareOptions {
|
|
18
|
+
/** Override token verification (e.g., RS256 with `jose`). */
|
|
19
|
+
verify?: (token: string) => Promise<{
|
|
20
|
+
valid: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
/** Extra public routes that bypass auth. Merged with config.auth.publicRoutes. */
|
|
23
|
+
publicRoutes?: string[];
|
|
24
|
+
}
|
|
25
|
+
type MiddlewareHandler = (req: Request) => Response | Promise<Response>;
|
|
26
|
+
declare function createAdminMiddleware(config: AdminConfig, opts?: AdminMiddlewareOptions): MiddlewareHandler;
|
|
27
|
+
|
|
28
|
+
export { type AdminMiddlewareOptions, createAdminMiddleware };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { A as AdminConfig } from './types-N0f4k4Ie.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Edge-safe middleware factory. Mount in the consumer's `middleware.ts`:
|
|
6
|
+
*
|
|
7
|
+
* // middleware.ts (consumer)
|
|
8
|
+
* import { createAdminMiddleware } from '@cortejojicoy/admin-kit/middleware'
|
|
9
|
+
* import { adminConfig } from './admin.config'
|
|
10
|
+
*
|
|
11
|
+
* export default createAdminMiddleware(adminConfig)
|
|
12
|
+
* export const config = { matcher: ['/((?!_next|api/auth|favicon).*)'] }
|
|
13
|
+
*
|
|
14
|
+
* Keep this file free of React / DOM / Node-only deps.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface AdminMiddlewareOptions {
|
|
18
|
+
/** Override token verification (e.g., RS256 with `jose`). */
|
|
19
|
+
verify?: (token: string) => Promise<{
|
|
20
|
+
valid: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
/** Extra public routes that bypass auth. Merged with config.auth.publicRoutes. */
|
|
23
|
+
publicRoutes?: string[];
|
|
24
|
+
}
|
|
25
|
+
type MiddlewareHandler = (req: Request) => Response | Promise<Response>;
|
|
26
|
+
declare function createAdminMiddleware(config: AdminConfig, opts?: AdminMiddlewareOptions): MiddlewareHandler;
|
|
27
|
+
|
|
28
|
+
export { type AdminMiddlewareOptions, createAdminMiddleware };
|