nextjs-cms 0.9.30 → 0.9.32
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/LICENSE +21 -21
- package/README.md +279 -279
- package/dist/api/actions/pages.d.ts +3 -3
- 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 -974
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +0 -13
- package/dist/api/lib/serverActions.d.ts +13 -49
- package/dist/api/lib/serverActions.d.ts.map +1 -1
- package/dist/api/lib/serverActions.js +103 -31
- package/dist/api/root.d.ts +18 -1916
- package/dist/api/root.d.ts.map +1 -1
- package/dist/api/root.js +18 -83
- package/dist/api/routers/config.d.ts.map +1 -1
- package/dist/api/routers/gallery.d.ts +1 -0
- package/dist/api/routers/gallery.d.ts.map +1 -1
- package/dist/api/routers/gallery.js +36 -8
- package/dist/api/routers/hasItemsSection.d.ts +5 -30
- package/dist/api/routers/hasItemsSection.d.ts.map +1 -1
- package/dist/api/routers/navigation.d.ts +3 -3
- package/dist/api/routers/simpleSection.d.ts +3 -15
- package/dist/api/routers/simpleSection.d.ts.map +1 -1
- 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/error-logging.d.ts +14 -0
- package/dist/api/trpc/error-logging.d.ts.map +1 -0
- package/dist/api/trpc/error-logging.js +75 -0
- package/dist/api/trpc/root.d.ts +3 -3
- package/dist/api/trpc/root.d.ts.map +1 -1
- package/dist/api/trpc/routers/config.d.ts.map +1 -1
- package/dist/api/trpc/routers/hasItemsSection.d.ts.map +1 -1
- package/dist/api/trpc/routers/navigation.d.ts +3 -3
- package/dist/api/trpc/routers/simpleSection.d.ts.map +1 -1
- package/dist/api/trpc/server.d.ts +9 -9
- package/dist/api/trpc/server.d.ts.map +1 -1
- 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/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/db-config.js +10 -10
- 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 +2 -2
- package/dist/core/db/table-checker/MysqlTable.js +10 -10
- package/dist/core/factories/section-factory-with-esbuild.js +9 -9
- package/dist/core/factories/section-factory-with-jiti.js +9 -9
- package/dist/core/sections/category.d.ts +2 -2
- package/dist/core/sections/hasItems.d.ts +2 -2
- package/dist/core/sections/section.d.ts +2 -2
- package/dist/core/sections/simple.d.ts +2 -2
- package/dist/plugins/loader.d.ts +3 -1
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +28 -6
- 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/registry.d.ts +22 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +25 -0
- package/dist/translations/base/en.d.ts +6 -0
- package/dist/translations/base/en.d.ts.map +1 -1
- package/dist/translations/base/en.js +6 -0
- package/dist/translations/client.d.ts +76 -4
- package/dist/translations/client.d.ts.map +1 -1
- package/dist/translations/server.d.ts +76 -4
- package/dist/translations/server.d.ts.map +1 -1
- 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/package.json +1 -1
- package/dist/core/fields/dateRange.d.ts +0 -115
- package/dist/core/fields/dateRange.d.ts.map +0 -1
- package/dist/core/fields/dateRange.js +0 -149
- package/dist/translations/locale-cookie.d.ts +0 -24
- package/dist/translations/locale-cookie.d.ts.map +0 -1
- package/dist/translations/locale-cookie.js +0 -44
- package/dist/translations/locale-utils.d.ts +0 -8
- package/dist/translations/locale-utils.d.ts.map +0 -1
- package/dist/translations/locale-utils.js +0 -11
- package/dist/translations/localization.d.ts +0 -40
- package/dist/translations/localization.d.ts.map +0 -1
- package/dist/translations/localization.js +0 -48
- package/dist/validators/dateRange.d.ts +0 -11
- package/dist/validators/dateRange.d.ts.map +0 -1
- package/dist/validators/dateRange.js +0 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
// import 'server-only'
|
|
2
|
-
import { db } from '../../db/client.js';
|
|
3
|
-
import { AdminPrivilegesTable, AdminsTable, EditorPhotosTable } from '../../db/schema.js';
|
|
4
|
-
import { and, eq, sql } from 'drizzle-orm';
|
|
5
|
-
import { TRPCError } from '@trpc/server';
|
|
6
|
-
import { FieldFactory, SectionFactory } from '../../core/factories/index.js';
|
|
7
|
-
import { SelectField } from '../../core/fields/index.js';
|
|
8
|
-
import { MysqlTableChecker } from '../../core/db/index.js';
|
|
9
2
|
import fs from 'fs';
|
|
10
|
-
import { Readable } from 'stream';
|
|
11
3
|
import path from 'path';
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
4
|
+
import { Readable } from 'stream';
|
|
5
|
+
import { TRPCError } from '@trpc/server';
|
|
6
|
+
import { and, eq, sql } from 'drizzle-orm';
|
|
15
7
|
import { fileTypeFromBuffer } from 'file-type';
|
|
8
|
+
import { readChunk } from 'read-chunk';
|
|
9
|
+
import sharp from 'sharp';
|
|
10
|
+
import through2 from 'through2';
|
|
16
11
|
import { getCMSConfig } from '../../core/config/index.js';
|
|
12
|
+
import { MysqlTableChecker } from '../../core/db/index.js';
|
|
13
|
+
import { FieldFactory, SectionFactory } from '../../core/factories/index.js';
|
|
14
|
+
import { SelectField } from '../../core/fields/index.js';
|
|
17
15
|
import { resolveLocale } from '../../core/localization/index.js';
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
16
|
+
import { db } from '../../db/client.js';
|
|
17
|
+
import { AdminPrivilegesTable, AdminsTable, EditorPhotosTable } from '../../db/schema.js';
|
|
20
18
|
import { recordLog } from '../../logging/index.js';
|
|
19
|
+
import { getPluginRoutes } from '../../plugins/loader.js';
|
|
21
20
|
import getString from '../../translations/index.js';
|
|
22
|
-
import { resolveMultilingualString } from '../../translations/language-utils.js';
|
|
23
|
-
import {
|
|
21
|
+
import { resolveLanguage, resolveMultilingualString } from '../../translations/language-utils.js';
|
|
22
|
+
import { sanitizeFileName, sanitizeFolderOrFileName } from '../../utils/index.js';
|
|
24
23
|
export const isAccessAllowed = async ({ sectionName, role, userId, }) => {
|
|
25
24
|
/**
|
|
26
25
|
* Check admin privileges
|
|
@@ -39,6 +38,35 @@ export const isAccessAllowed = async ({ sectionName, role, userId, }) => {
|
|
|
39
38
|
}
|
|
40
39
|
return true;
|
|
41
40
|
};
|
|
41
|
+
async function deleteGalleryFiles({ uploadsFolder, sectionName, photos, }) {
|
|
42
|
+
for (const photo of photos) {
|
|
43
|
+
try {
|
|
44
|
+
await fs.promises.unlink(path.join(uploadsFolder, '.photos', sectionName, photo));
|
|
45
|
+
await fs.promises.unlink(path.join(uploadsFolder, '.thumbs', sectionName, photo));
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('Error deleting gallery photo', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function deleteLocalizedGalleryRows({ section, gallery, sectionItemId, locale, uploadsFolder, }) {
|
|
53
|
+
if (!gallery.localized)
|
|
54
|
+
return;
|
|
55
|
+
const { tableName, referenceIdentifierField, photoNameField } = gallery.db;
|
|
56
|
+
const columns = await MysqlTableChecker.getColumns(tableName);
|
|
57
|
+
if (!columns.includes(referenceIdentifierField) ||
|
|
58
|
+
!columns.includes(photoNameField) ||
|
|
59
|
+
!columns.includes('locale')) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const [rows] = await db.execute(sql `SELECT \`${sql.raw(photoNameField)}\` AS photo FROM \`${sql.raw(tableName)}\` WHERE \`${sql.raw(referenceIdentifierField)}\` = ${sectionItemId} AND \`locale\` = ${locale}`);
|
|
63
|
+
const photos = (rows ?? []).map((row) => row.photo).filter(Boolean);
|
|
64
|
+
await deleteGalleryFiles({ uploadsFolder, sectionName: section.name, photos });
|
|
65
|
+
await db.execute(sql `DELETE FROM \`${sql.raw(tableName)}\` WHERE \`${sql.raw(referenceIdentifierField)}\` = ${sectionItemId} AND \`locale\` = ${locale}`);
|
|
66
|
+
}
|
|
67
|
+
function sectionHasLocalizedContent(section) {
|
|
68
|
+
return section.hasLocalizedContent ?? section.hasLocalizedFields ?? false;
|
|
69
|
+
}
|
|
42
70
|
export const getDocument = async (session, input) => {
|
|
43
71
|
const { name, sectionName, fieldName } = input;
|
|
44
72
|
// Sanitize the inputs
|
|
@@ -273,11 +301,11 @@ export const getAllPrivileges = async (session) => {
|
|
|
273
301
|
// Now, let's add the rest of the privileges to the list
|
|
274
302
|
sections.forEach((section, index) => {
|
|
275
303
|
let title;
|
|
276
|
-
if (
|
|
277
|
-
title = resolveMultilingualString(section.title, language, cmsConfig.i18n.fallbackLanguage);
|
|
304
|
+
if (section.type === 'has_items' || section.type === 'category') {
|
|
305
|
+
title = resolveMultilingualString(section.title.section, language, cmsConfig.i18n.fallbackLanguage);
|
|
278
306
|
}
|
|
279
307
|
else {
|
|
280
|
-
title = resolveMultilingualString(section.title
|
|
308
|
+
title = resolveMultilingualString(section.title, language, cmsConfig.i18n.fallbackLanguage);
|
|
281
309
|
}
|
|
282
310
|
privilegesList.push({
|
|
283
311
|
title,
|
|
@@ -380,7 +408,8 @@ export const createSimpleSectionPage = async (session, sectionName, locale) => {
|
|
|
380
408
|
let localizationData = null;
|
|
381
409
|
if (localeResult.localizationEnabled) {
|
|
382
410
|
let existingTranslations = [];
|
|
383
|
-
|
|
411
|
+
const hasLocalizedContent = sectionHasLocalizedContent(sectionInfo);
|
|
412
|
+
if (hasLocalizedContent) {
|
|
384
413
|
const localesTableName = sectionInfo.localesTableName;
|
|
385
414
|
const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
|
|
386
415
|
const localeTableExists = localeColumns.length > 0;
|
|
@@ -428,6 +457,9 @@ export const createSimpleSectionPage = async (session, sectionName, locale) => {
|
|
|
428
457
|
: [];
|
|
429
458
|
field.setValue(tags.join(','));
|
|
430
459
|
}
|
|
460
|
+
else if (field.type === 'date_range' && typeof f.setRangeValues === 'function') {
|
|
461
|
+
f.setRangeValues(localeRow ? (localeRow[f.startName] ?? null) : null, localeRow ? (localeRow[f.endName] ?? null) : null);
|
|
462
|
+
}
|
|
431
463
|
else {
|
|
432
464
|
// Simple field: override from locale row
|
|
433
465
|
field.setValue(localeRow ? (localeRow[field.name] ?? null) : null);
|
|
@@ -436,11 +468,22 @@ export const createSimpleSectionPage = async (session, sectionName, locale) => {
|
|
|
436
468
|
}
|
|
437
469
|
}
|
|
438
470
|
}
|
|
471
|
+
// Show the locale switcher when multiple locales are configured AND either:
|
|
472
|
+
// - the section has localized fields (production case), or
|
|
473
|
+
// - the app is in development mode (so devs can preview the switcher
|
|
474
|
+
// while wiring up localization on a section).
|
|
475
|
+
// The developer note is rendered in dev-mode only, when the switcher is
|
|
476
|
+
// visible but the section itself has no localized content yet.
|
|
477
|
+
const localeSwitcherEnabled = localeResult.availableLocales.length > 1 &&
|
|
478
|
+
(hasLocalizedContent === true || process.env.NODE_ENV === 'development');
|
|
479
|
+
const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedContent === false;
|
|
439
480
|
localizationData = {
|
|
440
481
|
defaultLocale: localeResult.defaultLocale,
|
|
441
482
|
currentLocale: localeResult.resolvedLocale ?? localeResult.defaultLocale,
|
|
442
483
|
existingTranslations,
|
|
443
484
|
locales: localeResult.availableLocales,
|
|
485
|
+
localeSwitcherEnabled,
|
|
486
|
+
developerNoteEnabled,
|
|
444
487
|
};
|
|
445
488
|
}
|
|
446
489
|
return {
|
|
@@ -520,7 +563,7 @@ export const deleteSectionItem = async (session, sectionName, sectionItemId, rec
|
|
|
520
563
|
* Use deleteLocaleTranslation per locale to ensure localized files are cleaned up from disk.
|
|
521
564
|
*/
|
|
522
565
|
const cmsConfig = await getCMSConfig();
|
|
523
|
-
if (cmsConfig.localization?.enabled && section
|
|
566
|
+
if (cmsConfig.localization?.enabled && sectionHasLocalizedContent(section)) {
|
|
524
567
|
const localesTableName = section.localesTableName;
|
|
525
568
|
const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
|
|
526
569
|
if (localeColumns.length > 0) {
|
|
@@ -723,7 +766,7 @@ export const deleteLocaleTranslation = async (session, sectionName, sectionItemI
|
|
|
723
766
|
};
|
|
724
767
|
}
|
|
725
768
|
const cmsConfig = await getCMSConfig();
|
|
726
|
-
if (!cmsConfig.localization?.enabled || !section
|
|
769
|
+
if (!cmsConfig.localization?.enabled || !sectionHasLocalizedContent(section)) {
|
|
727
770
|
return {
|
|
728
771
|
error: {
|
|
729
772
|
message: getString('localizationNotEnabledForSection', session.user.language),
|
|
@@ -794,11 +837,21 @@ export const deleteLocaleTranslation = async (session, sectionName, sectionItemI
|
|
|
794
837
|
}
|
|
795
838
|
}
|
|
796
839
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
840
|
+
const gallery = await section.getGallery();
|
|
841
|
+
if (gallery?.localized) {
|
|
842
|
+
await deleteLocalizedGalleryRows({
|
|
843
|
+
section,
|
|
844
|
+
gallery,
|
|
845
|
+
sectionItemId,
|
|
846
|
+
locale,
|
|
847
|
+
uploadsFolder: cmsConfig.media.upload.path,
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
// Delete locale-scoped editor photos for localized rich_text fields.
|
|
851
|
+
// Uses raw SQL because the `locale` column only exists on the DB table when
|
|
852
|
+
// localization is enabled; the Drizzle schema no longer declares it.
|
|
853
|
+
const [editorPhotoRows] = await db.execute(sql `SELECT \`photo\` as \`name\` FROM \`editor_photos\` WHERE \`section\` = ${sectionName} AND \`item_id\` = ${sectionItemId.toString()} AND \`locale\` = ${locale}`);
|
|
854
|
+
const editorPhotos = editorPhotoRows ?? [];
|
|
802
855
|
if (editorPhotos.length > 0) {
|
|
803
856
|
const uploadsFolder = cmsConfig.media.upload.path;
|
|
804
857
|
for (const photo of editorPhotos) {
|
|
@@ -809,9 +862,7 @@ export const deleteLocaleTranslation = async (session, sectionName, sectionItemI
|
|
|
809
862
|
console.error('Error deleting editor photo', error);
|
|
810
863
|
}
|
|
811
864
|
}
|
|
812
|
-
await db
|
|
813
|
-
.delete(EditorPhotosTable)
|
|
814
|
-
.where(and(eq(EditorPhotosTable.section, sectionName), eq(EditorPhotosTable.itemId, sectionItemId.toString()), eq(EditorPhotosTable.locale, locale)));
|
|
865
|
+
await db.execute(sql `DELETE FROM \`editor_photos\` WHERE \`section\` = ${sectionName} AND \`item_id\` = ${sectionItemId.toString()} AND \`locale\` = ${locale}`);
|
|
815
866
|
}
|
|
816
867
|
// Delete locale-scoped junction table rows for localized select/tags fields
|
|
817
868
|
const localizedJunctionFields = section.fieldConfigs.filter((f) => f.localized === true &&
|
|
@@ -942,13 +993,19 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
|
|
|
942
993
|
if (columns.includes(photoNameField) &&
|
|
943
994
|
columns.includes(referenceIdentifierField) &&
|
|
944
995
|
columns.includes(metaField)) {
|
|
945
|
-
const
|
|
996
|
+
const galleryIsLocalized = gallery.localized === true && localeResult.localizationEnabled;
|
|
997
|
+
const currentLocale = localeResult.resolvedLocale?.code;
|
|
998
|
+
const localeFilter = galleryIsLocalized && currentLocale && columns.includes('locale')
|
|
999
|
+
? sql ` AND \`locale\` = ${currentLocale}`
|
|
1000
|
+
: sql ``;
|
|
1001
|
+
const [items] = await db.execute(sql `select * from \`${sql.raw(tableName)}\` where \`${sql.raw(referenceIdentifierField)}\` = ${sectionItemId}${localeFilter}`);
|
|
946
1002
|
const galleryPhotos = items;
|
|
947
1003
|
galleryPhotos?.map((item) => {
|
|
948
1004
|
galleryItems.push({
|
|
949
1005
|
referenceId: item[referenceIdentifierField],
|
|
950
1006
|
photo: item[photoNameField],
|
|
951
1007
|
meta: item[metaField],
|
|
1008
|
+
locale: item.locale,
|
|
952
1009
|
});
|
|
953
1010
|
});
|
|
954
1011
|
}
|
|
@@ -967,7 +1024,8 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
|
|
|
967
1024
|
let localizationData = null;
|
|
968
1025
|
if (localeResult.localizationEnabled) {
|
|
969
1026
|
let existingTranslations = [];
|
|
970
|
-
|
|
1027
|
+
const hasLocalizedContent = sectionHasLocalizedContent(sectionInfo);
|
|
1028
|
+
if (hasLocalizedContent) {
|
|
971
1029
|
const localesTableName = sectionInfo.localesTableName;
|
|
972
1030
|
const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
|
|
973
1031
|
const localeTableExists = localeColumns.length > 0;
|
|
@@ -1013,6 +1071,9 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
|
|
|
1013
1071
|
: [];
|
|
1014
1072
|
field.setValue(tags.join(','));
|
|
1015
1073
|
}
|
|
1074
|
+
else if (field.type === 'date_range' && typeof f.setRangeValues === 'function') {
|
|
1075
|
+
f.setRangeValues(localeRow ? (localeRow[f.startName] ?? null) : null, localeRow ? (localeRow[f.endName] ?? null) : null);
|
|
1076
|
+
}
|
|
1016
1077
|
else {
|
|
1017
1078
|
// Simple field: override from locale row
|
|
1018
1079
|
field.setValue(localeRow ? (localeRow[field.name] ?? null) : null);
|
|
@@ -1021,11 +1082,22 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
|
|
|
1021
1082
|
}
|
|
1022
1083
|
}
|
|
1023
1084
|
}
|
|
1085
|
+
// Show the locale switcher when multiple locales are configured AND either:
|
|
1086
|
+
// - the section has localized fields (production case), or
|
|
1087
|
+
// - the app is in development mode (so devs can preview the switcher
|
|
1088
|
+
// while wiring up localization on a section).
|
|
1089
|
+
// The developer note is rendered in dev-mode only, when the switcher is
|
|
1090
|
+
// visible but the section itself has no localized content yet.
|
|
1091
|
+
const localeSwitcherEnabled = localeResult.availableLocales.length > 1 &&
|
|
1092
|
+
(hasLocalizedContent === true || process.env.NODE_ENV === 'development');
|
|
1093
|
+
const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedContent === false;
|
|
1024
1094
|
localizationData = {
|
|
1025
1095
|
defaultLocale: localeResult.defaultLocale,
|
|
1026
1096
|
currentLocale: localeResult.resolvedLocale ?? localeResult.defaultLocale,
|
|
1027
1097
|
existingTranslations,
|
|
1028
1098
|
locales: localeResult.availableLocales,
|
|
1099
|
+
localeSwitcherEnabled,
|
|
1100
|
+
developerNoteEnabled,
|
|
1029
1101
|
};
|
|
1030
1102
|
}
|
|
1031
1103
|
return {
|