nextjs-cms 0.7.1 → 0.7.3

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 (49) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +290 -290
  3. package/dist/api/index.d.ts +3 -3
  4. package/dist/api/lib/serverActions.d.ts +3 -3
  5. package/dist/api/root.d.ts +6 -6
  6. package/dist/api/routers/hasItemsSection.d.ts +2 -2
  7. package/dist/api/routers/simpleSection.d.ts +1 -1
  8. package/dist/cli/lib/db-config.js +10 -10
  9. package/dist/core/config/config-loader.d.ts +23 -3
  10. package/dist/core/config/config-loader.d.ts.map +1 -1
  11. package/dist/core/config/config-loader.js +32 -6
  12. package/dist/core/config/loader-with-jiti.d.ts.map +1 -1
  13. package/dist/core/config/loader-with-jiti.js +19 -15
  14. package/dist/core/db/table-checker/MysqlTable.js +8 -8
  15. package/dist/core/factories/section-factory-with-esbuild.d.ts.map +1 -1
  16. package/dist/core/factories/section-factory-with-esbuild.js +23 -9
  17. package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
  18. package/dist/core/factories/section-factory-with-jiti.js +51 -33
  19. package/dist/core/factories/section-name-validation.d.ts +10 -0
  20. package/dist/core/factories/section-name-validation.d.ts.map +1 -0
  21. package/dist/core/factories/section-name-validation.js +31 -0
  22. package/dist/core/fields/photo.d.ts +127 -85
  23. package/dist/core/fields/photo.d.ts.map +1 -1
  24. package/dist/core/fields/photo.js +83 -72
  25. package/dist/core/fields/richText.d.ts +9 -9
  26. package/dist/core/fields/select.d.ts +1 -1
  27. package/dist/core/sections/category.d.ts +42 -36
  28. package/dist/core/sections/category.d.ts.map +1 -1
  29. package/dist/core/sections/category.js +6 -1
  30. package/dist/core/sections/hasItems.d.ts +156 -54
  31. package/dist/core/sections/hasItems.d.ts.map +1 -1
  32. package/dist/core/sections/hasItems.js +6 -11
  33. package/dist/core/sections/section.d.ts +33 -20
  34. package/dist/core/sections/section.d.ts.map +1 -1
  35. package/dist/core/sections/section.js +37 -3
  36. package/dist/core/sections/simple.d.ts +14 -8
  37. package/dist/core/sections/simple.d.ts.map +1 -1
  38. package/dist/core/sections/simple.js +6 -1
  39. package/dist/core/submit/submit.js +1 -1
  40. package/dist/translations/client.d.ts.map +1 -1
  41. package/dist/translations/server.d.ts.map +1 -1
  42. package/dist/validators/photo.js +1 -1
  43. package/package.json +2 -1
  44. package/dist/translations/dictionaries/ar.d.ts +0 -433
  45. package/dist/translations/dictionaries/ar.d.ts.map +0 -1
  46. package/dist/translations/dictionaries/ar.js +0 -444
  47. package/dist/translations/dictionaries/en.d.ts +0 -433
  48. package/dist/translations/dictionaries/en.d.ts.map +0 -1
  49. package/dist/translations/dictionaries/en.js +0 -444
@@ -2,29 +2,54 @@ import type { BaseFieldConfig } from './field.js';
2
2
  import { entityKind } from '../helpers/index.js';
3
3
  import * as z from 'zod';
4
4
  import { FileField } from './fileField.js';
5
+ declare const sizeSchema: z.ZodUnion<readonly [z.ZodObject<{
6
+ width: z.ZodNumber;
7
+ height: z.ZodNumber;
8
+ strict: z.ZodLiteral<true>;
9
+ quality: z.ZodOptional<z.ZodNumber>;
10
+ }, z.core.$strict>, z.ZodDiscriminatedUnion<[z.ZodObject<{
11
+ width: z.ZodNumber;
12
+ height: z.ZodNumber;
13
+ fit: z.ZodLiteral<"cover">;
14
+ quality: z.ZodOptional<z.ZodNumber>;
15
+ }, z.core.$strict>, z.ZodObject<{
16
+ width: z.ZodNumber;
17
+ height: z.ZodNumber;
18
+ fit: z.ZodLiteral<"contain">;
19
+ quality: z.ZodOptional<z.ZodNumber>;
20
+ /**
21
+ * Background color for padding.
22
+ * Falls back to CMS config media.images.background if not provided.
23
+ */
24
+ background: z.ZodOptional<z.ZodObject<{
25
+ r: z.ZodNumber;
26
+ g: z.ZodNumber;
27
+ b: z.ZodNumber;
28
+ alpha: z.ZodNumber;
29
+ }, z.core.$strict>>;
30
+ }, z.core.$strict>], "fit">]>;
31
+ type SizeConfig = z.infer<typeof sizeSchema>;
5
32
  declare const configSchema: z.ZodObject<{
6
33
  /** Whether to add watermark to images */
7
34
  watermark: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
8
35
  blurPlaceholder: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
9
- size: z.ZodOptional<z.ZodObject<{
36
+ size: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
10
37
  width: z.ZodNumber;
11
38
  height: z.ZodNumber;
39
+ strict: z.ZodLiteral<true>;
40
+ quality: z.ZodOptional<z.ZodNumber>;
41
+ }, z.core.$strict>, z.ZodDiscriminatedUnion<[z.ZodObject<{
42
+ width: z.ZodNumber;
43
+ height: z.ZodNumber;
44
+ fit: z.ZodLiteral<"cover">;
45
+ quality: z.ZodOptional<z.ZodNumber>;
46
+ }, z.core.$strict>, z.ZodObject<{
47
+ width: z.ZodNumber;
48
+ height: z.ZodNumber;
49
+ fit: z.ZodLiteral<"contain">;
50
+ quality: z.ZodOptional<z.ZodNumber>;
12
51
  /**
13
- * @true The image will not have dimensions constraints,
14
- * and will be cropped to fit the specified dimensions
15
- *
16
- * @false The user will be forced to upload an image with the specified dimensions
17
- *
18
- * @example
19
- * size: {
20
- * width: 1200,
21
- * height: 450,
22
- * crop: true, // No constraints
23
- * }
24
- */
25
- crop: z.ZodBoolean;
26
- /**
27
- * Background color for padding when crop is false.
52
+ * Background color for padding.
28
53
  * Falls back to CMS config media.images.background if not provided.
29
54
  */
30
55
  background: z.ZodOptional<z.ZodObject<{
@@ -33,14 +58,19 @@ declare const configSchema: z.ZodObject<{
33
58
  b: z.ZodNumber;
34
59
  alpha: z.ZodNumber;
35
60
  }, z.core.$strict>>;
36
- }, z.core.$strict>>;
37
- thumbnail: z.ZodOptional<z.ZodObject<{
61
+ }, z.core.$strict>], "fit">]>>;
62
+ thumbnail: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
63
+ width: z.ZodNumber;
64
+ height: z.ZodNumber;
65
+ fit: z.ZodLiteral<"cover">;
66
+ quality: z.ZodOptional<z.ZodNumber>;
67
+ }, z.core.$strict>, z.ZodObject<{
38
68
  width: z.ZodNumber;
39
69
  height: z.ZodNumber;
40
- crop: z.ZodBoolean;
70
+ fit: z.ZodLiteral<"contain">;
41
71
  quality: z.ZodOptional<z.ZodNumber>;
42
72
  /**
43
- * Background color for padding when crop is false.
73
+ * Background color for padding.
44
74
  * Falls back to CMS config media.images.background if not provided.
45
75
  */
46
76
  background: z.ZodOptional<z.ZodObject<{
@@ -49,7 +79,7 @@ declare const configSchema: z.ZodObject<{
49
79
  b: z.ZodNumber;
50
80
  alpha: z.ZodNumber;
51
81
  }, z.core.$strict>>;
52
- }, z.core.$strict>>;
82
+ }, z.core.$strict>], "fit">>;
53
83
  /**
54
84
  * Maximum file size
55
85
  * @example
@@ -74,10 +104,10 @@ declare const configSchema: z.ZodObject<{
74
104
  * @hint 'jpg' is an alias for 'jpeg'
75
105
  */
76
106
  fileType: z.ZodOptional<z.ZodArray<z.ZodEnum<{
77
- webp: "webp";
78
- jpg: "jpg";
79
107
  jpeg: "jpeg";
108
+ jpg: "jpg";
80
109
  png: "png";
110
+ webp: "webp";
81
111
  }>>>;
82
112
  /**
83
113
  * Remove the extension from the file name
@@ -90,17 +120,7 @@ export declare class PhotoField extends FileField<'photo', Config> {
90
120
  static readonly [entityKind]: string;
91
121
  readonly watermark: boolean | null | undefined;
92
122
  readonly blurPlaceholder: boolean | null | undefined;
93
- readonly size: {
94
- width: number;
95
- height: number;
96
- crop: boolean;
97
- background?: {
98
- r: number;
99
- g: number;
100
- b: number;
101
- alpha: number;
102
- };
103
- } | undefined;
123
+ readonly size: SizeConfig | undefined;
104
124
  readonly maxFileSize: {
105
125
  size: number;
106
126
  unit: 'kb' | 'mb';
@@ -131,25 +151,41 @@ export declare class PhotoField extends FileField<'photo', Config> {
131
151
  thumbnail: {
132
152
  width: number;
133
153
  height: number;
134
- crop: boolean;
135
- quality?: number;
154
+ fit: "cover";
155
+ quality?: number | undefined;
156
+ } | {
157
+ width: number;
158
+ height: number;
159
+ fit: "contain";
160
+ quality?: number | undefined;
136
161
  background?: {
137
162
  r: number;
138
163
  g: number;
139
164
  b: number;
140
165
  alpha: number;
141
- };
166
+ } | undefined;
142
167
  };
143
168
  size: {
144
169
  width: number;
145
170
  height: number;
146
- crop: boolean;
171
+ fit: "cover";
172
+ quality?: number | undefined;
173
+ } | {
174
+ width: number;
175
+ height: number;
176
+ fit: "contain";
177
+ quality?: number | undefined;
147
178
  background?: {
148
179
  r: number;
149
180
  g: number;
150
181
  b: number;
151
182
  alpha: number;
152
- };
183
+ } | undefined;
184
+ } | {
185
+ width: number;
186
+ height: number;
187
+ strict: true;
188
+ quality?: number | undefined;
153
189
  } | undefined;
154
190
  maxFileSize: {
155
191
  size: number;
@@ -191,25 +227,23 @@ declare const optionsSchema: z.ZodObject<{
191
227
  /** Whether to add watermark to images */
192
228
  watermark: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
193
229
  blurPlaceholder: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
194
- size: z.ZodOptional<z.ZodObject<{
230
+ size: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
195
231
  width: z.ZodNumber;
196
232
  height: z.ZodNumber;
233
+ strict: z.ZodLiteral<true>;
234
+ quality: z.ZodOptional<z.ZodNumber>;
235
+ }, z.core.$strict>, z.ZodDiscriminatedUnion<[z.ZodObject<{
236
+ width: z.ZodNumber;
237
+ height: z.ZodNumber;
238
+ fit: z.ZodLiteral<"cover">;
239
+ quality: z.ZodOptional<z.ZodNumber>;
240
+ }, z.core.$strict>, z.ZodObject<{
241
+ width: z.ZodNumber;
242
+ height: z.ZodNumber;
243
+ fit: z.ZodLiteral<"contain">;
244
+ quality: z.ZodOptional<z.ZodNumber>;
197
245
  /**
198
- * @true The image will not have dimensions constraints,
199
- * and will be cropped to fit the specified dimensions
200
- *
201
- * @false The user will be forced to upload an image with the specified dimensions
202
- *
203
- * @example
204
- * size: {
205
- * width: 1200,
206
- * height: 450,
207
- * crop: true, // No constraints
208
- * }
209
- */
210
- crop: z.ZodBoolean;
211
- /**
212
- * Background color for padding when crop is false.
246
+ * Background color for padding.
213
247
  * Falls back to CMS config media.images.background if not provided.
214
248
  */
215
249
  background: z.ZodOptional<z.ZodObject<{
@@ -218,14 +252,19 @@ declare const optionsSchema: z.ZodObject<{
218
252
  b: z.ZodNumber;
219
253
  alpha: z.ZodNumber;
220
254
  }, z.core.$strict>>;
221
- }, z.core.$strict>>;
222
- thumbnail: z.ZodOptional<z.ZodObject<{
255
+ }, z.core.$strict>], "fit">]>>;
256
+ thumbnail: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
257
+ width: z.ZodNumber;
258
+ height: z.ZodNumber;
259
+ fit: z.ZodLiteral<"cover">;
260
+ quality: z.ZodOptional<z.ZodNumber>;
261
+ }, z.core.$strict>, z.ZodObject<{
223
262
  width: z.ZodNumber;
224
263
  height: z.ZodNumber;
225
- crop: z.ZodBoolean;
264
+ fit: z.ZodLiteral<"contain">;
226
265
  quality: z.ZodOptional<z.ZodNumber>;
227
266
  /**
228
- * Background color for padding when crop is false.
267
+ * Background color for padding.
229
268
  * Falls back to CMS config media.images.background if not provided.
230
269
  */
231
270
  background: z.ZodOptional<z.ZodObject<{
@@ -234,7 +273,7 @@ declare const optionsSchema: z.ZodObject<{
234
273
  b: z.ZodNumber;
235
274
  alpha: z.ZodNumber;
236
275
  }, z.core.$strict>>;
237
- }, z.core.$strict>>;
276
+ }, z.core.$strict>], "fit">>;
238
277
  /**
239
278
  * Maximum file size
240
279
  * @example
@@ -259,10 +298,10 @@ declare const optionsSchema: z.ZodObject<{
259
298
  * @hint 'jpg' is an alias for 'jpeg'
260
299
  */
261
300
  fileType: z.ZodOptional<z.ZodArray<z.ZodEnum<{
262
- webp: "webp";
263
- jpg: "jpg";
264
301
  jpeg: "jpeg";
302
+ jpg: "jpg";
265
303
  png: "png";
304
+ webp: "webp";
266
305
  }>>>;
267
306
  /**
268
307
  * Remove the extension from the file name
@@ -283,25 +322,23 @@ declare const photoFieldConfigSchema: z.ZodObject<{
283
322
  /** Whether to add watermark to images */
284
323
  watermark: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
285
324
  blurPlaceholder: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
286
- size: z.ZodOptional<z.ZodObject<{
325
+ size: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
287
326
  width: z.ZodNumber;
288
327
  height: z.ZodNumber;
328
+ strict: z.ZodLiteral<true>;
329
+ quality: z.ZodOptional<z.ZodNumber>;
330
+ }, z.core.$strict>, z.ZodDiscriminatedUnion<[z.ZodObject<{
331
+ width: z.ZodNumber;
332
+ height: z.ZodNumber;
333
+ fit: z.ZodLiteral<"cover">;
334
+ quality: z.ZodOptional<z.ZodNumber>;
335
+ }, z.core.$strict>, z.ZodObject<{
336
+ width: z.ZodNumber;
337
+ height: z.ZodNumber;
338
+ fit: z.ZodLiteral<"contain">;
339
+ quality: z.ZodOptional<z.ZodNumber>;
289
340
  /**
290
- * @true The image will not have dimensions constraints,
291
- * and will be cropped to fit the specified dimensions
292
- *
293
- * @false The user will be forced to upload an image with the specified dimensions
294
- *
295
- * @example
296
- * size: {
297
- * width: 1200,
298
- * height: 450,
299
- * crop: true, // No constraints
300
- * }
301
- */
302
- crop: z.ZodBoolean;
303
- /**
304
- * Background color for padding when crop is false.
341
+ * Background color for padding.
305
342
  * Falls back to CMS config media.images.background if not provided.
306
343
  */
307
344
  background: z.ZodOptional<z.ZodObject<{
@@ -310,14 +347,19 @@ declare const photoFieldConfigSchema: z.ZodObject<{
310
347
  b: z.ZodNumber;
311
348
  alpha: z.ZodNumber;
312
349
  }, z.core.$strict>>;
313
- }, z.core.$strict>>;
314
- thumbnail: z.ZodOptional<z.ZodObject<{
350
+ }, z.core.$strict>], "fit">]>>;
351
+ thumbnail: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
315
352
  width: z.ZodNumber;
316
353
  height: z.ZodNumber;
317
- crop: z.ZodBoolean;
354
+ fit: z.ZodLiteral<"cover">;
355
+ quality: z.ZodOptional<z.ZodNumber>;
356
+ }, z.core.$strict>, z.ZodObject<{
357
+ width: z.ZodNumber;
358
+ height: z.ZodNumber;
359
+ fit: z.ZodLiteral<"contain">;
318
360
  quality: z.ZodOptional<z.ZodNumber>;
319
361
  /**
320
- * Background color for padding when crop is false.
362
+ * Background color for padding.
321
363
  * Falls back to CMS config media.images.background if not provided.
322
364
  */
323
365
  background: z.ZodOptional<z.ZodObject<{
@@ -326,7 +368,7 @@ declare const photoFieldConfigSchema: z.ZodObject<{
326
368
  b: z.ZodNumber;
327
369
  alpha: z.ZodNumber;
328
370
  }, z.core.$strict>>;
329
- }, z.core.$strict>>;
371
+ }, z.core.$strict>], "fit">>;
330
372
  /**
331
373
  * Maximum file size
332
374
  * @example
@@ -351,10 +393,10 @@ declare const photoFieldConfigSchema: z.ZodObject<{
351
393
  * @hint 'jpg' is an alias for 'jpeg'
352
394
  */
353
395
  fileType: z.ZodOptional<z.ZodArray<z.ZodEnum<{
354
- webp: "webp";
355
- jpg: "jpg";
356
396
  jpeg: "jpeg";
397
+ jpg: "jpg";
357
398
  png: "png";
399
+ webp: "webp";
358
400
  }>>>;
359
401
  /**
360
402
  * Remove the extension from the file name
@@ -1 +1 @@
1
- {"version":3,"file":"photo.d.ts","sourceRoot":"","sources":["../../../src/core/fields/photo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"photo.d.ts","sourceRoot":"","sources":["../../../src/core/fields/photo.ts"],"names":[],"mappings":"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"}
@@ -16,41 +16,61 @@ const backgroundSchema = z
16
16
  b: z.number().min(0).max(255).describe('Blue channel (0-255)'),
17
17
  alpha: z.number().min(0).max(1).describe('Alpha channel (0-1)'),
18
18
  })
19
- .describe('Background color for image padding (used when crop is false)');
20
- const sizeSchema = z.strictObject({
19
+ .describe('Background color for image padding (used with fit: contain)');
20
+ /**
21
+ * Size schema — discriminated union of three variants:
22
+ * - strict: true — user must upload exact dimensions, no server resize
23
+ * - fit: 'cover' — accept any dimensions, crop to fill (sharp fit: cover)
24
+ * - fit: 'contain' — accept any dimensions, pad with background (sharp fit: contain)
25
+ */
26
+ const strictSizeSchema = z.strictObject({
21
27
  width: z.number().describe('Image width in pixels'),
22
28
  height: z.number().describe('Image height in pixels'),
23
- /**
24
- * @true The image will not have dimensions constraints,
25
- * and will be cropped to fit the specified dimensions
26
- *
27
- * @false The user will be forced to upload an image with the specified dimensions
28
- *
29
- * @example
30
- * size: {
31
- * width: 1200,
32
- * height: 450,
33
- * crop: true, // No constraints
34
- * }
35
- */
36
- crop: z.boolean().describe('Whether to crop the image to fit dimensions'),
37
- /**
38
- * Background color for padding when crop is false.
39
- * Falls back to CMS config media.images.background if not provided.
40
- */
41
- background: backgroundSchema.optional().describe('Background color for padding when not cropping'),
29
+ strict: z.literal(true).describe('Require exact upload dimensions, no server resize'),
30
+ quality: z.number().min(1).max(100).optional().describe('Output quality (1-100)'),
31
+ });
32
+ const coverSizeSchema = z.strictObject({
33
+ width: z.number().describe('Image width in pixels'),
34
+ height: z.number().describe('Image height in pixels'),
35
+ fit: z.literal('cover').describe('Crop to fill dimensions (sharp fit: cover)'),
36
+ quality: z.number().min(1).max(100).optional().describe('Output quality (1-100)'),
42
37
  });
43
- const thumbnailSchema = z.strictObject({
44
- width: z.number().describe('Thumbnail width in pixels'),
45
- height: z.number().describe('Thumbnail height in pixels'),
46
- crop: z.boolean().describe('Whether to crop the thumbnail'),
47
- quality: z.number().optional().describe('Thumbnail quality (0-100)'),
38
+ const containSizeSchema = z.strictObject({
39
+ width: z.number().describe('Image width in pixels'),
40
+ height: z.number().describe('Image height in pixels'),
41
+ fit: z.literal('contain').describe('Pad with background to fill dimensions (sharp fit: contain)'),
42
+ quality: z.number().min(1).max(100).optional().describe('Output quality (1-100)'),
48
43
  /**
49
- * Background color for padding when crop is false.
44
+ * Background color for padding.
50
45
  * Falls back to CMS config media.images.background if not provided.
51
46
  */
52
- background: backgroundSchema.optional().describe('Background color for padding when not cropping'),
47
+ background: backgroundSchema.optional().describe('Background color for padding'),
53
48
  });
49
+ const sizeSchema = z.union([strictSizeSchema, z.discriminatedUnion('fit', [coverSizeSchema, containSizeSchema])]);
50
+ /**
51
+ * Thumbnail schema — discriminated union:
52
+ * - fit: 'cover' — crop thumbnail to fill
53
+ * - fit: 'contain' — pad thumbnail with background
54
+ */
55
+ const thumbnailSchema = z.discriminatedUnion('fit', [
56
+ z.strictObject({
57
+ width: z.number().describe('Thumbnail width in pixels'),
58
+ height: z.number().describe('Thumbnail height in pixels'),
59
+ fit: z.literal('cover').describe('Crop thumbnail to fill'),
60
+ quality: z.number().min(1).max(100).optional().describe('Thumbnail quality (1-100)'),
61
+ }),
62
+ z.strictObject({
63
+ width: z.number().describe('Thumbnail width in pixels'),
64
+ height: z.number().describe('Thumbnail height in pixels'),
65
+ fit: z.literal('contain').describe('Pad thumbnail with background'),
66
+ quality: z.number().min(1).max(100).optional().describe('Thumbnail quality (1-100)'),
67
+ /**
68
+ * Background color for padding.
69
+ * Falls back to CMS config media.images.background if not provided.
70
+ */
71
+ background: backgroundSchema.optional().describe('Background color for padding'),
72
+ }),
73
+ ]);
54
74
  const maxFileSizeSchema = z.strictObject({
55
75
  size: z.number().describe('Maximum file size'),
56
76
  unit: z.enum(['kb', 'mb']).describe('Size unit'),
@@ -152,9 +172,13 @@ export class PhotoField extends FileField {
152
172
  this._thumbnail = this._thumbnailConfig;
153
173
  }
154
174
  else {
155
- // Always fetch fresh CMS config (getCMSConfig() is already cached with version checking)
175
+ // Fetch CMS config and construct a ThumbnailConfig from it
156
176
  const cmsConfig = await getCMSConfig();
157
- this._thumbnail = cmsConfig.media.images.thumbnail;
177
+ const t = cmsConfig.media.images.thumbnail;
178
+ const fit = t.fit ?? 'contain';
179
+ this._thumbnail = fit === 'contain'
180
+ ? { width: t.width, height: t.height, fit: 'contain', quality: t.quality }
181
+ : { width: t.width, height: t.height, fit: 'cover', quality: t.quality };
158
182
  }
159
183
  return this._thumbnail;
160
184
  }
@@ -206,55 +230,53 @@ export class PhotoField extends FileField {
206
230
  fs.mkdirSync(thumbsFolder, { recursive: true });
207
231
  }
208
232
  /**
209
- * Check if the image needs to be resized and write the file to disk
210
- * - crop: true -> fit: 'cover' (crops to fill dimensions)
211
- * - crop: false -> fit: 'contain' with background (preserves all content, adds padding)
233
+ * Write the main image to disk
234
+ * - strict: true -> no resize, just convert to webp
235
+ * - fit: 'cover' -> crop to fill dimensions
236
+ * - fit: 'contain' -> pad with background to fill dimensions
212
237
  */
238
+ const cmsImageQuality = cmsConfig.media.images.image.quality ?? 80;
213
239
  if (this.size) {
214
- if (this.size.crop) {
215
- // Crop mode: use 'cover' to fill dimensions by cropping excess
240
+ const quality = this.size.quality ?? cmsImageQuality;
241
+ const outputPath = path.join(uploadsFolder, '.photos', this._folder, this.value);
242
+ if ('strict' in this.size) {
243
+ // Strict mode: exact dimensions already validated, just convert to webp
244
+ await this._sharpImage.clone().webp({ quality }).toFile(outputPath);
245
+ }
246
+ else if (this.size.fit === 'cover') {
216
247
  await this._sharpImage
217
248
  .clone()
218
- .resize({
219
- width: this.size.width,
220
- height: this.size.height,
221
- fit: 'cover',
222
- })
223
- .webp()
224
- .toFile(path.join(uploadsFolder, '.photos', this._folder, this.value));
249
+ .resize({ width: this.size.width, height: this.size.height, fit: 'cover' })
250
+ .webp({ quality })
251
+ .toFile(outputPath);
225
252
  }
226
253
  else {
227
- // Contain mode: preserve all content with background padding
228
- // Use field-level background, fall back to CMS config background
254
+ // contain: pad with background
255
+ const background = this.size.background ?? cmsBackground;
229
256
  await this._sharpImage
230
257
  .clone()
231
- .resize({
232
- width: this.size.width,
233
- height: this.size.height,
234
- fit: 'contain',
235
- background: this.size.background ?? cmsBackground,
236
- })
237
- .webp()
238
- .toFile(path.join(uploadsFolder, '.photos', this._folder, this.value));
258
+ .resize({ width: this.size.width, height: this.size.height, fit: 'contain', background })
259
+ .webp({ quality })
260
+ .toFile(outputPath);
239
261
  }
240
262
  }
241
263
  else {
242
264
  await this._sharpImage.clone().toFile(path.join(uploadsFolder, '.photos', this._folder, this.value));
243
265
  }
244
266
  /**
245
- * Also, write a thumbnail
246
- * Use CMS config background for padding when crop is false
267
+ * Write a thumbnail
247
268
  */
269
+ const thumbBackground = ('background' in thumbnail ? thumbnail.background : undefined) ?? cmsBackground;
248
270
  await this._sharpImage
249
271
  .clone()
250
272
  .resize({
251
273
  width: thumbnail.width,
252
274
  height: thumbnail.height,
253
- fit: thumbnail.crop ? 'cover' : 'contain',
254
- background: thumbnail.background ?? cmsBackground,
275
+ fit: thumbnail.fit,
276
+ ...(thumbnail.fit === 'contain' ? { background: thumbBackground } : {}),
255
277
  })
256
278
  .webp({
257
- quality: thumbnail.quality ?? 80,
279
+ quality: thumbnail.quality ?? cmsImageQuality,
258
280
  })
259
281
  .toFile(path.join(uploadsFolder, '.thumbs', this._folder, this.value));
260
282
  }
@@ -416,22 +438,11 @@ export class PhotoField extends FileField {
416
438
  throw new Error(getString('fileCorrupted', this.locale));
417
439
  }
418
440
  /**
419
- * Check the size
441
+ * Check the size — only enforce exact dimensions when strict mode is set
420
442
  */
421
- if (this.size) {
422
- /**
423
- * Check if the image does not need to be cropped (dimensions are constrained)
424
- */
425
- if (!this.size.crop) {
426
- /**
427
- * Just resize the image?
428
- */
429
- /**
430
- * Check if the size matches the required size
431
- */
432
- if (metadata.width !== this.size.width || metadata.height !== 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
- }
443
+ if (this.size && 'strict' in this.size) {
444
+ if (metadata.width !== this.size.width || metadata.height !== this.size.height) {
445
+ throw new Error(getString('imageDimensionMismatchDetailed', this.locale, { field: this.getLocalizedLabel(), actual: `${metadata.width}x${metadata.height}`, required: `${this.size.width}x${this.size.height}` }));
435
446
  }
436
447
  }
437
448
  /**
@@ -31,10 +31,10 @@ declare const allowImageUploadsSchema: z.ZodObject<{
31
31
  */
32
32
  omitExtension: z.ZodOptional<z.ZodBoolean>;
33
33
  format: z.ZodOptional<z.ZodEnum<{
34
- webp: "webp";
35
- jpg: "jpg";
36
34
  jpeg: "jpeg";
35
+ jpg: "jpg";
37
36
  png: "png";
37
+ webp: "webp";
38
38
  }>>;
39
39
  }, z.core.$strict>;
40
40
  declare const configSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -72,10 +72,10 @@ declare const configSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
72
72
  */
73
73
  omitExtension: z.ZodOptional<z.ZodBoolean>;
74
74
  format: z.ZodOptional<z.ZodEnum<{
75
- webp: "webp";
76
- jpg: "jpg";
77
75
  jpeg: "jpeg";
76
+ jpg: "jpg";
78
77
  png: "png";
78
+ webp: "webp";
79
79
  }>>;
80
80
  }, z.core.$strict>>;
81
81
  }, z.core.$strict>, z.ZodObject<{
@@ -118,7 +118,7 @@ export declare class RichTextField extends Field<'rich_text', Config> {
118
118
  } | undefined;
119
119
  handleMethod?: "base64" | "tempSave" | undefined;
120
120
  omitExtension?: boolean | undefined;
121
- format?: "webp" | "jpg" | "jpeg" | "png" | undefined;
121
+ format?: "jpeg" | "jpg" | "png" | "webp" | undefined;
122
122
  };
123
123
  sanitize: boolean;
124
124
  type: "rich_text";
@@ -186,10 +186,10 @@ declare const optionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
186
186
  */
187
187
  omitExtension: z.ZodOptional<z.ZodBoolean>;
188
188
  format: z.ZodOptional<z.ZodEnum<{
189
- webp: "webp";
190
- jpg: "jpg";
191
189
  jpeg: "jpeg";
190
+ jpg: "jpg";
192
191
  png: "png";
192
+ webp: "webp";
193
193
  }>>;
194
194
  }, z.core.$strict>>;
195
195
  name: z.ZodString;
@@ -248,10 +248,10 @@ declare const richTextFieldConfigSchema: z.ZodIntersection<z.ZodDiscriminatedUni
248
248
  */
249
249
  omitExtension: z.ZodOptional<z.ZodBoolean>;
250
250
  format: z.ZodOptional<z.ZodEnum<{
251
- webp: "webp";
252
- jpg: "jpg";
253
251
  jpeg: "jpeg";
252
+ jpg: "jpg";
254
253
  png: "png";
254
+ webp: "webp";
255
255
  }>>;
256
256
  }, z.core.$strict>>;
257
257
  name: z.ZodString;
@@ -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
- section: "section";
350
349
  db: "db";
350
+ section: "section";
351
351
  static: "static";
352
352
  }>;
353
353
  build: z.ZodFunction<z.core.$ZodFunctionArgs, z.ZodCustom<SelectField, SelectField>>;