nextjs-cms 0.8.10 → 0.9.1

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 (178) hide show
  1. package/dist/api/index.d.ts +92 -9
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/lib/serverActions.d.ts +64 -9
  4. package/dist/api/lib/serverActions.d.ts.map +1 -1
  5. package/dist/api/lib/serverActions.js +463 -90
  6. package/dist/api/root.d.ts +184 -18
  7. package/dist/api/root.d.ts.map +1 -1
  8. package/dist/api/routers/accountSettings.d.ts +2 -2
  9. package/dist/api/routers/accountSettings.js +10 -10
  10. package/dist/api/routers/admins.js +11 -11
  11. package/dist/api/routers/auth.d.ts +1 -1
  12. package/dist/api/routers/config.d.ts +13 -0
  13. package/dist/api/routers/config.d.ts.map +1 -1
  14. package/dist/api/routers/config.js +4 -0
  15. package/dist/api/routers/cpanel.js +7 -7
  16. package/dist/api/routers/fields.d.ts +1 -0
  17. package/dist/api/routers/fields.d.ts.map +1 -1
  18. package/dist/api/routers/fields.js +39 -6
  19. package/dist/api/routers/gallery.js +1 -1
  20. package/dist/api/routers/hasItemsSection.d.ts +41 -2
  21. package/dist/api/routers/hasItemsSection.d.ts.map +1 -1
  22. package/dist/api/routers/hasItemsSection.js +43 -2
  23. package/dist/api/routers/logs.js +1 -1
  24. package/dist/api/routers/navigation.d.ts +3 -3
  25. package/dist/api/routers/simpleSection.d.ts +31 -1
  26. package/dist/api/routers/simpleSection.d.ts.map +1 -1
  27. package/dist/api/routers/simpleSection.js +44 -2
  28. package/dist/api/trpc.js +2 -2
  29. package/dist/auth/index.d.ts +1 -1
  30. package/dist/auth/index.d.ts.map +1 -1
  31. package/dist/auth/index.js +1 -1
  32. package/dist/auth/lib/actions.d.ts +3 -3
  33. package/dist/auth/lib/actions.d.ts.map +1 -1
  34. package/dist/auth/lib/actions.js +14 -14
  35. package/dist/auth/react.d.ts +2 -2
  36. package/dist/auth/react.d.ts.map +1 -1
  37. package/dist/auth/react.js +7 -7
  38. package/dist/cli/lib/update-sections.d.ts.map +1 -1
  39. package/dist/cli/lib/update-sections.js +145 -9
  40. package/dist/cli/utils/schema-generator.d.ts +20 -0
  41. package/dist/cli/utils/schema-generator.d.ts.map +1 -1
  42. package/dist/cli/utils/schema-generator.js +40 -0
  43. package/dist/core/config/config-loader.d.ts +49 -5
  44. package/dist/core/config/config-loader.d.ts.map +1 -1
  45. package/dist/core/config/config-loader.js +100 -21
  46. package/dist/core/config/index.d.ts +2 -2
  47. package/dist/core/config/index.d.ts.map +1 -1
  48. package/dist/core/config/index.js +1 -1
  49. package/dist/core/factories/FieldFactory.d.ts +5 -3
  50. package/dist/core/factories/FieldFactory.d.ts.map +1 -1
  51. package/dist/core/factories/FieldFactory.js +74 -16
  52. package/dist/core/factories/section-factory-with-esbuild.d.ts.map +1 -1
  53. package/dist/core/factories/section-factory-with-esbuild.js +6 -0
  54. package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
  55. package/dist/core/factories/section-factory-with-jiti.js +6 -0
  56. package/dist/core/fields/checkbox.d.ts +4 -1
  57. package/dist/core/fields/checkbox.d.ts.map +1 -1
  58. package/dist/core/fields/color.d.ts +4 -1
  59. package/dist/core/fields/color.d.ts.map +1 -1
  60. package/dist/core/fields/color.js +2 -2
  61. package/dist/core/fields/date.d.ts +4 -1
  62. package/dist/core/fields/date.d.ts.map +1 -1
  63. package/dist/core/fields/date.js +2 -2
  64. package/dist/core/fields/document.d.ts +4 -1
  65. package/dist/core/fields/document.d.ts.map +1 -1
  66. package/dist/core/fields/document.js +27 -18
  67. package/dist/core/fields/field-group.d.ts +3 -3
  68. package/dist/core/fields/field-group.d.ts.map +1 -1
  69. package/dist/core/fields/field.d.ts +11 -8
  70. package/dist/core/fields/field.d.ts.map +1 -1
  71. package/dist/core/fields/field.js +15 -11
  72. package/dist/core/fields/map.d.ts +4 -1
  73. package/dist/core/fields/map.d.ts.map +1 -1
  74. package/dist/core/fields/map.js +2 -2
  75. package/dist/core/fields/number.d.ts +26 -1
  76. package/dist/core/fields/number.d.ts.map +1 -1
  77. package/dist/core/fields/number.js +16 -7
  78. package/dist/core/fields/password.d.ts +4 -1
  79. package/dist/core/fields/password.d.ts.map +1 -1
  80. package/dist/core/fields/password.js +3 -3
  81. package/dist/core/fields/photo.d.ts +4 -1
  82. package/dist/core/fields/photo.d.ts.map +1 -1
  83. package/dist/core/fields/photo.js +17 -17
  84. package/dist/core/fields/richText.d.ts +17 -3
  85. package/dist/core/fields/richText.d.ts.map +1 -1
  86. package/dist/core/fields/richText.js +20 -8
  87. package/dist/core/fields/select.d.ts +11 -4
  88. package/dist/core/fields/select.d.ts.map +1 -1
  89. package/dist/core/fields/select.js +27 -34
  90. package/dist/core/fields/selectMultiple.d.ts +8 -4
  91. package/dist/core/fields/selectMultiple.d.ts.map +1 -1
  92. package/dist/core/fields/selectMultiple.js +32 -24
  93. package/dist/core/fields/slug.d.ts +16 -1
  94. package/dist/core/fields/slug.d.ts.map +1 -1
  95. package/dist/core/fields/slug.js +3 -3
  96. package/dist/core/fields/tags.d.ts +6 -3
  97. package/dist/core/fields/tags.d.ts.map +1 -1
  98. package/dist/core/fields/tags.js +26 -19
  99. package/dist/core/fields/text.d.ts +24 -1
  100. package/dist/core/fields/text.d.ts.map +1 -1
  101. package/dist/core/fields/text.js +12 -3
  102. package/dist/core/fields/textArea.d.ts +24 -1
  103. package/dist/core/fields/textArea.d.ts.map +1 -1
  104. package/dist/core/fields/textArea.js +9 -0
  105. package/dist/core/fields/video.d.ts +4 -1
  106. package/dist/core/fields/video.d.ts.map +1 -1
  107. package/dist/core/fields/video.js +14 -12
  108. package/dist/core/index.d.ts +1 -0
  109. package/dist/core/index.d.ts.map +1 -1
  110. package/dist/core/index.js +1 -0
  111. package/dist/core/localization/index.d.ts +3 -0
  112. package/dist/core/localization/index.d.ts.map +1 -0
  113. package/dist/core/localization/index.js +1 -0
  114. package/dist/core/localization/resolve-locale.d.ts +29 -0
  115. package/dist/core/localization/resolve-locale.d.ts.map +1 -0
  116. package/dist/core/localization/resolve-locale.js +43 -0
  117. package/dist/core/sections/category.d.ts +22 -10
  118. package/dist/core/sections/category.d.ts.map +1 -1
  119. package/dist/core/sections/category.js +3 -3
  120. package/dist/core/sections/hasItems.d.ts +46 -10
  121. package/dist/core/sections/hasItems.d.ts.map +1 -1
  122. package/dist/core/sections/section.d.ts +38 -11
  123. package/dist/core/sections/section.d.ts.map +1 -1
  124. package/dist/core/sections/section.js +22 -0
  125. package/dist/core/sections/simple.d.ts +8 -8
  126. package/dist/core/sections/simple.d.ts.map +1 -1
  127. package/dist/core/submit/ItemEditSubmit.d.ts +24 -16
  128. package/dist/core/submit/ItemEditSubmit.d.ts.map +1 -1
  129. package/dist/core/submit/ItemEditSubmit.js +62 -38
  130. package/dist/core/submit/LocaleSubmit.d.ts +97 -0
  131. package/dist/core/submit/LocaleSubmit.d.ts.map +1 -0
  132. package/dist/core/submit/LocaleSubmit.js +435 -0
  133. package/dist/core/submit/NewItemSubmit.d.ts +0 -8
  134. package/dist/core/submit/NewItemSubmit.d.ts.map +1 -1
  135. package/dist/core/submit/NewItemSubmit.js +6 -12
  136. package/dist/core/submit/index.d.ts +1 -0
  137. package/dist/core/submit/index.d.ts.map +1 -1
  138. package/dist/core/submit/index.js +1 -0
  139. package/dist/core/submit/submit.d.ts +35 -12
  140. package/dist/core/submit/submit.d.ts.map +1 -1
  141. package/dist/core/submit/submit.js +88 -69
  142. package/dist/db/schema.d.ts +17 -0
  143. package/dist/db/schema.d.ts.map +1 -1
  144. package/dist/db/schema.js +1 -0
  145. package/dist/logging/log.d.ts +1 -1
  146. package/dist/logging/log.d.ts.map +1 -1
  147. package/dist/plugins/index.d.ts +1 -1
  148. package/dist/plugins/index.d.ts.map +1 -1
  149. package/dist/plugins/loader.d.ts +3 -3
  150. package/dist/plugins/loader.d.ts.map +1 -1
  151. package/dist/translations/base/en.d.ts +24 -2
  152. package/dist/translations/base/en.d.ts.map +1 -1
  153. package/dist/translations/base/en.js +24 -2
  154. package/dist/translations/client.d.ts +292 -28
  155. package/dist/translations/client.d.ts.map +1 -1
  156. package/dist/translations/client.js +2 -2
  157. package/dist/translations/dict-store.d.ts +2 -2
  158. package/dist/translations/dict-store.d.ts.map +1 -1
  159. package/dist/translations/dict-store.js +9 -9
  160. package/dist/translations/index.d.ts +5 -5
  161. package/dist/translations/index.d.ts.map +1 -1
  162. package/dist/translations/index.js +6 -6
  163. package/dist/translations/language-cookie.d.ts +24 -0
  164. package/dist/translations/language-cookie.d.ts.map +1 -0
  165. package/dist/translations/language-cookie.js +44 -0
  166. package/dist/translations/language-utils.d.ts +42 -0
  167. package/dist/translations/language-utils.d.ts.map +1 -0
  168. package/dist/translations/language-utils.js +52 -0
  169. package/dist/translations/localization.d.ts +1 -39
  170. package/dist/translations/localization.d.ts.map +1 -1
  171. package/dist/translations/localization.js +0 -48
  172. package/dist/translations/server.d.ts +293 -29
  173. package/dist/translations/server.d.ts.map +1 -1
  174. package/dist/translations/server.js +5 -5
  175. package/dist/validators/select-multiple.d.ts +2 -2
  176. package/dist/validators/select-multiple.d.ts.map +1 -1
  177. package/dist/validators/select-multiple.js +1 -1
  178. package/package.json +7 -3
@@ -6,8 +6,8 @@ import { NumberField, PhotoField, SelectField, TextField } from '../fields';
6
6
  import { MysqlTableChecker } from '../db';
7
7
  import { recordLog } from '../../logging/index.js';
8
8
  import getString from '../../translations';
9
- import { resolveLocalizedString } from '../../translations/localization.js';
10
- import { resolveLocale } from '../../translations/locale-utils.js';
9
+ import { resolveMultilingualString } from '../../translations/language-utils.js';
10
+ import { resolveLanguage } from '../../translations/language-utils.js';
11
11
  import { getCMSConfig } from '../config/index.js';
12
12
  export class Submit {
13
13
  static [entityKind] = 'Submit';
@@ -23,6 +23,17 @@ export class Submit {
23
23
  sqlNamesAndValues = {};
24
24
  fields = [];
25
25
  requestMetadata;
26
+ /**
27
+ * Locale context for this submission:
28
+ * - `undefined` — localization is not enabled
29
+ * - the defaultLocale code (e.g. `'en'`) — localization enabled, editing the default/base locale
30
+ * - a non-default locale code (e.g. `'ar'`) — editing a specific non-default locale (set by LocaleSubmit constructor)
31
+ */
32
+ _locale = undefined;
33
+ /** Admin UI locale for resolving field labels in server-side validation messages */
34
+ /** We should probably find a better naming convention for ui i18n locales and data locales */
35
+ _adminUiLocale = 'en';
36
+ _i18nFallbackLocale = 'en';
26
37
  /**
27
38
  * Constructor
28
39
  */
@@ -49,23 +60,27 @@ export class Submit {
49
60
  async runPostSubmitHooks() {
50
61
  // No-op by default; overridden in NewSubmit and EditSubmit
51
62
  }
52
- /**
53
- * Run custom hooks when an error occurs
54
- * @protected
55
- */
63
+ resolveHook(hook) {
64
+ if (!hook)
65
+ return { handler: undefined, runForLocales: false };
66
+ if (typeof hook === 'function')
67
+ return { handler: hook, runForLocales: false };
68
+ return { handler: hook.handler, runForLocales: hook.runForLocales ?? false };
69
+ }
56
70
  async runErrorHooks(error) {
57
- if (!this._sectionInfo.hooks?.onError)
71
+ if (!this._sectionInfo?.hooks?.onError)
58
72
  return;
59
- // Only run if sectionInfo is available
60
- if (!this._sectionInfo)
73
+ const { handler } = this.resolveHook(this._sectionInfo.hooks.onError);
74
+ if (!handler)
61
75
  return;
62
76
  try {
63
- await this._sectionInfo.hooks?.onError?.({
77
+ await handler({
64
78
  itemId: this._itemId,
65
79
  values: this.sqlNamesAndValues,
66
80
  section: this._sectionInfo,
67
81
  errorMessage: this._errorMessage,
68
82
  error: error,
83
+ locale: this._locale,
69
84
  });
70
85
  }
71
86
  catch (e) {
@@ -127,6 +142,14 @@ export class Submit {
127
142
  */
128
143
  async initialize(requiredRole = 'C') {
129
144
  await this.initializeSectionInfo(this.user, requiredRole);
145
+ // When localization is enabled, ensure _locale is set for junction table scoping
146
+ // even for default locale edits (use the actual defaultLocale code, not an empty string)
147
+ if (!this._locale) {
148
+ const cmsConfig = await getCMSConfig();
149
+ if (cmsConfig.localization?.enabled) {
150
+ this._locale = cmsConfig.localization.defaultLocale;
151
+ }
152
+ }
130
153
  }
131
154
  /**
132
155
  * Gets the section info and assigns it to the `sectionInfo` property
@@ -147,7 +170,7 @@ export class Submit {
147
170
  });
148
171
  if (!s || !s.name) {
149
172
  this._error = true;
150
- this._errorMessage = getString('sectionNotFound', user.locale);
173
+ this._errorMessage = getString('sectionNotFound', user.language);
151
174
  return undefined;
152
175
  }
153
176
  /**
@@ -162,9 +185,35 @@ export class Submit {
162
185
  * Set locale for fields so validation errors are localized
163
186
  */
164
187
  const cmsConfig = await getCMSConfig();
165
- const locale = resolveLocale(user.locale, cmsConfig.i18n.supportedLanguages, cmsConfig.i18n.fallbackLanguage);
188
+ const language = resolveLanguage(user.language, cmsConfig.i18n.supportedLanguages, cmsConfig.i18n.fallbackLanguage);
189
+ this._adminUiLocale = language;
190
+ this._i18nFallbackLocale = cmsConfig.i18n.fallbackLanguage;
166
191
  for (const field of this._sectionInfo.fields) {
167
- field.setLocale(locale, cmsConfig.i18n.fallbackLanguage);
192
+ field.setLanguage(language, cmsConfig.i18n.fallbackLanguage);
193
+ }
194
+ }
195
+ async runFieldPostSubmit(field) {
196
+ switch (field.type) {
197
+ case 'photo':
198
+ case 'document':
199
+ case 'video':
200
+ await field.postSubmit(this._sectionInfo?.name);
201
+ break;
202
+ case 'select_multiple':
203
+ case 'select':
204
+ case 'tags':
205
+ await field.postSubmit(this._itemId, this._locale);
206
+ break;
207
+ case 'rich_text':
208
+ await field.postSubmit({
209
+ sectionName: this._sectionInfo?.name,
210
+ itemId: this._itemId,
211
+ locale: this._locale,
212
+ });
213
+ break;
214
+ default:
215
+ await field.postSubmit(undefined, this._locale);
216
+ break;
168
217
  }
169
218
  }
170
219
  /**
@@ -174,49 +223,8 @@ export class Submit {
174
223
  */
175
224
  async postSubmit() {
176
225
  try {
177
- /**
178
- * Perform post submit operations
179
- */
180
226
  for (const field of this._sectionInfo?.fields ?? []) {
181
- let variable = undefined;
182
- /**
183
- * Figure out the variable to pass to the post submit function
184
- */
185
- switch (field.type) {
186
- case 'photo':
187
- case 'document':
188
- case 'video':
189
- /**
190
- * File fields need the section name to save the file in the correct folder
191
- */
192
- variable = this._sectionInfo?.name;
193
- break;
194
- case 'select_multiple':
195
- case 'select':
196
- case 'tags':
197
- /**
198
- * Select multiple fields need the itemId,
199
- * to save the selected values in the correct table with the correct item id
200
- */
201
- variable = this._itemId;
202
- break;
203
- case 'rich_text':
204
- /**
205
- * Rich text fields need the section name to save the file in the correct folder,
206
- * and the itemId to save inline images with the correct item id in the `editor_photos` table
207
- */
208
- variable = {
209
- sectionName: this._sectionInfo?.name,
210
- itemId: this._itemId,
211
- };
212
- break;
213
- default:
214
- break;
215
- }
216
- /**
217
- * Call the post submit function
218
- */
219
- await field.postSubmit(variable);
227
+ await this.runFieldPostSubmit(field);
220
228
  }
221
229
  }
222
230
  catch (e) {
@@ -232,7 +240,7 @@ export class Submit {
232
240
  */
233
241
  async postSubmitRollback() {
234
242
  for (const field of this._sectionInfo?.fields ?? []) {
235
- await field.postSubmitRollback();
243
+ await field.postSubmitRollback(this._locale);
236
244
  }
237
245
  }
238
246
  /**
@@ -305,11 +313,13 @@ export class Submit {
305
313
  }
306
314
  }
307
315
  /**
308
- * Handle the field
316
+ * Core field handling logic. Subclasses that need to bypass intermediate
317
+ * overrides of handleField (e.g. LocaleSubmit skipping EditSubmit's
318
+ * readonly filter) can call this directly.
309
319
  * @param field
310
320
  * @protected
311
321
  */
312
- async handleField(field) {
322
+ async handleFieldBase(field) {
313
323
  /**
314
324
  * Get the value from the post request,
315
325
  * and assign it to the field object
@@ -357,6 +367,14 @@ export class Submit {
357
367
  */
358
368
  this.assignItemIdValue(field);
359
369
  }
370
+ /**
371
+ * Handle the field
372
+ * @param field
373
+ * @protected
374
+ */
375
+ async handleField(field) {
376
+ await this.handleFieldBase(field);
377
+ }
360
378
  async handleFields() {
361
379
  if (this._error)
362
380
  return;
@@ -379,9 +397,9 @@ export class Submit {
379
397
  }
380
398
  /**
381
399
  * Get a user-friendly label for a field config.
382
- * Resolves localized strings to English.
400
+ * Resolves localized strings using the admin UI locale (same as field validation).
383
401
  * @param fieldConfig - The field configuration
384
- * @private
402
+ * @protected
385
403
  */
386
404
  getFieldLabel(fieldConfig) {
387
405
  const label = fieldConfig.label;
@@ -391,7 +409,7 @@ export class Submit {
391
409
  .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
392
410
  .replace(/\b\w/g, (char) => char.toUpperCase());
393
411
  }
394
- return resolveLocalizedString(label, 'en', 'en');
412
+ return resolveMultilingualString(label, this._adminUiLocale, this._i18nFallbackLocale);
395
413
  }
396
414
  /**
397
415
  * Check all uniqueness constraints defined in the section.
@@ -413,10 +431,9 @@ export class Submit {
413
431
  * Check a single uniqueness constraint.
414
432
  * Handles both single-column and composite (multi-column) constraints.
415
433
  * @param constraint - The constraint to check
416
- * @private
434
+ * @protected
417
435
  */
418
436
  async checkUniqueConstraint(constraint) {
419
- const columnNames = constraint.columns.map((col) => col.name);
420
437
  // Check if ALL columns have values in sqlNamesAndValues
421
438
  // Skip if any column has null/undefined value
422
439
  const columnValues = [];
@@ -448,11 +465,13 @@ export class Submit {
448
465
  const firstColumn = columnValues[0];
449
466
  if (columnValues.length === 1 && firstColumn) {
450
467
  const label = this.getFieldLabel(firstColumn.fieldConfig);
451
- this._errorMessage = getString('recordWithFieldExists', this.user.locale, { field: label });
468
+ this._errorMessage = getString('recordWithFieldExists', this.user.language, { field: label });
452
469
  }
453
470
  else {
454
471
  const labels = columnValues.map(({ fieldConfig }) => this.getFieldLabel(fieldConfig));
455
- this._errorMessage = getString('recordWithCombinationExists', this.user.locale, { fields: labels.join(', ') });
472
+ this._errorMessage = getString('recordWithCombinationExists', this.user.language, {
473
+ fields: labels.join(', '),
474
+ });
456
475
  }
457
476
  }
458
477
  }
@@ -474,7 +493,7 @@ export class Submit {
474
493
  */
475
494
  if (!sqlQuery) {
476
495
  this._error = true;
477
- this._errorMessage = getString('sqlQueryNotDefined', this.user.locale);
496
+ this._errorMessage = getString('sqlQueryNotDefined', this.user.language);
478
497
  return;
479
498
  }
480
499
  try {
@@ -608,7 +627,7 @@ export class Submit {
608
627
  /**
609
628
  * The gallery table is not set up correctly, add it to the notices array
610
629
  */
611
- this.addNotice(getString('galleryTableNotSetUp', this.user.locale));
630
+ this.addNotice(getString('galleryTableNotSetUp', this.user.language));
612
631
  return;
613
632
  }
614
633
  const columns = await MysqlTableChecker.getColumns(gallery.db.tableName);
@@ -618,7 +637,7 @@ export class Submit {
618
637
  /**
619
638
  * The gallery table is not set up correctly, add it to the notices array
620
639
  */
621
- this.addNotice(getString('galleryTableNotSetUp', this.user.locale));
640
+ this.addNotice(getString('galleryTableNotSetUp', this.user.language));
622
641
  return;
623
642
  }
624
643
  /**
@@ -634,7 +653,7 @@ export class Submit {
634
653
  */
635
654
  const photoField = new PhotoField({
636
655
  name: 'dropzonePhoto',
637
- label: 'Photo',
656
+ label: getString('galleryPhoto', this.user.language),
638
657
  required: false,
639
658
  order: 0,
640
659
  fileType: ['jpg', 'jpeg', 'png', 'webp'],
@@ -504,6 +504,23 @@ export declare const EditorPhotosTable: import("drizzle-orm/mysql-core").MySqlTa
504
504
  identity: undefined;
505
505
  generated: undefined;
506
506
  }, {}, {}>;
507
+ locale: import("drizzle-orm/mysql-core").MySqlColumn<{
508
+ name: "locale";
509
+ tableName: "editor_photos";
510
+ dataType: "string";
511
+ columnType: "MySqlVarChar";
512
+ data: string;
513
+ driverParam: string | number;
514
+ notNull: true;
515
+ hasDefault: false;
516
+ isPrimaryKey: false;
517
+ isAutoincrement: false;
518
+ hasRuntimeDefault: false;
519
+ enumValues: [string, ...string[]];
520
+ baseColumn: never;
521
+ identity: undefined;
522
+ generated: undefined;
523
+ }, {}, {}>;
507
524
  meta: import("drizzle-orm/mysql-core").MySqlColumn<{
508
525
  name: "meta";
509
526
  tableName: "editor_photos";
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAchC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa7B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI/B,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ5B,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBrB,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAchC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa7B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI/B,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS5B,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBrB,CAAA"}
package/dist/db/schema.js CHANGED
@@ -58,6 +58,7 @@ export const EditorPhotosTable = mysqlTable('editor_photos', {
58
58
  section: varchar('section', { length: 100 }).notNull(),
59
59
  itemId: varchar('item_id', { length: 50 }).notNull(),
60
60
  field: varchar('field', { length: 100 }).notNull(),
61
+ locale: varchar('locale', { length: 10 }).notNull(),
61
62
  meta: longtext('meta'),
62
63
  linked: boolean('linked').default(false),
63
64
  createdAt: timestamp('created_at').defaultNow().notNull(),
@@ -1,4 +1,4 @@
1
- export type LogEventType = 'auth.login' | 'auth.logout' | 'section.item.create' | 'section.item.update' | 'section.item.delete' | 'admin.section.create' | 'admin.section.update' | 'admin.section.delete' | 'admin.username.change' | 'admin.settings.change';
1
+ export type LogEventType = 'auth.login' | 'auth.logout' | 'section.item.create' | 'section.item.update' | 'section.item.delete' | 'section.item.locale.delete' | 'admin.section.create' | 'admin.section.update' | 'admin.section.delete' | 'admin.username.change' | 'admin.settings.change';
2
2
  export type RequestMetadata = {
3
3
  ipAddress?: string | null;
4
4
  userAgent?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/logging/log.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAClB,YAAY,GACZ,aAAa,GACb,qBAAqB,GACrB,qBAAqB,GACrB,qBAAqB,GACrB,sBAAsB,GACtB,sBAAsB,GACtB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,CAAA;AAE7B,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACnB,SAAS,EAAE,YAAY,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,eAAe,CAAC,EAAE,eAAe,CAAA;CACpC,CAAA;AAcD,eAAO,MAAM,6BAA6B,GAAI,UAAU,OAAO,GAAG,IAAI,KAAG,eAaxE,CAAA;AAED,eAAO,MAAM,SAAS,GAAU,OAAO,QAAQ,KAAG,OAAO,CAAC,IAAI,CAqB7D,CAAA"}
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/logging/log.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAClB,YAAY,GACZ,aAAa,GACb,qBAAqB,GACrB,qBAAqB,GACrB,qBAAqB,GACrB,4BAA4B,GAC5B,sBAAsB,GACtB,sBAAsB,GACtB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,CAAA;AAE7B,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACnB,SAAS,EAAE,YAAY,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,eAAe,CAAC,EAAE,eAAe,CAAA;CACpC,CAAA;AAcD,eAAO,MAAM,6BAA6B,GAAI,UAAU,OAAO,GAAG,IAAI,KAAG,eAaxE,CAAA;AAED,eAAO,MAAM,SAAS,GAAU,OAAO,QAAQ,KAAG,OAAO,CAAC,IAAI,CAqB7D,CAAA"}
@@ -1,3 +1,3 @@
1
1
  export type { CMSPlugin, CMSPluginMultiRoute, CMSPluginSingleRoute, LoadedPlugin, LoadedPluginRoute, PluginInitContext, PluginModule, PluginRoute, PluginRouteWithoutComponent, PluginRouteWithComponent, } from './loader.js';
2
- export type { LocalizedString } from '../translations/localization.js';
2
+ export type { MultilingualString } from '../translations/language-utils.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,GAC3B,MAAM,aAAa,CAAA;AAGpB,YAAY,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,GAC3B,MAAM,aAAa,CAAA;AAGpB,YAAY,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import type { PluginConfigEntry } from '../core/config/config-loader.js';
2
- import type { LocalizedString } from '../translations/localization.js';
2
+ import type { MultilingualString } from '../translations/language-utils.js';
3
3
  import type { IconName } from 'lucide-react/dynamic';
4
4
  export interface CMSPlugin {
5
5
  /**
@@ -8,7 +8,7 @@ export interface CMSPlugin {
8
8
  * @example 'Some Plugin Title'
9
9
  * @example { en: 'Some Plugin Title', ar: 'عنوان الإضافة' }
10
10
  */
11
- title: LocalizedString;
11
+ title: MultilingualString;
12
12
  /**
13
13
  * The internal name of the plugin.
14
14
  * It should start with 'plugin_' and be in snake_case.
@@ -41,7 +41,7 @@ export interface PluginRoute {
41
41
  * The title of the route.
42
42
  * Can be a plain string or a localized object with language codes as keys.
43
43
  */
44
- title: LocalizedString;
44
+ title: MultilingualString;
45
45
  icon?: IconName | undefined;
46
46
  component?: string;
47
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/plugins/loader.ts"],"names":[],"mappings":"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"}
@@ -195,6 +195,19 @@ declare const _default: {
195
195
  readonly catDeleteWarning: "Warning! All associated items will be deleted!";
196
196
  readonly catDeleteWarningSubtitle: "Please don't proceed if you don't want to lose associated items.";
197
197
  readonly cancel: "Cancel";
198
+ readonly unsavedChangesConfirm: "You have unsaved changes. Are you sure you want to leave this page?";
199
+ readonly deleteLocaleTranslation: "Delete this translation";
200
+ readonly deleteLocaleTranslationText: "Are you sure you want to delete this translation? This action cannot be undone.";
201
+ readonly localesHeading: "Locales";
202
+ readonly baseLocaleBadge: "(base)";
203
+ readonly editingContentTranslation: "Editing translation: {locale}. Only localized fields are shown.";
204
+ readonly localizationNotEnabledForSection: "Localization is not enabled for this section";
205
+ readonly invalidLocale: "Invalid locale: \"{locale}\". Must be one of: {locales}";
206
+ readonly cannotDeleteBaseLocaleTranslation: "Cannot delete the base locale translation";
207
+ readonly localesTableDoesNotExist: "Locales table does not exist";
208
+ readonly deleteLocaleTranslationFailed: "Failed to delete locale translation: {detail}";
209
+ readonly unknownErrorOccurred: "Unknown error occurred";
210
+ readonly localeTranslationDeleted: "Translation deleted successfully";
198
211
  readonly itemCreatedSuccessfully: "Item created successfully";
199
212
  readonly itemUpdatedSuccessfully: "Item updated successfully";
200
213
  readonly sectionUpdatedSuccessfully: "Information updated successfully";
@@ -276,6 +289,8 @@ declare const _default: {
276
289
  readonly no: "No";
277
290
  readonly videoDeletedSuccessfully: "Video deleted successfully";
278
291
  readonly photoDeletedSuccessfully: "Photo deleted successfully";
292
+ readonly photoMarkedForDeletion: "Photo will be deleted when you save.";
293
+ readonly undo: "Undo";
279
294
  readonly selectFile: "Select File";
280
295
  readonly mandatory: "Mandatory";
281
296
  readonly imageDimensionsMustBe: "Image dimensions must be";
@@ -334,7 +349,7 @@ declare const _default: {
334
349
  readonly emailAccountsList: "Email Accounts List";
335
350
  readonly theme: "Theme";
336
351
  readonly noAccessToSection: "No access to this section";
337
- readonly localeNotSupported: "This language is not supported";
352
+ readonly languageNotSupported: "This language is not supported";
338
353
  readonly language: "Language";
339
354
  readonly addNewCar: "Add New Car";
340
355
  readonly createCarListing: "Create a new car listing";
@@ -403,7 +418,7 @@ declare const _default: {
403
418
  readonly parentId: "Parent ID";
404
419
  readonly selectFieldConfigError: "Select field requires either db, section or an options array";
405
420
  readonly tableIdentifierLabelRequired: "Table, identifier and label are required";
406
- readonly i18nMustHaveAtLeastOneLocale: "i18n.supportedLanguages must have at least one locale";
421
+ readonly i18nMustHaveAtLeastOneLanguage: "i18n.supportedLanguages must have at least one language";
407
422
  readonly fieldMinValueError: "{field} must be {min} and above";
408
423
  readonly fieldMaxValueError: "{field} must be {max} and below";
409
424
  readonly fieldMinMaxMismatch: "{field} has minValue > maxValue";
@@ -445,6 +460,13 @@ declare const _default: {
445
460
  readonly clear: "Clear";
446
461
  readonly close: "Close";
447
462
  readonly clearAllSelectedOptions: "Clear all {count} selected options";
463
+ readonly galleryPhoto: "Gallery Photo";
464
+ readonly parentItemNotFound: "Parent item not found";
465
+ readonly preSubmitHookFailed: "Pre-submit hook failed";
466
+ readonly failedToBuildLocaleSqlQuery: "Failed to build locale SQL query";
467
+ readonly noLocalizedFields: "This section has no localized fields.";
468
+ readonly sectionHasNoLocalizedFields: "Section \"{section}\" has no localized fields. Add localized: true to at least one field in the section definition to enable translations.";
469
+ readonly noLocalizedFieldsHint: "To enable translations for \"{section}\", update the section definition in \"{file}\" inside the sections folder and add localized: true to the fields you want to translate.";
448
470
  };
449
471
  export default _default;
450
472
  //# sourceMappingURL=en.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/base/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA6dU"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/base/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA0fU"}
@@ -195,6 +195,19 @@ export default {
195
195
  catDeleteWarning: 'Warning! All associated items will be deleted!',
196
196
  catDeleteWarningSubtitle: "Please don't proceed if you don't want to lose associated items.",
197
197
  cancel: 'Cancel',
198
+ unsavedChangesConfirm: 'You have unsaved changes. Are you sure you want to leave this page?',
199
+ deleteLocaleTranslation: 'Delete this translation',
200
+ deleteLocaleTranslationText: 'Are you sure you want to delete this translation? This action cannot be undone.',
201
+ localesHeading: 'Locales',
202
+ baseLocaleBadge: '(base)',
203
+ editingContentTranslation: 'Editing translation: {locale}. Only localized fields are shown.',
204
+ localizationNotEnabledForSection: 'Localization is not enabled for this section',
205
+ invalidLocale: 'Invalid locale: "{locale}". Must be one of: {locales}',
206
+ cannotDeleteBaseLocaleTranslation: 'Cannot delete the base locale translation',
207
+ localesTableDoesNotExist: 'Locales table does not exist',
208
+ deleteLocaleTranslationFailed: 'Failed to delete locale translation: {detail}',
209
+ unknownErrorOccurred: 'Unknown error occurred',
210
+ localeTranslationDeleted: 'Translation deleted successfully',
198
211
  itemCreatedSuccessfully: 'Item created successfully',
199
212
  itemUpdatedSuccessfully: 'Item updated successfully',
200
213
  sectionUpdatedSuccessfully: 'Information updated successfully',
@@ -276,6 +289,8 @@ export default {
276
289
  no: 'No',
277
290
  videoDeletedSuccessfully: 'Video deleted successfully',
278
291
  photoDeletedSuccessfully: 'Photo deleted successfully',
292
+ photoMarkedForDeletion: 'Photo will be deleted when you save.',
293
+ undo: 'Undo',
279
294
  selectFile: 'Select File',
280
295
  mandatory: 'Mandatory',
281
296
  imageDimensionsMustBe: 'Image dimensions must be',
@@ -334,7 +349,7 @@ export default {
334
349
  emailAccountsList: 'Email Accounts List',
335
350
  theme: 'Theme',
336
351
  noAccessToSection: 'No access to this section',
337
- localeNotSupported: 'This language is not supported',
352
+ languageNotSupported: 'This language is not supported',
338
353
  language: 'Language',
339
354
  addNewCar: 'Add New Car',
340
355
  createCarListing: 'Create a new car listing',
@@ -408,7 +423,7 @@ export default {
408
423
  // Config Errors
409
424
  selectFieldConfigError: 'Select field requires either db, section or an options array',
410
425
  tableIdentifierLabelRequired: 'Table, identifier and label are required',
411
- i18nMustHaveAtLeastOneLocale: 'i18n.supportedLanguages must have at least one locale',
426
+ i18nMustHaveAtLeastOneLanguage: 'i18n.supportedLanguages must have at least one language',
412
427
  // Field Validation - Min/Max
413
428
  fieldMinValueError: '{field} must be {min} and above',
414
429
  fieldMaxValueError: '{field} must be {max} and below',
@@ -459,4 +474,11 @@ export default {
459
474
  clear: 'Clear',
460
475
  close: 'Close',
461
476
  clearAllSelectedOptions: 'Clear all {count} selected options',
477
+ galleryPhoto: 'Gallery Photo',
478
+ parentItemNotFound: 'Parent item not found',
479
+ preSubmitHookFailed: 'Pre-submit hook failed',
480
+ failedToBuildLocaleSqlQuery: 'Failed to build locale SQL query',
481
+ noLocalizedFields: 'This section has no localized fields.',
482
+ sectionHasNoLocalizedFields: 'Section "{section}" has no localized fields. Add localized: true to at least one field in the section definition to enable translations.',
483
+ noLocalizedFieldsHint: 'To enable translations for "{section}", update the section definition in "{file}" inside the sections folder and add localized: true to the fields you want to translate.',
462
484
  };