@nextjscms/plugin-cpanel-dashboard 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ type CpanelDashboardPageProps = {
2
+ title?: string;
3
+ };
4
+ export declare const CpanelDashboardPage: ({ title }: CpanelDashboardPageProps) => import("react/jsx-runtime").JSX.Element;
5
+ export default CpanelDashboardPage;
6
+ //# sourceMappingURL=DashboardPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../src/client/DashboardPage.tsx"],"names":[],"mappings":"AAuBA,KAAK,wBAAwB,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,WAAW,wBAAwB,4CA0NtE,CAAA;AAkFD,eAAe,mBAAmB,CAAA"}
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { humanReadableFileSize } from 'nextjs-cms/utils';
4
+ import { trpc as trpcClient } from 'nextjs-cms/api/trpc/client';
5
+ import { useI18n } from 'nextjs-cms/translations/client';
6
+ // import { LucideIcon } from 'lucide-react'
7
+ import { HardDriveIcon, NetworkIcon, MailIcon, DatabaseIcon, ServerIcon, FolderIcon, HexagonIcon, PackageIcon } from 'lucide-react';
8
+ export const CpanelDashboardPage = ({ title }) => {
9
+ const t = useI18n();
10
+ const trpc = trpcClient;
11
+ const query = trpc?.cpanelDashboard?.getData.useQuery;
12
+ const { data, isLoading, isError, error } = query ? query() : { isLoading: true, isError: true, error: null };
13
+ if (!query) {
14
+ return (_jsx("div", { className: 'flex min-h-[200px] items-center justify-center p-6', children: _jsx("div", { className: 'rounded-lg border border-destructive/30 bg-destructive/5 px-6 py-4 text-sm text-destructive', children: t('cpanelPluginMisconfigured') }) }));
15
+ }
16
+ return (_jsxs("div", { className: 'w-full', children: [_jsx("div", { className: 'bg-orange-500 dark:bg-orange-800 p-8 font-extrabold text-foreground', children: _jsx("div", { className: 'relative', children: _jsx("h1", { className: 'text-3xl font-bold tracking-tight text-white', children: title || t('cPanelDashboard') }) }) }), _jsxs("div", { className: 'flex flex-col gap-6 p-6', children: [isLoading && (_jsx("div", { className: 'grid grid-cols-1 gap-4 md-sidebar:grid-cols-2 2xl-sidebar:grid-cols-4', children: [...Array(4)].map((_, i) => (_jsxs("div", { className: 'animate-pulse rounded-xl border bg-card p-5', children: [_jsxs("div", { className: 'mb-4 flex items-center gap-3', children: [_jsx("div", { className: 'size-10 rounded-lg bg-muted' }), _jsx("div", { className: 'h-4 w-24 rounded bg-muted' })] }), _jsx("div", { className: 'mb-2 h-8 w-20 rounded bg-muted' }), _jsx("div", { className: 'h-2 rounded-full bg-muted' })] }, i))) })), isError && !isLoading && (_jsxs("div", { className: 'flex items-center gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-4', children: [_jsx("div", { className: 'flex size-10 shrink-0 items-center justify-center rounded-full bg-destructive/10', children: _jsx("svg", { className: 'size-5 text-destructive', fill: 'none', stroke: 'currentColor', viewBox: '0 0 24 24', children: _jsx("path", { strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: 2, d: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z' }) }) }), _jsxs("div", { children: [_jsx("p", { className: 'font-medium text-destructive', children: t('unableToLoadCpanelData') }), error instanceof Error && (_jsx("p", { className: 'mt-0.5 text-sm text-destructive/80', children: error.message }))] })] })), data && (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'grid grid-cols-1 gap-4 md-sidebar:grid-cols-2 2xl-sidebar:grid-cols-4', children: [_jsx(StatCard, { icon: _jsx(HardDriveIcon, { color: 'blue' }), title: t('diskSpace'), used: data.diskSpaceUsage, total: data.diskSpaceLimit, formatFn: humanReadableFileSize }), _jsx(StatCard, { icon: _jsx(NetworkIcon, { color: 'green' }), title: t('thisMothBandwidth'), used: data.bandwidthUsage, total: data.bandwidthLimit, formatFn: humanReadableFileSize }), _jsx(StatCard, { icon: _jsx(MailIcon, { color: 'red' }), title: t('emailAccounts'), used: data.emailsUsage, total: data.emailsLimit }), _jsx(StatCard, { icon: _jsx(DatabaseIcon, { color: 'purple' }), title: t('mysqlDatabases'), used: data.dbsCount, total: data.dbsLimit })] }), _jsxs("div", { className: 'grid grid-cols-1 gap-6 lg-sidebar:grid-cols-2', children: [_jsxs("div", { className: 'overflow-hidden rounded-xl border bg-card shadow-sm', children: [_jsxs("div", { className: 'flex items-center gap-3 border-b bg-gradient-to-r from-cyan-500/10 via-transparent to-transparent px-6 py-5', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-xl bg-cyan-500/15 text-cyan-600 dark:bg-cyan-500/20 dark:text-cyan-400', children: _jsx(ServerIcon, {}) }), _jsx("h2", { className: 'text-lg font-semibold text-card-foreground', children: t('accountInformation') })] }), _jsxs("div", { className: 'divide-y p-2', children: [_jsx(InfoRow, { icon: _jsx(HexagonIcon, {}), iconColor: 'text-green-800', label: t('nodeVersion'), value: data?.nodeVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('pnpmVersion'), value: data?.pnpmVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('npmVersion'), value: data?.npmVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx(PackageIcon, {}), iconColor: 'text-red-800', label: t('bunVersion'), value: data?.bunVersion ?? 'N/A', valueColor: 'text-green-600 dark:text-green-400' }), _jsx(InfoRow, { icon: _jsx("span", { className: 'font-mono text-xs font-bold text-indigo-600 dark:text-indigo-400', children: "PHP" }), label: t('phpVersion'), value: data?.phpVersion ?? 'N/A', valueColor: 'text-indigo-600 dark:text-indigo-400' }), _jsx(InfoRow, { icon: _jsx(FolderIcon, {}), iconColor: 'text-amber-500', label: t('documentRoot'), value: data?.documentRoot ?? 'N/A', mono: true })] })] }), _jsxs("div", { className: 'overflow-hidden rounded-xl border bg-card shadow-sm', children: [_jsxs("div", { className: 'flex items-center gap-3 border-b bg-gradient-to-r from-purple-500/10 via-transparent to-transparent px-6 py-5', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-xl bg-purple-500/15 text-purple-600 dark:bg-purple-500/20 dark:text-purple-400', children: _jsx(DatabaseIcon, {}) }), _jsx("h2", { className: 'text-lg font-semibold text-card-foreground', children: t('database') })] }), data?.dbInfo ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'divide-y border-b p-2', children: [_jsx(InfoRow, { label: t('version'), value: data.dbInfo.version, valueColor: 'text-purple-600 dark:text-purple-400 font-semibold' }), _jsx(InfoRow, { label: t('remote'), value: _jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ${data.dbInfo.is_remote ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-400' : 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-400'}`, children: data.dbInfo.is_remote ? t('yes') : t('no') }) })] }), data?.dbsList?.length > 0 && (_jsxs("div", { className: 'p-4', children: [_jsxs("p", { className: 'mb-4 text-xs font-semibold uppercase tracking-wider text-purple-600 dark:text-purple-400', children: [t('databases'), " (", data.dbsList.length, ")"] }), _jsx("div", { className: 'space-y-3', children: data.dbsList.map((db, index) => (_jsxs("div", { className: 'flex items-center justify-between rounded-xl border border-purple-200/50 bg-gradient-to-r from-purple-50 to-transparent p-4 transition-all hover:border-purple-300 hover:shadow-sm dark:border-purple-800/30 dark:from-purple-900/20 dark:hover:border-purple-700', children: [_jsxs("div", { className: 'flex items-center gap-3', children: [_jsx("div", { className: 'flex size-10 items-center justify-center rounded-lg bg-purple-500/15 text-purple-600 dark:bg-purple-500/25 dark:text-purple-400', children: _jsx(DatabaseIcon, {}) }), _jsxs("div", { children: [_jsx("p", { className: 'font-semibold text-card-foreground', children: db.database }), _jsxs("p", { className: 'text-xs text-muted-foreground', children: [db.users?.length ?? 0, " ", t('users')] })] })] }), _jsxs("div", { className: 'text-right', children: [_jsx("p", { className: 'text-sm font-bold text-purple-600 dark:text-purple-400', children: humanReadableFileSize(db.disk_usage) }), _jsx("p", { className: 'text-xs text-muted-foreground', children: t('diskUsage') })] })] }, `${db.name}_${db.database}_${index}`))) })] }))] })) : (_jsx("div", { className: 'flex items-center justify-center py-12 text-sm text-muted-foreground', children: t('mysqlNotInstalled') }))] })] })] }))] })] }));
17
+ };
18
+ const StatCard = ({ icon, title, used, total, formatFn }) => {
19
+ const t = useI18n();
20
+ const percentage = total > 0 ? Math.min((used / total) * 100, 100) : 0;
21
+ const displayUsed = formatFn ? formatFn(used) : used.toString();
22
+ const displayTotal = formatFn ? formatFn(total) : total.toString();
23
+ // Warning colors for high usage
24
+ const getProgressColor = () => {
25
+ if (percentage >= 90)
26
+ return 'bg-red-500';
27
+ if (percentage >= 75)
28
+ return 'bg-yellow-500';
29
+ return 'bg-green-500';
30
+ };
31
+ return (_jsx("div", { className: `group relative overflow-hidden rounded-xl border border-l-4 bg-card p-6 shadow-sm transition-all hover:shadow-lg`, children: _jsxs("div", { className: 'flex flex-col relative', children: [_jsxs("div", { className: 'mb-4 flex items-center justify-between', children: [_jsx("span", { className: 'text-sm font-medium text-muted-foreground', children: title }), _jsx("div", { className: `flex size-11 items-center justify-center rounded-xl`, children: icon })] }), _jsxs("div", { className: 'flex items-end gap-2 justify-start content-end mb-4 text-start w-full', children: [_jsx("span", { dir: 'ltr', className: 'text-3xl font-bold tracking-tight text-card-foreground', children: displayUsed }), _jsx("span", { children: "/" }), _jsxs("span", { dir: 'ltr', className: 'text-sm text-muted-foreground', children: [" ", displayTotal] })] }), _jsx("div", { className: 'h-2.5 overflow-hidden rounded-full bg-muted/50', children: _jsx("div", { className: `h-full rounded-full transition-all duration-500 ${getProgressColor()}`, style: { width: `${percentage}%` } }) }), _jsxs("div", { className: 'flex flex-row gap-2 pt-3 text-xs font-medium text-muted-foreground', children: [_jsxs("span", { className: percentage >= 75 ? 'text-amber-600 dark:text-amber-400' : percentage >= 90 ? 'text-red-600 dark:text-red-400' : '', children: [percentage.toFixed(1), "%"] }), _jsx("span", { children: t('usedLabel') })] })] }) }));
32
+ };
33
+ const InfoRow = ({ icon, iconColor, label, value, valueColor, mono }) => (_jsxs("div", { className: 'flex items-center justify-between rounded-lg px-4 py-4 transition-colors hover:bg-muted/30', children: [_jsxs("div", { className: 'flex items-center gap-3 text-sm text-muted-foreground', children: [icon && _jsx("span", { className: iconColor || 'text-muted-foreground/70', children: icon }), _jsx("span", { className: 'font-medium', children: label })] }), _jsx("span", { className: `text-sm ${valueColor || 'text-card-foreground'} ${mono ? 'font-mono text-xs' : 'font-medium'}`, children: value })] }));
34
+ export default CpanelDashboardPage;
@@ -0,0 +1,3 @@
1
+ export declare const PLUGIN_TITLE = "cPanel Dashboard";
2
+ export declare function createPlugin(): import("nextjs-cms/plugins/server").CMSPluginSingleRoute;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,qBAAqB,CAAA;AAC9C,wBAAgB,YAAY,6DAc3B"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ import { definePlugin } from 'nextjs-cms/plugins/server';
2
+ import { cpanelDashboardRouter } from './router.js';
3
+ export const PLUGIN_TITLE = 'cPanel Dashboard';
4
+ export function createPlugin() {
5
+ return definePlugin({
6
+ title: PLUGIN_TITLE,
7
+ name: 'plugin_cpanel_dashboard',
8
+ registryName: 'cpanel-dashboard',
9
+ router: cpanelDashboardRouter,
10
+ routes: [
11
+ {
12
+ path: '/cpanel-dashboard',
13
+ title: PLUGIN_TITLE,
14
+ icon: 'home',
15
+ },
16
+ ],
17
+ });
18
+ }
@@ -0,0 +1,47 @@
1
+ export declare const cpanelDashboardRouter: import("@trpc/server").TRPCBuiltRouter<{
2
+ ctx: {
3
+ headers: Headers;
4
+ db: import("drizzle-orm/mysql2").MySql2Database<typeof import("nextjs-cms/db/schema")> & {
5
+ $client: import("mysql2/promise").Pool;
6
+ };
7
+ session: import("nextjs-cms").Session | null;
8
+ };
9
+ meta: object;
10
+ errorShape: {
11
+ data: {
12
+ zodError: import("zod").ZodFlattenedError<unknown, string> | null;
13
+ code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
14
+ httpStatus: number;
15
+ path?: string;
16
+ stack?: string;
17
+ };
18
+ message: string;
19
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
20
+ };
21
+ transformer: true;
22
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
23
+ getData: import("@trpc/server").TRPCQueryProcedure<{
24
+ input: void;
25
+ output: {
26
+ dbsLimit: number;
27
+ dbsCount: number;
28
+ bandwidthUsage: number;
29
+ bandwidthLimit: number;
30
+ diskSpaceUsage: number;
31
+ diskSpaceLimit: number;
32
+ emailsUsage: number;
33
+ emailsLimit: number;
34
+ dbInfo: any;
35
+ dbsList: any;
36
+ phpVersion: any;
37
+ nodeVersion: string | null;
38
+ pnpmVersion: string | null;
39
+ npmVersion: string | null;
40
+ bunVersion: string | null;
41
+ passengerAppList: never[];
42
+ documentRoot: any;
43
+ };
44
+ meta: object;
45
+ }>;
46
+ }>>;
47
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;gBAsBvB,CAAC;iBACA,CAAH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEP,CAAA"}
package/dist/router.js ADDED
@@ -0,0 +1,118 @@
1
+ import { TRPCError } from '@trpc/server';
2
+ import { execSync } from 'child_process';
3
+ import getString from 'nextjs-cms/translations';
4
+ import { CpanelAPI } from 'nextjs-cms/utils';
5
+ import { pluginProcedure, router } from 'nextjs-cms/api/trpc';
6
+ const getNodeVersion = () => {
7
+ try {
8
+ const version = execSync('node -v', { encoding: 'utf-8' }).trim();
9
+ return version; // Returns something like "v20.10.0"
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ };
15
+ const getPnpmVersion = () => {
16
+ try {
17
+ const version = execSync('pnpm -v', { encoding: 'utf-8' }).trim();
18
+ return version; // Returns something like "10.10.0"
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ };
24
+ const getNpmVersion = () => {
25
+ try {
26
+ const version = execSync('npm -v', { encoding: 'utf-8' }).trim();
27
+ return version; // Returns something like "10.10.0"
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ };
33
+ const getBunVersion = () => {
34
+ try {
35
+ const version = execSync('bun -v', { encoding: 'utf-8' }).trim();
36
+ return version; // Returns something like "10.10.0"
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ };
42
+ export const cpanelDashboardRouter = router({
43
+ getData: pluginProcedure('plugin_cpanel_dashboard').query(async ({ ctx }) => {
44
+ if (!process.env.CPANEL_USER || !process.env.CPANEL_PASSWORD || !process.env.CPANEL_DOMAIN) {
45
+ throw new TRPCError({
46
+ code: 'BAD_REQUEST',
47
+ message: getString('cpanelCredentialsNotSet'),
48
+ });
49
+ }
50
+ const cPanel = new CpanelAPI(process.env.CPANEL_USER, process.env.CPANEL_PASSWORD, `cpanel.${process.env.CPANEL_DOMAIN}`);
51
+ const data = await Promise.all([
52
+ cPanel.callApi('DomainInfo', 'single_domain_data', {
53
+ domain: process.env.CPANEL_DOMAIN,
54
+ }),
55
+ cPanel.callApi('ResourceUsage', 'get_usages'),
56
+ cPanel.callApi('Mysql', 'get_server_information'),
57
+ cPanel.callApi('Mysql', 'list_databases'),
58
+ ]);
59
+ if (cPanel.isError) {
60
+ throw new TRPCError({
61
+ code: 'BAD_REQUEST',
62
+ message: cPanel.getError(),
63
+ });
64
+ }
65
+ const dbInfo = data[2];
66
+ const dbsList = data[3];
67
+ let bandwidthLimit = 0, bandwidthUsage = 0;
68
+ let diskSpaceLimit = 0, usedDiskSpace = 0;
69
+ let emailsLimit = 0, emailsCount = 0;
70
+ let dbsLimit = 0, dbsCount = 0;
71
+ const domainInfoData = data[0].data;
72
+ const cpanelUsagesArray = data[1].data;
73
+ cpanelUsagesArray.forEach((singleItemUsage) => {
74
+ switch (singleItemUsage.id) {
75
+ case 'bandwidth':
76
+ bandwidthLimit = singleItemUsage.maximum || 1000000000000;
77
+ bandwidthUsage = singleItemUsage.usage;
78
+ break;
79
+ case 'disk_usage':
80
+ diskSpaceLimit = singleItemUsage.maximum || 1000000000000;
81
+ usedDiskSpace = singleItemUsage.usage;
82
+ break;
83
+ case 'email_accounts':
84
+ emailsLimit = singleItemUsage.maximum || 1000000000000;
85
+ emailsCount = singleItemUsage.usage;
86
+ break;
87
+ case 'mysql_databases':
88
+ dbsLimit = singleItemUsage.maximum || 1000000000000;
89
+ dbsCount = singleItemUsage.usage;
90
+ break;
91
+ }
92
+ });
93
+ // Get Node.js version from the server
94
+ const nodeVersion = getNodeVersion();
95
+ const pnpmVersion = getPnpmVersion();
96
+ const npmVersion = getNpmVersion();
97
+ const bunVersion = getBunVersion();
98
+ return {
99
+ dbsLimit,
100
+ dbsCount,
101
+ bandwidthUsage,
102
+ bandwidthLimit,
103
+ diskSpaceUsage: usedDiskSpace,
104
+ diskSpaceLimit,
105
+ emailsUsage: emailsCount,
106
+ emailsLimit,
107
+ dbInfo: dbInfo.data,
108
+ dbsList: dbsList.data,
109
+ phpVersion: domainInfoData?.phpversion,
110
+ nodeVersion,
111
+ pnpmVersion,
112
+ npmVersion,
113
+ bunVersion,
114
+ passengerAppList: [],
115
+ documentRoot: domainInfoData?.documentroot,
116
+ };
117
+ }),
118
+ });
@@ -0,0 +1,2 @@
1
+ export default function CpanelDashboardServer(): Promise<import("react/jsx-runtime").JSX.Element>;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":"AAOA,wBAA8B,qBAAqB,qDA6BlD"}
package/dist/server.js ADDED
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { api, HydrateClient } from 'nextjs-cms/api/trpc/server';
3
+ import { CpanelDashboardPage } from './client/DashboardPage.js';
4
+ import { findPluginRouteByPath } from 'nextjs-cms/plugins/server';
5
+ import { resolveLocalizedString, resolveLocale } from 'nextjs-cms/translations';
6
+ import { getCMSConfig } from 'nextjs-cms/core';
7
+ import auth from 'nextjs-cms/auth';
8
+ export default async function CpanelDashboardServer() {
9
+ const helpers = api;
10
+ const prefetch = helpers.cpanelDashboard?.getData?.prefetch;
11
+ if (!prefetch) {
12
+ throw new Error('[cpanel-dashboard] Missing cpanelDashboard.getData prefetch helper.');
13
+ }
14
+ await prefetch();
15
+ // Resolve the plugin route title
16
+ const [route, session, config] = await Promise.all([
17
+ findPluginRouteByPath('/cpanel-dashboard'),
18
+ auth(),
19
+ getCMSConfig(),
20
+ ]);
21
+ const { supportedLanguages, fallbackLanguage } = config.i18n;
22
+ const locale = resolveLocale(session?.user?.locale, supportedLanguages, fallbackLanguage);
23
+ const resolvedTitle = route ? resolveLocalizedString(route.title, locale, fallbackLanguage) : '';
24
+ return (_jsx(HydrateClient, { children: _jsx(CpanelDashboardPage, { title: resolvedTitle }) }));
25
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@nextjscms/plugin-cpanel-dashboard",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./server": {
13
+ "types": "./dist/server.d.ts",
14
+ "default": "./dist/server.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/**/*",
19
+ "README.md"
20
+ ],
21
+ "private": false,
22
+ "dependencies": {
23
+ "@trpc/server": "^11.4.2",
24
+ "zod": "4.1.12"
25
+ },
26
+ "peerDependencies": {
27
+ "lucide-react": "^0.563.0",
28
+ "react": "19.2.3",
29
+ "react-dom": "19.2.3",
30
+ "nextjs-cms": "0.7.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^19.2.7",
34
+ "@types/react-dom": "^19.2.3",
35
+ "typescript": "^5.9.2"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "dev": "tsc --watch",
40
+ "clean": "git clean -xdf .cache .turbo dist node_modules"
41
+ }
42
+ }