nextjs-cms 0.6.7 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/config/config-loader.d.ts +4 -10
- package/dist/core/config/config-loader.d.ts.map +1 -1
- package/dist/core/config/config-loader.js +17 -16
- package/dist/core/factories/FieldFactory.d.ts.map +1 -1
- package/dist/core/factories/FieldFactory.js +8 -0
- package/dist/core/fields/color.js +2 -2
- package/dist/core/fields/date.js +2 -2
- package/dist/core/fields/document.js +13 -13
- package/dist/core/fields/field.d.ts +5 -1
- package/dist/core/fields/field.d.ts.map +1 -1
- package/dist/core/fields/field.js +12 -0
- package/dist/core/fields/map.js +2 -2
- package/dist/core/fields/number.js +7 -7
- package/dist/core/fields/password.js +4 -4
- package/dist/core/fields/photo.js +17 -17
- package/dist/core/fields/select.d.ts +1 -1
- package/dist/core/fields/select.js +2 -2
- package/dist/core/fields/slug.js +3 -3
- package/dist/core/fields/text.js +3 -3
- package/dist/core/fields/video.js +12 -12
- package/dist/core/sections/category.d.ts +34 -34
- package/dist/core/sections/hasItems.d.ts +34 -34
- package/dist/core/sections/section.d.ts +17 -17
- package/dist/core/sections/simple.d.ts +6 -6
- package/dist/core/submit/submit.d.ts.map +1 -1
- package/dist/core/submit/submit.js +10 -0
- package/dist/translations/client.d.ts +5178 -1
- package/dist/translations/client.d.ts.map +1 -1
- package/dist/translations/client.js +29 -4
- package/dist/translations/dict-store.d.ts +5 -1
- package/dist/translations/dict-store.d.ts.map +1 -1
- package/dist/translations/dict-store.js +30 -3
- package/dist/translations/index.d.ts +1 -1
- package/dist/translations/index.js +1 -1
- package/dist/translations/server.d.ts +5171 -1
- package/dist/translations/server.d.ts.map +1 -1
- package/dist/translations/server.js +26 -4
- package/package.json +1 -1
- package/dist/core/helpers/i18n.d.ts +0 -2
- package/dist/core/helpers/i18n.d.ts.map +0 -1
- package/dist/core/helpers/i18n.js +0 -3
- package/dist/core/localization.d.ts +0 -40
- package/dist/core/localization.d.ts.map +0 -1
- package/dist/core/localization.js +0 -48
- package/dist/logging/audit.d.ts +0 -20
- package/dist/logging/audit.d.ts.map +0 -1
- package/dist/logging/audit.js +0 -48
- package/dist/translations/localized-string.d.ts +0 -17
- package/dist/translations/localized-string.d.ts.map +0 -1
- package/dist/translations/localized-string.js +0 -32
- package/dist/translations/use-project-translation.d.ts +0 -19
- package/dist/translations/use-project-translation.d.ts.map +0 -1
- package/dist/translations/use-project-translation.js +0 -25
- package/dist/validators/types.d.ts +0 -7
- package/dist/validators/types.d.ts.map +0 -1
- package/dist/validators/types.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
import type { LocalizedString } from '../../translations/localization.js';
|
|
3
|
-
/** Locale codes for which we ship dictionaries
|
|
4
|
-
export declare const AVAILABLE_I18N_LOCALES: readonly ["en"
|
|
3
|
+
/** Locale codes for which we ship dictionaries in core. */
|
|
4
|
+
export declare const AVAILABLE_I18N_LOCALES: readonly ["en"];
|
|
5
5
|
export type AvailableLocale = (typeof AVAILABLE_I18N_LOCALES)[number];
|
|
6
6
|
declare const cmsConfigSchema: z.ZodObject<{
|
|
7
7
|
ui: z.ZodOptional<z.ZodObject<{
|
|
@@ -66,14 +66,8 @@ 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.
|
|
70
|
-
|
|
71
|
-
ar: "ar";
|
|
72
|
-
}>, z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
73
|
-
fallbackLanguage: z.ZodOptional<z.ZodEnum<{
|
|
74
|
-
en: "en";
|
|
75
|
-
ar: "ar";
|
|
76
|
-
}>>;
|
|
69
|
+
supportedLanguages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
70
|
+
fallbackLanguage: z.ZodOptional<z.ZodString>;
|
|
77
71
|
}, z.core.$strip>>;
|
|
78
72
|
dashboard: z.ZodOptional<z.ZodObject<{
|
|
79
73
|
override: z.ZodOptional<z.ZodString>;
|
|
@@ -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,
|
|
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,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,iBAAkB,CAAA;AAErD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAGrE,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8OnB,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;AA4KD;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
|
|
@@ -6,8 +6,8 @@ if (typeof window !== 'undefined') {
|
|
|
6
6
|
import * as z from 'zod';
|
|
7
7
|
import { loadConfigModule, getConfigImportVersion } from './loader.js';
|
|
8
8
|
import { setConfigDicts } from '../../translations/dict-store.js';
|
|
9
|
-
/** Locale codes for which we ship dictionaries
|
|
10
|
-
export const AVAILABLE_I18N_LOCALES = ['en'
|
|
9
|
+
/** Locale codes for which we ship dictionaries in core. */
|
|
10
|
+
export const AVAILABLE_I18N_LOCALES = ['en'];
|
|
11
11
|
// 1. Define config schema
|
|
12
12
|
const cmsConfigSchema = z.object({
|
|
13
13
|
/**
|
|
@@ -191,28 +191,31 @@ const cmsConfigSchema = z.object({
|
|
|
191
191
|
.optional(),
|
|
192
192
|
/**
|
|
193
193
|
* Interface (admin UI) i18n configuration.
|
|
194
|
-
* Import
|
|
195
|
-
*
|
|
194
|
+
* Import dictionaries (core provides `en`) and pass them as supportedLanguages.
|
|
195
|
+
* Keys are locale codes; only those locales are offered.
|
|
196
196
|
*/
|
|
197
197
|
i18n: z
|
|
198
198
|
.object({
|
|
199
199
|
/**
|
|
200
200
|
* Supported locales and their translation dictionaries.
|
|
201
|
-
*
|
|
202
|
-
*
|
|
201
|
+
* Core ships `en`; additional locales should be installed and imported by the app.
|
|
202
|
+
* Example: `{ en, ar }`, `{ en, fr }`, etc. Keys = locale codes offered in the dropdown.
|
|
203
|
+
* Dictionaries can be partial overrides; they are merged with the built-in defaults.
|
|
204
|
+
* English is always included by core as the base fallback locale.
|
|
205
|
+
* At least one locale is required.
|
|
203
206
|
*/
|
|
204
207
|
supportedLanguages: z
|
|
205
|
-
.record(z.
|
|
206
|
-
.
|
|
207
|
-
.refine((v) => v === undefined || Object.keys(v).length >= 1, {
|
|
208
|
+
.record(z.string(), z.record(z.string(), z.string()))
|
|
209
|
+
.refine((v) => Object.keys(v).length > 0, {
|
|
208
210
|
message: 'i18n.supportedLanguages must have at least one locale',
|
|
209
|
-
})
|
|
211
|
+
})
|
|
212
|
+
.optional(),
|
|
210
213
|
/**
|
|
211
214
|
* Fallback locale when the user's stored locale is not in supportedLanguages,
|
|
212
215
|
* or when no session exists (e.g. login page).
|
|
213
216
|
* @default 'en'
|
|
214
217
|
*/
|
|
215
|
-
fallbackLanguage: z.
|
|
218
|
+
fallbackLanguage: z.string().optional(),
|
|
216
219
|
})
|
|
217
220
|
.optional(),
|
|
218
221
|
/**
|
|
@@ -231,21 +234,19 @@ const cmsConfigSchema = z.object({
|
|
|
231
234
|
.optional(),
|
|
232
235
|
});
|
|
233
236
|
function normalizeI18n(userConfig) {
|
|
234
|
-
const available = new Set(AVAILABLE_I18N_LOCALES);
|
|
235
237
|
const fallback = userConfig.i18n?.fallbackLanguage ?? 'en';
|
|
236
238
|
const record = userConfig.i18n?.supportedLanguages;
|
|
237
239
|
let supported;
|
|
238
240
|
if (record && Object.keys(record).length >= 1) {
|
|
239
|
-
supported = Object.keys(record).filter((
|
|
240
|
-
if (supported.length === 0)
|
|
241
|
-
supported = ['en'];
|
|
241
|
+
supported = ['en', ...Object.keys(record).filter((locale) => locale !== 'en')];
|
|
242
242
|
setConfigDicts(record);
|
|
243
243
|
}
|
|
244
244
|
else {
|
|
245
245
|
supported = ['en'];
|
|
246
|
+
setConfigDicts({});
|
|
246
247
|
}
|
|
247
248
|
const supportedSet = new Set(supported);
|
|
248
|
-
const effectiveFallback = supportedSet.has(fallback) ? fallback :
|
|
249
|
+
const effectiveFallback = supportedSet.has(fallback) ? fallback : 'en';
|
|
249
250
|
return {
|
|
250
251
|
supportedLanguages: supported,
|
|
251
252
|
fallbackLanguage: effectiveFallback,
|
|
@@ -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;
|
|
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',
|
|
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',
|
|
57
|
+
throw new Error(getString('invalidColorPleaseProvideValidHex', this.locale));
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
package/dist/core/fields/date.js
CHANGED
|
@@ -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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
117
|
+
throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
|
|
118
118
|
}
|
|
119
119
|
if (!this._buffer) {
|
|
120
|
-
throw new Error(getString('bufferNotSet',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
|
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,
|
|
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
|
*/
|
package/dist/core/fields/map.js
CHANGED
|
@@ -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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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(`${
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
187
|
+
throw new Error(getString('folderNotSet', this.locale, { field: this.getLocalizedLabel() }));
|
|
188
188
|
}
|
|
189
189
|
if (!this._sharpImage) {
|
|
190
|
-
throw new Error(getString('imageNotSet',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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',
|
|
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>>;
|