nextjs-cms 0.5.66 → 0.5.68

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.
@@ -1,7 +1,7 @@
1
1
  import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
2
2
  import type { AppRouter } from './root.js';
3
- import { appRouter } from './root.js';
4
- import { createTRPCContext } from './trpc.js';
3
+ import { appRouter, createCallerWithPlugins, getAppRouter } from './root.js';
4
+ import { createTRPCContext, privateProcedure, publicProcedure, router } from './trpc.js';
5
5
  /**
6
6
  * Create a server-side caller for the tRPC API
7
7
  * @example
@@ -759,7 +759,7 @@ declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
759
759
  meta: object;
760
760
  }>;
761
761
  }>>;
762
- cpanel: import("@trpc/server").TRPCBuiltRouter<{
762
+ plugins: import("@trpc/server").TRPCBuiltRouter<{
763
763
  ctx: {
764
764
  headers: Headers;
765
765
  db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
@@ -781,89 +781,26 @@ declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
781
781
  };
782
782
  transformer: true;
783
783
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
784
- getData: import("@trpc/server").TRPCQueryProcedure<{
784
+ list: import("@trpc/server").TRPCQueryProcedure<{
785
785
  input: void;
786
786
  output: {
787
- dbsLimit: number;
788
- dbsCount: number;
789
- bandwidthUsage: number;
790
- bandwidthLimit: number;
791
- diskSpaceUsage: number;
792
- diskSpaceLimit: number;
793
- emailsUsage: number;
794
- emailsLimit: number;
795
- dbInfo: any;
796
- dbsList: any;
797
- phpVersion: any;
798
- passengerAppList: never[];
799
- documentRoot: any;
800
- };
787
+ id: string;
788
+ name: string;
789
+ version: string | undefined;
790
+ package: string;
791
+ }[];
801
792
  meta: object;
802
793
  }>;
803
- getEmails: import("@trpc/server").TRPCQueryProcedure<{
794
+ routes: import("@trpc/server").TRPCQueryProcedure<{
804
795
  input: void;
805
796
  output: {
806
- emails: any;
807
- };
808
- meta: object;
809
- }>;
810
- createEmail: import("@trpc/server").TRPCMutationProcedure<{
811
- input: {
812
- email: string;
813
- password: string;
814
- quota: string;
815
- };
816
- output: any;
817
- meta: object;
818
- }>;
819
- quotaChange: import("@trpc/server").TRPCMutationProcedure<{
820
- input: {
821
- email: string;
822
- quota: string;
823
- };
824
- output: any;
825
- meta: object;
826
- }>;
827
- passwordChange: import("@trpc/server").TRPCMutationProcedure<{
828
- input: {
829
- email: string;
830
- password: string;
831
- passwordConfirm: string;
832
- };
833
- output: any;
834
- meta: object;
835
- }>;
836
- deleteEmail: import("@trpc/server").TRPCMutationProcedure<{
837
- input: string;
838
- output: any;
839
- meta: object;
840
- }>;
841
- }>>;
842
- googleAnalytics: import("@trpc/server").TRPCBuiltRouter<{
843
- ctx: {
844
- headers: Headers;
845
- db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
846
- $client: import("mysql2/promise").Pool;
847
- };
848
- session: import("../index.js").Session | null;
849
- };
850
- meta: object;
851
- errorShape: {
852
- data: {
853
- zodError: import("zod").ZodFlattenedError<unknown, string> | null;
854
- code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
855
- httpStatus: number;
856
- path?: string;
857
- stack?: string;
858
- };
859
- message: string;
860
- code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
861
- };
862
- transformer: true;
863
- }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
864
- test: import("@trpc/server").TRPCQueryProcedure<{
865
- input: void;
866
- output: boolean;
797
+ pluginId: string;
798
+ pluginName?: string;
799
+ path: string;
800
+ title: string;
801
+ icon?: string;
802
+ component: string;
803
+ }[];
867
804
  meta: object;
868
805
  }>;
869
806
  }>>;
@@ -895,7 +832,8 @@ type RouterInputs = inferRouterInputs<AppRouter>;
895
832
  * ^? Post[]
896
833
  **/
897
834
  type RouterOutputs = inferRouterOutputs<AppRouter>;
898
- export { createTRPCContext, appRouter, createCaller };
835
+ export { createTRPCContext, appRouter, createCaller, createCallerWithPlugins, getAppRouter };
836
+ export { router, publicProcedure, privateProcedure };
899
837
  export type { AppRouter, RouterInputs, RouterOutputs };
900
- export { axiosPrivate } from './axios/axiosInstance';
838
+ export { axiosPrivate } from './axios/axiosInstance.js';
901
839
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAuB,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAElE;;;;;;GAMG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA;AAEnD;;;;;IAKI;AACJ,KAAK,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAA;AAEhD;;;;;IAKI;AACJ,KAAK,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;AAElD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,CAAA;AACrD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC5E,OAAO,EAAuB,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAE7G;;;;;;GAMG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA;AAEnD;;;;;IAKI;AACJ,KAAK,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAA;AAEhD;;;;;IAKI;AACJ,KAAK,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;AAElD,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,CAAA;AAC5F,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAA;AACpD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA"}
package/dist/api/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { appRouter } from './root.js';
2
- import { createCallerFactory, createTRPCContext } from './trpc.js';
1
+ import { appRouter, createCallerWithPlugins, getAppRouter } from './root.js';
2
+ import { createCallerFactory, createTRPCContext, privateProcedure, publicProcedure, router } from './trpc.js';
3
3
  /**
4
4
  * Create a server-side caller for the tRPC API
5
5
  * @example
@@ -8,5 +8,6 @@ import { createCallerFactory, createTRPCContext } from './trpc.js';
8
8
  * ^? Post[]
9
9
  */
10
10
  const createCaller = createCallerFactory(appRouter);
11
- export { createTRPCContext, appRouter, createCaller };
12
- export { axiosPrivate } from './axios/axiosInstance';
11
+ export { createTRPCContext, appRouter, createCaller, createCallerWithPlugins, getAppRouter };
12
+ export { router, publicProcedure, privateProcedure };
13
+ export { axiosPrivate } from './axios/axiosInstance.js';
@@ -1 +1 @@
1
- {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import sharp from 'sharp';
13
13
  import { readChunk } from 'read-chunk';
14
14
  import { fileTypeFromBuffer } from 'file-type';
15
15
  import { getCMSConfig } from '../../core/config/index.js';
16
+ import { getPluginRoutes } from '../../plugins/loader.js';
16
17
  import through2 from 'through2';
17
18
  export const getDocument = async (session, input) => {
18
19
  const { name, sectionName, fieldName } = input;
@@ -795,6 +796,7 @@ export const getSidebar = async (session) => {
795
796
  const { simple, has_items, category, fixed } = await SectionFactory.getSectionsForAdmin({
796
797
  admin: { id: session.user.id },
797
798
  });
799
+ const pluginRoutes = await getPluginRoutes();
798
800
  // Let's loop through the sections and add path, icon and title to each section item
799
801
  const simpleSectionItems = simple.map((section) => {
800
802
  return {
@@ -817,21 +819,17 @@ export const getSidebar = async (session) => {
817
819
  icon: section.icon,
818
820
  };
819
821
  });
822
+ const pluginSections = pluginRoutes.map((route) => ({
823
+ title: route.title,
824
+ path: route.path,
825
+ icon: route.icon ?? 'home',
826
+ }));
827
+ const fixedSections = [
828
+ ...pluginSections,
829
+ ...fixed.map((section) => ({ title: section, path: `/${section}`, icon: 'home' })),
830
+ ];
820
831
  return {
821
- fixed_sections: [
822
- {
823
- title: 'Dashboard',
824
- path: '/dashboard',
825
- icon: 'home',
826
- },
827
- ...fixed.map((section) => {
828
- return {
829
- title: section,
830
- path: `/${section}`,
831
- icon: 'home',
832
- };
833
- }),
834
- ],
832
+ fixed_sections: fixedSections,
835
833
  cat_sections: categorySectionsItems,
836
834
  has_items_sections: hasItemsSectionItems,
837
835
  simple_sections: simpleSectionItems,
@@ -1,3 +1,4 @@
1
+ import type { TRPCContext } from './trpc.js';
1
2
  export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
2
3
  ctx: {
3
4
  headers: Headers;
@@ -748,7 +749,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
748
749
  meta: object;
749
750
  }>;
750
751
  }>>;
751
- cpanel: import("@trpc/server").TRPCBuiltRouter<{
752
+ plugins: import("@trpc/server").TRPCBuiltRouter<{
752
753
  ctx: {
753
754
  headers: Headers;
754
755
  db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
@@ -770,89 +771,26 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
770
771
  };
771
772
  transformer: true;
772
773
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
773
- getData: import("@trpc/server").TRPCQueryProcedure<{
774
+ list: import("@trpc/server").TRPCQueryProcedure<{
774
775
  input: void;
775
776
  output: {
776
- dbsLimit: number;
777
- dbsCount: number;
778
- bandwidthUsage: number;
779
- bandwidthLimit: number;
780
- diskSpaceUsage: number;
781
- diskSpaceLimit: number;
782
- emailsUsage: number;
783
- emailsLimit: number;
784
- dbInfo: any;
785
- dbsList: any;
786
- phpVersion: any;
787
- passengerAppList: never[];
788
- documentRoot: any;
789
- };
777
+ id: string;
778
+ name: string;
779
+ version: string | undefined;
780
+ package: string;
781
+ }[];
790
782
  meta: object;
791
783
  }>;
792
- getEmails: import("@trpc/server").TRPCQueryProcedure<{
784
+ routes: import("@trpc/server").TRPCQueryProcedure<{
793
785
  input: void;
794
786
  output: {
795
- emails: any;
796
- };
797
- meta: object;
798
- }>;
799
- createEmail: import("@trpc/server").TRPCMutationProcedure<{
800
- input: {
801
- email: string;
802
- password: string;
803
- quota: string;
804
- };
805
- output: any;
806
- meta: object;
807
- }>;
808
- quotaChange: import("@trpc/server").TRPCMutationProcedure<{
809
- input: {
810
- email: string;
811
- quota: string;
812
- };
813
- output: any;
814
- meta: object;
815
- }>;
816
- passwordChange: import("@trpc/server").TRPCMutationProcedure<{
817
- input: {
818
- email: string;
819
- password: string;
820
- passwordConfirm: string;
821
- };
822
- output: any;
823
- meta: object;
824
- }>;
825
- deleteEmail: import("@trpc/server").TRPCMutationProcedure<{
826
- input: string;
827
- output: any;
828
- meta: object;
829
- }>;
830
- }>>;
831
- googleAnalytics: import("@trpc/server").TRPCBuiltRouter<{
832
- ctx: {
833
- headers: Headers;
834
- db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
835
- $client: import("mysql2/promise").Pool;
836
- };
837
- session: import("../index.js").Session | null;
838
- };
839
- meta: object;
840
- errorShape: {
841
- data: {
842
- zodError: import("zod").ZodFlattenedError<unknown, string> | null;
843
- code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
844
- httpStatus: number;
845
- path?: string;
846
- stack?: string;
847
- };
848
- message: string;
849
- code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
850
- };
851
- transformer: true;
852
- }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
853
- test: import("@trpc/server").TRPCQueryProcedure<{
854
- input: void;
855
- output: boolean;
787
+ pluginId: string;
788
+ pluginName?: string;
789
+ path: string;
790
+ title: string;
791
+ icon?: string;
792
+ component: string;
793
+ }[];
856
794
  meta: object;
857
795
  }>;
858
796
  }>>;
@@ -870,6 +808,29 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
870
808
  meta: object;
871
809
  }>;
872
810
  }>>;
811
+ export declare function getAppRouter(): Promise<import("@trpc/server").TRPCBuiltRouter<{
812
+ ctx: {
813
+ headers: Headers;
814
+ db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
815
+ $client: import("mysql2/promise").Pool;
816
+ };
817
+ session: import("../index.js").Session | null;
818
+ };
819
+ meta: object;
820
+ errorShape: {
821
+ data: {
822
+ zodError: import("zod").ZodFlattenedError<unknown, string> | null;
823
+ code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
824
+ httpStatus: number;
825
+ path?: string;
826
+ stack?: string;
827
+ };
828
+ message: string;
829
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
830
+ };
831
+ transformer: true;
832
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<import("@trpc/server").TRPCCreateRouterOptions>>>;
833
+ export declare function createCallerWithPlugins(ctx: TRPCContext): Promise<import("@trpc/server/unstable-core-do-not-import").DecorateRouterRecord<import("@trpc/server").TRPCDecorateCreateRouterOptions<import("@trpc/server").TRPCCreateRouterOptions>>>;
873
834
  export type AppRouter = typeof appRouter;
874
835
  export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
875
836
  ctx: {
@@ -1621,7 +1582,7 @@ export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
1621
1582
  meta: object;
1622
1583
  }>;
1623
1584
  }>>;
1624
- cpanel: import("@trpc/server").TRPCBuiltRouter<{
1585
+ plugins: import("@trpc/server").TRPCBuiltRouter<{
1625
1586
  ctx: {
1626
1587
  headers: Headers;
1627
1588
  db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
@@ -1643,89 +1604,26 @@ export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
1643
1604
  };
1644
1605
  transformer: true;
1645
1606
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
1646
- getData: import("@trpc/server").TRPCQueryProcedure<{
1607
+ list: import("@trpc/server").TRPCQueryProcedure<{
1647
1608
  input: void;
1648
1609
  output: {
1649
- dbsLimit: number;
1650
- dbsCount: number;
1651
- bandwidthUsage: number;
1652
- bandwidthLimit: number;
1653
- diskSpaceUsage: number;
1654
- diskSpaceLimit: number;
1655
- emailsUsage: number;
1656
- emailsLimit: number;
1657
- dbInfo: any;
1658
- dbsList: any;
1659
- phpVersion: any;
1660
- passengerAppList: never[];
1661
- documentRoot: any;
1662
- };
1610
+ id: string;
1611
+ name: string;
1612
+ version: string | undefined;
1613
+ package: string;
1614
+ }[];
1663
1615
  meta: object;
1664
1616
  }>;
1665
- getEmails: import("@trpc/server").TRPCQueryProcedure<{
1617
+ routes: import("@trpc/server").TRPCQueryProcedure<{
1666
1618
  input: void;
1667
1619
  output: {
1668
- emails: any;
1669
- };
1670
- meta: object;
1671
- }>;
1672
- createEmail: import("@trpc/server").TRPCMutationProcedure<{
1673
- input: {
1674
- email: string;
1675
- password: string;
1676
- quota: string;
1677
- };
1678
- output: any;
1679
- meta: object;
1680
- }>;
1681
- quotaChange: import("@trpc/server").TRPCMutationProcedure<{
1682
- input: {
1683
- email: string;
1684
- quota: string;
1685
- };
1686
- output: any;
1687
- meta: object;
1688
- }>;
1689
- passwordChange: import("@trpc/server").TRPCMutationProcedure<{
1690
- input: {
1691
- email: string;
1692
- password: string;
1693
- passwordConfirm: string;
1694
- };
1695
- output: any;
1696
- meta: object;
1697
- }>;
1698
- deleteEmail: import("@trpc/server").TRPCMutationProcedure<{
1699
- input: string;
1700
- output: any;
1701
- meta: object;
1702
- }>;
1703
- }>>;
1704
- googleAnalytics: import("@trpc/server").TRPCBuiltRouter<{
1705
- ctx: {
1706
- headers: Headers;
1707
- db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../db/schema.js")> & {
1708
- $client: import("mysql2/promise").Pool;
1709
- };
1710
- session: import("../index.js").Session | null;
1711
- };
1712
- meta: object;
1713
- errorShape: {
1714
- data: {
1715
- zodError: import("zod").ZodFlattenedError<unknown, string> | null;
1716
- code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
1717
- httpStatus: number;
1718
- path?: string;
1719
- stack?: string;
1720
- };
1721
- message: string;
1722
- code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
1723
- };
1724
- transformer: true;
1725
- }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
1726
- test: import("@trpc/server").TRPCQueryProcedure<{
1727
- input: void;
1728
- output: boolean;
1620
+ pluginId: string;
1621
+ pluginName?: string;
1622
+ path: string;
1623
+ title: string;
1624
+ icon?: string;
1625
+ component: string;
1626
+ }[];
1729
1627
  meta: object;
1730
1628
  }>;
1731
1629
  }>>;
@@ -1 +1 @@
1
- {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/api/root.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgBpB,CAAA;AAIF,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAA;AAExC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA"}
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/api/root.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AA4G5C,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAsB,CAAA;AAU5C,wBAAsB,YAAY;;;;;;;;;;;;;;;;;;;;;4GAEjC;AAED,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,WAAW,4LAG7D;AAGD,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAA;AAGxC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAA"}
package/dist/api/root.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createCallerFactory, privateProcedure, router } from './trpc.js';
1
+ import { createCallerFactory, privateProcedure, publicProcedure, router } from './trpc.js';
2
2
  import { adminsRouter } from './routers/admins.js';
3
3
  import { hasItemsSectionRouter } from './routers/hasItemsSection.js';
4
4
  import { filesRouter } from './routers/files.js';
@@ -9,9 +9,36 @@ import { categorySectionRouter } from './routers/categorySection.js';
9
9
  import { accountSettings } from './routers/accountSettings.js';
10
10
  import { cmsSettings } from './routers/cmsSettings.js';
11
11
  import { galleryRouter } from './routers/gallery.js';
12
- import { cpanelRouter } from './routers/cpanel.js';
13
- import { googleAnalyticsRouter } from './routers/googleAnalytics.js';
14
- export const appRouter = router({
12
+ import { getConfigImportVersion } from '../core/config/index.js';
13
+ import { getPluginRoutes, loadPlugins } from '../plugins/loader.js';
14
+ async function getActivePlugins() {
15
+ const loadedPlugins = await loadPlugins();
16
+ return loadedPlugins.map((item) => ({
17
+ id: item.config.package,
18
+ name: item.plugin.name ?? item.config.package,
19
+ version: item.plugin.version,
20
+ package: item.moduleName,
21
+ }));
22
+ }
23
+ async function getPluginRouters() {
24
+ const loadedPlugins = await loadPlugins();
25
+ return loadedPlugins.reduce((acc, current) => {
26
+ if (current.plugin.router) {
27
+ acc[current.routerKey] = current.plugin.router;
28
+ }
29
+ return acc;
30
+ }, {});
31
+ }
32
+ const pluginsRouter = router({
33
+ list: publicProcedure.query(async () => {
34
+ return getActivePlugins();
35
+ }),
36
+ routes: publicProcedure.query(async () => {
37
+ const routes = await getPluginRoutes();
38
+ return routes.map(({ prefetch, ...rest }) => rest);
39
+ }),
40
+ });
41
+ const coreRouters = {
15
42
  auth: authRouter,
16
43
  admins: adminsRouter,
17
44
  hasItemsSections: hasItemsSectionRouter,
@@ -22,10 +49,66 @@ export const appRouter = router({
22
49
  navigation: navRouter,
23
50
  accountSettings: accountSettings,
24
51
  cmsSettings: cmsSettings,
25
- cpanel: cpanelRouter,
26
- googleAnalytics: googleAnalyticsRouter,
52
+ plugins: pluginsRouter,
27
53
  getHello1: privateProcedure.query(async ({ ctx }) => {
28
54
  return ctx;
29
55
  }),
56
+ };
57
+ // Lazy router creation - cache the result
58
+ let _appRouter = null;
59
+ let routerInitPromise = null;
60
+ let appRouterConfigVersion = -1;
61
+ async function createAppRouterWithPlugins() {
62
+ const currentVersion = getConfigImportVersion();
63
+ if (appRouterConfigVersion !== currentVersion) {
64
+ _appRouter = null;
65
+ routerInitPromise = null;
66
+ }
67
+ if (_appRouter) {
68
+ return _appRouter;
69
+ }
70
+ if (routerInitPromise) {
71
+ return routerInitPromise;
72
+ }
73
+ routerInitPromise = (async () => {
74
+ const pluginRouters = await getPluginRouters();
75
+ const safePluginRouters = Object.entries(pluginRouters).reduce((acc, [key, pluginRouter]) => {
76
+ if (key in coreRouters) {
77
+ console.error(`[plugins] Router key "${key}" conflicts with a core router. Skipping.`);
78
+ return acc;
79
+ }
80
+ acc[key] = pluginRouter;
81
+ return acc;
82
+ }, {});
83
+ const routerInstance = router({
84
+ ...coreRouters,
85
+ ...safePluginRouters,
86
+ });
87
+ _appRouter = routerInstance;
88
+ appRouterConfigVersion = currentVersion;
89
+ return routerInstance;
90
+ })();
91
+ return routerInitPromise;
92
+ }
93
+ // Create router synchronously with core routes only
94
+ // This allows the module to load without top-level await
95
+ // NOTE: Plugin routes will not be available until plugins are loaded
96
+ // For now, we export the core router. Plugin routes should be added
97
+ // via the plugins router's list/routes procedures
98
+ export const appRouter = router(coreRouters);
99
+ // Start loading plugins in the background (non-blocking)
100
+ // Plugin routes can be accessed through the plugins.list/routes procedures
101
+ createAppRouterWithPlugins().catch((error) => {
102
+ console.error('Failed to load plugins for router:', error);
30
103
  });
104
+ // Export a function to get the full router with plugins
105
+ // This should be used in server contexts where async is allowed
106
+ export async function getAppRouter() {
107
+ return createAppRouterWithPlugins();
108
+ }
109
+ export async function createCallerWithPlugins(ctx) {
110
+ const routerWithPlugins = await getAppRouter();
111
+ return routerWithPlugins.createCaller(ctx);
112
+ }
113
+ // createCaller factory
31
114
  export const createCaller = createCallerFactory(appRouter);
@@ -1,6 +1,6 @@
1
1
  import { privateProcedure, router } from '../trpc.js';
2
2
  import * as z from 'zod';
3
- import { deleteSectionItem, getCategorySection, getCategorySectionChildren } from '../lib/serverActions';
3
+ import { deleteSectionItem, getCategorySection, getCategorySectionChildren } from '../lib/serverActions.js';
4
4
  export const categorySectionRouter = router({
5
5
  get: privateProcedure
6
6
  .input(z.object({
@@ -1,6 +1,6 @@
1
1
  import { privateProcedure, router } from '../trpc.js';
2
2
  import * as z from 'zod';
3
- import { createEditPage, createNewPage, deleteSectionItem, getBrowsePage } from '../lib/serverActions';
3
+ import { createEditPage, createNewPage, deleteSectionItem, getBrowsePage } from '../lib/serverActions.js';
4
4
  export const hasItemsSectionRouter = router({
5
5
  listItems: privateProcedure
6
6
  .input(z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/api/trpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAI9D,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAqBzD,eAAO,MAAM,GAAG,EAAc,UAAU,CAAC,OAAO,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1F,eAAO,MAAM,aAAa;;iCAAmB,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/api/trpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAI9D,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AA8DzD,eAAO,MAAM,GAAG,EAAc,UAAU,CAAC,OAAO,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC1F,eAAO,MAAM,aAAa;;iCAAmB,CAAA"}
@@ -2,7 +2,7 @@ import 'server-only';
2
2
  import { createHydrationHelpers } from '@trpc/react-query/rsc';
3
3
  import { headers } from 'next/headers';
4
4
  import { cache } from 'react';
5
- import { createCaller } from '../root.js';
5
+ import { getAppRouter } from '../root.js';
6
6
  import { createTRPCContext } from '../trpc.js';
7
7
  import { createQueryClient } from './query-client.js';
8
8
  /**
@@ -17,7 +17,45 @@ const createContext = cache(async () => {
17
17
  });
18
18
  });
19
19
  const getQueryClient = cache(createQueryClient);
20
- const caller = createCaller(createContext);
21
- const _t = createHydrationHelpers(caller, getQueryClient);
20
+ const getCaller = cache(async () => {
21
+ const routerWithPlugins = await getAppRouter();
22
+ return routerWithPlugins.createCaller(await createContext());
23
+ });
24
+ const resolveCallerPath = (root, path) => {
25
+ let current = root;
26
+ for (const key of path) {
27
+ if (!current || (typeof current !== 'object' && typeof current !== 'function')) {
28
+ return undefined;
29
+ }
30
+ current = current[key];
31
+ }
32
+ return current;
33
+ };
34
+ const callProcedure = async (path, args) => {
35
+ const caller = await getCaller();
36
+ const proc = resolveCallerPath(caller, path);
37
+ if (typeof proc !== 'function') {
38
+ throw new Error(`tRPC procedure not found: ${path.join('.')}`);
39
+ }
40
+ return proc(...args);
41
+ };
42
+ const createCallerProxy = (path = []) => {
43
+ const proxyTarget = (...args) => callProcedure(path, args);
44
+ return new Proxy(proxyTarget, {
45
+ get(_target, prop) {
46
+ if (prop === 'then')
47
+ return undefined;
48
+ if (typeof prop !== 'string')
49
+ return undefined;
50
+ return createCallerProxy([...path, prop]);
51
+ },
52
+ apply(_target, _thisArg, args) {
53
+ return callProcedure(path, args);
54
+ },
55
+ });
56
+ };
57
+ // Lazily resolves the caller so plugin routers are available without top-level await.
58
+ const callerProxy = createCallerProxy();
59
+ const _t = createHydrationHelpers(callerProxy, getQueryClient);
22
60
  export const api = _t.trpc;
23
61
  export const HydrateClient = _t.HydrateClient;
@@ -12,6 +12,8 @@ export declare const createTRPCContext: (opts: {
12
12
  };
13
13
  session: import("../index.js").Session | null;
14
14
  }>;
15
+ type Context = Awaited<ReturnType<typeof createTRPCContext>>;
16
+ export type TRPCContext = Context;
15
17
  export declare const transformer: {
16
18
  input: typeof superjson;
17
19
  output: typeof superjson;
@@ -93,4 +95,5 @@ export declare const privateProcedure: import("@trpc/server").TRPCProcedureBuild
93
95
  user: import("../index.js").User;
94
96
  };
95
97
  }, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, false>;
98
+ export {};
96
99
  //# sourceMappingURL=trpc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/api/trpc.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAA;AAKjC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE;aAAT,OAAO;;;;;EAQ/D,CAAA;AAID,eAAO,MAAM,WAAW;;;CAGvB,CAAA;AAkBD;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;iBArCyB,OAAO;;;;;;;;;;;;;;;;;;;EAqCR,CAAA;AAiBxD;;;GAGG;AACH,eAAO,MAAM,MAAM;;iBA1DsC,OAAO;;;;;;;;;;;;;;;;;;;EA0DlC,CAAA;AAE9B;;GAEG;AACH,eAAO,MAAM,eAAe;aA/D6B,OAAO;;;;;yLA+DtB,CAAA;AAE1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB;aArE4B,OAAO;;;;;;;;;yKAqEG,CAAA"}
1
+ {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/api/trpc.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAA;AAKjC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE;aAAT,OAAO;;;;;EAQ/D,CAAA;AAED,KAAK,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAA;AAC5D,MAAM,MAAM,WAAW,GAAG,OAAO,CAAA;AAEjC,eAAO,MAAM,WAAW;;;CAGvB,CAAA;AAkBD;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;iBAtCyB,OAAO;;;;;;;;;;;;;;;;;;;EAsCR,CAAA;AAiBxD;;;GAGG;AACH,eAAO,MAAM,MAAM;;iBA3DsC,OAAO;;;;;;;;;;;;;;;;;;;EA2DlC,CAAA;AAE9B;;GAEG;AACH,eAAO,MAAM,eAAe;aAhE6B,OAAO;;;;;yLAgEtB,CAAA;AAE1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB;aAtE4B,OAAO;;;;;;;;;yKAsEG,CAAA"}
@@ -47,8 +47,15 @@ declare const cmsConfigSchema: z.ZodObject<{
47
47
  }, z.core.$strip>>;
48
48
  }, z.core.$strip>>;
49
49
  }, z.core.$strip>>;
50
+ plugins: z.ZodOptional<z.ZodArray<z.ZodObject<{
51
+ package: z.ZodString;
52
+ }, z.core.$strip>>>;
50
53
  }, z.core.$strip>;
51
54
  export type CMSConfig = z.infer<typeof cmsConfigSchema>;
55
+ export interface PluginConfigEntry {
56
+ package: string;
57
+ options?: Record<string, unknown>;
58
+ }
52
59
  export interface ComputedCMSConfig {
53
60
  ui: {
54
61
  title: string;
@@ -89,6 +96,7 @@ export interface ComputedCMSConfig {
89
96
  };
90
97
  };
91
98
  };
99
+ plugins: PluginConfigEntry[];
92
100
  }
93
101
  /**
94
102
  * Gets the CMS configuration, loading it lazily on first access.
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAIxB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+InB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAGvD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;KACf,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;CACJ;AAoID;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAIxB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiKnB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;KACf,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC/B;AAsID;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
@@ -143,6 +143,21 @@ const cmsConfigSchema = z.object({
143
143
  .optional(),
144
144
  })
145
145
  .optional(),
146
+ /**
147
+ * Plugins configuration
148
+ */
149
+ plugins: z
150
+ .array(z.object({
151
+ /**
152
+ * The npm package name of the plugin to load
153
+ */
154
+ package: z.string(),
155
+ /**
156
+ * Arbitrary options passed to the plugin factory
157
+ */
158
+ // options: z.record(z.unknown()).optional(),
159
+ }))
160
+ .optional(),
146
161
  });
147
162
  // Merge utility function
148
163
  function mergeConfig(defaults, userConfig) {
@@ -189,6 +204,7 @@ function mergeConfig(defaults, userConfig) {
189
204
  },
190
205
  },
191
206
  },
207
+ plugins: userConfig.plugins ?? defaults.plugins,
192
208
  };
193
209
  }
194
210
  // Default configuration values
@@ -232,6 +248,7 @@ const defaultConfig = {
232
248
  },
233
249
  },
234
250
  },
251
+ plugins: [],
235
252
  };
236
253
  /*const error = (error: string, greyMsg = ''): string => {
237
254
  return `${chalk.bgRed.bold(' Error ')} ${error} ${greyMsg ? chalk.grey(greyMsg) : ''}`.trim()
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/db/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAClG,QAAQ,EAAE,MAAM,CAAA;CACnB;AAQD,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,QAAQ,CAAM,GAAG,QAAQ,CAyC3E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/db/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAClG,QAAQ,EAAE,MAAM,CAAA;CACnB;AAQD,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,QAAQ,CAAM,GAAG,QAAQ,CA4D3E"}
package/dist/db/config.js CHANGED
@@ -30,10 +30,31 @@ export function resolveDbConfig(overrides = {}) {
30
30
  }
31
31
  catch (error) {
32
32
  const idDev = process.env.NODE_ENV === 'development';
33
+ let preferredPM = 'pnpm';
34
+ // This environment variable is set by npm and yarn but pnpm seems less consistent
35
+ const userAgent = process.env.npm_config_user_agent;
36
+ if (userAgent) {
37
+ if (userAgent.startsWith('yarn')) {
38
+ preferredPM = 'yarn';
39
+ }
40
+ else if (userAgent.startsWith('pnpm')) {
41
+ preferredPM = 'pnpm';
42
+ }
43
+ else if (userAgent.startsWith('bun')) {
44
+ preferredPM = 'bun';
45
+ }
46
+ else {
47
+ preferredPM = 'npm';
48
+ }
49
+ }
50
+ else {
51
+ // If no user agent is set, assume npm
52
+ preferredPM = 'npm';
53
+ }
33
54
  console.log('');
34
55
  console.error(chalk.redBright('Database name and user are required'));
35
56
  console.log(chalk.gray(`Make sure to set the ${chalk.white.italic('DB_NAME')} and ${chalk.white.italic('DB_USER')} in your ${idDev ? 'development' : 'production'} environment variables.`));
36
- console.log(chalk.gray(`Or, you can run ${chalk.greenBright.italic(`nextjs-cms-kit ${idDev ? '--dev' : ''} db-config`)} command at the root of your nextjs-cms project to set db config interactively.`));
57
+ console.log(chalk.gray(`Or, you can run ${chalk.greenBright.italic(`${preferredPM} nextjs-cms-kit ${idDev ? '--dev' : ''} db-config`)} command at the root of your nextjs-cms project to set db config interactively.`));
37
58
  process.exit(1);
38
59
  }
39
60
  }
@@ -0,0 +1,2 @@
1
+ export type { CMSPlugin, LoadedPlugin, LoadedPluginRoute, PluginInitContext, PluginModule, PluginRoute, } from './loader.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,SAAS,EACT,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,WAAW,GACd,MAAM,aAAa,CAAA"}
File without changes
@@ -0,0 +1,40 @@
1
+ import type { PluginConfigEntry } from '../core/config/config-loader.js';
2
+ export interface CMSPlugin {
3
+ name?: string;
4
+ version?: string;
5
+ router?: any;
6
+ routes?: PluginRoute[];
7
+ init?: (ctx: PluginInitContext) => Promise<void> | void;
8
+ }
9
+ export interface PluginInitContext {
10
+ config: PluginConfigEntry;
11
+ }
12
+ export interface LoadedPlugin {
13
+ config: PluginConfigEntry;
14
+ plugin: CMSPlugin;
15
+ moduleName: string;
16
+ routerKey: string;
17
+ }
18
+ export interface PluginModule {
19
+ createPlugin?: (options?: Record<string, unknown>) => CMSPlugin;
20
+ plugin?: CMSPlugin;
21
+ default?: CMSPlugin | (() => CMSPlugin);
22
+ }
23
+ export interface PluginRoute {
24
+ path: string;
25
+ title: string;
26
+ icon?: string;
27
+ component: string;
28
+ prefetch?: (helpers: {
29
+ api: unknown;
30
+ }) => Promise<void> | void;
31
+ }
32
+ export interface LoadedPluginRoute extends PluginRoute {
33
+ pluginId: string;
34
+ pluginName?: string;
35
+ }
36
+ export declare const loadPluginModule: (pluginPackage: string) => Promise<unknown>;
37
+ export declare function loadPlugins(): Promise<LoadedPlugin[]>;
38
+ export declare function getPluginRoutes(): Promise<LoadedPluginRoute[]>;
39
+ export declare function findPluginRouteByPath(path: string): Promise<LoadedPluginRoute | null>;
40
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAGxE,MAAM,WAAW,SAAS;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,MAAM,CAAC,EAAE,WAAW,EAAE,CAAA;IACtB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC1D;AAED,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,iBAAiB,CAAA;CAC5B;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,iBAAiB,CAAA;IACzB,MAAM,EAAE,SAAS,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,YAAY;IACzB,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,SAAS,CAAA;IAC/D,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,CAAC,EAAE,SAAS,GAAG,CAAC,MAAM,SAAS,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACjE;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AAwCD,eAAO,MAAM,gBAAgB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,OAAO,CAwB7E,CAAA;AAuBD,wBAAsB,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAmE3D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAWpE;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAI3F"}
@@ -0,0 +1,154 @@
1
+ // import 'server-only'
2
+ if (typeof window !== 'undefined') {
3
+ throw new Error('This module can only run on the server');
4
+ }
5
+ import { createRequire } from 'module';
6
+ import path from 'path';
7
+ import { getCMSConfig, getConfigImportVersion } from '../core/config/index.js';
8
+ const deriveRouterKey = (packageName) => {
9
+ const baseName = packageName.split('/').pop() ?? packageName;
10
+ const withoutPrefix = baseName.startsWith('plugin-') ? baseName.slice('plugin-'.length) : baseName;
11
+ const parts = withoutPrefix.split(/[-_]/g).filter(Boolean);
12
+ const [first, ...rest] = parts;
13
+ let key = first ? first + rest.map((part) => part[0]?.toUpperCase() + part.slice(1)).join('') : withoutPrefix;
14
+ if (!key) {
15
+ key = baseName.replace(/[^A-Za-z0-9_]/g, '_');
16
+ }
17
+ if (!/^[A-Za-z_]/.test(key)) {
18
+ key = `plugin${key ? key[0]?.toUpperCase() + key.slice(1) : ''}`;
19
+ }
20
+ return key;
21
+ };
22
+ let cachedPlugins = null;
23
+ let cachedConfigVersion = -1;
24
+ let loadPromise = null;
25
+ let jitiInstance = null;
26
+ const appRequire = createRequire(path.join(process.cwd(), 'package.json'));
27
+ const pkgRequire = createRequire(import.meta.url);
28
+ const resolvePluginPath = (pluginPackage) => {
29
+ try {
30
+ return appRequire.resolve(pluginPackage);
31
+ }
32
+ catch {
33
+ try {
34
+ return pkgRequire.resolve(pluginPackage, { paths: [process.cwd()] });
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ };
41
+ export const loadPluginModule = async (pluginPackage) => {
42
+ if (!jitiInstance) {
43
+ const { createJiti } = await import('jiti');
44
+ jitiInstance = createJiti(import.meta.url, {
45
+ // Keep your previous behavior:
46
+ // - return default export compatibly
47
+ interopDefault: true,
48
+ // Caching (new API uses fsCache/moduleCache)
49
+ // Keep them enabled for better performance.
50
+ fsCache: true,
51
+ moduleCache: true,
52
+ rebuildFsCache: true,
53
+ // Optional: nicer debugging in stack traces (off by default in jiti)
54
+ // sourceMaps: true,
55
+ });
56
+ }
57
+ const resolved = resolvePluginPath(pluginPackage) ?? pluginPackage;
58
+ // Synchronous API works with Turbopack.
59
+ const mod = jitiInstance(resolved);
60
+ return mod?.default ?? mod;
61
+ };
62
+ function resolvePluginInstance(registration, mod) {
63
+ const candidate = mod.createPlugin
64
+ ? mod.createPlugin(registration.options)
65
+ : typeof mod.default === 'function'
66
+ ? mod.default()
67
+ : (mod.default ?? mod.plugin);
68
+ if (!candidate) {
69
+ console.warn(`[plugins] Plugin "${registration.package}" did not return a plugin instance`);
70
+ return null;
71
+ }
72
+ return {
73
+ name: candidate.name ?? registration.package,
74
+ version: candidate.version,
75
+ router: candidate.router,
76
+ routes: candidate.routes ?? [],
77
+ init: candidate.init,
78
+ };
79
+ }
80
+ export async function loadPlugins() {
81
+ const currentVersion = getConfigImportVersion();
82
+ if (cachedPlugins && cachedConfigVersion === currentVersion) {
83
+ return cachedPlugins;
84
+ }
85
+ if (loadPromise) {
86
+ return loadPromise;
87
+ }
88
+ loadPromise = (async () => {
89
+ const config = await getCMSConfig();
90
+ const registrations = config.plugins ?? [];
91
+ const seenPackages = new Set();
92
+ const seenRouterKeys = new Set();
93
+ const loaded = [];
94
+ for (const registration of registrations) {
95
+ const mod = await loadPluginModule(registration.package);
96
+ if (!mod)
97
+ continue;
98
+ const plugin = resolvePluginInstance(registration, mod);
99
+ if (!plugin)
100
+ continue;
101
+ const routerKey = deriveRouterKey(registration.package);
102
+ if (seenPackages.has(registration.package)) {
103
+ console.error(`[plugins] Duplicate plugin package "${registration.package}" registered. Skipping duplicate.`);
104
+ continue;
105
+ }
106
+ if (seenRouterKeys.has(routerKey)) {
107
+ console.error(`[plugins] Duplicate plugin router key "${routerKey}" derived from "${registration.package}". Skipping.`);
108
+ continue;
109
+ }
110
+ seenPackages.add(registration.package);
111
+ seenRouterKeys.add(routerKey);
112
+ if (typeof plugin.init === 'function') {
113
+ try {
114
+ await plugin.init({ config: registration });
115
+ }
116
+ catch (error) {
117
+ console.error(`[plugins] Plugin "${registration.package}" init failed:`, error);
118
+ }
119
+ }
120
+ loaded.push({
121
+ config: registration,
122
+ plugin,
123
+ moduleName: registration.package,
124
+ routerKey,
125
+ });
126
+ }
127
+ cachedPlugins = loaded;
128
+ cachedConfigVersion = currentVersion;
129
+ return loaded;
130
+ })();
131
+ try {
132
+ return await loadPromise;
133
+ }
134
+ finally {
135
+ loadPromise = null;
136
+ }
137
+ }
138
+ export async function getPluginRoutes() {
139
+ const loaded = await loadPlugins();
140
+ return loaded.flatMap((entry) => {
141
+ const pluginId = entry.config.package;
142
+ const pluginName = entry.plugin.name ?? entry.config.package;
143
+ return (entry.plugin.routes ?? []).map((route) => ({
144
+ ...route,
145
+ pluginId,
146
+ pluginName,
147
+ }));
148
+ });
149
+ }
150
+ export async function findPluginRouteByPath(path) {
151
+ const normalized = path.startsWith('/') ? path : `/${path}`;
152
+ const routes = await getPluginRoutes();
153
+ return routes.find((route) => route.path === normalized) ?? null;
154
+ }
@@ -0,0 +1,2 @@
1
+ export * from './loader.js';
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/plugins/server.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -0,0 +1 @@
1
+ export * from './loader.js';
@@ -1,5 +1,5 @@
1
- import arStrings from './dictionaries/ar.json';
2
- import enStrings from './dictionaries/en.json';
1
+ import arStrings from './dictionaries/ar.json' with { type: 'json' };
2
+ import enStrings from './dictionaries/en.json' with { type: 'json' };
3
3
  function getString(key, lang = 'en') {
4
4
  const dict = lang === 'en' ? enStrings : arStrings;
5
5
  // @ts-expect-error key is string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextjs-cms",
3
- "version": "0.5.66",
3
+ "version": "0.5.68",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",
@@ -14,6 +14,10 @@
14
14
  "types": "./dist/api/index.d.ts",
15
15
  "default": "./dist/api/index.js"
16
16
  },
17
+ "./api/trpc": {
18
+ "types": "./dist/api/trpc.d.ts",
19
+ "default": "./dist/api/trpc.js"
20
+ },
17
21
  "./api/helpers": {
18
22
  "types": "./dist/api/lib/serverActions.d.ts",
19
23
  "default": "./dist/api/lib/serverActions.js"
@@ -101,6 +105,14 @@
101
105
  "./translations": {
102
106
  "types": "./dist/translations/index.d.ts",
103
107
  "default": "./dist/translations/index.js"
108
+ },
109
+ "./plugins": {
110
+ "types": "./dist/plugins/index.d.ts",
111
+ "default": "./dist/plugins/index.js"
112
+ },
113
+ "./plugins/server": {
114
+ "types": "./dist/plugins/server.d.ts",
115
+ "default": "./dist/plugins/server.js"
104
116
  }
105
117
  },
106
118
  "files": [