nextjs-cms 0.9.22 → 0.9.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -13
- package/dist/api/actions/files.d.ts +30 -0
- package/dist/api/actions/files.d.ts.map +1 -0
- package/dist/api/actions/files.js +234 -0
- package/dist/api/actions/index.d.ts +4 -0
- package/dist/api/actions/index.d.ts.map +1 -0
- package/dist/api/actions/index.js +3 -0
- package/dist/api/actions/pages.d.ts +297 -0
- package/dist/api/actions/pages.d.ts.map +1 -0
- package/dist/api/actions/pages.js +1215 -0
- package/dist/api/actions/privileges.d.ts +25 -0
- package/dist/api/actions/privileges.d.ts.map +1 -0
- package/dist/api/actions/privileges.js +98 -0
- package/dist/api/client/index.d.ts +4 -0
- package/dist/api/client/index.d.ts.map +1 -0
- package/dist/api/client/index.js +3 -0
- package/dist/api/client.d.ts +30 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +82 -0
- package/dist/api/index.d.ts +1 -938
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +0 -13
- package/dist/api/plugin/index.d.ts +7 -0
- package/dist/api/plugin/index.d.ts.map +1 -0
- package/dist/api/plugin/index.js +5 -0
- package/dist/api/root.d.ts +18 -1844
- package/dist/api/root.d.ts.map +1 -1
- package/dist/api/root.js +18 -83
- package/dist/api/server/index.d.ts +8 -0
- package/dist/api/server/index.d.ts.map +1 -0
- package/dist/api/server/index.js +3 -0
- package/dist/api/server.d.ts +2748 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +100 -0
- package/dist/api/trpc/client.d.ts +19 -3
- package/dist/api/trpc/client.d.ts.map +1 -1
- package/dist/api/trpc/client.js +55 -1
- package/dist/api/trpc/query-client.d.ts +3 -1
- package/dist/api/trpc/query-client.d.ts.map +1 -1
- package/dist/api/trpc/query-client.js +25 -20
- package/dist/api/trpc/root.d.ts +906 -0
- package/dist/api/trpc/root.d.ts.map +1 -0
- package/dist/api/trpc/root.js +47 -0
- package/dist/api/trpc/routers/accountSettings.d.ts +66 -0
- package/dist/api/trpc/routers/accountSettings.d.ts.map +1 -0
- package/dist/api/trpc/routers/accountSettings.js +200 -0
- package/dist/api/trpc/routers/admins.d.ts +112 -0
- package/dist/api/trpc/routers/admins.d.ts.map +1 -0
- package/dist/api/trpc/routers/admins.js +331 -0
- package/dist/api/trpc/routers/auth.d.ts +54 -0
- package/dist/api/trpc/routers/auth.d.ts.map +1 -0
- package/dist/api/trpc/routers/auth.js +50 -0
- package/dist/api/trpc/routers/categorySection.d.ts +105 -0
- package/dist/api/trpc/routers/categorySection.d.ts.map +1 -0
- package/dist/api/trpc/routers/categorySection.js +49 -0
- package/dist/api/trpc/routers/config.d.ts +48 -0
- package/dist/api/trpc/routers/config.d.ts.map +1 -0
- package/dist/api/trpc/routers/config.js +18 -0
- package/dist/api/trpc/routers/cpanel.d.ts +82 -0
- package/dist/api/trpc/routers/cpanel.d.ts.map +1 -0
- package/dist/api/trpc/routers/cpanel.js +216 -0
- package/dist/api/trpc/routers/fields.d.ts +35 -0
- package/dist/api/trpc/routers/fields.d.ts.map +1 -0
- package/dist/api/trpc/routers/fields.js +81 -0
- package/dist/api/trpc/routers/files.d.ts +34 -0
- package/dist/api/trpc/routers/files.d.ts.map +1 -0
- package/dist/api/trpc/routers/files.js +14 -0
- package/dist/api/trpc/routers/gallery.d.ts +35 -0
- package/dist/api/trpc/routers/gallery.d.ts.map +1 -0
- package/dist/api/trpc/routers/gallery.js +92 -0
- package/dist/api/trpc/routers/hasItemsSection.d.ts +194 -0
- package/dist/api/trpc/routers/hasItemsSection.d.ts.map +1 -0
- package/dist/api/trpc/routers/hasItemsSection.js +86 -0
- package/dist/api/trpc/routers/logs.d.ts +59 -0
- package/dist/api/trpc/routers/logs.d.ts.map +1 -0
- package/dist/api/trpc/routers/logs.js +79 -0
- package/dist/api/trpc/routers/navigation.d.ts +65 -0
- package/dist/api/trpc/routers/navigation.d.ts.map +1 -0
- package/dist/api/trpc/routers/navigation.js +11 -0
- package/dist/api/trpc/routers/simpleSection.d.ts +93 -0
- package/dist/api/trpc/routers/simpleSection.d.ts.map +1 -0
- package/dist/api/trpc/routers/simpleSection.js +54 -0
- package/dist/api/trpc/server.d.ts +2789 -5
- package/dist/api/trpc/server.d.ts.map +1 -1
- package/dist/api/trpc/server.js +91 -52
- package/dist/api/trpc/trpc.d.ts +111 -0
- package/dist/api/trpc/trpc.d.ts.map +1 -0
- package/dist/api/trpc/trpc.js +99 -0
- package/dist/api/trpc/utils/async-caller-proxy.d.ts +2 -0
- package/dist/api/trpc/utils/async-caller-proxy.d.ts.map +1 -0
- package/dist/api/trpc/utils/async-caller-proxy.js +38 -0
- package/dist/api/trpc/utils/refresh-token-link.d.ts +6 -0
- package/dist/api/trpc/utils/refresh-token-link.d.ts.map +1 -0
- package/dist/api/trpc/utils/refresh-token-link.js +81 -0
- package/dist/api/trpc/utils/router-types.d.ts +7 -0
- package/dist/api/trpc/utils/router-types.d.ts.map +1 -0
- package/dist/api/trpc/utils/router-types.js +0 -0
- package/dist/api/use-axios-private.d.ts +6 -0
- package/dist/api/use-axios-private.d.ts.map +1 -0
- package/dist/api/use-axios-private.js +57 -0
- package/dist/api/utils/async-caller-proxy.d.ts +2 -0
- package/dist/api/utils/async-caller-proxy.d.ts.map +1 -0
- package/dist/api/utils/async-caller-proxy.js +36 -0
- package/dist/api/utils/lazy-caller-proxy.d.ts +2 -0
- package/dist/api/utils/lazy-caller-proxy.d.ts.map +1 -0
- package/dist/api/utils/lazy-caller-proxy.js +36 -0
- package/dist/api/utils/router-types.d.ts +7 -0
- package/dist/api/utils/router-types.d.ts.map +1 -0
- package/dist/api/utils/router-types.js +0 -0
- package/dist/auth/hooks/index.d.ts +1 -2
- package/dist/auth/hooks/index.d.ts.map +1 -1
- package/dist/auth/hooks/index.js +1 -2
- package/dist/auth/react.d.ts +1 -2
- package/dist/auth/react.d.ts.map +1 -1
- package/dist/auth/react.js +1 -2
- package/dist/auth/trpc.d.ts +1 -1
- package/dist/auth/trpc.d.ts.map +1 -1
- package/dist/auth/trpc.js +0 -1
- package/dist/cli/lib/fix-master-admin.d.ts.map +1 -1
- package/dist/cli/lib/fix-master-admin.js +12 -25
- package/dist/cli/lib/update-sections.d.ts.map +1 -1
- package/dist/cli/lib/update-sections.js +29 -24
- package/dist/core/config/config-loader.d.ts +40 -16
- package/dist/core/config/config-loader.d.ts.map +1 -1
- package/dist/core/config/config-loader.js +58 -10
- package/dist/core/config/index.d.ts +1 -1
- package/dist/core/config/index.d.ts.map +1 -1
- package/dist/core/config/loader-with-jiti.d.ts.map +1 -1
- package/dist/core/config/loader-with-jiti.js +13 -12
- package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-jiti.js +2 -1
- package/dist/core/sections/category.d.ts +6 -6
- package/dist/core/sections/hasItems.d.ts +6 -6
- package/dist/core/sections/section.d.ts +4 -4
- package/dist/core/sections/simple.d.ts +2 -2
- package/dist/core/types/index.d.ts +17 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/plugins/client.d.ts +19 -0
- package/dist/plugins/client.d.ts.map +1 -0
- package/dist/plugins/client.js +24 -0
- package/dist/plugins/define.d.ts +6 -0
- package/dist/plugins/define.d.ts.map +1 -0
- package/dist/plugins/define.js +3 -0
- package/dist/plugins/derive.d.ts +32 -0
- package/dist/plugins/derive.d.ts.map +1 -0
- package/dist/plugins/derive.js +77 -0
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/loader.d.ts +43 -51
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +115 -58
- package/dist/plugins/manifest.d.ts +28 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +83 -0
- package/dist/plugins/prefetch.d.ts +16 -0
- package/dist/plugins/prefetch.d.ts.map +1 -0
- package/dist/plugins/prefetch.js +40 -0
- package/dist/plugins/registry.d.ts +22 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +25 -0
- package/dist/plugins/server.d.ts +2 -0
- package/dist/plugins/server.d.ts.map +1 -1
- package/dist/plugins/server.js +2 -0
- package/dist/plugins/types.d.ts +79 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +0 -0
- package/dist/translations/base/en.d.ts +1 -0
- package/dist/translations/base/en.d.ts.map +1 -1
- package/dist/translations/base/en.js +1 -0
- package/dist/translations/client.d.ts +16 -4
- package/dist/translations/client.d.ts.map +1 -1
- package/dist/translations/server.d.ts +16 -4
- package/dist/translations/server.d.ts.map +1 -1
- package/dist/utils/console-log.d.ts +18 -0
- package/dist/utils/console-log.d.ts.map +1 -0
- package/dist/utils/console-log.js +28 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/log.d.ts +18 -0
- package/dist/utils/log.d.ts.map +1 -0
- package/dist/utils/log.js +28 -0
- package/dist/validators/index.d.ts +1 -0
- package/dist/validators/index.d.ts.map +1 -1
- package/dist/validators/index.js +1 -0
- package/dist/validators/tags.d.ts +4 -0
- package/dist/validators/tags.d.ts.map +1 -0
- package/dist/validators/tags.js +8 -0
- package/package.json +28 -18
package/dist/plugins/loader.js
CHANGED
|
@@ -5,30 +5,21 @@ if (typeof window !== 'undefined') {
|
|
|
5
5
|
import { createRequire } from 'module';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { getCMSConfig, getConfigImportVersion } from '../core/config/index.js';
|
|
8
|
-
import
|
|
9
|
-
|
|
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
|
-
};
|
|
8
|
+
import { derivePluginName, derivePluginRouterKey } from './derive.js';
|
|
9
|
+
import { logWarn, logError, logInfo } from '../utils/console-log.js';
|
|
26
10
|
let cachedPlugins = null;
|
|
27
11
|
let cachedConfigVersion = -1;
|
|
28
12
|
let loadPromise = null;
|
|
29
13
|
let jitiInstance = null;
|
|
30
14
|
const appRequire = createRequire(path.join(process.cwd(), 'package.json'));
|
|
31
15
|
const pkgRequire = createRequire(import.meta.url);
|
|
16
|
+
let serverOnlyEmptyPath = null;
|
|
17
|
+
const getServerOnlyEmptyPath = () => {
|
|
18
|
+
if (!serverOnlyEmptyPath) {
|
|
19
|
+
serverOnlyEmptyPath = path.join(path.dirname(pkgRequire.resolve('server-only')), 'empty.js');
|
|
20
|
+
}
|
|
21
|
+
return serverOnlyEmptyPath;
|
|
22
|
+
};
|
|
32
23
|
const resolvePluginPath = (pluginPackage) => {
|
|
33
24
|
try {
|
|
34
25
|
return appRequire.resolve(pluginPackage);
|
|
@@ -54,6 +45,9 @@ export const loadPluginModule = async (pluginPackage) => {
|
|
|
54
45
|
fsCache: true,
|
|
55
46
|
moduleCache: true,
|
|
56
47
|
rebuildFsCache: true,
|
|
48
|
+
alias: {
|
|
49
|
+
'server-only': getServerOnlyEmptyPath(),
|
|
50
|
+
},
|
|
57
51
|
// Optional: nicer debugging in stack traces (off by default in jiti)
|
|
58
52
|
// sourceMaps: true,
|
|
59
53
|
});
|
|
@@ -63,38 +57,66 @@ export const loadPluginModule = async (pluginPackage) => {
|
|
|
63
57
|
const mod = jitiInstance(resolved);
|
|
64
58
|
return mod?.default ?? mod;
|
|
65
59
|
};
|
|
66
|
-
function resolvePluginInstance(registration, mod) {
|
|
67
|
-
const candidate = mod.createPlugin
|
|
60
|
+
async function resolvePluginInstance(registration, mod) {
|
|
61
|
+
const candidate = await (mod.createPlugin
|
|
68
62
|
? mod.createPlugin(registration.options)
|
|
69
63
|
: typeof mod.default === 'function'
|
|
70
64
|
? mod.default()
|
|
71
|
-
: (mod.default ?? mod.plugin);
|
|
65
|
+
: (mod.default ?? mod.plugin));
|
|
72
66
|
if (!candidate) {
|
|
73
|
-
|
|
67
|
+
logWarn('plugins', `Plugin "${registration.package}" did not return a plugin instance.`);
|
|
74
68
|
return null;
|
|
75
69
|
}
|
|
76
|
-
if (!candidate.
|
|
77
|
-
|
|
70
|
+
if (!candidate.title) {
|
|
71
|
+
logWarn('plugins', `Plugin "${registration.package}" is missing required "title". Skipping.`);
|
|
78
72
|
return null;
|
|
79
73
|
}
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const isSingleRoute =
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
const name = derivePluginName(registration.package);
|
|
75
|
+
const pkg = registration.package;
|
|
76
|
+
const override = registration.override;
|
|
77
|
+
const declaredRoutes = candidate.routes ?? [];
|
|
78
|
+
const isSingleRoute = declaredRoutes.length <= 1;
|
|
79
|
+
const groupRoutes = registration.groupRoutes ?? true;
|
|
80
|
+
// Validate override.routes keys against declared paths
|
|
81
|
+
if (override?.routes) {
|
|
82
|
+
const declaredPaths = new Set(declaredRoutes.map((r) => r.path));
|
|
83
|
+
for (const path of Object.keys(override.routes)) {
|
|
84
|
+
if (!declaredPaths.has(path)) {
|
|
85
|
+
const known = Array.from(declaredPaths).join(', ') || '(none)';
|
|
86
|
+
logWarn('plugins', `override.routes["${path}"] in "${pkg}" does not match any declared route. Known paths: ${known}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Warn on ineffective override shapes
|
|
91
|
+
if (!isSingleRoute && groupRoutes === false && (override?.title || override?.icon)) {
|
|
92
|
+
logWarn('plugins', `override.title / override.icon set for "${pkg}" but groupRoutes is false — group label is not rendered, so these have no effect.`);
|
|
93
|
+
}
|
|
94
|
+
// Resolve route titles/icons
|
|
95
|
+
const resolvedRoutes = declaredRoutes.map((route) => {
|
|
96
|
+
let title = route.title;
|
|
97
|
+
let icon = route.icon;
|
|
98
|
+
// Single-route: plugin-level override applies to the route itself.
|
|
99
|
+
if (isSingleRoute) {
|
|
100
|
+
if (override?.title)
|
|
101
|
+
title = override.title;
|
|
102
|
+
if (override?.icon)
|
|
103
|
+
icon = override.icon;
|
|
104
|
+
}
|
|
105
|
+
// Per-route override always wins over plugin-level.
|
|
106
|
+
const routeOverride = override?.routes?.[route.path];
|
|
107
|
+
if (routeOverride?.title)
|
|
108
|
+
title = routeOverride.title;
|
|
109
|
+
if (routeOverride?.icon)
|
|
110
|
+
icon = routeOverride.icon;
|
|
111
|
+
return { ...route, title, icon };
|
|
93
112
|
});
|
|
113
|
+
// Resolve plugin-level title/icon — only used as group label for multi-route grouped plugins.
|
|
114
|
+
const resolvedPluginTitle = !isSingleRoute && override?.title ? override.title : candidate.title;
|
|
115
|
+
const resolvedPluginIcon = !isSingleRoute && override?.icon ? override.icon : candidate.icon;
|
|
94
116
|
return {
|
|
95
|
-
title:
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
title: resolvedPluginTitle,
|
|
118
|
+
icon: resolvedPluginIcon,
|
|
119
|
+
name,
|
|
98
120
|
version: candidate.version,
|
|
99
121
|
router: candidate.router,
|
|
100
122
|
routes: resolvedRoutes,
|
|
@@ -113,45 +135,42 @@ export async function loadPlugins() {
|
|
|
113
135
|
const config = await getCMSConfig();
|
|
114
136
|
const registrations = config.plugins ?? [];
|
|
115
137
|
const seenPackages = new Set();
|
|
116
|
-
const
|
|
138
|
+
const seenNames = new Set();
|
|
117
139
|
const loaded = [];
|
|
118
140
|
for (const registration of registrations) {
|
|
119
141
|
if (!registration.package) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
142
|
+
logWarn('plugins', 'Plugin registration is missing "package" field — check your cms.config.ts. Skipping.');
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (seenPackages.has(registration.package)) {
|
|
146
|
+
logError('plugins', `Duplicate plugin package "${registration.package}" registered. Skipping duplicate.`);
|
|
123
147
|
continue;
|
|
124
148
|
}
|
|
125
149
|
const mod = await loadPluginModule(registration.package);
|
|
126
150
|
if (!mod)
|
|
127
151
|
continue;
|
|
128
|
-
const plugin = resolvePluginInstance(registration, mod);
|
|
152
|
+
const plugin = await resolvePluginInstance(registration, mod);
|
|
129
153
|
if (!plugin)
|
|
130
154
|
continue;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
console.error(`[plugins] Duplicate plugin package "${registration.package}" registered. Skipping duplicate.`);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (seenRouterKeys.has(routerKey)) {
|
|
137
|
-
console.error(`[plugins] Duplicate plugin router key "${routerKey}" derived from "${registration.package}". Skipping.`);
|
|
155
|
+
if (seenNames.has(plugin.name)) {
|
|
156
|
+
logError('plugins', `Duplicate plugin name "${plugin.name}" derived from "${registration.package}". Skipping.`);
|
|
138
157
|
continue;
|
|
139
158
|
}
|
|
140
159
|
seenPackages.add(registration.package);
|
|
141
|
-
|
|
160
|
+
seenNames.add(plugin.name);
|
|
142
161
|
if (typeof plugin.init === 'function') {
|
|
143
162
|
try {
|
|
144
163
|
await plugin.init({ config: registration });
|
|
145
164
|
}
|
|
146
165
|
catch (error) {
|
|
147
|
-
|
|
166
|
+
logError('plugins', `Plugin "${registration.package}" init failed.`, error);
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
loaded.push({
|
|
151
170
|
config: registration,
|
|
152
171
|
plugin,
|
|
153
172
|
moduleName: registration.package,
|
|
154
|
-
routerKey,
|
|
173
|
+
routerKey: derivePluginRouterKey(registration.package),
|
|
155
174
|
});
|
|
156
175
|
}
|
|
157
176
|
cachedPlugins = loaded;
|
|
@@ -172,17 +191,16 @@ export async function getPluginRoutes() {
|
|
|
172
191
|
const requireComponent = routes.length > 1;
|
|
173
192
|
return routes.map((route) => {
|
|
174
193
|
if (requireComponent && !route.component) {
|
|
175
|
-
|
|
194
|
+
logWarn('plugins', `Route "${route.path}" from "${entry.config.package}" should set "component" because the plugin defines multiple routes.`);
|
|
176
195
|
}
|
|
177
196
|
if (!requireComponent && route.component) {
|
|
178
|
-
|
|
197
|
+
logInfo('plugins', `Route "${route.path}" from "${entry.config.package}" should omit "component" and export a default component, because the plugin defines a single route.`);
|
|
179
198
|
}
|
|
180
199
|
return {
|
|
181
200
|
...route,
|
|
182
201
|
title: route.title,
|
|
183
202
|
pluginId: entry.config.package,
|
|
184
203
|
pluginName: entry.plugin.name,
|
|
185
|
-
pluginRegistryName: entry.plugin.registryName,
|
|
186
204
|
};
|
|
187
205
|
});
|
|
188
206
|
});
|
|
@@ -192,6 +210,45 @@ export async function findPluginRouteByPath(path) {
|
|
|
192
210
|
const routes = await getPluginRoutes();
|
|
193
211
|
return routes.find((route) => route.path === normalized) ?? null;
|
|
194
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns the navigation structure for all loaded plugins, accounting for
|
|
215
|
+
* `groupRoutes` and per-plugin `override` resolution. Single-route plugins emit
|
|
216
|
+
* one leaf. Multi-route plugins emit a group (default) or one leaf per route
|
|
217
|
+
* when `groupRoutes: false`.
|
|
218
|
+
*
|
|
219
|
+
* Pure data — does not filter by privilege. The sidebar layer applies that.
|
|
220
|
+
*/
|
|
221
|
+
export async function getPluginNavigation() {
|
|
222
|
+
const loaded = await loadPlugins();
|
|
223
|
+
const items = [];
|
|
224
|
+
for (const entry of loaded) {
|
|
225
|
+
const routes = entry.plugin.routes ?? [];
|
|
226
|
+
if (routes.length === 0)
|
|
227
|
+
continue;
|
|
228
|
+
const isSingleRoute = routes.length === 1;
|
|
229
|
+
const groupRoutes = entry.config.groupRoutes ?? true;
|
|
230
|
+
if (isSingleRoute || !groupRoutes) {
|
|
231
|
+
for (const route of routes) {
|
|
232
|
+
items.push({
|
|
233
|
+
kind: 'leaf',
|
|
234
|
+
title: route.title,
|
|
235
|
+
path: route.path,
|
|
236
|
+
icon: route.icon,
|
|
237
|
+
pluginName: entry.plugin.name,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
items.push({
|
|
243
|
+
kind: 'group',
|
|
244
|
+
title: entry.plugin.title,
|
|
245
|
+
icon: entry.plugin.icon,
|
|
246
|
+
pluginName: entry.plugin.name,
|
|
247
|
+
children: routes.map((r) => ({ title: r.title, path: r.path, icon: r.icon })),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return items;
|
|
251
|
+
}
|
|
195
252
|
/**
|
|
196
253
|
* Gets the dashboard override plugin route if configured.
|
|
197
254
|
* @returns The LoadedPluginRoute for the dashboard override, or null if not configured
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PluginConfigEntry } from '../core/config/config-loader.js';
|
|
2
|
+
import type { MultilingualString } from '../translations/language-utils.js';
|
|
3
|
+
import type { IconName } from 'lucide-react/dynamic';
|
|
4
|
+
export interface PluginManifestRoute {
|
|
5
|
+
path: string;
|
|
6
|
+
title: MultilingualString;
|
|
7
|
+
icon?: IconName;
|
|
8
|
+
component?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PluginManifest {
|
|
11
|
+
name: string;
|
|
12
|
+
registryName: string;
|
|
13
|
+
title: MultilingualString;
|
|
14
|
+
routes?: PluginManifestRoute[];
|
|
15
|
+
}
|
|
16
|
+
export interface LoadedPluginManifestRoute extends PluginManifestRoute {
|
|
17
|
+
pluginId: string;
|
|
18
|
+
pluginName: string;
|
|
19
|
+
pluginRegistryName: string;
|
|
20
|
+
}
|
|
21
|
+
export interface LoadedPluginManifest {
|
|
22
|
+
config: PluginConfigEntry;
|
|
23
|
+
manifest: PluginManifest;
|
|
24
|
+
moduleName: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function getPluginManifests(): Promise<LoadedPluginManifest[]>;
|
|
27
|
+
export declare function getPluginRouteManifests(): Promise<LoadedPluginManifestRoute[]>;
|
|
28
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/plugins/manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,kBAAkB,CAAA;IACzB,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACjC,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,cAAc,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;CACrB;AAoDD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA+B1E;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAUpF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { getCMSConfig } from '../core/config/index.js';
|
|
5
|
+
const appRequire = createRequire(path.join(process.cwd(), 'package.json'));
|
|
6
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
7
|
+
const resolvePluginPackageJson = (pluginPackage) => {
|
|
8
|
+
const target = `${pluginPackage}/package.json`;
|
|
9
|
+
try {
|
|
10
|
+
return appRequire.resolve(target);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
try {
|
|
14
|
+
return pkgRequire.resolve(target, { paths: [process.cwd()] });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const readManifestFromPackage = (pluginPackage) => {
|
|
22
|
+
const pkgJsonPath = resolvePluginPackageJson(pluginPackage);
|
|
23
|
+
if (!pkgJsonPath) {
|
|
24
|
+
console.warn(`[plugins] Could not resolve "${pluginPackage}/package.json".`);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
let pkg;
|
|
28
|
+
try {
|
|
29
|
+
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.warn(`[plugins] Failed to read "${pkgJsonPath}":`, error);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const manifest = pkg.pluginManifest;
|
|
36
|
+
if (!manifest) {
|
|
37
|
+
console.warn(`[plugins] Package "${pluginPackage}" is missing the "pluginManifest" field in package.json. ` +
|
|
38
|
+
`Plugins must declare metadata statically so the CLI can read it without evaluating plugin code.`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
if (!manifest.name || !manifest.registryName || !manifest.title) {
|
|
42
|
+
console.warn(`[plugins] Package "${pluginPackage}" has an invalid "pluginManifest" — required fields: name, registryName, title.`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return manifest;
|
|
46
|
+
};
|
|
47
|
+
export async function getPluginManifests() {
|
|
48
|
+
const config = await getCMSConfig();
|
|
49
|
+
const registrations = config.plugins ?? [];
|
|
50
|
+
const seenPackages = new Set();
|
|
51
|
+
const seenNames = new Set();
|
|
52
|
+
const loaded = [];
|
|
53
|
+
for (const registration of registrations) {
|
|
54
|
+
if (!registration.package)
|
|
55
|
+
continue;
|
|
56
|
+
if (seenPackages.has(registration.package))
|
|
57
|
+
continue;
|
|
58
|
+
const manifest = readManifestFromPackage(registration.package);
|
|
59
|
+
if (!manifest)
|
|
60
|
+
continue;
|
|
61
|
+
if (seenNames.has(manifest.name)) {
|
|
62
|
+
console.warn(`[plugins] Duplicate plugin name "${manifest.name}" — skipping "${registration.package}".`);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
seenPackages.add(registration.package);
|
|
66
|
+
seenNames.add(manifest.name);
|
|
67
|
+
loaded.push({
|
|
68
|
+
config: registration,
|
|
69
|
+
manifest,
|
|
70
|
+
moduleName: registration.package,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return loaded;
|
|
74
|
+
}
|
|
75
|
+
export async function getPluginRouteManifests() {
|
|
76
|
+
const loaded = await getPluginManifests();
|
|
77
|
+
return loaded.flatMap((entry) => (entry.manifest.routes ?? []).map((route) => ({
|
|
78
|
+
...route,
|
|
79
|
+
pluginId: entry.config.package,
|
|
80
|
+
pluginName: entry.manifest.name,
|
|
81
|
+
pluginRegistryName: entry.manifest.registryName,
|
|
82
|
+
})));
|
|
83
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LoadedPluginRoute } from './loader.js';
|
|
2
|
+
/**
|
|
3
|
+
* Walks a dot-path into a tRPC RSC `api` proxy and invokes `.prefetch()` at the leaf.
|
|
4
|
+
*
|
|
5
|
+
* Example: `runApiPrefetch(api, 'cpanelEmails.getEmails')` runs
|
|
6
|
+
* `await api.cpanelEmails.getEmails.prefetch()`.
|
|
7
|
+
*
|
|
8
|
+
* Throws if any segment is missing or the leaf has no `prefetch` helper, so a typo
|
|
9
|
+
* in `PluginRoute.prefetch` fails loudly during development.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runApiPrefetch(api: unknown, dotPath: string): Promise<void>;
|
|
12
|
+
/** Normalizes a route's `prefetch` field (string | string[] | undefined) into an array. */
|
|
13
|
+
export declare function getRoutePrefetchPaths(route: Pick<LoadedPluginRoute, 'prefetch'>): string[];
|
|
14
|
+
/** Runs all declared prefetches for a route in parallel. */
|
|
15
|
+
export declare function runRoutePrefetches(api: unknown, route: Pick<LoadedPluginRoute, 'prefetch'>): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=prefetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefetch.d.ts","sourceRoot":"","sources":["../../src/plugins/prefetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBjF;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAG1F;AAED,4DAA4D;AAC5D,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhH"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks a dot-path into a tRPC RSC `api` proxy and invokes `.prefetch()` at the leaf.
|
|
3
|
+
*
|
|
4
|
+
* Example: `runApiPrefetch(api, 'cpanelEmails.getEmails')` runs
|
|
5
|
+
* `await api.cpanelEmails.getEmails.prefetch()`.
|
|
6
|
+
*
|
|
7
|
+
* Throws if any segment is missing or the leaf has no `prefetch` helper, so a typo
|
|
8
|
+
* in `PluginRoute.prefetch` fails loudly during development.
|
|
9
|
+
*/
|
|
10
|
+
export async function runApiPrefetch(api, dotPath) {
|
|
11
|
+
const segments = dotPath.split('.').filter(Boolean);
|
|
12
|
+
if (segments.length === 0) {
|
|
13
|
+
throw new Error('[plugins] Empty prefetch path.');
|
|
14
|
+
}
|
|
15
|
+
let node = api;
|
|
16
|
+
for (const key of segments) {
|
|
17
|
+
if (node == null || (typeof node !== 'object' && typeof node !== 'function')) {
|
|
18
|
+
throw new Error(`[plugins] Cannot resolve prefetch path "${dotPath}" — segment "${key}" is unreachable.`);
|
|
19
|
+
}
|
|
20
|
+
node = node[key];
|
|
21
|
+
}
|
|
22
|
+
const prefetch = node?.prefetch;
|
|
23
|
+
if (typeof prefetch !== 'function') {
|
|
24
|
+
throw new Error(`[plugins] Prefetch path "${dotPath}" does not resolve to a procedure with a prefetch helper.`);
|
|
25
|
+
}
|
|
26
|
+
await prefetch();
|
|
27
|
+
}
|
|
28
|
+
/** Normalizes a route's `prefetch` field (string | string[] | undefined) into an array. */
|
|
29
|
+
export function getRoutePrefetchPaths(route) {
|
|
30
|
+
if (!route.prefetch)
|
|
31
|
+
return [];
|
|
32
|
+
return Array.isArray(route.prefetch) ? route.prefetch : [route.prefetch];
|
|
33
|
+
}
|
|
34
|
+
/** Runs all declared prefetches for a route in parallel. */
|
|
35
|
+
export async function runRoutePrefetches(api, route) {
|
|
36
|
+
const paths = getRoutePrefetchPaths(route);
|
|
37
|
+
if (paths.length === 0)
|
|
38
|
+
return;
|
|
39
|
+
await Promise.all(paths.map((path) => runApiPrefetch(api, path)));
|
|
40
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static import map for all official @nextjscms plugins.
|
|
3
|
+
*
|
|
4
|
+
* Why this file exists: the plugin loader needs to import plugin packages by
|
|
5
|
+
* name at runtime. Bare `await import(variable)` calls are rejected by
|
|
6
|
+
* Turbopack/webpack as "too dynamic" because the bundler cannot statically
|
|
7
|
+
* see which packages may be loaded. Listing each package as a literal
|
|
8
|
+
* `() => import('@nextjscms/plugin-x')` thunk lets the bundler analyze the
|
|
9
|
+
* import sites, and the host's module loader applies the correct export
|
|
10
|
+
* conditions at runtime — most importantly "react-server" during RSC
|
|
11
|
+
* requests, so plugin transitive deps marked `import 'server-only'` resolve
|
|
12
|
+
* to a no-op instead of throwing.
|
|
13
|
+
*
|
|
14
|
+
* Each thunk is wrapped in its own arrow so the import is deferred until the
|
|
15
|
+
* plugin is actually configured in cms.config.ts. Plugins not installed in
|
|
16
|
+
* the host app will fail at thunk invocation, which the loader treats as a
|
|
17
|
+
* normal "plugin not available" outcome.
|
|
18
|
+
*
|
|
19
|
+
* When a new official plugin is published, add an entry here.
|
|
20
|
+
*/
|
|
21
|
+
export declare const officialPluginRegistry: Record<string, () => Promise<unknown>>;
|
|
22
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAIzE,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static import map for all official @nextjscms plugins.
|
|
3
|
+
*
|
|
4
|
+
* Why this file exists: the plugin loader needs to import plugin packages by
|
|
5
|
+
* name at runtime. Bare `await import(variable)` calls are rejected by
|
|
6
|
+
* Turbopack/webpack as "too dynamic" because the bundler cannot statically
|
|
7
|
+
* see which packages may be loaded. Listing each package as a literal
|
|
8
|
+
* `() => import('@nextjscms/plugin-x')` thunk lets the bundler analyze the
|
|
9
|
+
* import sites, and the host's module loader applies the correct export
|
|
10
|
+
* conditions at runtime — most importantly "react-server" during RSC
|
|
11
|
+
* requests, so plugin transitive deps marked `import 'server-only'` resolve
|
|
12
|
+
* to a no-op instead of throwing.
|
|
13
|
+
*
|
|
14
|
+
* Each thunk is wrapped in its own arrow so the import is deferred until the
|
|
15
|
+
* plugin is actually configured in cms.config.ts. Plugins not installed in
|
|
16
|
+
* the host app will fail at thunk invocation, which the loader treats as a
|
|
17
|
+
* normal "plugin not available" outcome.
|
|
18
|
+
*
|
|
19
|
+
* When a new official plugin is published, add an entry here.
|
|
20
|
+
*/
|
|
21
|
+
export const officialPluginRegistry = {
|
|
22
|
+
'@nextjscms/plugin-cpanel-dashboard': () => import('@nextjscms/plugin-cpanel-dashboard'),
|
|
23
|
+
'@nextjscms/plugin-cpanel-emails': () => import('@nextjscms/plugin-cpanel-emails'),
|
|
24
|
+
'@nextjscms/plugin-google-analytics': () => import('@nextjscms/plugin-google-analytics'),
|
|
25
|
+
};
|
package/dist/plugins/server.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export * from './loader.js';
|
|
2
|
+
export { derivePluginName, derivePluginRouterKey, extractPluginName, PLUGIN_PACKAGE_PREFIX } from './derive.js';
|
|
3
|
+
export { runApiPrefetch, runRoutePrefetches, getRoutePrefetchPaths } from './prefetch.js';
|
|
2
4
|
//# sourceMappingURL=server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/plugins/server.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/plugins/server.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAC/G,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/plugins/server.js
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { IconName } from 'lucide-react/dynamic';
|
|
2
|
+
import type { MultilingualString } from '../translations/language-utils.js';
|
|
3
|
+
export interface PluginRouteOverride {
|
|
4
|
+
title?: MultilingualString;
|
|
5
|
+
icon?: IconName;
|
|
6
|
+
}
|
|
7
|
+
export interface PluginRuntimeConfigEntry {
|
|
8
|
+
package: string;
|
|
9
|
+
options?: Record<string, unknown>;
|
|
10
|
+
override?: {
|
|
11
|
+
title?: MultilingualString;
|
|
12
|
+
icon?: IconName;
|
|
13
|
+
routes?: Record<string, PluginRouteOverride>;
|
|
14
|
+
};
|
|
15
|
+
groupRoutes?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface PluginInitContext {
|
|
18
|
+
config: PluginRuntimeConfigEntry;
|
|
19
|
+
}
|
|
20
|
+
export interface PluginRoute {
|
|
21
|
+
path: string;
|
|
22
|
+
/**
|
|
23
|
+
* The title of the route.
|
|
24
|
+
* Can be a plain string or a localized object with language codes as keys.
|
|
25
|
+
*/
|
|
26
|
+
title: MultilingualString;
|
|
27
|
+
icon?: IconName | undefined;
|
|
28
|
+
component?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Dot-paths into the host's tRPC router (e.g. `'cpanelEmails.getEmails'`) that the
|
|
31
|
+
* host should prefetch on the server before rendering the plugin's component. The
|
|
32
|
+
* results are placed into the React Query cache and hydrated into the client tree
|
|
33
|
+
* via the host-rendered `<HydrateClient>` boundary.
|
|
34
|
+
*/
|
|
35
|
+
prefetch?: string | string[];
|
|
36
|
+
}
|
|
37
|
+
export type PluginRouteWithoutComponent = Omit<PluginRoute, 'component'> & {
|
|
38
|
+
component?: never;
|
|
39
|
+
};
|
|
40
|
+
export type PluginRouteWithComponent = PluginRoute & {
|
|
41
|
+
component: string;
|
|
42
|
+
};
|
|
43
|
+
export interface CMSPlugin {
|
|
44
|
+
/**
|
|
45
|
+
* The human facing title of the plugin.
|
|
46
|
+
* Can be a plain string or a localized object with language codes as keys.
|
|
47
|
+
* @example 'Some Plugin Title'
|
|
48
|
+
* @example { en: 'Some Plugin Title', ar: 'عنوان الإضافة' }
|
|
49
|
+
*/
|
|
50
|
+
title: MultilingualString;
|
|
51
|
+
/**
|
|
52
|
+
* Optional sidebar icon for the plugin group (multi-route, when `groupRoutes !== false`).
|
|
53
|
+
* Single-route plugins use the route's own `icon` instead.
|
|
54
|
+
*/
|
|
55
|
+
icon?: IconName;
|
|
56
|
+
version?: string;
|
|
57
|
+
router?: unknown;
|
|
58
|
+
routes?: readonly PluginRoute[];
|
|
59
|
+
init?: (ctx: PluginInitContext) => Promise<void> | void;
|
|
60
|
+
}
|
|
61
|
+
type CMSPluginBase = Omit<CMSPlugin, 'routes'>;
|
|
62
|
+
export type CMSPluginSingleRoute = CMSPluginBase & {
|
|
63
|
+
routes?: readonly [] | readonly [PluginRouteWithoutComponent];
|
|
64
|
+
};
|
|
65
|
+
export type CMSPluginMultiRoute = CMSPluginBase & {
|
|
66
|
+
routes: readonly [PluginRouteWithComponent, PluginRouteWithComponent, ...PluginRouteWithComponent[]];
|
|
67
|
+
};
|
|
68
|
+
export type CMSPluginDescriptorBase = Omit<CMSPluginBase, 'router' | 'init'> & {
|
|
69
|
+
package: string;
|
|
70
|
+
};
|
|
71
|
+
export type CMSPluginDescriptorSingleRoute = CMSPluginDescriptorBase & {
|
|
72
|
+
routes?: readonly [] | readonly [PluginRouteWithoutComponent];
|
|
73
|
+
};
|
|
74
|
+
export type CMSPluginDescriptorMultiRoute = CMSPluginDescriptorBase & {
|
|
75
|
+
routes: readonly [PluginRouteWithComponent, PluginRouteWithComponent, ...PluginRouteWithComponent[]];
|
|
76
|
+
};
|
|
77
|
+
export type CMSPluginDescriptor = CMSPluginDescriptorSingleRoute | CMSPluginDescriptorMultiRoute;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AAE3E,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,IAAI,CAAC,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,wBAAwB;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,kBAAkB,CAAA;QAC1B,IAAI,CAAC,EAAE,QAAQ,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;KAC/C,CAAA;IACD,WAAW,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,wBAAwB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC/B;AAED,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAEhG,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1E,MAAM,WAAW,SAAS;IACtB;;;;;OAKG;IACH,KAAK,EAAE,kBAAkB,CAAA;IACzB;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC1D;AAED,KAAK,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AAE9C,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IAC/C,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAA;CAChE,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG;IAC9C,MAAM,EAAE,SAAS,CAAC,wBAAwB,EAAE,wBAAwB,EAAE,GAAG,wBAAwB,EAAE,CAAC,CAAA;CACvG,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,MAAM,CAAC,GAAG;IAC3E,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG,uBAAuB,GAAG;IACnE,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAA;CAChE,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG,uBAAuB,GAAG;IAClE,MAAM,EAAE,SAAS,CAAC,wBAAwB,EAAE,wBAAwB,EAAE,GAAG,wBAAwB,EAAE,CAAC,CAAA;CACvG,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,8BAA8B,GAAG,6BAA6B,CAAA"}
|
|
File without changes
|
|
@@ -369,6 +369,7 @@ declare const _default: {
|
|
|
369
369
|
readonly addedAgo: "Added {time} ago";
|
|
370
370
|
readonly hoursAgo: "hours ago";
|
|
371
371
|
readonly main: "Main";
|
|
372
|
+
readonly plugins: "Plugins";
|
|
372
373
|
readonly categorySections: "Category Sections";
|
|
373
374
|
readonly sectionsWithItems: "Sections with Items";
|
|
374
375
|
readonly simpleSections: "Simple Sections";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/base/en.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/base/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAqgBU"}
|