nextjs-cms 0.9.20 → 0.9.22

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.
Files changed (62) hide show
  1. package/dist/api/index.d.ts +8 -48
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/lib/serverActions.d.ts +9 -49
  4. package/dist/api/lib/serverActions.d.ts.map +1 -1
  5. package/dist/api/lib/serverActions.js +82 -34
  6. package/dist/api/root.d.ts +16 -96
  7. package/dist/api/root.d.ts.map +1 -1
  8. package/dist/api/routers/gallery.d.ts +1 -0
  9. package/dist/api/routers/gallery.d.ts.map +1 -1
  10. package/dist/api/routers/gallery.js +36 -8
  11. package/dist/api/routers/hasItemsSection.d.ts +3 -30
  12. package/dist/api/routers/hasItemsSection.d.ts.map +1 -1
  13. package/dist/api/routers/navigation.d.ts +3 -3
  14. package/dist/api/routers/simpleSection.d.ts +1 -15
  15. package/dist/api/routers/simpleSection.d.ts.map +1 -1
  16. package/dist/cli/lib/update-sections.d.ts.map +1 -1
  17. package/dist/cli/lib/update-sections.js +660 -213
  18. package/dist/core/db/table-checker/MysqlTable.d.ts.map +1 -1
  19. package/dist/core/db/table-checker/MysqlTable.js +3 -1
  20. package/dist/core/factories/FieldFactory.d.ts +1 -1
  21. package/dist/core/factories/FieldFactory.d.ts.map +1 -1
  22. package/dist/core/factories/FieldFactory.js +11 -9
  23. package/dist/core/fields/date.d.ts.map +1 -1
  24. package/dist/core/fields/date.js +10 -6
  25. package/dist/core/fields/select.d.ts +23 -11
  26. package/dist/core/fields/select.d.ts.map +1 -1
  27. package/dist/core/fields/select.js +9 -5
  28. package/dist/core/fields/selectMultiple.d.ts +12 -4
  29. package/dist/core/fields/selectMultiple.d.ts.map +1 -1
  30. package/dist/core/fields/selectMultiple.js +10 -6
  31. package/dist/core/sections/category.d.ts +44 -42
  32. package/dist/core/sections/category.d.ts.map +1 -1
  33. package/dist/core/sections/hasItems.d.ts +44 -42
  34. package/dist/core/sections/hasItems.d.ts.map +1 -1
  35. package/dist/core/sections/section.d.ts +64 -43
  36. package/dist/core/sections/section.d.ts.map +1 -1
  37. package/dist/core/sections/section.js +18 -3
  38. package/dist/core/sections/simple.d.ts +8 -6
  39. package/dist/core/sections/simple.d.ts.map +1 -1
  40. package/dist/core/submit/ItemEditSubmit.d.ts.map +1 -1
  41. package/dist/core/submit/ItemEditSubmit.js +7 -1
  42. package/dist/core/submit/LocaleSubmit.d.ts +3 -3
  43. package/dist/core/submit/LocaleSubmit.d.ts.map +1 -1
  44. package/dist/core/submit/LocaleSubmit.js +9 -6
  45. package/dist/core/submit/submit.d.ts +4 -4
  46. package/dist/core/submit/submit.d.ts.map +1 -1
  47. package/dist/core/submit/submit.js +13 -9
  48. package/dist/core/types/index.d.ts +2 -2
  49. package/dist/core/types/index.d.ts.map +1 -1
  50. package/dist/db/cms-system-tables.d.ts.map +1 -1
  51. package/dist/db/cms-system-tables.js +2 -1
  52. package/dist/db/schema.d.ts +61 -0
  53. package/dist/db/schema.d.ts.map +1 -1
  54. package/dist/db/schema.js +8 -0
  55. package/dist/translations/base/en.d.ts +4 -0
  56. package/dist/translations/base/en.d.ts.map +1 -1
  57. package/dist/translations/base/en.js +4 -0
  58. package/dist/translations/client.d.ts +52 -4
  59. package/dist/translations/client.d.ts.map +1 -1
  60. package/dist/translations/server.d.ts +52 -4
  61. package/dist/translations/server.d.ts.map +1 -1
  62. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/api/lib/serverActions.ts"],"names":[],"mappings":"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"}
@@ -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 { sanitizeFileName, sanitizeFolderOrFileName } from '../../utils/index.js';
13
- import sharp from 'sharp';
14
- import { readChunk } from 'read-chunk';
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 { getPluginRoutes } from '../../plugins/loader.js';
19
- import through2 from 'through2';
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 { resolveLanguage } from '../../translations/language-utils.js';
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
@@ -380,8 +408,8 @@ export const createSimpleSectionPage = async (session, sectionName, locale) => {
380
408
  let localizationData = null;
381
409
  if (localeResult.localizationEnabled) {
382
410
  let existingTranslations = [];
383
- const hasLocalizedFields = sectionInfo.hasLocalizedFields;
384
- if (hasLocalizedFields) {
411
+ const hasLocalizedContent = sectionHasLocalizedContent(sectionInfo);
412
+ if (hasLocalizedContent) {
385
413
  const localesTableName = sectionInfo.localesTableName;
386
414
  const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
387
415
  const localeTableExists = localeColumns.length > 0;
@@ -440,18 +468,20 @@ export const createSimpleSectionPage = async (session, sectionName, locale) => {
440
468
  }
441
469
  }
442
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.
443
477
  const localeSwitcherEnabled = localeResult.availableLocales.length > 1 &&
444
- (hasLocalizedFields === true || process.env.NODE_ENV === 'development');
445
- const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedFields === false;
478
+ (hasLocalizedContent === true || process.env.NODE_ENV === 'development');
479
+ const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedContent === false;
446
480
  localizationData = {
447
481
  defaultLocale: localeResult.defaultLocale,
448
482
  currentLocale: localeResult.resolvedLocale ?? localeResult.defaultLocale,
449
483
  existingTranslations,
450
484
  locales: localeResult.availableLocales,
451
- // If there are multiple locales, show the locale switcher only if:
452
- // - The section has localized fields
453
- // - The application is in development mode
454
- // If there is only one locale, do not show the locale switcher
455
485
  localeSwitcherEnabled,
456
486
  developerNoteEnabled,
457
487
  };
@@ -533,7 +563,7 @@ export const deleteSectionItem = async (session, sectionName, sectionItemId, rec
533
563
  * Use deleteLocaleTranslation per locale to ensure localized files are cleaned up from disk.
534
564
  */
535
565
  const cmsConfig = await getCMSConfig();
536
- if (cmsConfig.localization?.enabled && section.hasLocalizedFields) {
566
+ if (cmsConfig.localization?.enabled && sectionHasLocalizedContent(section)) {
537
567
  const localesTableName = section.localesTableName;
538
568
  const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
539
569
  if (localeColumns.length > 0) {
@@ -736,7 +766,7 @@ export const deleteLocaleTranslation = async (session, sectionName, sectionItemI
736
766
  };
737
767
  }
738
768
  const cmsConfig = await getCMSConfig();
739
- if (!cmsConfig.localization?.enabled || !section.hasLocalizedFields) {
769
+ if (!cmsConfig.localization?.enabled || !sectionHasLocalizedContent(section)) {
740
770
  return {
741
771
  error: {
742
772
  message: getString('localizationNotEnabledForSection', session.user.language),
@@ -807,6 +837,16 @@ export const deleteLocaleTranslation = async (session, sectionName, sectionItemI
807
837
  }
808
838
  }
809
839
  }
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
+ }
810
850
  // Delete locale-scoped editor photos for localized rich_text fields.
811
851
  // Uses raw SQL because the `locale` column only exists on the DB table when
812
852
  // localization is enabled; the Drizzle schema no longer declares it.
@@ -953,13 +993,19 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
953
993
  if (columns.includes(photoNameField) &&
954
994
  columns.includes(referenceIdentifierField) &&
955
995
  columns.includes(metaField)) {
956
- const [items, fields] = await db.execute(sql `select * from \`${sql.raw(tableName)}\` where \`${sql.raw(referenceIdentifierField)}\` = ${sectionItemId}`);
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}`);
957
1002
  const galleryPhotos = items;
958
1003
  galleryPhotos?.map((item) => {
959
1004
  galleryItems.push({
960
1005
  referenceId: item[referenceIdentifierField],
961
1006
  photo: item[photoNameField],
962
1007
  meta: item[metaField],
1008
+ locale: item.locale,
963
1009
  });
964
1010
  });
965
1011
  }
@@ -978,8 +1024,8 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
978
1024
  let localizationData = null;
979
1025
  if (localeResult.localizationEnabled) {
980
1026
  let existingTranslations = [];
981
- const hasLocalizedFields = sectionInfo.hasLocalizedFields;
982
- if (hasLocalizedFields) {
1027
+ const hasLocalizedContent = sectionHasLocalizedContent(sectionInfo);
1028
+ if (hasLocalizedContent) {
983
1029
  const localesTableName = sectionInfo.localesTableName;
984
1030
  const localeColumns = await MysqlTableChecker.getColumns(localesTableName);
985
1031
  const localeTableExists = localeColumns.length > 0;
@@ -1036,18 +1082,20 @@ export const createEditPage = async (session, sectionName, sectionItemId, locale
1036
1082
  }
1037
1083
  }
1038
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.
1039
1091
  const localeSwitcherEnabled = localeResult.availableLocales.length > 1 &&
1040
- (hasLocalizedFields === true || process.env.NODE_ENV === 'development');
1041
- const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedFields === false;
1092
+ (hasLocalizedContent === true || process.env.NODE_ENV === 'development');
1093
+ const developerNoteEnabled = localeSwitcherEnabled && hasLocalizedContent === false;
1042
1094
  localizationData = {
1043
1095
  defaultLocale: localeResult.defaultLocale,
1044
1096
  currentLocale: localeResult.resolvedLocale ?? localeResult.defaultLocale,
1045
1097
  existingTranslations,
1046
1098
  locales: localeResult.availableLocales,
1047
- // If there are multiple locales, show the locale switcher only if:
1048
- // - The section has localized fields
1049
- // - The application is in development mode
1050
- // If there is only one locale, do not show the locale switcher
1051
1099
  localeSwitcherEnabled,
1052
1100
  developerNoteEnabled,
1053
1101
  };