nextjs-cms 0.6.7 → 0.6.8

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.
@@ -66,10 +66,10 @@ declare const cmsConfigSchema: z.ZodObject<{
66
66
  }, z.core.$strip>>>;
67
67
  }, z.core.$strip>>>;
68
68
  i18n: z.ZodOptional<z.ZodObject<{
69
- supportedLanguages: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
70
- en: "en";
71
- ar: "ar";
72
- }>, z.ZodRecord<z.ZodString, z.ZodString>>>;
69
+ supportedLanguages: z.ZodOptional<z.ZodObject<{
70
+ en: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
71
+ ar: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
72
+ }, z.core.$strip>>;
73
73
  fallbackLanguage: z.ZodOptional<z.ZodEnum<{
74
74
  en: "en";
75
75
  ar: "ar";
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAGxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAEzE,uGAAuG;AACvG,eAAO,MAAM,sBAAsB,uBAAwB,CAAA;AAE3D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAGrE,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2OnB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,eAAe,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,iEAAiE;IACjE,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;CAC/C;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,UAAU,EAAE;gBAAE,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,CAAA;YAC9D,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,IAAI,EAAE;QACF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAA;QACrC,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;IACD,SAAS,EAAE;QACP,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAC1B,CAAA;CACJ;AA6KD;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAGxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAEzE,uGAAuG;AACvG,eAAO,MAAM,sBAAsB,uBAAwB,CAAA;AAE3D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAGrE,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkPnB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,eAAe,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,iEAAiE;IACjE,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;CAC/C;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,UAAU,EAAE;gBAAE,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,CAAA;YAC9D,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,IAAI,EAAE;QACF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAA;QACrC,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;IACD,SAAS,EAAE;QACP,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAC1B,CAAA;CACJ;AA6KD;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
@@ -199,14 +199,15 @@ const cmsConfigSchema = z.object({
199
199
  /**
200
200
  * Supported locales and their translation dictionaries.
201
201
  * Import from `nextjs-cms/translations/dictionaries/en` (and /ar) and pass
202
- * e.g. `{ en, ar }`. Keys = locale codes offered in the dropdown.
202
+ * e.g. `{ en }`, `{ ar }`, or `{ en, ar }`. Keys = locale codes offered in the dropdown.
203
+ * At least one locale is required.
203
204
  */
204
205
  supportedLanguages: z
205
- .record(z.enum(AVAILABLE_I18N_LOCALES), z.record(z.string(), z.string()))
206
- .optional()
207
- .refine((v) => v === undefined || Object.keys(v).length >= 1, {
206
+ .object(Object.fromEntries(AVAILABLE_I18N_LOCALES.map((locale) => [locale, z.record(z.string(), z.string()).optional()])))
207
+ .refine((v) => v === undefined || Object.values(v).some((dict) => dict !== undefined), {
208
208
  message: 'i18n.supportedLanguages must have at least one locale',
209
- }),
209
+ })
210
+ .optional(),
210
211
  /**
211
212
  * Fallback locale when the user's stored locale is not in supportedLanguages,
212
213
  * or when no session exists (e.g. login page).
@@ -1 +1 @@
1
- {"version":3,"file":"FieldFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/FieldFactory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAQlD,KAAK,eAAe,GACd;IACI,IAAI,EAAE,KAAK,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACI,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,CAAA;AAEP,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAAa;IAClC,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC9B,SAAS,CAAC,WAAW,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,YAAY,CAA4B;IAGhD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAY;IAEjD;;OAEG;gBACS,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe;IASnE;;OAEG;IACU,UAAU;YAUT,aAAa;YASb,qBAAqB;IAwFnC;;;;OAIG;YACW,qBAAqB;IAuCnC;;;;OAIG;YACW,cAAc;IAuB5B;;;;;OAKG;YACW,YAAY;IAiB1B,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,cAAc;IAqB3B;;;OAGG;IACH,OAAO,CAAC,UAAU;IA4ElB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;OAGG;IACU,gBAAgB;;;;;;;;;;;;;;;IAmF7B,IAAI,WAAW,IAAI,OAAO,GAAG,SAAS,CAErC;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,KAAK,IAAI,OAAO,CAEnB;CACJ"}
1
+ {"version":3,"file":"FieldFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/FieldFactory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAQlD,KAAK,eAAe,GACd;IACI,IAAI,EAAE,KAAK,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACI,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,CAAA;AAEP,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAAa;IAClC,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC9B,SAAS,CAAC,WAAW,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,YAAY,CAA4B;IAGhD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAY;IAEjD;;OAEG;gBACS,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe;IASnE;;OAEG;IACU,UAAU;YAUT,aAAa;YASb,qBAAqB;IAwFnC;;;;OAIG;YACW,qBAAqB;IAoDnC;;;;OAIG;YACW,cAAc;IAuB5B;;;;;OAKG;YACW,YAAY;IAiB1B,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,cAAc;IAqB3B;;;OAGG;IACH,OAAO,CAAC,UAAU;IA4ElB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;OAGG;IACU,gBAAgB;;;;;;;;;;;;;;;IAmF7B,IAAI,WAAW,IAAI,OAAO,GAAG,SAAS,CAErC;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,KAAK,IAAI,OAAO,CAEnB;CACJ"}
@@ -158,6 +158,14 @@ export class FieldFactory {
158
158
  * Build the fields from the field configs
159
159
  */
160
160
  this._sectionInfo.buildFields();
161
+ /**
162
+ * Set locale for fields so validation/build errors are localized
163
+ */
164
+ const cmsConfig = await getCMSConfig();
165
+ const locale = resolveLocale(this.session.user.locale, cmsConfig.i18n.supportedLanguages, cmsConfig.i18n.fallbackLanguage);
166
+ for (const field of this._sectionInfo.fields) {
167
+ field.setLocale(locale, cmsConfig.i18n.fallbackLanguage);
168
+ }
161
169
  }
162
170
  else {
163
171
  const errorMessage = 'Section config must have a build() method. Use helper functions like simpleSection(), hasItemsSection(), categorySection() to create section configs.';
@@ -36,7 +36,7 @@ export class ColorField extends Field {
36
36
  */
37
37
  if (this.required) {
38
38
  if (!this.value || this.value.trim().length === 0) {
39
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
39
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
40
40
  }
41
41
  }
42
42
  }
@@ -54,7 +54,7 @@ export class ColorField extends Field {
54
54
  * Check if the value represents a color
55
55
  */
56
56
  if (this.value && !/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(this.value)) {
57
- throw new Error(getString('invalidColorPleaseProvideValidHex', 'en'));
57
+ throw new Error(getString('invalidColorPleaseProvideValidHex', this.locale));
58
58
  }
59
59
  }
60
60
  }
@@ -78,7 +78,7 @@ export class DateField extends Field {
78
78
  if (this.required) {
79
79
  const date = this.parseDate();
80
80
  if (!date) {
81
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
81
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
82
82
  }
83
83
  }
84
84
  }
@@ -98,7 +98,7 @@ export class DateField extends Field {
98
98
  this.value = date.toISOString();
99
99
  }
100
100
  else if (this.required) {
101
- throw new Error(getString('invalidDatePleaseProvideValid', 'en', { field: String(this.label) }));
101
+ throw new Error(getString('invalidDatePleaseProvideValid', this.locale, { field: this.getLocalizedLabel() }));
102
102
  }
103
103
  // If not required and no valid date, keep value as-is (null/undefined)
104
104
  }
@@ -81,7 +81,7 @@ export class DocumentField extends FileField {
81
81
  case 'csv':
82
82
  return 'text/csv';
83
83
  default:
84
- throw new Error(getString('invalidFileExtension', 'en', { extensions: e }));
84
+ throw new Error(getString('invalidFileExtension', this.locale, { extensions: e }));
85
85
  }
86
86
  });
87
87
  /**
@@ -99,13 +99,13 @@ export class DocumentField extends FileField {
99
99
  }
100
100
  async readChunkFromFile({ arrayBuffer, length, startPosition = 0, }) {
101
101
  if (!arrayBuffer) {
102
- throw new Error(getString('errorReadingFile', 'en'));
102
+ throw new Error(getString('errorReadingFile', this.locale));
103
103
  }
104
104
  const buffer = new Uint8Array(arrayBuffer);
105
105
  const start = Math.max(0, startPosition);
106
106
  const end = Math.min(start + length, buffer.length);
107
107
  if (start >= end) {
108
- throw new Error(getString('errorReadingFile', 'en'));
108
+ throw new Error(getString('errorReadingFile', this.locale));
109
109
  }
110
110
  return buffer.subarray(start, end);
111
111
  }
@@ -114,10 +114,10 @@ export class DocumentField extends FileField {
114
114
  */
115
115
  async writeToFile() {
116
116
  if (!this._folder) {
117
- throw new Error(getString('folderNotSet', 'en', { field: String(this.label) }));
117
+ throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
118
118
  }
119
119
  if (!this._buffer) {
120
- throw new Error(getString('bufferNotSet', 'en', { field: String(this.label) }));
120
+ throw new Error(getString('bufferNotSet', this.locale, { field: this.getLocalizedLabel() }));
121
121
  }
122
122
  try {
123
123
  /**
@@ -134,7 +134,7 @@ export class DocumentField extends FileField {
134
134
  await fs.promises.writeFile(path.join(uploadsFolder, '.documents', this._folder, this.value), this._buffer);
135
135
  }
136
136
  catch (error) {
137
- throw new Error(getString('documentWriteError', 'en', { field: String(this.label) }) + ` ${error.message}`);
137
+ throw new Error(getString('documentWriteError', this.locale, { field: this.getLocalizedLabel() }) + ` ${error.message}`);
138
138
  }
139
139
  }
140
140
  async postSubmit(folder) {
@@ -147,7 +147,7 @@ export class DocumentField extends FileField {
147
147
  if (!this._file)
148
148
  return;
149
149
  if (!this._folder) {
150
- throw new Error(getString('folderNotSet', 'en', { field: String(this.label) }));
150
+ throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
151
151
  }
152
152
  try {
153
153
  const uploadsFolder = (await getCMSConfig()).media.upload.path;
@@ -155,7 +155,7 @@ export class DocumentField extends FileField {
155
155
  await fs.promises.unlink(pathToFile);
156
156
  }
157
157
  catch (error) {
158
- throw new Error(getString('documentDeleteError', 'en', { field: String(this.label) }));
158
+ throw new Error(getString('documentDeleteError', this.locale, { field: this.getLocalizedLabel() }));
159
159
  }
160
160
  }
161
161
  async cleanupReplacedFile(previousValue, sectionName) {
@@ -195,7 +195,7 @@ export class DocumentField extends FileField {
195
195
  if (!this.required)
196
196
  return;
197
197
  if (!this._file || !this._file?.type || !this._file?.name || !this._file?.size) {
198
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
198
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
199
199
  }
200
200
  }
201
201
  /**
@@ -210,14 +210,14 @@ export class DocumentField extends FileField {
210
210
  const arrayBuffer = await this._file.arrayBuffer();
211
211
  this._buffer = Buffer.from(arrayBuffer);
212
212
  if (!this._buffer.length) {
213
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
213
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
214
214
  }
215
215
  /**
216
216
  * Check extension
217
217
  */
218
218
  const ext = this._file.name.split('.').pop();
219
219
  if (!ext || !this.extensions.includes(ext)) {
220
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
220
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
221
221
  }
222
222
  /**
223
223
  * Read the first 4100 bytes of the file
@@ -232,14 +232,14 @@ export class DocumentField extends FileField {
232
232
  * If the file type is invalid, return an error
233
233
  */
234
234
  if (!fileType) {
235
- throw new Error(getString('invalidDocumentFileType', 'en', { field: String(this.label) }));
235
+ throw new Error(getString('invalidDocumentFileType', this.locale, { field: this.getLocalizedLabel() }));
236
236
  }
237
237
  /**
238
238
  * Don't just trust the file extension
239
239
  * Check the `fileType.ext` against the allowed extensions
240
240
  */
241
241
  if (!fileType.ext || !this.extensions.includes(fileType.ext)) {
242
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
242
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
243
243
  }
244
244
  /**
245
245
  * Generate a random name for the file
@@ -1,6 +1,6 @@
1
1
  import { entityKind } from '../helpers/index.js';
2
2
  import type { ConditionalField, ConditionalRule, FieldType } from '../types/index.js';
3
- import type { LocalizedString } from '../../translations/localization.js';
3
+ import { type LocalizedString } from '../../translations/localization.js';
4
4
  import * as z from 'zod';
5
5
  /**
6
6
  * The Field class is used in the submit class to handle submission of the field
@@ -19,6 +19,8 @@ export declare abstract class Field<TType extends FieldType = FieldType, TExtraF
19
19
  readonly order: number | undefined;
20
20
  readonly groupId: number | undefined;
21
21
  readonly conditionalRules: ConditionalRule[] | undefined;
22
+ protected locale: string;
23
+ protected fallbackLocale: string;
22
24
  /**
23
25
  * adminGenerated is used to determine if the field is generated by the admin or not.
24
26
  * If set to false, the field will not be included in the form.
@@ -49,6 +51,8 @@ export declare abstract class Field<TType extends FieldType = FieldType, TExtraF
49
51
  constructor(config: BaseFieldConfig<TExtraFieldConfig>, fieldType: TType);
50
52
  abstract checkRequired(): void;
51
53
  setValue(value: any): void;
54
+ setLocale(locale: string, fallbackLocale?: string): void;
55
+ protected getLocalizedLabel(): string;
52
56
  /**
53
57
  * Perform any action after submitting the form
54
58
  */
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/core/fields/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AACzE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAExB;;;GAGG;AACH,8BAAsB,KAAK,CAEvB,KAAK,SAAS,SAAS,GAAG,SAAS,EACnC,iBAAiB,SAAS,MAAM,GAAG,MAAM,CAC3C,YAAW,QAAQ,CAAC,KAAK,CAAC;IAExB,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,CAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,EAAE,GAAG,SAAS,CAAA;IAExD;;;;OAIG;IACH,cAAc,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,UAAU,CAAA;IAE1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACrB,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,MAAM,CAAA;QACtB,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;IAED;;OAEG;IACI,iBAAiB,EAAE,gBAAgB,EAAE,CAAK;IACnC,KAAK,EAAE,GAAG,CAAA;gBAKZ,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,KAAK;IAaxE,QAAQ,CAAC,aAAa,IAAI,IAAI;IAE9B,QAAQ,CAAC,KAAK,EAAE,GAAG;IAInB;;OAEG;IACU,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD;;OAEG;IACH,QAAQ,CAAC,QAAQ,IAAI,GAAG;IAExB,cAAc,IAAI,GAAG;IAIrB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,QAAQ,CAAC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9C;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAY1C,eAAe;;;;;;;;;;IAef,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,aAAa,IAAI,OAAO;CAa3B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,+CAA8B,CAAA;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;IAW9B;;;;OAIG;;IAEH;;;;OAIG;;kBAEL,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,iBAAiB,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1G,iBAAiB,CAAA;AAErB;;GAEG;AACH,UAAU,QAAQ,CAAC,KAAK,SAAS,SAAS,CAAE,SAAQ,eAAe,CAAC,EAAE,CAAC;IACnE,IAAI,EAAE,KAAK,CAAA;CACd"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/core/fields/field.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { entityKind } from '../helpers/index.js';
2
+ import { resolveLocalizedString } from '../../translations/localization.js';
2
3
  import * as z from 'zod';
3
4
  /**
4
5
  * The Field class is used in the submit class to handle submission of the field
@@ -17,6 +18,8 @@ export class Field {
17
18
  order;
18
19
  groupId;
19
20
  conditionalRules;
21
+ locale;
22
+ fallbackLocale;
20
23
  /**
21
24
  * adminGenerated is used to determine if the field is generated by the admin or not.
22
25
  * If set to false, the field will not be included in the form.
@@ -53,10 +56,19 @@ export class Field {
53
56
  this.conditionalRules = config.conditionalRules;
54
57
  this.adminGenerated = config.adminGenerated ?? true;
55
58
  this.value = undefined;
59
+ this.locale = 'en';
60
+ this.fallbackLocale = 'en';
56
61
  }
57
62
  setValue(value) {
58
63
  this.value = value;
59
64
  }
65
+ setLocale(locale, fallbackLocale = 'en') {
66
+ this.locale = locale;
67
+ this.fallbackLocale = fallbackLocale;
68
+ }
69
+ getLocalizedLabel() {
70
+ return resolveLocalizedString(this.label, this.locale, this.fallbackLocale);
71
+ }
60
72
  /**
61
73
  * Perform any action after submitting the form
62
74
  */
@@ -97,7 +97,7 @@ export class MapField extends Field {
97
97
  */
98
98
  if (this.required) {
99
99
  if (!this.value) {
100
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
100
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
101
101
  }
102
102
  }
103
103
  }
@@ -115,7 +115,7 @@ export class MapField extends Field {
115
115
  * Check if the value if well formatted as `lat,lng` string
116
116
  */
117
117
  if (!/^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/.test(`${this.value?.lat},${this.value?.lng}`)) {
118
- throw new Error(getString('invalidMapFormat', 'en'));
118
+ throw new Error(getString('invalidMapFormat', this.locale));
119
119
  }
120
120
  }
121
121
  }
@@ -76,10 +76,10 @@ export class NumberField extends Field {
76
76
  * Basic structural logic checks
77
77
  */
78
78
  if (this.minValue !== undefined && this.maxValue !== undefined && this.minValue > this.maxValue) {
79
- throw new Error(getString('fieldMinMaxMismatch', 'en', { field: String(this.label) }));
79
+ throw new Error(getString('fieldMinMaxMismatch', this.locale, { field: this.getLocalizedLabel() }));
80
80
  }
81
81
  if (this.minLength !== undefined && this.maxLength !== undefined && this.minLength > this.maxLength) {
82
- throw new Error(getString('fieldLengthMismatch', 'en', { field: String(this.label) }));
82
+ throw new Error(getString('fieldLengthMismatch', this.locale, { field: this.getLocalizedLabel() }));
83
83
  }
84
84
  /**
85
85
  * Attempt to coerce the value
@@ -143,7 +143,7 @@ export class NumberField extends Field {
143
143
  */
144
144
  if (this.required) {
145
145
  if (this.value === undefined || this.value === null || Number.isNaN(this.value)) {
146
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
146
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
147
147
  }
148
148
  }
149
149
  }
@@ -164,7 +164,7 @@ export class NumberField extends Field {
164
164
  */
165
165
  if (this.minValue) {
166
166
  if (this.minValue > this.value) {
167
- throw new Error(getString('fieldMinValueError', 'en', { field: String(this.label), min: this.minValue }));
167
+ throw new Error(getString('fieldMinValueError', this.locale, { field: this.getLocalizedLabel(), min: this.minValue }));
168
168
  }
169
169
  }
170
170
  /**
@@ -172,7 +172,7 @@ export class NumberField extends Field {
172
172
  */
173
173
  if (this.maxValue) {
174
174
  if (this.maxValue < this.value) {
175
- throw new Error(getString('fieldMaxValueError', 'en', { field: String(this.label), max: this.maxValue }));
175
+ throw new Error(getString('fieldMaxValueError', this.locale, { field: this.getLocalizedLabel(), max: this.maxValue }));
176
176
  }
177
177
  }
178
178
  /**
@@ -180,7 +180,7 @@ export class NumberField extends Field {
180
180
  */
181
181
  if (this.minLength) {
182
182
  if (this.minLength > this.value.toString().length) {
183
- throw new Error(getString('numberMinLength', 'en', { min: this.minLength }));
183
+ throw new Error(getString('numberMinLength', this.locale, { min: this.minLength }));
184
184
  }
185
185
  }
186
186
  /**
@@ -188,7 +188,7 @@ export class NumberField extends Field {
188
188
  */
189
189
  if (this.maxLength) {
190
190
  if (this.maxLength < this.value.toString().length) {
191
- throw new Error(getString('numberMaxLength', 'en', { max: this.maxLength }));
191
+ throw new Error(getString('numberMaxLength', this.locale, { max: this.maxLength }));
192
192
  }
193
193
  }
194
194
  }
@@ -56,7 +56,7 @@ export class PasswordField extends Field {
56
56
  */
57
57
  if (this.adminGenerated && this.required) {
58
58
  if (!this.value || this.value.trim().length === 0) {
59
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
59
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
60
60
  }
61
61
  }
62
62
  }
@@ -75,7 +75,7 @@ export class PasswordField extends Field {
75
75
  /**
76
76
  * Display the provided message
77
77
  */
78
- throw new Error(`${String(this.label)}: ${this.validation.message}`);
78
+ throw new Error(`${this.getLocalizedLabel()}: ${this.validation.message}`);
79
79
  }
80
80
  }
81
81
  /**
@@ -83,7 +83,7 @@ export class PasswordField extends Field {
83
83
  */
84
84
  if (this.minLength) {
85
85
  if (this.minLength > this.value.length) {
86
- throw new Error(getString('minLength', 'en', { min: this.minLength }));
86
+ throw new Error(getString('minLength', this.locale, { min: this.minLength }));
87
87
  }
88
88
  }
89
89
  /**
@@ -91,7 +91,7 @@ export class PasswordField extends Field {
91
91
  */
92
92
  if (this.maxLength) {
93
93
  if (this.maxLength < this.value.length) {
94
- throw new Error(getString('maxLength', 'en', { max: this.maxLength }));
94
+ throw new Error(getString('maxLength', this.locale, { max: this.maxLength }));
95
95
  }
96
96
  }
97
97
  /**
@@ -131,7 +131,7 @@ export class PhotoField extends FileField {
131
131
  return 'image/png';
132
132
  if (e === 'webp')
133
133
  return 'image/webp';
134
- throw new Error(getString('invalidImageExtension', 'en', { extensions: e }));
134
+ throw new Error(getString('invalidImageExtension', this.locale, { extensions: e }));
135
135
  });
136
136
  /**
137
137
  * Set the allowed extensions, add jpg if jpeg is present
@@ -166,7 +166,7 @@ export class PhotoField extends FileField {
166
166
  }
167
167
  exportForClient() {
168
168
  if (this._thumbnail === undefined) {
169
- throw new Error(getString('photoFieldBuildRequired', 'en'));
169
+ throw new Error(getString('photoFieldBuildRequired', this.locale));
170
170
  }
171
171
  return {
172
172
  ...super.exportForClient(),
@@ -184,10 +184,10 @@ export class PhotoField extends FileField {
184
184
  */
185
185
  async writeToFile() {
186
186
  if (!this._folder) {
187
- throw new Error(getString('folderNotSet', 'en', { field: String(this.label) }));
187
+ throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
188
188
  }
189
189
  if (!this._sharpImage) {
190
- throw new Error(getString('imageNotSet', 'en', { field: String(this.label) }));
190
+ throw new Error(getString('imageNotSet', this.locale, { field: this.getLocalizedLabel() }));
191
191
  }
192
192
  try {
193
193
  /**
@@ -259,7 +259,7 @@ export class PhotoField extends FileField {
259
259
  .toFile(path.join(uploadsFolder, '.thumbs', this._folder, this.value));
260
260
  }
261
261
  catch (error) {
262
- throw new Error(getString('fileWriteError', 'en', { field: String(this.label) }) + ` ${error.message}`);
262
+ throw new Error(getString('fileWriteError', this.locale, { field: this.getLocalizedLabel() }) + ` ${error.message}`);
263
263
  }
264
264
  }
265
265
  async postSubmit(folder) {
@@ -272,7 +272,7 @@ export class PhotoField extends FileField {
272
272
  if (!this._file)
273
273
  return;
274
274
  if (!this._folder) {
275
- throw new Error(getString('folderNotSet', 'en', { field: String(this.label) }));
275
+ throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
276
276
  }
277
277
  try {
278
278
  const uploadsFolder = (await getCMSConfig()).media.upload.path;
@@ -280,7 +280,7 @@ export class PhotoField extends FileField {
280
280
  await fs.promises.unlink(pathToFile);
281
281
  }
282
282
  catch (error) {
283
- throw new Error(getString('fileDeleteError', 'en', { field: String(this.label) }));
283
+ throw new Error(getString('fileDeleteError', this.locale, { field: this.getLocalizedLabel() }));
284
284
  }
285
285
  }
286
286
  async cleanupReplacedFile(previousValue, sectionName) {
@@ -319,7 +319,7 @@ export class PhotoField extends FileField {
319
319
  */
320
320
  if (this.required) {
321
321
  if (!this._file?.type || !this._file?.name || !this._file?.size) {
322
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
322
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
323
323
  }
324
324
  }
325
325
  }
@@ -340,7 +340,7 @@ export class PhotoField extends FileField {
340
340
  if (ext === 'jpg')
341
341
  ext = 'jpeg';
342
342
  if (!ext || !this.extensions.includes(ext)) {
343
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
343
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
344
344
  }
345
345
  /**
346
346
  * Construct the image
@@ -351,7 +351,7 @@ export class PhotoField extends FileField {
351
351
  * Check mime type
352
352
  */
353
353
  if (!this.mimeType.includes(this._file.type)) {
354
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
354
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
355
355
  }
356
356
  /**
357
357
  * Check actual mime type
@@ -361,7 +361,7 @@ export class PhotoField extends FileField {
361
361
  if (!actualMimeType ||
362
362
  !this.extensions.includes(actualMimeType.ext) ||
363
363
  !this.mimeType.includes(actualMimeType.mime)) {
364
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
364
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
365
365
  }
366
366
  /**
367
367
  * Disable caching for the image to avoid unlink issues
@@ -382,20 +382,20 @@ export class PhotoField extends FileField {
382
382
  */
383
383
  const fileSize = buffer.length;
384
384
  if (!fileSize || !metadata.size) {
385
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
385
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
386
386
  }
387
387
  /**
388
388
  * Check the file size
389
389
  */
390
390
  if (fileSize > this.maxFileSize.size * (this.maxFileSize.unit === 'kb' ? 1024 : 1024 * 1024)) {
391
- throw new Error(getString('fileSizeExceedsMax', 'en', { field: String(this.label), actual: humanReadableFileSize(fileSize), max: `${this.maxFileSize.size} ${this.maxFileSize.unit}` }));
391
+ throw new Error(getString('fileSizeExceedsMax', this.locale, { field: this.getLocalizedLabel(), actual: humanReadableFileSize(fileSize), max: `${this.maxFileSize.size} ${this.maxFileSize.unit}` }));
392
392
  }
393
393
  /**
394
394
  * Don't just trust the file extension
395
395
  * Check the format
396
396
  */
397
397
  if (!metadata.format || !this.extensions.includes(metadata.format)) {
398
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
398
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
399
399
  }
400
400
  /**
401
401
  * Check stat
@@ -404,7 +404,7 @@ export class PhotoField extends FileField {
404
404
  await image.stats();
405
405
  }
406
406
  catch (error) {
407
- throw new Error(getString('fileCorrupted', 'en'));
407
+ throw new Error(getString('fileCorrupted', this.locale));
408
408
  }
409
409
  /**
410
410
  * Convert the image to webp
@@ -413,7 +413,7 @@ export class PhotoField extends FileField {
413
413
  image.toFormat('webp').withExif({});
414
414
  }
415
415
  catch (error) {
416
- throw new Error(getString('fileCorrupted', 'en'));
416
+ throw new Error(getString('fileCorrupted', this.locale));
417
417
  }
418
418
  /**
419
419
  * Check the size
@@ -430,7 +430,7 @@ export class PhotoField extends FileField {
430
430
  * Check if the size matches the required size
431
431
  */
432
432
  if (metadata.width !== this.size.width || metadata.height !== this.size.height) {
433
- throw new Error(getString('imageDimensionMismatchDetailed', 'en', { field: String(this.label), actual: `${metadata.width}x${metadata.height}`, required: `${this.size.width}x${this.size.height}` }));
433
+ throw new Error(getString('imageDimensionMismatchDetailed', this.locale, { field: this.getLocalizedLabel(), actual: `${metadata.width}x${metadata.height}`, required: `${this.size.width}x${this.size.height}` }));
434
434
  }
435
435
  }
436
436
  }
@@ -346,8 +346,8 @@ declare const selectFieldConfigSchema: z.ZodIntersection<z.ZodUnion<readonly [z.
346
346
  }, z.core.$strict>]>, z.ZodObject<{
347
347
  type: z.ZodLiteral<"select">;
348
348
  optionsType: z.ZodEnum<{
349
- db: "db";
350
349
  section: "section";
350
+ db: "db";
351
351
  static: "static";
352
352
  }>;
353
353
  build: z.ZodFunction<z.core.$ZodFunctionArgs, z.ZodCustom<SelectField, SelectField>>;
@@ -402,7 +402,7 @@ export class SelectField extends Field {
402
402
  if (this.db.table.trim().length === 0 ||
403
403
  this.db.identifier.trim().length === 0 ||
404
404
  this.db.label.trim().length === 0) {
405
- throw new Error(`Field ${String(this.label)}: Table, identifier and label are required`);
405
+ throw new Error(`Field ${this.getLocalizedLabel()}: Table, identifier and label are required`);
406
406
  }
407
407
  }
408
408
  checkRequired() {
@@ -411,7 +411,7 @@ export class SelectField extends Field {
411
411
  */
412
412
  if (this.required) {
413
413
  if (!this.value || this.value.toString().trim().length === 0) {
414
- throw new Error(`Field ${String(this.label)} is required`);
414
+ throw new Error(`Field ${this.getLocalizedLabel()} is required`);
415
415
  }
416
416
  }
417
417
  }
@@ -72,7 +72,7 @@ export class SlugField extends Field {
72
72
  checkRequired() {
73
73
  if (this.required) {
74
74
  if (!this.value || this.value.trim().length === 0) {
75
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
75
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
76
76
  }
77
77
  }
78
78
  }
@@ -96,7 +96,7 @@ export class SlugField extends Field {
96
96
  */
97
97
  if (this.minLength) {
98
98
  if (this.minLength > this.value.length) {
99
- throw new Error(getString('minLength', 'en', { min: this.minLength }));
99
+ throw new Error(getString('minLength', this.locale, { min: this.minLength }));
100
100
  }
101
101
  }
102
102
  /**
@@ -104,7 +104,7 @@ export class SlugField extends Field {
104
104
  */
105
105
  if (this.maxLength) {
106
106
  if (this.maxLength < this.value.length) {
107
- throw new Error(getString('maxLength', 'en', { max: this.maxLength }));
107
+ throw new Error(getString('maxLength', this.locale, { max: this.maxLength }));
108
108
  }
109
109
  }
110
110
  }
@@ -76,7 +76,7 @@ export class TextField extends Field {
76
76
  */
77
77
  if (this.required) {
78
78
  if (!this.value || this.value.trim().length === 0) {
79
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
79
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
80
80
  }
81
81
  }
82
82
  }
@@ -100,7 +100,7 @@ export class TextField extends Field {
100
100
  */
101
101
  if (this.minLength) {
102
102
  if (this.minLength > this.value.length) {
103
- throw new Error(getString('minLength', 'en', { min: this.minLength }));
103
+ throw new Error(getString('minLength', this.locale, { min: this.minLength }));
104
104
  }
105
105
  }
106
106
  /**
@@ -108,7 +108,7 @@ export class TextField extends Field {
108
108
  */
109
109
  if (this.maxLength) {
110
110
  if (this.maxLength < this.value.length) {
111
- throw new Error(getString('maxLength', 'en', { max: this.maxLength }));
111
+ throw new Error(getString('maxLength', this.locale, { max: this.maxLength }));
112
112
  }
113
113
  }
114
114
  }
@@ -76,13 +76,13 @@ export class VideoField extends FileField {
76
76
  }
77
77
  async readChunkFromFile({ arrayBuffer, length, startPosition = 0, }) {
78
78
  if (!arrayBuffer) {
79
- throw new Error(getString('errorReadingFile', 'en'));
79
+ throw new Error(getString('errorReadingFile', this.locale));
80
80
  }
81
81
  const buffer = new Uint8Array(arrayBuffer);
82
82
  const start = Math.max(0, startPosition);
83
83
  const end = Math.min(start + length, buffer.length);
84
84
  if (start >= end) {
85
- throw new Error(getString('errorReadingFile', 'en'));
85
+ throw new Error(getString('errorReadingFile', this.locale));
86
86
  }
87
87
  return buffer.subarray(start, end);
88
88
  }
@@ -91,10 +91,10 @@ export class VideoField extends FileField {
91
91
  */
92
92
  async writeToFile() {
93
93
  if (!this._folder) {
94
- throw new Error(getString('videoFolderNotSet', 'en', { field: String(this.label) }));
94
+ throw new Error(getString('videoFolderNotSet', this.locale, { field: this.getLocalizedLabel() }));
95
95
  }
96
96
  if (!this._buffer) {
97
- throw new Error(getString('videoBufferNotSet', 'en', { field: String(this.label) }));
97
+ throw new Error(getString('videoBufferNotSet', this.locale, { field: this.getLocalizedLabel() }));
98
98
  }
99
99
  try {
100
100
  /**
@@ -111,7 +111,7 @@ export class VideoField extends FileField {
111
111
  await fs.promises.writeFile(path.join(uploadsFolder, '.videos', this._folder, this.value), this._buffer);
112
112
  }
113
113
  catch (error) {
114
- throw new Error(getString('videoWriteError', 'en', { field: String(this.label) }) + ` ${error.message}`);
114
+ throw new Error(getString('videoWriteError', this.locale, { field: this.getLocalizedLabel() }) + ` ${error.message}`);
115
115
  }
116
116
  }
117
117
  async postSubmit(folder) {
@@ -120,7 +120,7 @@ export class VideoField extends FileField {
120
120
  }
121
121
  async postSubmitRollback() {
122
122
  if (!this._folder) {
123
- throw new Error(getString('videoFolderNotSet', 'en', { field: String(this.label) }));
123
+ throw new Error(getString('videoFolderNotSet', this.locale, { field: this.getLocalizedLabel() }));
124
124
  }
125
125
  try {
126
126
  const uploadsFolder = (await getCMSConfig()).media.upload.path;
@@ -128,7 +128,7 @@ export class VideoField extends FileField {
128
128
  await fs.promises.unlink(pathToFile);
129
129
  }
130
130
  catch (error) {
131
- throw new Error(getString('fileDeleteError', 'en', { field: String(this.label) }));
131
+ throw new Error(getString('fileDeleteError', this.locale, { field: this.getLocalizedLabel() }));
132
132
  }
133
133
  }
134
134
  async cleanupReplacedFile(previousValue, sectionName) {
@@ -166,7 +166,7 @@ export class VideoField extends FileField {
166
166
  * Note: Those values are coming from the browser (not safe)
167
167
  */
168
168
  if ((this.required && !this._file) || !this._file?.type || !this._file?.name || !this._file?.size) {
169
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
169
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
170
170
  }
171
171
  }
172
172
  /**
@@ -181,14 +181,14 @@ export class VideoField extends FileField {
181
181
  const arrayBuffer = await this._file.arrayBuffer();
182
182
  this._buffer = Buffer.from(arrayBuffer);
183
183
  if (!this._buffer.length) {
184
- throw new Error(getString('fieldIsRequired', 'en', { field: String(this.label) }));
184
+ throw new Error(getString('fieldIsRequired', this.locale, { field: this.getLocalizedLabel() }));
185
185
  }
186
186
  /**
187
187
  * Check extension
188
188
  */
189
189
  const ext = this._file.name.split('.').pop();
190
190
  if (!ext || !this.extensions.includes(ext)) {
191
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
191
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
192
192
  }
193
193
  /**
194
194
  * Read the first 4100 bytes of the file
@@ -203,14 +203,14 @@ export class VideoField extends FileField {
203
203
  * If the file type is invalid, return an error
204
204
  */
205
205
  if (!fileType) {
206
- throw new Error(getString('invalidDocumentFileType', 'en', { field: String(this.label) }));
206
+ throw new Error(getString('invalidDocumentFileType', this.locale, { field: this.getLocalizedLabel() }));
207
207
  }
208
208
  /**
209
209
  * Don't just trust the file extension
210
210
  * Check the `fileType.ext` against the allowed extensions
211
211
  */
212
212
  if (!fileType.ext || !this.extensions.includes(fileType.ext)) {
213
- throw new Error(getString('invalidFileTypeOrExtension', 'en', { field: String(this.label), extensions: this.extensions.join(', ') }));
213
+ throw new Error(getString('invalidFileTypeOrExtension', this.locale, { field: this.getLocalizedLabel(), extensions: this.extensions.join(', ') }));
214
214
  }
215
215
  /**
216
216
  * Generate a random name for the file
@@ -118,9 +118,9 @@ declare const optionsSchema: z.ZodObject<{
118
118
  */
119
119
  allowRecursiveDelete: z.ZodOptional<z.ZodBoolean>;
120
120
  fields: z.ZodUnion<[z.ZodArray<z.ZodCustom<FieldConfig, FieldConfig>>, z.ZodArray<z.ZodCustom<FieldGroupConfig, FieldGroupConfig>>]>;
121
- name: z.ZodString;
122
121
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
123
- order: z.ZodNumber;
122
+ icon: z.ZodOptional<z.ZodString>;
123
+ name: z.ZodString;
124
124
  db: z.ZodObject<{
125
125
  table: z.ZodString;
126
126
  identifier: z.ZodOptional<z.ZodCustom<FieldConfig, FieldConfig>>;
@@ -144,7 +144,8 @@ declare const optionsSchema: z.ZodObject<{
144
144
  name: z.ZodOptional<z.ZodString>;
145
145
  }, z.core.$strict>>>;
146
146
  }, z.core.$strict>;
147
- icon: z.ZodOptional<z.ZodString>;
147
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
148
+ order: z.ZodNumber;
148
149
  gallery: z.ZodOptional<z.ZodObject<{
149
150
  db: z.ZodObject<{
150
151
  tableName: z.ZodString;
@@ -160,7 +161,6 @@ declare const optionsSchema: z.ZodObject<{
160
161
  quality: z.ZodNumber;
161
162
  }, z.core.$strict>>;
162
163
  }, z.core.$strict>>;
163
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
164
164
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
165
165
  }, z.core.$strict>;
166
166
  export declare const categorySectionConfigSchema: z.ZodObject<{
@@ -215,9 +215,9 @@ export declare const categorySectionConfigSchema: z.ZodObject<{
215
215
  * @default false
216
216
  */
217
217
  allowRecursiveDelete: z.ZodOptional<z.ZodBoolean>;
218
- name: z.ZodString;
219
218
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
220
- order: z.ZodNumber;
219
+ icon: z.ZodOptional<z.ZodString>;
220
+ name: z.ZodString;
221
221
  db: z.ZodObject<{
222
222
  table: z.ZodString;
223
223
  identifier: z.ZodOptional<z.ZodCustom<FieldConfig, FieldConfig>>;
@@ -241,7 +241,8 @@ export declare const categorySectionConfigSchema: z.ZodObject<{
241
241
  name: z.ZodOptional<z.ZodString>;
242
242
  }, z.core.$strict>>>;
243
243
  }, z.core.$strict>;
244
- icon: z.ZodOptional<z.ZodString>;
244
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
245
+ order: z.ZodNumber;
245
246
  gallery: z.ZodOptional<z.ZodObject<{
246
247
  db: z.ZodObject<{
247
248
  tableName: z.ZodString;
@@ -257,7 +258,6 @@ export declare const categorySectionConfigSchema: z.ZodObject<{
257
258
  quality: z.ZodNumber;
258
259
  }, z.core.$strict>>;
259
260
  }, z.core.$strict>>;
260
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
261
261
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
262
262
  }, z.core.$strict>;
263
263
  export type CategorySectionOptions = z.infer<typeof optionsSchema>;
@@ -417,9 +417,9 @@ declare const optionsSchema: z.ZodObject<{
417
417
  }>>;
418
418
  generateQR: z.ZodOptional<z.ZodBoolean>;
419
419
  fields: z.ZodUnion<[z.ZodArray<z.ZodCustom<FieldConfig, FieldConfig>>, z.ZodArray<z.ZodCustom<FieldGroupConfig, FieldGroupConfig>>]>;
420
- name: z.ZodString;
421
420
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
422
- order: z.ZodNumber;
421
+ icon: z.ZodOptional<z.ZodString>;
422
+ name: z.ZodString;
423
423
  db: z.ZodObject<{
424
424
  table: z.ZodString;
425
425
  identifier: z.ZodOptional<z.ZodCustom<FieldConfig, FieldConfig>>;
@@ -443,7 +443,8 @@ declare const optionsSchema: z.ZodObject<{
443
443
  name: z.ZodOptional<z.ZodString>;
444
444
  }, z.core.$strict>>>;
445
445
  }, z.core.$strict>;
446
- icon: z.ZodOptional<z.ZodString>;
446
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
447
+ order: z.ZodNumber;
447
448
  gallery: z.ZodOptional<z.ZodObject<{
448
449
  db: z.ZodObject<{
449
450
  tableName: z.ZodString;
@@ -459,7 +460,6 @@ declare const optionsSchema: z.ZodObject<{
459
460
  quality: z.ZodNumber;
460
461
  }, z.core.$strict>>;
461
462
  }, z.core.$strict>>;
462
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
463
463
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
464
464
  }, z.core.$strict>;
465
465
  declare const hasItemsSectionConfigSchema: z.ZodObject<{
@@ -658,9 +658,9 @@ declare const hasItemsSectionConfigSchema: z.ZodObject<{
658
658
  adminGenerated?: boolean | "readonly" | undefined;
659
659
  }>>;
660
660
  generateQR: z.ZodOptional<z.ZodBoolean>;
661
- name: z.ZodString;
662
661
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
663
- order: z.ZodNumber;
662
+ icon: z.ZodOptional<z.ZodString>;
663
+ name: z.ZodString;
664
664
  db: z.ZodObject<{
665
665
  table: z.ZodString;
666
666
  identifier: z.ZodOptional<z.ZodCustom<FieldConfig, FieldConfig>>;
@@ -684,7 +684,8 @@ declare const hasItemsSectionConfigSchema: z.ZodObject<{
684
684
  name: z.ZodOptional<z.ZodString>;
685
685
  }, z.core.$strict>>>;
686
686
  }, z.core.$strict>;
687
- icon: z.ZodOptional<z.ZodString>;
687
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
688
+ order: z.ZodNumber;
688
689
  gallery: z.ZodOptional<z.ZodObject<{
689
690
  db: z.ZodObject<{
690
691
  tableName: z.ZodString;
@@ -700,7 +701,6 @@ declare const hasItemsSectionConfigSchema: z.ZodObject<{
700
701
  quality: z.ZodNumber;
701
702
  }, z.core.$strict>>;
702
703
  }, z.core.$strict>>;
703
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
704
704
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
705
705
  }, z.core.$strict>;
706
706
  export type HasItemsSectionOptions = z.infer<typeof optionsSchema>;
@@ -62,9 +62,9 @@ export declare const baseSectionOptionsSchema: z.ZodObject<{
62
62
  */
63
63
  export declare const baseHelperFunctionOptionsSchema: z.ZodObject<{
64
64
  fields: z.ZodUnion<[z.ZodArray<z.ZodCustom<FieldConfig, FieldConfig>>, z.ZodArray<z.ZodCustom<FieldGroupConfig, FieldGroupConfig>>]>;
65
- name: z.ZodString;
66
65
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
67
- order: z.ZodNumber;
66
+ icon: z.ZodOptional<z.ZodString>;
67
+ name: z.ZodString;
68
68
  db: z.ZodObject<{
69
69
  table: z.ZodString;
70
70
  identifier: z.ZodOptional<z.ZodCustom<FieldConfig, FieldConfig>>;
@@ -88,7 +88,8 @@ export declare const baseHelperFunctionOptionsSchema: z.ZodObject<{
88
88
  name: z.ZodOptional<z.ZodString>;
89
89
  }, z.core.$strict>>>;
90
90
  }, z.core.$strict>;
91
- icon: z.ZodOptional<z.ZodString>;
91
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<Variant, Variant>>>;
92
+ order: z.ZodNumber;
92
93
  gallery: z.ZodOptional<z.ZodObject<{
93
94
  db: z.ZodObject<{
94
95
  tableName: z.ZodString;
@@ -104,7 +105,6 @@ export declare const baseHelperFunctionOptionsSchema: z.ZodObject<{
104
105
  quality: z.ZodNumber;
105
106
  }, z.core.$strict>>;
106
107
  }, z.core.$strict>>;
107
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<Variant, Variant>>>;
108
108
  hooks: z.ZodOptional<z.ZodCustom<Hooks, Hooks>>;
109
109
  }, z.core.$strict>;
110
110
  export declare function validateSectionConfig(config: BaseSectionOptions): void;
@@ -23,10 +23,11 @@ declare const optionsSchema: z.ZodObject<{
23
23
  table: z.ZodString;
24
24
  }, z.core.$strict>;
25
25
  fields: z.ZodUnion<[z.ZodArray<z.ZodCustom<FieldConfig, FieldConfig>>, z.ZodArray<z.ZodCustom<FieldGroupConfig, FieldGroupConfig>>]>;
26
- name: z.ZodString;
27
26
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
28
- order: z.ZodNumber;
29
27
  icon: z.ZodOptional<z.ZodString>;
28
+ name: z.ZodString;
29
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
30
+ order: z.ZodNumber;
30
31
  gallery: z.ZodOptional<z.ZodObject<{
31
32
  db: z.ZodObject<{
32
33
  tableName: z.ZodString;
@@ -42,7 +43,6 @@ declare const optionsSchema: z.ZodObject<{
42
43
  quality: z.ZodNumber;
43
44
  }, z.core.$strict>>;
44
45
  }, z.core.$strict>>;
45
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
46
46
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
47
47
  }, z.core.$strict>;
48
48
  declare const simpleSectionConfigSchema: z.ZodObject<{
@@ -54,10 +54,11 @@ declare const simpleSectionConfigSchema: z.ZodObject<{
54
54
  db: z.ZodObject<{
55
55
  table: z.ZodString;
56
56
  }, z.core.$strict>;
57
- name: z.ZodString;
58
57
  readonly: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
59
- order: z.ZodNumber;
60
58
  icon: z.ZodOptional<z.ZodString>;
59
+ name: z.ZodString;
60
+ variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
61
+ order: z.ZodNumber;
61
62
  gallery: z.ZodOptional<z.ZodObject<{
62
63
  db: z.ZodObject<{
63
64
  tableName: z.ZodString;
@@ -73,7 +74,6 @@ declare const simpleSectionConfigSchema: z.ZodObject<{
73
74
  quality: z.ZodNumber;
74
75
  }, z.core.$strict>>;
75
76
  }, z.core.$strict>>;
76
- variants: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").Variant, import("../types/index.js").Variant>>>;
77
77
  hooks: z.ZodOptional<z.ZodCustom<import("./section.js").Hooks, import("./section.js").Hooks>>;
78
78
  }, z.core.$strict>;
79
79
  export type SimpleSectionOptions = z.infer<typeof optionsSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../../src/core/submit/submit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../../src/core/submit/submit.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@ import { MysqlTableChecker } from '../db';
7
7
  import { recordLog } from '../../logging/index.js';
8
8
  import getString from '../../translations';
9
9
  import { resolveLocalizedString } from '../../translations/localization.js';
10
+ import { resolveLocale } from '../../translations/locale-utils.js';
11
+ import { getCMSConfig } from '../config/index.js';
10
12
  export class Submit {
11
13
  static [entityKind] = 'Submit';
12
14
  user;
@@ -178,6 +180,14 @@ export class Submit {
178
180
  * Build the fields from the field configs
179
181
  */
180
182
  this._sectionInfo.buildFields();
183
+ /**
184
+ * Set locale for fields so validation errors are localized
185
+ */
186
+ const cmsConfig = await getCMSConfig();
187
+ const locale = resolveLocale(user.locale, cmsConfig.i18n.supportedLanguages, cmsConfig.i18n.fallbackLanguage);
188
+ for (const field of this._sectionInfo.fields) {
189
+ field.setLocale(locale, cmsConfig.i18n.fallbackLanguage);
190
+ }
181
191
  }
182
192
  /**
183
193
  * Perform post submit operations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextjs-cms",
3
- "version": "0.6.7",
3
+ "version": "0.6.8",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",
@@ -192,8 +192,8 @@
192
192
  "tsx": "^4.20.6",
193
193
  "typescript": "^5.9.2",
194
194
  "@lzcms/eslint-config": "0.3.0",
195
- "@lzcms/prettier-config": "0.1.0",
196
- "@lzcms/tsconfig": "0.1.0"
195
+ "@lzcms/tsconfig": "0.1.0",
196
+ "@lzcms/prettier-config": "0.1.0"
197
197
  },
198
198
  "license": "MIT",
199
199
  "keywords": [