nextjs-cms 0.5.9 → 0.5.10
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/api/axios/axiosInstance.d.ts +1 -1
- package/dist/api/axios/axiosInstance.js +8 -8
- package/dist/api/index.d.ts +855 -855
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +12 -12
- package/dist/api/lib/serverActions.d.ts +239 -239
- package/dist/api/lib/serverActions.d.ts.map +1 -1
- package/dist/api/lib/serverActions.js +834 -834
- package/dist/api/root.d.ts +828 -828
- package/dist/api/root.js +30 -30
- package/dist/api/routers/accountSettings.d.ts +60 -60
- package/dist/api/routers/accountSettings.js +108 -108
- package/dist/api/routers/admins.d.ts +105 -105
- package/dist/api/routers/admins.js +219 -219
- package/dist/api/routers/auth.d.ts +47 -47
- package/dist/api/routers/auth.js +25 -25
- package/dist/api/routers/categorySection.d.ts +103 -103
- package/dist/api/routers/categorySection.js +38 -38
- package/dist/api/routers/cmsSettings.d.ts +48 -48
- package/dist/api/routers/cmsSettings.js +51 -51
- package/dist/api/routers/cpanel.d.ts +83 -83
- package/dist/api/routers/cpanel.js +216 -216
- package/dist/api/routers/files.d.ts +47 -47
- package/dist/api/routers/files.js +23 -23
- package/dist/api/routers/gallery.d.ts +35 -35
- package/dist/api/routers/gallery.js +62 -62
- package/dist/api/routers/googleAnalytics.d.ts +30 -30
- package/dist/api/routers/googleAnalytics.js +7 -7
- package/dist/api/routers/hasItemsSection.d.ts +139 -139
- package/dist/api/routers/hasItemsSection.js +34 -34
- package/dist/api/routers/navigation.d.ts +51 -51
- package/dist/api/routers/navigation.js +11 -11
- package/dist/api/routers/simpleSection.d.ts +57 -57
- package/dist/api/routers/simpleSection.js +12 -12
- package/dist/api/trpc.d.ts +106 -106
- package/dist/api/trpc.js +72 -72
- package/dist/auth/axios/axiosInstance.d.ts +1 -1
- package/dist/auth/axios/axiosInstance.js +8 -8
- package/dist/auth/csrf.d.ts +29 -29
- package/dist/auth/csrf.js +76 -76
- package/dist/auth/hooks/index.d.ts +3 -3
- package/dist/auth/hooks/index.d.ts.map +1 -1
- package/dist/auth/hooks/index.js +3 -3
- package/dist/auth/hooks/useAxiosPrivate.d.ts +4 -4
- package/dist/auth/hooks/useAxiosPrivate.js +74 -74
- package/dist/auth/hooks/useRefreshToken.d.ts +6 -6
- package/dist/auth/hooks/useRefreshToken.js +79 -79
- package/dist/auth/index.d.ts +22 -22
- package/dist/auth/index.js +44 -44
- package/dist/auth/jwt.d.ts +5 -5
- package/dist/auth/jwt.js +25 -25
- package/dist/auth/lib/actions.d.ts +32 -32
- package/dist/auth/lib/actions.d.ts.map +1 -1
- package/dist/auth/lib/actions.js +209 -209
- package/dist/auth/lib/client.d.ts +3 -3
- package/dist/auth/lib/client.js +46 -46
- package/dist/auth/lib/index.d.ts +2 -2
- package/dist/auth/lib/index.d.ts.map +1 -1
- package/dist/auth/lib/index.js +2 -2
- package/dist/auth/react.d.ts +105 -105
- package/dist/auth/react.d.ts.map +1 -1
- package/dist/auth/react.js +347 -347
- package/dist/auth/trpc.d.ts +5 -5
- package/dist/auth/trpc.d.ts.map +1 -1
- package/dist/auth/trpc.js +81 -81
- package/dist/core/config/config-loader.d.ts +91 -91
- package/dist/core/config/config-loader.js +230 -230
- package/dist/core/config/index.d.ts +2 -2
- package/dist/core/config/index.d.ts.map +1 -1
- package/dist/core/config/index.js +1 -1
- package/dist/core/config/loader.d.ts +1 -1
- package/dist/core/config/loader.js +42 -42
- package/dist/core/db/index.d.ts +1 -1
- package/dist/core/db/index.d.ts.map +1 -1
- package/dist/core/db/index.js +1 -1
- package/dist/core/db/table-checker/DbTable.d.ts +5 -5
- package/dist/core/db/table-checker/DbTable.js +5 -5
- package/dist/core/db/table-checker/MysqlTable.d.ts +33 -33
- package/dist/core/db/table-checker/MysqlTable.d.ts.map +1 -1
- package/dist/core/db/table-checker/MysqlTable.js +94 -94
- package/dist/core/db/table-checker/index.d.ts +1 -1
- package/dist/core/db/table-checker/index.d.ts.map +1 -1
- package/dist/core/db/table-checker/index.js +1 -1
- package/dist/core/factories/FieldFactory.d.ts +123 -123
- package/dist/core/factories/FieldFactory.d.ts.map +1 -1
- package/dist/core/factories/FieldFactory.js +411 -411
- package/dist/core/factories/SectionFactory.d.ts +109 -109
- package/dist/core/factories/SectionFactory.d.ts.map +1 -1
- package/dist/core/factories/SectionFactory.js +415 -415
- package/dist/core/factories/index.d.ts +2 -2
- package/dist/core/factories/index.d.ts.map +1 -1
- package/dist/core/factories/index.js +2 -2
- package/dist/core/fields/checkbox.d.ts +62 -62
- package/dist/core/fields/checkbox.d.ts.map +1 -1
- package/dist/core/fields/checkbox.js +62 -62
- package/dist/core/fields/color.d.ts +83 -83
- package/dist/core/fields/color.d.ts.map +1 -1
- package/dist/core/fields/color.js +91 -91
- package/dist/core/fields/date.d.ts +99 -99
- package/dist/core/fields/date.d.ts.map +1 -1
- package/dist/core/fields/date.js +108 -108
- package/dist/core/fields/document.d.ts +179 -179
- package/dist/core/fields/document.d.ts.map +1 -1
- package/dist/core/fields/document.js +277 -277
- package/dist/core/fields/field-group.d.ts +17 -17
- package/dist/core/fields/field-group.d.ts.map +1 -1
- package/dist/core/fields/field-group.js +6 -6
- package/dist/core/fields/field.d.ts +125 -125
- package/dist/core/fields/field.d.ts.map +1 -1
- package/dist/core/fields/field.js +148 -148
- package/dist/core/fields/fileField.d.ts +14 -14
- package/dist/core/fields/fileField.d.ts.map +1 -1
- package/dist/core/fields/fileField.js +5 -5
- package/dist/core/fields/index.d.ts +64 -64
- package/dist/core/fields/index.d.ts.map +1 -1
- package/dist/core/fields/index.js +18 -18
- package/dist/core/fields/map.d.ts +166 -166
- package/dist/core/fields/map.d.ts.map +1 -1
- package/dist/core/fields/map.js +152 -152
- package/dist/core/fields/number.d.ts +185 -185
- package/dist/core/fields/number.d.ts.map +1 -1
- package/dist/core/fields/number.js +241 -241
- package/dist/core/fields/password.d.ts +108 -108
- package/dist/core/fields/password.d.ts.map +1 -1
- package/dist/core/fields/password.js +133 -133
- package/dist/core/fields/photo.d.ts +288 -288
- package/dist/core/fields/photo.d.ts.map +1 -1
- package/dist/core/fields/photo.js +410 -410
- package/dist/core/fields/richText.d.ts +294 -294
- package/dist/core/fields/richText.d.ts.map +1 -1
- package/dist/core/fields/richText.js +338 -338
- package/dist/core/fields/select.d.ts +365 -365
- package/dist/core/fields/select.d.ts.map +1 -1
- package/dist/core/fields/select.js +499 -499
- package/dist/core/fields/selectMultiple.d.ts +235 -235
- package/dist/core/fields/selectMultiple.d.ts.map +1 -1
- package/dist/core/fields/selectMultiple.js +417 -417
- package/dist/core/fields/tags.d.ts +130 -130
- package/dist/core/fields/tags.d.ts.map +1 -1
- package/dist/core/fields/tags.js +105 -105
- package/dist/core/fields/text.d.ts +135 -135
- package/dist/core/fields/text.d.ts.map +1 -1
- package/dist/core/fields/text.js +157 -157
- package/dist/core/fields/textArea.d.ts +106 -106
- package/dist/core/fields/textArea.d.ts.map +1 -1
- package/dist/core/fields/textArea.js +126 -126
- package/dist/core/fields/video.d.ts +147 -147
- package/dist/core/fields/video.d.ts.map +1 -1
- package/dist/core/fields/video.js +248 -248
- package/dist/core/helpers/entity.d.ts +7 -7
- package/dist/core/helpers/entity.js +27 -27
- package/dist/core/helpers/index.d.ts +4 -4
- package/dist/core/helpers/index.d.ts.map +1 -1
- package/dist/core/helpers/index.js +3 -3
- package/dist/core/index.d.ts +7 -7
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -7
- package/dist/core/sections/category.d.ts +282 -282
- package/dist/core/sections/category.d.ts.map +1 -1
- package/dist/core/sections/category.js +147 -147
- package/dist/core/sections/hasItems.d.ts +631 -631
- package/dist/core/sections/hasItems.d.ts.map +1 -1
- package/dist/core/sections/hasItems.js +144 -144
- package/dist/core/sections/index.d.ts +4 -4
- package/dist/core/sections/index.d.ts.map +1 -1
- package/dist/core/sections/index.js +4 -4
- package/dist/core/sections/section.d.ts +225 -225
- package/dist/core/sections/section.d.ts.map +1 -1
- package/dist/core/sections/section.js +341 -341
- package/dist/core/sections/simple.d.ts +98 -98
- package/dist/core/sections/simple.d.ts.map +1 -1
- package/dist/core/sections/simple.js +95 -95
- package/dist/core/security/dom.d.ts +10 -10
- package/dist/core/security/dom.js +92 -92
- package/dist/core/submit/ItemEditSubmit.d.ts +75 -75
- package/dist/core/submit/ItemEditSubmit.js +186 -186
- package/dist/core/submit/NewItemSubmit.d.ts +13 -13
- package/dist/core/submit/NewItemSubmit.js +93 -93
- package/dist/core/submit/SimpleSectionSubmit.d.ts +12 -12
- package/dist/core/submit/SimpleSectionSubmit.js +93 -93
- package/dist/core/submit/index.d.ts +4 -4
- package/dist/core/submit/index.js +4 -4
- package/dist/core/submit/submit.d.ts +115 -115
- package/dist/core/submit/submit.js +479 -479
- package/dist/core/types/index.d.ts +279 -279
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js +1 -1
- package/dist/db/client.d.ts +8 -8
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +19 -19
- package/dist/db/config.d.ts +5 -5
- package/dist/db/config.js +22 -22
- package/dist/db/drizzle.config.d.ts +5 -5
- package/dist/db/drizzle.config.js +18 -18
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +3 -3
- package/dist/db/schema.d.ts +638 -638
- package/dist/db/schema.js +73 -73
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/translations/index.d.ts +2 -2
- package/dist/translations/index.js +15 -15
- package/dist/utils/CpanelApi.d.ts +24 -24
- package/dist/utils/CpanelApi.js +64 -64
- package/dist/utils/constants.d.ts +13 -13
- package/dist/utils/constants.js +61 -61
- package/dist/utils/index.d.ts +4 -4
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/utils/utils.d.ts +59 -59
- package/dist/utils/utils.js +132 -132
- package/dist/validators/checkbox.d.ts +3 -3
- package/dist/validators/checkbox.d.ts.map +1 -1
- package/dist/validators/checkbox.js +12 -12
- package/dist/validators/color.d.ts +3 -3
- package/dist/validators/color.d.ts.map +1 -1
- package/dist/validators/color.js +7 -7
- package/dist/validators/date.d.ts +3 -3
- package/dist/validators/date.d.ts.map +1 -1
- package/dist/validators/date.js +5 -5
- package/dist/validators/document.d.ts +3 -3
- package/dist/validators/document.d.ts.map +1 -1
- package/dist/validators/document.js +57 -57
- package/dist/validators/index.d.ts +14 -14
- package/dist/validators/index.d.ts.map +1 -1
- package/dist/validators/index.js +14 -14
- package/dist/validators/map.d.ts +3 -3
- package/dist/validators/map.d.ts.map +1 -1
- package/dist/validators/map.js +5 -5
- package/dist/validators/number.d.ts +3 -3
- package/dist/validators/number.d.ts.map +1 -1
- package/dist/validators/number.js +20 -20
- package/dist/validators/password.d.ts +3 -3
- package/dist/validators/password.d.ts.map +1 -1
- package/dist/validators/password.js +11 -11
- package/dist/validators/photo.d.ts +3 -3
- package/dist/validators/photo.d.ts.map +1 -1
- package/dist/validators/photo.js +100 -100
- package/dist/validators/richText.d.ts +3 -3
- package/dist/validators/richText.d.ts.map +1 -1
- package/dist/validators/richText.js +8 -8
- package/dist/validators/select-multiple.d.ts +9 -9
- package/dist/validators/select-multiple.d.ts.map +1 -1
- package/dist/validators/select-multiple.js +20 -20
- package/dist/validators/select.d.ts +3 -3
- package/dist/validators/select.d.ts.map +1 -1
- package/dist/validators/select.js +5 -5
- package/dist/validators/text.d.ts +3 -3
- package/dist/validators/text.d.ts.map +1 -1
- package/dist/validators/text.js +7 -7
- package/dist/validators/textarea.d.ts +3 -3
- package/dist/validators/textarea.d.ts.map +1 -1
- package/dist/validators/textarea.js +7 -7
- package/dist/validators/video.d.ts +3 -3
- package/dist/validators/video.d.ts.map +1 -1
- package/dist/validators/video.js +57 -57
- package/package.json +2 -3
|
@@ -1,241 +1,241 @@
|
|
|
1
|
-
import { Field, baseFieldConfigSchema } from
|
|
2
|
-
import { entityKind } from
|
|
3
|
-
import * as z from 'zod';
|
|
4
|
-
const numberFieldAutoIncConfigSchema = z.strictObject({
|
|
5
|
-
hasAutoIncrement: z.literal(true).describe('Enable auto-increment for this field'),
|
|
6
|
-
/** Auto-increment is always integer. Allowing override to 'int' only (optional). */
|
|
7
|
-
format: z.literal('int').optional().describe('Format for auto-increment (must be int)'),
|
|
8
|
-
adminGenerated: z.never().optional(),
|
|
9
|
-
placeholder: z.never().optional(),
|
|
10
|
-
minValue: z.never().optional(),
|
|
11
|
-
maxValue: z.never().optional(),
|
|
12
|
-
minLength: z.never().optional(),
|
|
13
|
-
maxLength: z.never().optional(),
|
|
14
|
-
defaultValue: z.never().optional(),
|
|
15
|
-
});
|
|
16
|
-
const numberFieldManualConfigSchema = z.strictObject({
|
|
17
|
-
hasAutoIncrement: z.literal(false).optional().describe('Disable auto-increment (manual input)'),
|
|
18
|
-
format: z.enum(['int', 'float', 'double']).optional().describe('Number format'),
|
|
19
|
-
adminGenerated: z.union([z.literal(true), z.literal(false), z.literal('readonly')]).optional(),
|
|
20
|
-
placeholder: z.string().optional().describe('Placeholder text for the input'),
|
|
21
|
-
minValue: z.number().optional().describe('Minimum allowed value'),
|
|
22
|
-
maxValue: z.number().optional().describe('Maximum allowed value'),
|
|
23
|
-
minLength: z.number().optional().describe('Minimum string length of the number'),
|
|
24
|
-
maxLength: z.number().optional().describe('Maximum string length of the number'),
|
|
25
|
-
/**
|
|
26
|
-
* The default value of the field.
|
|
27
|
-
* If set, the field will be pre-populated with this value when the form is loaded.
|
|
28
|
-
* If `adminGenerated` is not true, the field will be included when submitting the form with this value.
|
|
29
|
-
*/
|
|
30
|
-
defaultValue: z.number().optional().describe('Default value for the field'),
|
|
31
|
-
});
|
|
32
|
-
const configSchema = z.discriminatedUnion('hasAutoIncrement', [
|
|
33
|
-
numberFieldAutoIncConfigSchema,
|
|
34
|
-
numberFieldManualConfigSchema,
|
|
35
|
-
]);
|
|
36
|
-
export class NumberField extends Field {
|
|
37
|
-
static [entityKind] = 'NumberField';
|
|
38
|
-
format;
|
|
39
|
-
minValue;
|
|
40
|
-
maxValue;
|
|
41
|
-
placeholder;
|
|
42
|
-
hasAutoIncrement;
|
|
43
|
-
minLength;
|
|
44
|
-
maxLength;
|
|
45
|
-
_defaultValue;
|
|
46
|
-
value;
|
|
47
|
-
constructor(config) {
|
|
48
|
-
super(config, 'number');
|
|
49
|
-
this.hasAutoIncrement = config.hasAutoIncrement;
|
|
50
|
-
this.minValue = config.minValue;
|
|
51
|
-
this.maxValue = config.maxValue;
|
|
52
|
-
this.placeholder = config.placeholder;
|
|
53
|
-
this.minLength = config.minLength;
|
|
54
|
-
this.maxLength = config.maxLength;
|
|
55
|
-
// default to 'int' whether auto-increment or not
|
|
56
|
-
this.format = this.hasAutoIncrement ? (config.format ?? 'int') : (config.format ?? 'int');
|
|
57
|
-
/**
|
|
58
|
-
* Logic: if auto-increment and format not 'int', force it.
|
|
59
|
-
*/
|
|
60
|
-
if (this.hasAutoIncrement && this.format !== 'int') {
|
|
61
|
-
console.warn(`[NumberField:${this.label}] auto-increment forces format 'int'. Received '${config.format}'. Coercing to 'int'.`);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Apply initial value from default
|
|
65
|
-
*/
|
|
66
|
-
this.value = config.defaultValue;
|
|
67
|
-
this._defaultValue = config.defaultValue;
|
|
68
|
-
/**
|
|
69
|
-
* Force the userGenerated to false if the field has auto increment
|
|
70
|
-
*/
|
|
71
|
-
if (this.hasAutoIncrement === true) {
|
|
72
|
-
this.adminGenerated = false;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Basic structural logic checks
|
|
76
|
-
*/
|
|
77
|
-
if (this.minValue !== undefined && this.maxValue !== undefined && this.minValue > this.maxValue) {
|
|
78
|
-
throw new Error(`Field ${this.label} has minValue > maxValue`);
|
|
79
|
-
}
|
|
80
|
-
if (this.minLength !== undefined && this.maxLength !== undefined && this.minLength > this.maxLength) {
|
|
81
|
-
throw new Error(`Field ${this.label} has minLength > maxLength`);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Attempt to coerce the value
|
|
85
|
-
*/
|
|
86
|
-
this.coerceValue();
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Coerce the value to a number
|
|
90
|
-
*/
|
|
91
|
-
coerceValue() {
|
|
92
|
-
/**
|
|
93
|
-
* Check if the value is not undefined
|
|
94
|
-
*/
|
|
95
|
-
if (this.value !== undefined) {
|
|
96
|
-
/**
|
|
97
|
-
* Coerce the value
|
|
98
|
-
*/
|
|
99
|
-
this.value = Number(this.value);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
exportForClient() {
|
|
103
|
-
return {
|
|
104
|
-
...super.exportForClient(),
|
|
105
|
-
format: this.format,
|
|
106
|
-
placeholder: this.placeholder,
|
|
107
|
-
minValue: this.minValue,
|
|
108
|
-
maxValue: this.maxValue,
|
|
109
|
-
minLength: this.minLength,
|
|
110
|
-
maxLength: this.maxLength,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Get the value of the field
|
|
115
|
-
*/
|
|
116
|
-
getValue() {
|
|
117
|
-
return Number.isNaN(this.value) ? undefined : this.value;
|
|
118
|
-
}
|
|
119
|
-
hasSqlNameAndValue() {
|
|
120
|
-
/**
|
|
121
|
-
* Skip if the field has auto increment enabled in the database
|
|
122
|
-
*/
|
|
123
|
-
if (this.hasAutoIncrement) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Include the field in the SQL if it is admin-generated, or not admin-generated but has a default value
|
|
128
|
-
*/
|
|
129
|
-
return this.adminGenerated === true || this._defaultValue !== undefined;
|
|
130
|
-
}
|
|
131
|
-
checkRequired() {
|
|
132
|
-
/**
|
|
133
|
-
* Skip if the field has auto increment enabled,
|
|
134
|
-
* because it will be auto generated in the database
|
|
135
|
-
*/
|
|
136
|
-
if (this.hasAutoIncrement)
|
|
137
|
-
return;
|
|
138
|
-
/**
|
|
139
|
-
* Check if the field is required
|
|
140
|
-
* Note: We explicitly check for undefined/null instead of using !this.value
|
|
141
|
-
* because 0 is a valid number value but falsy in JavaScript
|
|
142
|
-
*/
|
|
143
|
-
if (this.required) {
|
|
144
|
-
if (this.value === undefined || this.value === null || Number.isNaN(this.value)) {
|
|
145
|
-
throw new Error(`Field ${this.label} is required`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Prepare the field for submission
|
|
151
|
-
*/
|
|
152
|
-
async prepareForSubmission() {
|
|
153
|
-
/**
|
|
154
|
-
* Check if the field has auto increment enabled
|
|
155
|
-
* If it does, we don't need to do anything
|
|
156
|
-
*/
|
|
157
|
-
if (this.hasAutoIncrement) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
if (this.value) {
|
|
161
|
-
/**
|
|
162
|
-
* Check min
|
|
163
|
-
*/
|
|
164
|
-
if (this.minValue) {
|
|
165
|
-
if (this.minValue > this.value) {
|
|
166
|
-
throw new Error(`Field ${this.label} must be ${this.minValue} and above`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Check max
|
|
171
|
-
*/
|
|
172
|
-
if (this.maxValue) {
|
|
173
|
-
if (this.maxValue < this.value) {
|
|
174
|
-
throw new Error(`Field ${this.label} must be ${this.maxValue} and below`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Check minimum length
|
|
179
|
-
*/
|
|
180
|
-
if (this.minLength) {
|
|
181
|
-
if (this.minLength > this.value.toString().length) {
|
|
182
|
-
throw new Error(`Field ${this.label} must be at least ${this.minLength} characters long`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Check maximum length
|
|
187
|
-
*/
|
|
188
|
-
if (this.maxLength) {
|
|
189
|
-
if (this.maxLength < this.value.toString().length) {
|
|
190
|
-
throw new Error(`Field ${this.label} must be at most ${this.maxLength} characters long`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const numberFieldAutoIncOptionsSchema = z.strictObject({
|
|
197
|
-
...baseFieldConfigSchema.shape,
|
|
198
|
-
...numberFieldAutoIncConfigSchema.shape,
|
|
199
|
-
});
|
|
200
|
-
const numberFieldManualOptionsSchema = z.strictObject({
|
|
201
|
-
...baseFieldConfigSchema.shape,
|
|
202
|
-
...numberFieldManualConfigSchema.shape,
|
|
203
|
-
});
|
|
204
|
-
const optionsSchema = z.discriminatedUnion('hasAutoIncrement', [
|
|
205
|
-
numberFieldAutoIncOptionsSchema,
|
|
206
|
-
numberFieldManualOptionsSchema,
|
|
207
|
-
]);
|
|
208
|
-
const numberFieldConfigSchema = z.intersection(optionsSchema, z.strictObject({
|
|
209
|
-
type: z.literal('number').describe('The type of the field'),
|
|
210
|
-
build: z.function().output(z.instanceof(NumberField)).describe('Build a NumberField instance from this config'),
|
|
211
|
-
}));
|
|
212
|
-
/**
|
|
213
|
-
* Helper function to create a number field configuration
|
|
214
|
-
* Returns a config object with a build() method that can be serialized and used anywhere
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* ```typescript
|
|
218
|
-
* const fieldConfig = numberField({ name: 'age', label: 'Age', required: true, order: 1 })
|
|
219
|
-
* const fieldInstance = fieldConfig.build()
|
|
220
|
-
* ```
|
|
221
|
-
*
|
|
222
|
-
* @param field
|
|
223
|
-
*/
|
|
224
|
-
export function numberField(field) {
|
|
225
|
-
/**
|
|
226
|
-
* Validate the field config
|
|
227
|
-
*/
|
|
228
|
-
const result = optionsSchema.safeParse(field);
|
|
229
|
-
if (!result.success) {
|
|
230
|
-
throw new Error(`[Field: ${field.name}]: ${z.prettifyError(result.error)}`);
|
|
231
|
-
}
|
|
232
|
-
const config = {
|
|
233
|
-
...field,
|
|
234
|
-
type: 'number',
|
|
235
|
-
build() {
|
|
236
|
-
// Use the original field config directly (it doesn't have build() method)
|
|
237
|
-
return new NumberField(field);
|
|
238
|
-
},
|
|
239
|
-
};
|
|
240
|
-
return config;
|
|
241
|
-
}
|
|
1
|
+
import { Field, baseFieldConfigSchema } from './field.js';
|
|
2
|
+
import { entityKind } from '../helpers/index.js';
|
|
3
|
+
import * as z from 'zod';
|
|
4
|
+
const numberFieldAutoIncConfigSchema = z.strictObject({
|
|
5
|
+
hasAutoIncrement: z.literal(true).describe('Enable auto-increment for this field'),
|
|
6
|
+
/** Auto-increment is always integer. Allowing override to 'int' only (optional). */
|
|
7
|
+
format: z.literal('int').optional().describe('Format for auto-increment (must be int)'),
|
|
8
|
+
adminGenerated: z.never().optional(),
|
|
9
|
+
placeholder: z.never().optional(),
|
|
10
|
+
minValue: z.never().optional(),
|
|
11
|
+
maxValue: z.never().optional(),
|
|
12
|
+
minLength: z.never().optional(),
|
|
13
|
+
maxLength: z.never().optional(),
|
|
14
|
+
defaultValue: z.never().optional(),
|
|
15
|
+
});
|
|
16
|
+
const numberFieldManualConfigSchema = z.strictObject({
|
|
17
|
+
hasAutoIncrement: z.literal(false).optional().describe('Disable auto-increment (manual input)'),
|
|
18
|
+
format: z.enum(['int', 'float', 'double']).optional().describe('Number format'),
|
|
19
|
+
adminGenerated: z.union([z.literal(true), z.literal(false), z.literal('readonly')]).optional(),
|
|
20
|
+
placeholder: z.string().optional().describe('Placeholder text for the input'),
|
|
21
|
+
minValue: z.number().optional().describe('Minimum allowed value'),
|
|
22
|
+
maxValue: z.number().optional().describe('Maximum allowed value'),
|
|
23
|
+
minLength: z.number().optional().describe('Minimum string length of the number'),
|
|
24
|
+
maxLength: z.number().optional().describe('Maximum string length of the number'),
|
|
25
|
+
/**
|
|
26
|
+
* The default value of the field.
|
|
27
|
+
* If set, the field will be pre-populated with this value when the form is loaded.
|
|
28
|
+
* If `adminGenerated` is not true, the field will be included when submitting the form with this value.
|
|
29
|
+
*/
|
|
30
|
+
defaultValue: z.number().optional().describe('Default value for the field'),
|
|
31
|
+
});
|
|
32
|
+
const configSchema = z.discriminatedUnion('hasAutoIncrement', [
|
|
33
|
+
numberFieldAutoIncConfigSchema,
|
|
34
|
+
numberFieldManualConfigSchema,
|
|
35
|
+
]);
|
|
36
|
+
export class NumberField extends Field {
|
|
37
|
+
static [entityKind] = 'NumberField';
|
|
38
|
+
format;
|
|
39
|
+
minValue;
|
|
40
|
+
maxValue;
|
|
41
|
+
placeholder;
|
|
42
|
+
hasAutoIncrement;
|
|
43
|
+
minLength;
|
|
44
|
+
maxLength;
|
|
45
|
+
_defaultValue;
|
|
46
|
+
value;
|
|
47
|
+
constructor(config) {
|
|
48
|
+
super(config, 'number');
|
|
49
|
+
this.hasAutoIncrement = config.hasAutoIncrement;
|
|
50
|
+
this.minValue = config.minValue;
|
|
51
|
+
this.maxValue = config.maxValue;
|
|
52
|
+
this.placeholder = config.placeholder;
|
|
53
|
+
this.minLength = config.minLength;
|
|
54
|
+
this.maxLength = config.maxLength;
|
|
55
|
+
// default to 'int' whether auto-increment or not
|
|
56
|
+
this.format = this.hasAutoIncrement ? (config.format ?? 'int') : (config.format ?? 'int');
|
|
57
|
+
/**
|
|
58
|
+
* Logic: if auto-increment and format not 'int', force it.
|
|
59
|
+
*/
|
|
60
|
+
if (this.hasAutoIncrement && this.format !== 'int') {
|
|
61
|
+
console.warn(`[NumberField:${this.label}] auto-increment forces format 'int'. Received '${config.format}'. Coercing to 'int'.`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Apply initial value from default
|
|
65
|
+
*/
|
|
66
|
+
this.value = config.defaultValue;
|
|
67
|
+
this._defaultValue = config.defaultValue;
|
|
68
|
+
/**
|
|
69
|
+
* Force the userGenerated to false if the field has auto increment
|
|
70
|
+
*/
|
|
71
|
+
if (this.hasAutoIncrement === true) {
|
|
72
|
+
this.adminGenerated = false;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Basic structural logic checks
|
|
76
|
+
*/
|
|
77
|
+
if (this.minValue !== undefined && this.maxValue !== undefined && this.minValue > this.maxValue) {
|
|
78
|
+
throw new Error(`Field ${this.label} has minValue > maxValue`);
|
|
79
|
+
}
|
|
80
|
+
if (this.minLength !== undefined && this.maxLength !== undefined && this.minLength > this.maxLength) {
|
|
81
|
+
throw new Error(`Field ${this.label} has minLength > maxLength`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Attempt to coerce the value
|
|
85
|
+
*/
|
|
86
|
+
this.coerceValue();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Coerce the value to a number
|
|
90
|
+
*/
|
|
91
|
+
coerceValue() {
|
|
92
|
+
/**
|
|
93
|
+
* Check if the value is not undefined
|
|
94
|
+
*/
|
|
95
|
+
if (this.value !== undefined) {
|
|
96
|
+
/**
|
|
97
|
+
* Coerce the value
|
|
98
|
+
*/
|
|
99
|
+
this.value = Number(this.value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exportForClient() {
|
|
103
|
+
return {
|
|
104
|
+
...super.exportForClient(),
|
|
105
|
+
format: this.format,
|
|
106
|
+
placeholder: this.placeholder,
|
|
107
|
+
minValue: this.minValue,
|
|
108
|
+
maxValue: this.maxValue,
|
|
109
|
+
minLength: this.minLength,
|
|
110
|
+
maxLength: this.maxLength,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the value of the field
|
|
115
|
+
*/
|
|
116
|
+
getValue() {
|
|
117
|
+
return Number.isNaN(this.value) ? undefined : this.value;
|
|
118
|
+
}
|
|
119
|
+
hasSqlNameAndValue() {
|
|
120
|
+
/**
|
|
121
|
+
* Skip if the field has auto increment enabled in the database
|
|
122
|
+
*/
|
|
123
|
+
if (this.hasAutoIncrement) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Include the field in the SQL if it is admin-generated, or not admin-generated but has a default value
|
|
128
|
+
*/
|
|
129
|
+
return this.adminGenerated === true || this._defaultValue !== undefined;
|
|
130
|
+
}
|
|
131
|
+
checkRequired() {
|
|
132
|
+
/**
|
|
133
|
+
* Skip if the field has auto increment enabled,
|
|
134
|
+
* because it will be auto generated in the database
|
|
135
|
+
*/
|
|
136
|
+
if (this.hasAutoIncrement)
|
|
137
|
+
return;
|
|
138
|
+
/**
|
|
139
|
+
* Check if the field is required
|
|
140
|
+
* Note: We explicitly check for undefined/null instead of using !this.value
|
|
141
|
+
* because 0 is a valid number value but falsy in JavaScript
|
|
142
|
+
*/
|
|
143
|
+
if (this.required) {
|
|
144
|
+
if (this.value === undefined || this.value === null || Number.isNaN(this.value)) {
|
|
145
|
+
throw new Error(`Field ${this.label} is required`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Prepare the field for submission
|
|
151
|
+
*/
|
|
152
|
+
async prepareForSubmission() {
|
|
153
|
+
/**
|
|
154
|
+
* Check if the field has auto increment enabled
|
|
155
|
+
* If it does, we don't need to do anything
|
|
156
|
+
*/
|
|
157
|
+
if (this.hasAutoIncrement) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (this.value) {
|
|
161
|
+
/**
|
|
162
|
+
* Check min
|
|
163
|
+
*/
|
|
164
|
+
if (this.minValue) {
|
|
165
|
+
if (this.minValue > this.value) {
|
|
166
|
+
throw new Error(`Field ${this.label} must be ${this.minValue} and above`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check max
|
|
171
|
+
*/
|
|
172
|
+
if (this.maxValue) {
|
|
173
|
+
if (this.maxValue < this.value) {
|
|
174
|
+
throw new Error(`Field ${this.label} must be ${this.maxValue} and below`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check minimum length
|
|
179
|
+
*/
|
|
180
|
+
if (this.minLength) {
|
|
181
|
+
if (this.minLength > this.value.toString().length) {
|
|
182
|
+
throw new Error(`Field ${this.label} must be at least ${this.minLength} characters long`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check maximum length
|
|
187
|
+
*/
|
|
188
|
+
if (this.maxLength) {
|
|
189
|
+
if (this.maxLength < this.value.toString().length) {
|
|
190
|
+
throw new Error(`Field ${this.label} must be at most ${this.maxLength} characters long`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const numberFieldAutoIncOptionsSchema = z.strictObject({
|
|
197
|
+
...baseFieldConfigSchema.shape,
|
|
198
|
+
...numberFieldAutoIncConfigSchema.shape,
|
|
199
|
+
});
|
|
200
|
+
const numberFieldManualOptionsSchema = z.strictObject({
|
|
201
|
+
...baseFieldConfigSchema.shape,
|
|
202
|
+
...numberFieldManualConfigSchema.shape,
|
|
203
|
+
});
|
|
204
|
+
const optionsSchema = z.discriminatedUnion('hasAutoIncrement', [
|
|
205
|
+
numberFieldAutoIncOptionsSchema,
|
|
206
|
+
numberFieldManualOptionsSchema,
|
|
207
|
+
]);
|
|
208
|
+
const numberFieldConfigSchema = z.intersection(optionsSchema, z.strictObject({
|
|
209
|
+
type: z.literal('number').describe('The type of the field'),
|
|
210
|
+
build: z.function().output(z.instanceof(NumberField)).describe('Build a NumberField instance from this config'),
|
|
211
|
+
}));
|
|
212
|
+
/**
|
|
213
|
+
* Helper function to create a number field configuration
|
|
214
|
+
* Returns a config object with a build() method that can be serialized and used anywhere
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const fieldConfig = numberField({ name: 'age', label: 'Age', required: true, order: 1 })
|
|
219
|
+
* const fieldInstance = fieldConfig.build()
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* @param field
|
|
223
|
+
*/
|
|
224
|
+
export function numberField(field) {
|
|
225
|
+
/**
|
|
226
|
+
* Validate the field config
|
|
227
|
+
*/
|
|
228
|
+
const result = optionsSchema.safeParse(field);
|
|
229
|
+
if (!result.success) {
|
|
230
|
+
throw new Error(`[Field: ${field.name}]: ${z.prettifyError(result.error)}`);
|
|
231
|
+
}
|
|
232
|
+
const config = {
|
|
233
|
+
...field,
|
|
234
|
+
type: 'number',
|
|
235
|
+
build() {
|
|
236
|
+
// Use the original field config directly (it doesn't have build() method)
|
|
237
|
+
return new NumberField(field);
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
return config;
|
|
241
|
+
}
|