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.
- package/LICENSE +21 -21
- package/README.md +290 -290
- package/dist/api/index.d.ts +3 -3
- package/dist/api/lib/serverActions.d.ts +3 -3
- package/dist/api/root.d.ts +6 -6
- package/dist/api/routers/hasItemsSection.d.ts +2 -2
- package/dist/api/routers/simpleSection.d.ts +1 -1
- package/dist/cli/lib/db-config.js +10 -10
- package/dist/core/config/config-loader.d.ts +23 -3
- package/dist/core/config/config-loader.d.ts.map +1 -1
- package/dist/core/config/config-loader.js +32 -6
- package/dist/core/config/loader-with-jiti.d.ts.map +1 -1
- package/dist/core/config/loader-with-jiti.js +19 -15
- package/dist/core/db/table-checker/MysqlTable.js +8 -8
- package/dist/core/factories/section-factory-with-esbuild.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-esbuild.js +23 -9
- package/dist/core/factories/section-factory-with-jiti.d.ts.map +1 -1
- package/dist/core/factories/section-factory-with-jiti.js +51 -33
- package/dist/core/factories/section-name-validation.d.ts +10 -0
- package/dist/core/factories/section-name-validation.d.ts.map +1 -0
- package/dist/core/factories/section-name-validation.js +31 -0
- package/dist/core/fields/photo.d.ts +127 -85
- package/dist/core/fields/photo.d.ts.map +1 -1
- package/dist/core/fields/photo.js +83 -72
- package/dist/core/fields/richText.d.ts +9 -9
- package/dist/core/fields/select.d.ts +1 -1
- package/dist/core/sections/category.d.ts +42 -36
- package/dist/core/sections/category.d.ts.map +1 -1
- package/dist/core/sections/category.js +6 -1
- package/dist/core/sections/hasItems.d.ts +156 -54
- package/dist/core/sections/hasItems.d.ts.map +1 -1
- package/dist/core/sections/hasItems.js +6 -11
- package/dist/core/sections/section.d.ts +33 -20
- package/dist/core/sections/section.d.ts.map +1 -1
- package/dist/core/sections/section.js +37 -3
- package/dist/core/sections/simple.d.ts +14 -8
- package/dist/core/sections/simple.d.ts.map +1 -1
- package/dist/core/sections/simple.js +6 -1
- package/dist/core/submit/submit.js +1 -1
- package/dist/translations/client.d.ts.map +1 -1
- package/dist/translations/server.d.ts.map +1 -1
- package/dist/validators/photo.js +1 -1
- package/package.json +2 -1
- package/dist/translations/dictionaries/ar.d.ts +0 -433
- package/dist/translations/dictionaries/ar.d.ts.map +0 -1
- package/dist/translations/dictionaries/ar.js +0 -444
- package/dist/translations/dictionaries/en.d.ts +0 -433
- package/dist/translations/dictionaries/en.d.ts.map +0 -1
- 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
|
-
*
|
|
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
|
-
|
|
70
|
+
fit: z.ZodLiteral<"contain">;
|
|
41
71
|
quality: z.ZodOptional<z.ZodNumber>;
|
|
42
72
|
/**
|
|
43
|
-
* Background color for padding
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
264
|
+
fit: z.ZodLiteral<"contain">;
|
|
226
265
|
quality: z.ZodOptional<z.ZodNumber>;
|
|
227
266
|
/**
|
|
228
|
-
* Background color for padding
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAKxB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"photo.d.ts","sourceRoot":"","sources":["../../../src/core/fields/photo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAKxB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AA8C1C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;IAPZ;;;OAGG;;;;;;;6BAI0G,CAAA;AAEjH,KAAK,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAkC5C,QAAA,MAAM,YAAY;IACd,yCAAyC;;;;;;;;;;;;;;;;;;QA5CzC;;;WAGG;;;;;;;;;;;;;;;;;;QAyBC;;;WAGG;;;;;;;;IAkBP;;;;;;;OAOG;;;;;;;;IAEH;;;;;;;OAOG;;;;;;;IAEH;;;OAGG;;kBAEL,CAAA;AAEF,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAE1C,qBAAa,UAAW,SAAQ,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IACtD,gBAAyB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAe;IAC5D,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;IAC9C,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;IACpD,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;KAAE,CAAA;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;IAC7B,OAAO,CAAC,UAAU,CAAyC;IAC3D,yFAAyF;IACzF,OAAO,CAAC,gBAAgB,CAAyC;IACjE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IAEjC;;;OAGG;IACH,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,kBAAkB,CAAU;gBAExB,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI;IAoCxD;;;;OAIG;YACW,YAAY;IAiBX,KAAK;IAOJ,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAlFD,MAAM;kBAAQ,IAAI,GAAG,IAAI;;;;;;;;;;;;;IAkGvD;;OAEG;IACG,WAAW;IA+EK,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAcnC,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpG;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIX,WAAW,CAAC,KAAK,EAAE,MAAM;IAIvB,QAAQ,CAAC,KAAK,EAAE,GAAG;IAQ5B,OAAO,CAAC,IAAI,EAAE,IAAI;IAKlB,aAAa;IAab;;OAEG;IACG,oBAAoB;CAyI7B;AAED,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAE9E,QAAA,MAAM,aAAa;IAzaf,yCAAyC;;;;;;;;;;;;;;;;;;QA5CzC;;;WAGG;;;;;;;;;;;;;;;;;;QAyBC;;;WAGG;;;;;;;;IAkBP;;;;;;;OAOG;;;;;;;;IAEH;;;;;;;OAOG;;;;;;;IAEH;;;OAGG;;;;;;;;;kBAkZL,CAAA;AAEF,QAAA,MAAM,sBAAsB;;;IA9axB,yCAAyC;;;;;;;;;;;;;;;;;;QA5CzC;;;WAGG;;;;;;;;;;;;;;;;;;QAyBC;;;WAGG;;;;;;;;IAkBP;;;;;;;OAOG;;;;;;;;IAEH;;;;;;;OAOG;;;;;;;IAEH;;;OAGG;;;;;;;;;kBAwZL,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,GAAG,gBAAgB,CAmBjF"}
|
|
@@ -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
|
|
20
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
44
|
-
width: z.number().describe('
|
|
45
|
-
height: z.number().describe('
|
|
46
|
-
|
|
47
|
-
quality: z.number().optional().describe('
|
|
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
|
|
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
|
|
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
|
-
//
|
|
175
|
+
// Fetch CMS config and construct a ThumbnailConfig from it
|
|
156
176
|
const cmsConfig = await getCMSConfig();
|
|
157
|
-
|
|
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
|
-
*
|
|
210
|
-
* -
|
|
211
|
-
* -
|
|
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
|
-
|
|
215
|
-
|
|
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
|
-
|
|
220
|
-
|
|
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
|
-
//
|
|
228
|
-
|
|
254
|
+
// contain: pad with background
|
|
255
|
+
const background = this.size.background ?? cmsBackground;
|
|
229
256
|
await this._sharpImage
|
|
230
257
|
.clone()
|
|
231
|
-
.resize({
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
*
|
|
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.
|
|
254
|
-
|
|
275
|
+
fit: thumbnail.fit,
|
|
276
|
+
...(thumbnail.fit === 'contain' ? { background: thumbBackground } : {}),
|
|
255
277
|
})
|
|
256
278
|
.webp({
|
|
257
|
-
quality: thumbnail.quality ??
|
|
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
|
-
|
|
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?: "
|
|
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>>;
|