@sonicjs-cms/core 3.0.0-beta.22 → 3.0.0-beta.23
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/adapters.cjs +512 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +342 -0
- package/dist/adapters.d.ts +342 -0
- package/dist/adapters.js +501 -0
- package/dist/adapters.js.map +1 -0
- package/dist/admin-documents-form.template-55V2ZGWT.js +6 -0
- package/dist/{admin-documents-form.template-DDSH6ROU.js.map → admin-documents-form.template-55V2ZGWT.js.map} +1 -1
- package/dist/admin-documents-form.template-YNAVMJCV.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-YQ4EMF2J.js.map → admin-documents-form.template-YNAVMJCV.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-3XZXDGF7.cjs +21 -0
- package/dist/{admin-layout-catalyst.template-KDHKVLXR.cjs.map → admin-layout-catalyst.template-3XZXDGF7.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-6UQGLCKI.js +7 -0
- package/dist/{admin-documents-form.template-LSZKGA5J.cjs.map → admin-layout-catalyst.template-6UQGLCKI.js.map} +1 -1
- package/dist/{chunk-I2DM27HP.js → chunk-2MIYYAO4.js} +49 -4
- package/dist/chunk-2MIYYAO4.js.map +1 -0
- package/dist/{chunk-EUJAEB6W.cjs → chunk-4WMZGHIC.cjs} +53 -4
- package/dist/chunk-4WMZGHIC.cjs.map +1 -0
- package/dist/{chunk-2FCKKOA5.js → chunk-A46IRC5A.js} +3 -3
- package/dist/chunk-A46IRC5A.js.map +1 -0
- package/dist/{chunk-PYZYU7EK.cjs → chunk-AT4ZQGEZ.cjs} +17 -2
- package/dist/chunk-AT4ZQGEZ.cjs.map +1 -0
- package/dist/{chunk-CRGUD4KC.cjs → chunk-BBEKHLTW.cjs} +9 -9
- package/dist/{chunk-CRGUD4KC.cjs.map → chunk-BBEKHLTW.cjs.map} +1 -1
- package/dist/{chunk-RMRJGMDE.js → chunk-BHND5PEV.js} +3 -3
- package/dist/{chunk-RMRJGMDE.js.map → chunk-BHND5PEV.js.map} +1 -1
- package/dist/{chunk-OBA2RYZN.js → chunk-BJROXF4N.js} +3 -3
- package/dist/{chunk-OBA2RYZN.js.map → chunk-BJROXF4N.js.map} +1 -1
- package/dist/{chunk-QWSR4THH.cjs → chunk-C3ZQP5NW.cjs} +12 -5
- package/dist/chunk-C3ZQP5NW.cjs.map +1 -0
- package/dist/{chunk-JFLZHOQP.cjs → chunk-CTYLCWMO.cjs} +486 -409
- package/dist/chunk-CTYLCWMO.cjs.map +1 -0
- package/dist/{chunk-CHWT5KBK.js → chunk-DIBCKCUE.js} +6 -6
- package/dist/{chunk-CHWT5KBK.js.map → chunk-DIBCKCUE.js.map} +1 -1
- package/dist/{chunk-73O4GPJ6.js → chunk-DPLJYTHE.js} +12 -5
- package/dist/chunk-DPLJYTHE.js.map +1 -0
- package/dist/{chunk-PXNTCCPE.cjs → chunk-E66UVONV.cjs} +8 -8
- package/dist/{chunk-PXNTCCPE.cjs.map → chunk-E66UVONV.cjs.map} +1 -1
- package/dist/{chunk-FTXGZ3BF.cjs → chunk-IS54FPB7.cjs} +18 -18
- package/dist/{chunk-FTXGZ3BF.cjs.map → chunk-IS54FPB7.cjs.map} +1 -1
- package/dist/{chunk-N32OWET6.cjs → chunk-JMJM7DMM.cjs} +5 -5
- package/dist/{chunk-N32OWET6.cjs.map → chunk-JMJM7DMM.cjs.map} +1 -1
- package/dist/{chunk-DOMXI5PM.js → chunk-KS24NPPL.js} +17 -2
- package/dist/chunk-KS24NPPL.js.map +1 -0
- package/dist/{chunk-MGHHPNJN.cjs → chunk-RFBW5RRH.cjs} +11 -59
- package/dist/chunk-RFBW5RRH.cjs.map +1 -0
- package/dist/{chunk-6KNTZ67K.js → chunk-SK5CHFJP.js} +192 -116
- package/dist/chunk-SK5CHFJP.js.map +1 -0
- package/dist/{chunk-5V62WT6M.js → chunk-THFZSDIU.js} +4 -2
- package/dist/chunk-THFZSDIU.js.map +1 -0
- package/dist/{chunk-JQISFW6U.js → chunk-URIBTX27.js} +3 -3
- package/dist/{chunk-JQISFW6U.js.map → chunk-URIBTX27.js.map} +1 -1
- package/dist/{chunk-K623Q6WD.cjs → chunk-UYJQDDEE.cjs} +4 -2
- package/dist/chunk-UYJQDDEE.cjs.map +1 -0
- package/dist/{chunk-3CT3SUR4.cjs → chunk-VGHEKIJL.cjs} +3 -3
- package/dist/chunk-VGHEKIJL.cjs.map +1 -0
- package/dist/{chunk-GB2Q2DNK.js → chunk-XXRR54AB.js} +5 -49
- package/dist/chunk-XXRR54AB.js.map +1 -0
- package/dist/{define-plugin-DsKiGu1q.d.cts → define-plugin-DMcvEy_C.d.cts} +33 -0
- package/dist/{define-plugin-BYIey6sp.d.ts → define-plugin-D_6D9vVZ.d.ts} +33 -0
- package/dist/index.cjs +1758 -326
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1453 -21
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +34 -34
- package/dist/middleware.js +5 -5
- package/dist/migrations-XQ6EX6HX.js +4 -0
- package/dist/{migrations-HLK2QF4T.js.map → migrations-XQ6EX6HX.js.map} +1 -1
- package/dist/migrations-ZD7Y5NUC.cjs +13 -0
- package/dist/{migrations-UIMA6ZL6.cjs.map → migrations-ZD7Y5NUC.cjs.map} +1 -1
- package/dist/plugins.cjs +40 -40
- package/dist/plugins.d.cts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +3 -3
- package/dist/routes.cjs +29 -29
- package/dist/routes.js +9 -9
- package/dist/services.cjs +18 -18
- package/dist/services.js +2 -2
- package/dist/templates.cjs +17 -17
- package/dist/templates.js +3 -3
- package/dist/utils.cjs +3 -3
- package/dist/utils.js +1 -1
- package/migrations/0001_core.sql +7 -1
- package/package.json +10 -3
- package/dist/admin-documents-form.template-DDSH6ROU.js +0 -6
- package/dist/admin-documents-form.template-LSZKGA5J.cjs +0 -19
- package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +0 -21
- package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +0 -7
- package/dist/chunk-2FCKKOA5.js.map +0 -1
- package/dist/chunk-3CT3SUR4.cjs.map +0 -1
- package/dist/chunk-5V62WT6M.js.map +0 -1
- package/dist/chunk-6KNTZ67K.js.map +0 -1
- package/dist/chunk-73O4GPJ6.js.map +0 -1
- package/dist/chunk-DOMXI5PM.js.map +0 -1
- package/dist/chunk-EUJAEB6W.cjs.map +0 -1
- package/dist/chunk-GB2Q2DNK.js.map +0 -1
- package/dist/chunk-I2DM27HP.js.map +0 -1
- package/dist/chunk-JFLZHOQP.cjs.map +0 -1
- package/dist/chunk-K623Q6WD.cjs.map +0 -1
- package/dist/chunk-MGHHPNJN.cjs.map +0 -1
- package/dist/chunk-PYZYU7EK.cjs.map +0 -1
- package/dist/chunk-QWSR4THH.cjs.map +0 -1
- package/dist/migrations-HLK2QF4T.js +0 -4
- package/dist/migrations-UIMA6ZL6.cjs +0 -13
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { isFirstUserRegistration, isRegistrationEnabled, authValidationService } from './chunk-VVYVFCML.js';
|
|
2
|
-
import { renderDocumentFormPage, renderAlert } from './chunk-
|
|
2
|
+
import { renderDocumentFormPage, renderAlert } from './chunk-BHND5PEV.js';
|
|
3
3
|
import { getCacheService, CACHE_CONFIGS, SettingsService, getLogger, getAppInstance, buildRouteList, CATEGORY_INFO } from './chunk-2XAQTPAE.js';
|
|
4
|
-
import { DocumentTypeRegistry, requireAuth, requireRole, optionalAuth, isPluginActive, rateLimit, AuthManager, getJwtExpirySecondsFromDb, getJwtRefreshGraceSecondsFromDb, logActivity, generateCsrfToken } from './chunk-
|
|
4
|
+
import { DocumentTypeRegistry, requireAuth, requireRole, optionalAuth, isPluginActive, rateLimit, AuthManager, getJwtExpirySecondsFromDb, getJwtRefreshGraceSecondsFromDb, logActivity, generateCsrfToken } from './chunk-DIBCKCUE.js';
|
|
5
5
|
import { DocumentsService, documentSecondsToMs, RbacService } from './chunk-3TMTYJAJ.js';
|
|
6
6
|
import { nanoid } from './chunk-UWUP2VMT.js';
|
|
7
|
-
import { getCollectionRegistry, collectionRecordToRow, loadCollectionConfigs, getVisibleCollections, PluginService, PLUGIN_REGISTRY, findPluginByCodeName, isCodeCollectionInternal, isDbDocTypeInternal, invalidateTenantCache } from './chunk-
|
|
8
|
-
import { MigrationService } from './chunk-
|
|
9
|
-
import { renderCheckboxPage, renderAlert as renderAlert$1, renderTable, renderPagination, renderConfirmationDialog, getConfirmationDialogScript, renderAdminLayout, adminLayoutV2, renderForm } from './chunk-
|
|
10
|
-
import { init_admin_layout_catalyst_template, renderAdminLayoutCatalyst } from './chunk-
|
|
11
|
-
import { createServiceSingleton, definePlugin, getPluginDefinition, applySchemaDefaults, renderSchemaFields, parseFormDataToSettings } from './chunk-
|
|
7
|
+
import { getCollectionRegistry, collectionRecordToRow, loadCollectionConfigs, getVisibleCollections, PluginService, PLUGIN_REGISTRY, findPluginByCodeName, isCodeCollectionInternal, isDbDocTypeInternal, invalidateTenantCache } from './chunk-KS24NPPL.js';
|
|
8
|
+
import { MigrationService } from './chunk-A46IRC5A.js';
|
|
9
|
+
import { renderCheckboxPage, renderAlert as renderAlert$1, renderTable, renderPagination, renderConfirmationDialog, getConfirmationDialogScript, renderAdminLayout, adminLayoutV2, renderForm } from './chunk-BJROXF4N.js';
|
|
10
|
+
import { init_admin_layout_catalyst_template, renderAdminLayoutCatalyst } from './chunk-THFZSDIU.js';
|
|
11
|
+
import { createServiceSingleton, definePlugin, getPluginDefinition, applySchemaDefaults, renderSchemaFields, parseFormDataToSettings, getPluginMenu } from './chunk-2MIYYAO4.js';
|
|
12
12
|
import { hasHookSystem, getTypedHooks } from './chunk-RNZFGN4R.js';
|
|
13
13
|
import { QueryFilterBuilder, getBlocksFieldConfig, parseBlocksValue } from './chunk-QZGABF2M.js';
|
|
14
14
|
import { metricsTracker } from './chunk-FICTAGD4.js';
|
|
15
|
-
import { getCoreVersion } from './chunk-
|
|
15
|
+
import { getCoreVersion } from './chunk-DPLJYTHE.js';
|
|
16
16
|
import { escapeHtml, sanitizeRichText, sanitizeInput } from './chunk-TQABQWOP.js';
|
|
17
17
|
import { Hono } from 'hono';
|
|
18
18
|
import { z } from 'zod';
|
|
@@ -3399,7 +3399,7 @@ adminApiRoutes.patch("/collections/:id", collectionsReadOnly);
|
|
|
3399
3399
|
adminApiRoutes.delete("/collections/:id", collectionsReadOnly);
|
|
3400
3400
|
adminApiRoutes.get("/migrations/status", async (c) => {
|
|
3401
3401
|
try {
|
|
3402
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3402
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-XQ6EX6HX.js');
|
|
3403
3403
|
const db = c.env.DB;
|
|
3404
3404
|
const migrationService = new MigrationService2(db);
|
|
3405
3405
|
const status = await migrationService.getMigrationStatus();
|
|
@@ -3442,7 +3442,7 @@ adminApiRoutes.post("/migrations/run", async (c) => {
|
|
|
3442
3442
|
});
|
|
3443
3443
|
adminApiRoutes.get("/migrations/validate", async (c) => {
|
|
3444
3444
|
try {
|
|
3445
|
-
const { MigrationService: MigrationService2 } = await import('./migrations-
|
|
3445
|
+
const { MigrationService: MigrationService2 } = await import('./migrations-XQ6EX6HX.js');
|
|
3446
3446
|
const db = c.env.DB;
|
|
3447
3447
|
const migrationService = new MigrationService2(db);
|
|
3448
3448
|
const validation = await migrationService.validateSchema();
|
|
@@ -13071,7 +13071,7 @@ adminContentRoutes.post("/documents/:typeId/:documentId/delete", async (c) => {
|
|
|
13071
13071
|
adminContentRoutes.get("/documents/:typeId/:rootId/versions", async (c) => {
|
|
13072
13072
|
const { typeId, rootId } = c.req.param();
|
|
13073
13073
|
const db = c.env.DB;
|
|
13074
|
-
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-
|
|
13074
|
+
const { renderVersionHistoryFragment } = await import('./admin-documents-form.template-55V2ZGWT.js');
|
|
13075
13075
|
const registry = new DocumentTypeRegistry(db);
|
|
13076
13076
|
const docType = await registry.findById(typeId);
|
|
13077
13077
|
if (!docType) return c.html("<div>Unknown type.</div>", 404);
|
|
@@ -19344,8 +19344,9 @@ function escapeHtmlAttr(value) {
|
|
|
19344
19344
|
return value.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
19345
19345
|
}
|
|
19346
19346
|
function renderPluginSettingsPage(data) {
|
|
19347
|
-
const { plugin, activity = [], user } = data;
|
|
19348
|
-
const
|
|
19347
|
+
const { plugin, activity = [], user, settingsTabData } = data;
|
|
19348
|
+
const pluginDef = getPluginDefinition(plugin.id || plugin.name);
|
|
19349
|
+
const hasUserSettings = pluginDef?.settingsTabContent != null || Object.keys(plugin.settings || {}).some((k) => !k.startsWith("_"));
|
|
19349
19350
|
const defaultTab = hasUserSettings ? "settings" : "info";
|
|
19350
19351
|
const pageContent = `
|
|
19351
19352
|
<div class="w-full px-4 sm:px-6 lg:px-8 py-6">
|
|
@@ -19425,7 +19426,7 @@ function renderPluginSettingsPage(data) {
|
|
|
19425
19426
|
<div id="tab-content">
|
|
19426
19427
|
<!-- Settings Tab -->
|
|
19427
19428
|
<div id="settings-content" class="tab-content hidden">
|
|
19428
|
-
${hasUserSettings ? renderSettingsTab(plugin) : ""}
|
|
19429
|
+
${hasUserSettings ? renderSettingsTab(plugin, settingsTabData) : ""}
|
|
19429
19430
|
</div>
|
|
19430
19431
|
|
|
19431
19432
|
<!-- Activity Tab -->
|
|
@@ -19646,10 +19647,14 @@ function renderToggleButton(plugin) {
|
|
|
19646
19647
|
}
|
|
19647
19648
|
return plugin.status === "active" ? `<button onclick="togglePlugin('${plugin.id}', 'deactivate')" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors">Deactivate</button>` : `<button onclick="togglePlugin('${plugin.id}', 'activate')" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg text-sm font-medium transition-colors">Activate</button>`;
|
|
19648
19649
|
}
|
|
19649
|
-
function renderSettingsTab(plugin) {
|
|
19650
|
+
function renderSettingsTab(plugin, settingsTabData) {
|
|
19650
19651
|
const settings = plugin.settings || {};
|
|
19651
19652
|
const pluginId = plugin.id || plugin.name;
|
|
19652
19653
|
const hasUserKeys = Object.keys(settings).some((k) => !k.startsWith("_"));
|
|
19654
|
+
const pluginDef = getPluginDefinition(pluginId);
|
|
19655
|
+
if (pluginDef?.settingsTabContent) {
|
|
19656
|
+
return pluginDef.settingsTabContent.render({ plugin, settings, data: settingsTabData });
|
|
19657
|
+
}
|
|
19653
19658
|
const customRenderer = pluginSettingsComponents[pluginId];
|
|
19654
19659
|
if (customRenderer) {
|
|
19655
19660
|
return `
|
|
@@ -19996,8 +20001,7 @@ function formatTimestamp(timestamp) {
|
|
|
19996
20001
|
}
|
|
19997
20002
|
var pluginSettingsComponents = {
|
|
19998
20003
|
"otp-login": renderOTPLoginSettingsContent,
|
|
19999
|
-
"email": renderEmailSettingsContent
|
|
20000
|
-
"oauth-providers": renderOAuthProvidersSettingsContent
|
|
20004
|
+
"email": renderEmailSettingsContent
|
|
20001
20005
|
};
|
|
20002
20006
|
function renderOTPLoginSettingsContent(plugin, settings) {
|
|
20003
20007
|
const siteName = settings.siteName || "SonicJS";
|
|
@@ -20720,99 +20724,157 @@ defineUserProfile({
|
|
|
20720
20724
|
</div>
|
|
20721
20725
|
`;
|
|
20722
20726
|
}
|
|
20723
|
-
function renderOAuthProvidersSettingsContent(_plugin, settings) {
|
|
20724
|
-
const providers = settings.providers || {};
|
|
20725
|
-
const github = providers.github || {};
|
|
20726
|
-
const google = providers.google || {};
|
|
20727
|
-
const inputClass = "w-full px-3 py-2 rounded-lg bg-white/5 border border-white/10 focus:border-blue-500 focus:outline-none text-white";
|
|
20728
|
-
function renderProviderCard(name, label, icon, data) {
|
|
20729
|
-
const clientId = escapeHtmlAttr(data.clientId || "");
|
|
20730
|
-
const clientSecret = escapeHtmlAttr(data.clientSecret || "");
|
|
20731
|
-
const enabled = data.enabled === true;
|
|
20732
|
-
return `
|
|
20733
|
-
<div class="backdrop-blur-md bg-white/5 rounded-xl border border-white/10 p-6">
|
|
20734
|
-
<div class="flex items-center justify-between mb-4">
|
|
20735
|
-
<h3 class="text-lg font-semibold text-white flex items-center gap-2">
|
|
20736
|
-
<span>${icon}</span> ${label}
|
|
20737
|
-
</h3>
|
|
20738
|
-
<label class="relative inline-flex items-center cursor-pointer">
|
|
20739
|
-
<input type="checkbox" id="oauth_${name}_enabled" ${enabled ? "checked" : ""} class="sr-only peer">
|
|
20740
|
-
<div class="w-11 h-6 bg-gray-600 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
|
|
20741
|
-
<span class="ml-2 text-sm text-gray-300">Enabled</span>
|
|
20742
|
-
</label>
|
|
20743
|
-
</div>
|
|
20744
|
-
<div class="space-y-4">
|
|
20745
|
-
<div>
|
|
20746
|
-
<label for="oauth_${name}_clientId" class="block text-sm font-medium text-gray-300 mb-2">Client ID</label>
|
|
20747
|
-
<input type="text" id="oauth_${name}_clientId" value="${clientId}" placeholder="${label} OAuth Client ID" class="${inputClass}">
|
|
20748
|
-
</div>
|
|
20749
|
-
<div>
|
|
20750
|
-
<label for="oauth_${name}_clientSecret" class="block text-sm font-medium text-gray-300 mb-2">Client Secret</label>
|
|
20751
|
-
<input type="password" id="oauth_${name}_clientSecret" value="${clientSecret}" placeholder="${label} OAuth Client Secret" class="${inputClass}">
|
|
20752
|
-
</div>
|
|
20753
|
-
</div>
|
|
20754
|
-
</div>
|
|
20755
|
-
`;
|
|
20756
|
-
}
|
|
20757
|
-
return `
|
|
20758
|
-
<div class="space-y-6">
|
|
20759
|
-
<div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-4">
|
|
20760
|
-
<p class="text-blue-200 text-sm">
|
|
20761
|
-
Configure OAuth provider credentials below. Credentials are stored securely and used server-side only.
|
|
20762
|
-
Make sure to add the callback URL <code class="text-blue-300">/auth/oauth/[provider]/callback</code> to your OAuth app's allowed redirect URIs.
|
|
20763
|
-
</p>
|
|
20764
|
-
</div>
|
|
20765
|
-
|
|
20766
|
-
${renderProviderCard("github", "GitHub", "\u{1F419}", github)}
|
|
20767
|
-
${renderProviderCard("google", "Google", "\u{1F535}", google)}
|
|
20768
|
-
</div>
|
|
20769
|
-
|
|
20770
|
-
<script>
|
|
20771
|
-
(function () {
|
|
20772
|
-
const origSave = window.saveSettings;
|
|
20773
|
-
window.saveSettings = async function () {
|
|
20774
|
-
const settings = {
|
|
20775
|
-
providers: {
|
|
20776
|
-
github: {
|
|
20777
|
-
clientId: document.getElementById('oauth_github_clientId').value,
|
|
20778
|
-
clientSecret: document.getElementById('oauth_github_clientSecret').value,
|
|
20779
|
-
enabled: document.getElementById('oauth_github_enabled').checked,
|
|
20780
|
-
},
|
|
20781
|
-
google: {
|
|
20782
|
-
clientId: document.getElementById('oauth_google_clientId').value,
|
|
20783
|
-
clientSecret: document.getElementById('oauth_google_clientSecret').value,
|
|
20784
|
-
enabled: document.getElementById('oauth_google_enabled').checked,
|
|
20785
|
-
},
|
|
20786
|
-
}
|
|
20787
|
-
};
|
|
20788
|
-
|
|
20789
|
-
const saveButton = document.getElementById('save-button');
|
|
20790
|
-
saveButton.disabled = true;
|
|
20791
|
-
saveButton.textContent = 'Saving...';
|
|
20792
20727
|
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
|
|
20815
|
-
|
|
20728
|
+
// src/plugins/core-plugins/menu-plugin/services/menu-reconcile.ts
|
|
20729
|
+
async function upsertPluginRow(db, slug, entry, visible) {
|
|
20730
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
20731
|
+
const existing = await db.prepare(
|
|
20732
|
+
`SELECT id FROM documents
|
|
20733
|
+
WHERE slug = ? AND type_id = 'menu_item' AND tenant_id = 'default'
|
|
20734
|
+
AND is_current_draft = 1 AND deleted_at IS NULL`
|
|
20735
|
+
).bind(slug).first();
|
|
20736
|
+
if (existing) {
|
|
20737
|
+
await db.prepare(
|
|
20738
|
+
`UPDATE documents
|
|
20739
|
+
SET data = json_set(data, '$.url', ?, '$.pluginId', ?, '$.visible', ?),
|
|
20740
|
+
visible = ?,
|
|
20741
|
+
updated_at = ?
|
|
20742
|
+
WHERE id = ? AND tenant_id = 'default'`
|
|
20743
|
+
).bind(entry.url, entry.pluginId, visible ? 1 : 0, visible ? 1 : 0, now, existing.id).run();
|
|
20744
|
+
return;
|
|
20745
|
+
}
|
|
20746
|
+
const id = nanoid();
|
|
20747
|
+
const data = JSON.stringify({
|
|
20748
|
+
label: entry.label,
|
|
20749
|
+
url: entry.url,
|
|
20750
|
+
icon: entry.icon,
|
|
20751
|
+
target: "_self",
|
|
20752
|
+
isExternal: false,
|
|
20753
|
+
visible,
|
|
20754
|
+
parent: null,
|
|
20755
|
+
source: "plugin",
|
|
20756
|
+
pluginId: entry.pluginId,
|
|
20757
|
+
permissions: [],
|
|
20758
|
+
lockedFields: ["url"],
|
|
20759
|
+
sortOrder: entry.sortOrder
|
|
20760
|
+
});
|
|
20761
|
+
await db.prepare(
|
|
20762
|
+
`INSERT INTO documents (id, root_id, type_id, type_version, version_of_id, version_number,
|
|
20763
|
+
is_current_draft, is_published, status, parent_root_id, slug, path, title, zone,
|
|
20764
|
+
sort_order, visible, published_at, scheduled_at, expires_at, deleted_at,
|
|
20765
|
+
tenant_id, locale, translation_group_id, data, metadata,
|
|
20766
|
+
owner_id, created_by, updated_by, created_at, updated_at)
|
|
20767
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
|
|
20768
|
+
).bind(
|
|
20769
|
+
id,
|
|
20770
|
+
id,
|
|
20771
|
+
"menu_item",
|
|
20772
|
+
1,
|
|
20773
|
+
null,
|
|
20774
|
+
1,
|
|
20775
|
+
1,
|
|
20776
|
+
0,
|
|
20777
|
+
"draft",
|
|
20778
|
+
"",
|
|
20779
|
+
slug,
|
|
20780
|
+
null,
|
|
20781
|
+
entry.label,
|
|
20782
|
+
null,
|
|
20783
|
+
entry.sortOrder,
|
|
20784
|
+
visible ? 1 : 0,
|
|
20785
|
+
null,
|
|
20786
|
+
null,
|
|
20787
|
+
null,
|
|
20788
|
+
null,
|
|
20789
|
+
"default",
|
|
20790
|
+
"default",
|
|
20791
|
+
"",
|
|
20792
|
+
data,
|
|
20793
|
+
"{}",
|
|
20794
|
+
null,
|
|
20795
|
+
null,
|
|
20796
|
+
null,
|
|
20797
|
+
now,
|
|
20798
|
+
now
|
|
20799
|
+
).run();
|
|
20800
|
+
}
|
|
20801
|
+
async function deactivateStalePluginRows(db, activePluginIds) {
|
|
20802
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
20803
|
+
const rows = await db.prepare(
|
|
20804
|
+
`SELECT id, data FROM documents
|
|
20805
|
+
WHERE type_id = 'menu_item' AND tenant_id = 'default'
|
|
20806
|
+
AND is_current_draft = 1 AND deleted_at IS NULL
|
|
20807
|
+
AND json_extract(data, '$.source') = 'plugin'`
|
|
20808
|
+
).all();
|
|
20809
|
+
const stale = (rows.results ?? []).filter((row) => {
|
|
20810
|
+
let pluginId;
|
|
20811
|
+
try {
|
|
20812
|
+
pluginId = JSON.parse(row.data)?.pluginId;
|
|
20813
|
+
} catch {
|
|
20814
|
+
return false;
|
|
20815
|
+
}
|
|
20816
|
+
return pluginId !== void 0 && !activePluginIds.has(pluginId);
|
|
20817
|
+
});
|
|
20818
|
+
if (stale.length === 0) return;
|
|
20819
|
+
await db.batch(
|
|
20820
|
+
stale.map(
|
|
20821
|
+
(row) => db.prepare(
|
|
20822
|
+
`UPDATE documents
|
|
20823
|
+
SET data = json_set(data, '$.visible', 0), visible = 0, updated_at = ?
|
|
20824
|
+
WHERE id = ? AND tenant_id = 'default'`
|
|
20825
|
+
).bind(now, row.id)
|
|
20826
|
+
)
|
|
20827
|
+
);
|
|
20828
|
+
}
|
|
20829
|
+
async function fetchActivePluginIds(db) {
|
|
20830
|
+
try {
|
|
20831
|
+
const rows = await db.prepare(
|
|
20832
|
+
`SELECT slug FROM documents
|
|
20833
|
+
WHERE type_id = 'plugin' AND tenant_id = 'default'
|
|
20834
|
+
AND is_current_draft = 1 AND deleted_at IS NULL
|
|
20835
|
+
AND json_extract(data, '$.status') = 'active'`
|
|
20836
|
+
).all();
|
|
20837
|
+
return new Set((rows.results ?? []).map((r) => r.slug));
|
|
20838
|
+
} catch {
|
|
20839
|
+
return /* @__PURE__ */ new Set();
|
|
20840
|
+
}
|
|
20841
|
+
}
|
|
20842
|
+
async function reconcileMenuFromPlugins(db) {
|
|
20843
|
+
try {
|
|
20844
|
+
const singletonEntries = getPluginMenu();
|
|
20845
|
+
const manifestEntries = Object.values(PLUGIN_REGISTRY).filter(
|
|
20846
|
+
(p) => p.adminMenu !== null
|
|
20847
|
+
);
|
|
20848
|
+
const byPluginId = /* @__PURE__ */ new Map();
|
|
20849
|
+
manifestEntries.forEach((p, idx) => {
|
|
20850
|
+
const menu = p.adminMenu;
|
|
20851
|
+
byPluginId.set(p.id, {
|
|
20852
|
+
pluginId: p.id,
|
|
20853
|
+
label: menu.label,
|
|
20854
|
+
url: menu.path,
|
|
20855
|
+
icon: menu.icon,
|
|
20856
|
+
sortOrder: 100 + idx * 10
|
|
20857
|
+
});
|
|
20858
|
+
});
|
|
20859
|
+
singletonEntries.forEach((entry, idx) => {
|
|
20860
|
+
const pathParts = entry.path.replace(/\/$/, "").split("/");
|
|
20861
|
+
const pluginId = pathParts[pathParts.length - 1] || entry.label.toLowerCase().replace(/\s+/g, "-");
|
|
20862
|
+
byPluginId.set(pluginId, {
|
|
20863
|
+
pluginId,
|
|
20864
|
+
label: entry.label,
|
|
20865
|
+
url: entry.path,
|
|
20866
|
+
icon: entry.icon ?? "puzzle-piece",
|
|
20867
|
+
sortOrder: 100 + idx * 10
|
|
20868
|
+
});
|
|
20869
|
+
});
|
|
20870
|
+
const activeIds = await fetchActivePluginIds(db);
|
|
20871
|
+
for (const [pluginId, entry] of byPluginId) {
|
|
20872
|
+
const slug = `menu:plugin:${pluginId}`;
|
|
20873
|
+
await upsertPluginRow(db, slug, entry, activeIds.has(pluginId));
|
|
20874
|
+
}
|
|
20875
|
+
await deactivateStalePluginRows(db, activeIds);
|
|
20876
|
+
} catch {
|
|
20877
|
+
}
|
|
20816
20878
|
}
|
|
20817
20879
|
|
|
20818
20880
|
// src/routes/admin-plugins.ts
|
|
@@ -20847,9 +20909,11 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20847
20909
|
} catch (error) {
|
|
20848
20910
|
console.error("Error loading plugins:", error);
|
|
20849
20911
|
}
|
|
20850
|
-
const
|
|
20912
|
+
const registryIds = new Set(AVAILABLE_PLUGINS.map((p) => p.id));
|
|
20913
|
+
const validInstalledPlugins = installedPlugins.filter((p) => registryIds.has(p.id));
|
|
20914
|
+
const installedPluginIds = new Set(validInstalledPlugins.map((p) => p.id));
|
|
20851
20915
|
const uninstalledPlugins = AVAILABLE_PLUGINS.filter((p) => !installedPluginIds.has(p.id));
|
|
20852
|
-
const templatePlugins =
|
|
20916
|
+
const templatePlugins = validInstalledPlugins.map((p) => ({
|
|
20853
20917
|
id: p.id,
|
|
20854
20918
|
name: p.name,
|
|
20855
20919
|
displayName: p.display_name,
|
|
@@ -20885,7 +20949,7 @@ adminPluginRoutes.get("/", async (c) => {
|
|
|
20885
20949
|
}));
|
|
20886
20950
|
const allPlugins = [...templatePlugins, ...uninstalledTemplatePlugins];
|
|
20887
20951
|
stats.uninstalled = uninstalledPlugins.length;
|
|
20888
|
-
stats.total =
|
|
20952
|
+
stats.total = validInstalledPlugins.length + uninstalledPlugins.length;
|
|
20889
20953
|
const pageData = {
|
|
20890
20954
|
plugins: allPlugins,
|
|
20891
20955
|
stats,
|
|
@@ -20984,6 +21048,15 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20984
21048
|
timestamp: item.timestamp,
|
|
20985
21049
|
user: item.userId || null
|
|
20986
21050
|
}));
|
|
21051
|
+
const pluginDef = getPluginDefinition(pluginId);
|
|
21052
|
+
let settingsTabData = void 0;
|
|
21053
|
+
if (pluginDef?.settingsTabContent?.loadData) {
|
|
21054
|
+
try {
|
|
21055
|
+
settingsTabData = await pluginDef.settingsTabContent.loadData(db);
|
|
21056
|
+
} catch (e) {
|
|
21057
|
+
console.error(`settingsTabContent.loadData failed for plugin "${pluginId}":`, e);
|
|
21058
|
+
}
|
|
21059
|
+
}
|
|
20987
21060
|
const pageData = {
|
|
20988
21061
|
plugin: templatePlugin,
|
|
20989
21062
|
activity: templateActivity,
|
|
@@ -20991,7 +21064,8 @@ adminPluginRoutes.get("/:id", async (c) => {
|
|
|
20991
21064
|
name: user?.email || "User",
|
|
20992
21065
|
email: user?.email || "",
|
|
20993
21066
|
role: user?.role || "user"
|
|
20994
|
-
}
|
|
21067
|
+
},
|
|
21068
|
+
settingsTabData
|
|
20995
21069
|
};
|
|
20996
21070
|
return c.html(renderPluginSettingsPage(pageData));
|
|
20997
21071
|
} catch (error) {
|
|
@@ -21069,6 +21143,7 @@ adminPluginRoutes.post("/:id/activate", async (c) => {
|
|
|
21069
21143
|
}
|
|
21070
21144
|
const pluginService = new PluginService(db);
|
|
21071
21145
|
await pluginService.activatePlugin(pluginId);
|
|
21146
|
+
await reconcileMenuFromPlugins(db);
|
|
21072
21147
|
return c.json({ success: true });
|
|
21073
21148
|
} catch (error) {
|
|
21074
21149
|
console.error("Error activating plugin:", error);
|
|
@@ -21086,6 +21161,7 @@ adminPluginRoutes.post("/:id/deactivate", async (c) => {
|
|
|
21086
21161
|
}
|
|
21087
21162
|
const pluginService = new PluginService(db);
|
|
21088
21163
|
await pluginService.deactivatePlugin(pluginId);
|
|
21164
|
+
await reconcileMenuFromPlugins(db);
|
|
21089
21165
|
return c.json({ success: true });
|
|
21090
21166
|
} catch (error) {
|
|
21091
21167
|
console.error("Error deactivating plugin:", error);
|
|
@@ -27008,6 +27084,6 @@ var ROUTES_INFO = {
|
|
|
27008
27084
|
reference: "https://github.com/sonicjs/sonicjs"
|
|
27009
27085
|
};
|
|
27010
27086
|
|
|
27011
|
-
export { DocumentRepository, ROUTES_INFO, TenantService, VALID_MEMBER_ROLES, adminCheckboxRoutes, adminCollectionsRoutes, adminDocumentsRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_api_default, admin_content_default, apiDocumentsRoutes, api_content_crud_default, api_default, api_media_default, api_system_default, auth_default, createDocumentSchema, createUserProfilesPlugin, defineUserProfile, denyIfNotAllowed, dispatchHookEvent, getConfirmationDialogScript2 as getConfirmationDialogScript, getCustomData, getEmailService, getUserProfileConfig, getVariablesCached, hasEmailService, invalidateVariablesCache, isValidMemberRole, lexicalEditorPlugin, renderConfirmationDialog2 as renderConfirmationDialog, renderTable2 as renderTable, resolveDocScope, resolveVariablesInObject, router, router2, setEmailService, setVariablesCache, test_cleanup_default, userProfilesPlugin, userRoutes };
|
|
27012
|
-
//# sourceMappingURL=chunk-
|
|
27013
|
-
//# sourceMappingURL=chunk-
|
|
27087
|
+
export { DocumentRepository, ROUTES_INFO, TenantService, VALID_MEMBER_ROLES, adminCheckboxRoutes, adminCollectionsRoutes, adminDocumentsRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_api_default, admin_content_default, apiDocumentsRoutes, api_content_crud_default, api_default, api_media_default, api_system_default, auth_default, createDocumentSchema, createUserProfilesPlugin, defineUserProfile, denyIfNotAllowed, dispatchHookEvent, getConfirmationDialogScript2 as getConfirmationDialogScript, getCustomData, getEmailService, getUserProfileConfig, getVariablesCached, hasEmailService, invalidateVariablesCache, isValidMemberRole, lexicalEditorPlugin, reconcileMenuFromPlugins, renderConfirmationDialog2 as renderConfirmationDialog, renderTable2 as renderTable, resolveDocScope, resolveVariablesInObject, router, router2, setEmailService, setVariablesCache, test_cleanup_default, userProfilesPlugin, userRoutes };
|
|
27088
|
+
//# sourceMappingURL=chunk-SK5CHFJP.js.map
|
|
27089
|
+
//# sourceMappingURL=chunk-SK5CHFJP.js.map
|