nextjs-cms 0.5.67 → 0.5.69
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/dist/api/index.d.ts +9 -99
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +5 -4
- package/dist/api/lib/serverActions.d.ts +6 -0
- package/dist/api/lib/serverActions.d.ts.map +1 -1
- package/dist/api/lib/serverActions.js +73 -20
- package/dist/api/root.d.ts +56 -213
- package/dist/api/root.d.ts.map +1 -1
- package/dist/api/root.js +88 -8
- package/dist/api/routers/admins.d.ts.map +1 -1
- package/dist/api/routers/admins.js +53 -3
- package/dist/api/routers/categorySection.js +1 -1
- package/dist/api/routers/gallery.d.ts.map +1 -1
- package/dist/api/routers/gallery.js +1 -0
- package/dist/api/routers/hasItemsSection.js +1 -1
- package/dist/api/trpc/client.d.ts +4 -0
- package/dist/api/trpc/client.d.ts.map +1 -0
- package/dist/api/trpc/client.js +3 -0
- package/dist/api/trpc/server.d.ts.map +1 -1
- package/dist/api/trpc/server.js +41 -3
- package/dist/api/trpc.d.ts +15 -0
- package/dist/api/trpc.d.ts.map +1 -1
- package/dist/api/trpc.js +24 -0
- package/dist/core/config/config-loader.d.ts +8 -0
- package/dist/core/config/config-loader.d.ts.map +1 -1
- package/dist/core/config/config-loader.js +17 -0
- package/dist/core/config/loader.d.ts +1 -1
- package/dist/core/config/loader.d.ts.map +1 -1
- package/dist/core/config/loader.js +1 -1
- package/dist/core/factories/SectionFactory.d.ts +1 -1
- package/dist/core/factories/SectionFactory.d.ts.map +1 -1
- package/dist/core/factories/SectionFactory.js +1 -1
- package/dist/core/factories/section-factory-with-esbuild.d.ts +0 -4
- package/dist/core/factories/section-factory-with-esbuild.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-esbuild.js +1 -5
- package/dist/core/factories/section-factory-with-jiti.d.ts +0 -4
- package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-jiti.js +1 -5
- package/dist/core/submit/ItemEditSubmit.d.ts.map +1 -1
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/loader.d.ts +71 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +187 -0
- package/dist/plugins/server.d.ts +2 -0
- package/dist/plugins/server.d.ts.map +1 -0
- package/dist/plugins/server.js +1 -0
- package/dist/translations/index.js +2 -2
- package/package.json +19 -3
- package/dist/api/routers/googleAnalytics.d.ts +0 -29
- package/dist/api/routers/googleAnalytics.d.ts.map +0 -1
- package/dist/api/routers/googleAnalytics.js +0 -7
|
@@ -0,0 +1,187 @@
|
|
|
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
|
+
import chalk from 'chalk';
|
|
9
|
+
export function definePlugin(plugin) {
|
|
10
|
+
return plugin;
|
|
11
|
+
}
|
|
12
|
+
const deriveRouterKey = (packageName) => {
|
|
13
|
+
const baseName = packageName.split('/').pop() ?? packageName;
|
|
14
|
+
const withoutPrefix = baseName.startsWith('plugin-') ? baseName.slice('plugin-'.length) : baseName;
|
|
15
|
+
const parts = withoutPrefix.split(/[-_]/g).filter(Boolean);
|
|
16
|
+
const [first, ...rest] = parts;
|
|
17
|
+
let key = first ? first + rest.map((part) => part[0]?.toUpperCase() + part.slice(1)).join('') : withoutPrefix;
|
|
18
|
+
if (!key) {
|
|
19
|
+
key = baseName.replace(/[^A-Za-z0-9_]/g, '_');
|
|
20
|
+
}
|
|
21
|
+
if (!/^[A-Za-z_]/.test(key)) {
|
|
22
|
+
key = `plugin${key ? key[0]?.toUpperCase() + key.slice(1) : ''}`;
|
|
23
|
+
}
|
|
24
|
+
return key;
|
|
25
|
+
};
|
|
26
|
+
let cachedPlugins = null;
|
|
27
|
+
let cachedConfigVersion = -1;
|
|
28
|
+
let loadPromise = null;
|
|
29
|
+
let jitiInstance = null;
|
|
30
|
+
const appRequire = createRequire(path.join(process.cwd(), 'package.json'));
|
|
31
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
32
|
+
const resolvePluginPath = (pluginPackage) => {
|
|
33
|
+
try {
|
|
34
|
+
return appRequire.resolve(pluginPackage);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
try {
|
|
38
|
+
return pkgRequire.resolve(pluginPackage, { paths: [process.cwd()] });
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export const loadPluginModule = async (pluginPackage) => {
|
|
46
|
+
if (!jitiInstance) {
|
|
47
|
+
const { createJiti } = await import('jiti');
|
|
48
|
+
jitiInstance = createJiti(import.meta.url, {
|
|
49
|
+
// Keep your previous behavior:
|
|
50
|
+
// - return default export compatibly
|
|
51
|
+
interopDefault: true,
|
|
52
|
+
// Caching (new API uses fsCache/moduleCache)
|
|
53
|
+
// Keep them enabled for better performance.
|
|
54
|
+
fsCache: true,
|
|
55
|
+
moduleCache: true,
|
|
56
|
+
rebuildFsCache: true,
|
|
57
|
+
// Optional: nicer debugging in stack traces (off by default in jiti)
|
|
58
|
+
// sourceMaps: true,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const resolved = resolvePluginPath(pluginPackage) ?? pluginPackage;
|
|
62
|
+
// Synchronous API works with Turbopack.
|
|
63
|
+
const mod = jitiInstance(resolved);
|
|
64
|
+
return mod?.default ?? mod;
|
|
65
|
+
};
|
|
66
|
+
function resolvePluginInstance(registration, mod) {
|
|
67
|
+
const candidate = mod.createPlugin
|
|
68
|
+
? mod.createPlugin(registration.options)
|
|
69
|
+
: typeof mod.default === 'function'
|
|
70
|
+
? mod.default()
|
|
71
|
+
: (mod.default ?? mod.plugin);
|
|
72
|
+
if (!candidate) {
|
|
73
|
+
console.warn(`[plugins] Plugin "${registration.package}" did not return a plugin instance`);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
if (!candidate.name || !candidate.title) {
|
|
77
|
+
console.warn(`[plugins] Plugin "${registration.package}" is missing required "name" or "title". Skipping.`);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
title: candidate.title,
|
|
82
|
+
name: candidate.name,
|
|
83
|
+
version: candidate.version,
|
|
84
|
+
router: candidate.router,
|
|
85
|
+
routes: candidate.routes ?? [],
|
|
86
|
+
init: candidate.init,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export async function loadPlugins() {
|
|
90
|
+
const currentVersion = getConfigImportVersion();
|
|
91
|
+
if (cachedPlugins && cachedConfigVersion === currentVersion) {
|
|
92
|
+
return cachedPlugins;
|
|
93
|
+
}
|
|
94
|
+
if (loadPromise) {
|
|
95
|
+
return loadPromise;
|
|
96
|
+
}
|
|
97
|
+
loadPromise = (async () => {
|
|
98
|
+
const config = await getCMSConfig();
|
|
99
|
+
const registrations = config.plugins ?? [];
|
|
100
|
+
const seenPackages = new Set();
|
|
101
|
+
const seenRouterKeys = new Set();
|
|
102
|
+
const loaded = [];
|
|
103
|
+
for (const registration of registrations) {
|
|
104
|
+
if (!registration.package) {
|
|
105
|
+
console.warn(`[plugins] Plugin registration is missing "package" field.`);
|
|
106
|
+
console.warn(`[plugins] Please check your cms.config.ts file.`);
|
|
107
|
+
console.warn(`[plugins] Skipping this plugin registration.`);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const mod = await loadPluginModule(registration.package);
|
|
111
|
+
if (!mod)
|
|
112
|
+
continue;
|
|
113
|
+
const plugin = resolvePluginInstance(registration, mod);
|
|
114
|
+
if (!plugin)
|
|
115
|
+
continue;
|
|
116
|
+
const routerKey = deriveRouterKey(registration.package);
|
|
117
|
+
if (seenPackages.has(registration.package)) {
|
|
118
|
+
console.error(`[plugins] Duplicate plugin package "${registration.package}" registered. Skipping duplicate.`);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (seenRouterKeys.has(routerKey)) {
|
|
122
|
+
console.error(`[plugins] Duplicate plugin router key "${routerKey}" derived from "${registration.package}". Skipping.`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
seenPackages.add(registration.package);
|
|
126
|
+
seenRouterKeys.add(routerKey);
|
|
127
|
+
if (typeof plugin.init === 'function') {
|
|
128
|
+
try {
|
|
129
|
+
await plugin.init({ config: registration });
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error(`[plugins] Plugin "${registration.package}" init failed:`, error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
loaded.push({
|
|
136
|
+
config: registration,
|
|
137
|
+
plugin,
|
|
138
|
+
moduleName: registration.package,
|
|
139
|
+
routerKey,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
cachedPlugins = loaded;
|
|
143
|
+
cachedConfigVersion = currentVersion;
|
|
144
|
+
return loaded;
|
|
145
|
+
})();
|
|
146
|
+
try {
|
|
147
|
+
return await loadPromise;
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
loadPromise = null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export async function getPluginRoutes() {
|
|
154
|
+
const loaded = await loadPlugins();
|
|
155
|
+
return loaded.flatMap((entry) => {
|
|
156
|
+
const routes = entry.plugin.routes ?? [];
|
|
157
|
+
const requireComponent = routes.length > 1;
|
|
158
|
+
return routes.map((route) => {
|
|
159
|
+
if (requireComponent && !route.component) {
|
|
160
|
+
console.warn(chalk.red(`[plugins] Route "${route.path}" from "${entry.config.package}" should set "component" because the plugin defines multiple routes.`));
|
|
161
|
+
}
|
|
162
|
+
if (!requireComponent && route.component) {
|
|
163
|
+
console.warn(chalk.gray(`[plugins] Route "${route.path}" from "${entry.config.package}" should omit "component" and export a default component, because the plugin defines a single route.`));
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
...route,
|
|
167
|
+
pluginId: entry.config.package,
|
|
168
|
+
pluginName: entry.plugin.name,
|
|
169
|
+
pluginTitle: entry.plugin.title,
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
export async function findPluginRouteByPath(path) {
|
|
175
|
+
const normalized = path.startsWith('/') ? path : `/${path}`;
|
|
176
|
+
const routes = await getPluginRoutes();
|
|
177
|
+
return routes.find((route) => route.path === normalized) ?? null;
|
|
178
|
+
}
|
|
179
|
+
// Keep this list in sync with cms.config.ts and apps/cms/package.json.
|
|
180
|
+
export const pluginServerLoaders = {
|
|
181
|
+
// @ts-ignore - The package should be in dependencies if you want to use it
|
|
182
|
+
'@nextjs-cms-plugins/cpanel-dashboard': () => import('@nextjs-cms-plugins/cpanel-dashboard/server'),
|
|
183
|
+
// @ts-ignore - The package should be in dependencies if you want to use it
|
|
184
|
+
'@nextjs-cms-plugins/cpanel-emails': () => import('@nextjs-cms-plugins/cpanel-emails/server'),
|
|
185
|
+
// @ts-ignore - The package should be in dependencies if you want to use it
|
|
186
|
+
'@nextjs-cms-plugins/google-analytics': () => import('@nextjs-cms-plugins/google-analytics/server'),
|
|
187
|
+
};
|
|
@@ -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.
|
|
3
|
+
"version": "0.5.69",
|
|
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"
|
|
@@ -22,6 +26,10 @@
|
|
|
22
26
|
"types": "./dist/api/trpc/server.d.ts",
|
|
23
27
|
"default": "./dist/api/trpc/server.js"
|
|
24
28
|
},
|
|
29
|
+
"./api/trpc/client": {
|
|
30
|
+
"types": "./dist/api/trpc/client.d.ts",
|
|
31
|
+
"default": "./dist/api/trpc/client.js"
|
|
32
|
+
},
|
|
25
33
|
"./auth": {
|
|
26
34
|
"types": "./dist/auth/index.d.ts",
|
|
27
35
|
"default": "./dist/auth/index.js"
|
|
@@ -101,6 +109,14 @@
|
|
|
101
109
|
"./translations": {
|
|
102
110
|
"types": "./dist/translations/index.d.ts",
|
|
103
111
|
"default": "./dist/translations/index.js"
|
|
112
|
+
},
|
|
113
|
+
"./plugins": {
|
|
114
|
+
"types": "./dist/plugins/index.d.ts",
|
|
115
|
+
"default": "./dist/plugins/index.js"
|
|
116
|
+
},
|
|
117
|
+
"./plugins/server": {
|
|
118
|
+
"types": "./dist/plugins/server.d.ts",
|
|
119
|
+
"default": "./dist/plugins/server.js"
|
|
104
120
|
}
|
|
105
121
|
},
|
|
106
122
|
"files": [
|
|
@@ -150,9 +166,9 @@
|
|
|
150
166
|
"prettier": "^3.3.3",
|
|
151
167
|
"tsx": "^4.20.6",
|
|
152
168
|
"typescript": "^5.9.2",
|
|
153
|
-
"@lzcms/
|
|
169
|
+
"@lzcms/prettier-config": "0.1.0",
|
|
154
170
|
"@lzcms/tsconfig": "0.1.0",
|
|
155
|
-
"@lzcms/
|
|
171
|
+
"@lzcms/eslint-config": "0.3.0"
|
|
156
172
|
},
|
|
157
173
|
"license": "MIT",
|
|
158
174
|
"keywords": [
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export declare const googleAnalyticsRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
2
|
-
ctx: {
|
|
3
|
-
headers: Headers;
|
|
4
|
-
db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../../db/schema.js")> & {
|
|
5
|
-
$client: import("mysql2/promise").Pool;
|
|
6
|
-
};
|
|
7
|
-
session: import("../../index.js").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
|
-
test: import("@trpc/server").TRPCQueryProcedure<{
|
|
24
|
-
input: void;
|
|
25
|
-
output: boolean;
|
|
26
|
-
meta: object;
|
|
27
|
-
}>;
|
|
28
|
-
}>>;
|
|
29
|
-
//# sourceMappingURL=googleAnalytics.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"googleAnalytics.d.ts","sourceRoot":"","sources":["../../../src/api/routers/googleAnalytics.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIhC,CAAA"}
|