@classic-homes/theme-svelte 0.1.0
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/README.md +305 -0
- package/dist/lib/components/Alert.svelte +51 -0
- package/dist/lib/components/Alert.svelte.d.ts +9 -0
- package/dist/lib/components/AlertDescription.svelte +16 -0
- package/dist/lib/components/AlertDescription.svelte.d.ts +9 -0
- package/dist/lib/components/AlertDialog.svelte +136 -0
- package/dist/lib/components/AlertDialog.svelte.d.ts +79 -0
- package/dist/lib/components/AlertTitle.svelte +16 -0
- package/dist/lib/components/AlertTitle.svelte.d.ts +9 -0
- package/dist/lib/components/Avatar.svelte +56 -0
- package/dist/lib/components/Avatar.svelte.d.ts +26 -0
- package/dist/lib/components/AvatarFallback.svelte +31 -0
- package/dist/lib/components/AvatarFallback.svelte.d.ts +17 -0
- package/dist/lib/components/AvatarImage.svelte +29 -0
- package/dist/lib/components/AvatarImage.svelte.d.ts +12 -0
- package/dist/lib/components/Badge.svelte +73 -0
- package/dist/lib/components/Badge.svelte.d.ts +11 -0
- package/dist/lib/components/Button.svelte +130 -0
- package/dist/lib/components/Button.svelte.d.ts +17 -0
- package/dist/lib/components/Card.svelte +58 -0
- package/dist/lib/components/Card.svelte.d.ts +26 -0
- package/dist/lib/components/CardContent.svelte +16 -0
- package/dist/lib/components/CardContent.svelte.d.ts +9 -0
- package/dist/lib/components/CardDescription.svelte +16 -0
- package/dist/lib/components/CardDescription.svelte.d.ts +9 -0
- package/dist/lib/components/CardFooter.svelte +16 -0
- package/dist/lib/components/CardFooter.svelte.d.ts +9 -0
- package/dist/lib/components/CardHeader.svelte +16 -0
- package/dist/lib/components/CardHeader.svelte.d.ts +9 -0
- package/dist/lib/components/CardTitle.svelte +16 -0
- package/dist/lib/components/CardTitle.svelte.d.ts +9 -0
- package/dist/lib/components/Checkbox.svelte +65 -0
- package/dist/lib/components/Checkbox.svelte.d.ts +14 -0
- package/dist/lib/components/DataTable.svelte +334 -0
- package/dist/lib/components/DataTable.svelte.d.ts +103 -0
- package/dist/lib/components/Dialog.svelte +111 -0
- package/dist/lib/components/Dialog.svelte.d.ts +22 -0
- package/dist/lib/components/DropdownMenu.svelte +135 -0
- package/dist/lib/components/DropdownMenu.svelte.d.ts +33 -0
- package/dist/lib/components/FileUpload.svelte +448 -0
- package/dist/lib/components/FileUpload.svelte.d.ts +42 -0
- package/dist/lib/components/FormField.svelte +134 -0
- package/dist/lib/components/FormField.svelte.d.ts +37 -0
- package/dist/lib/components/Input.svelte +61 -0
- package/dist/lib/components/Input.svelte.d.ts +19 -0
- package/dist/lib/components/Label.svelte +33 -0
- package/dist/lib/components/Label.svelte.d.ts +11 -0
- package/dist/lib/components/LoadingLogo.svelte +124 -0
- package/dist/lib/components/LoadingLogo.svelte.d.ts +16 -0
- package/dist/lib/components/LogoMain.svelte +237 -0
- package/dist/lib/components/LogoMain.svelte.d.ts +20 -0
- package/dist/lib/components/PageHeader.svelte +90 -0
- package/dist/lib/components/PageHeader.svelte.d.ts +28 -0
- package/dist/lib/components/Section.svelte +44 -0
- package/dist/lib/components/Section.svelte.d.ts +28 -0
- package/dist/lib/components/Select.svelte +174 -0
- package/dist/lib/components/Select.svelte.d.ts +32 -0
- package/dist/lib/components/Separator.svelte +29 -0
- package/dist/lib/components/Separator.svelte.d.ts +9 -0
- package/dist/lib/components/Skeleton.svelte +35 -0
- package/dist/lib/components/Skeleton.svelte.d.ts +7 -0
- package/dist/lib/components/Spinner.svelte +50 -0
- package/dist/lib/components/Spinner.svelte.d.ts +8 -0
- package/dist/lib/components/Switch.svelte +56 -0
- package/dist/lib/components/Switch.svelte.d.ts +14 -0
- package/dist/lib/components/TabPanel.svelte +44 -0
- package/dist/lib/components/TabPanel.svelte.d.ts +12 -0
- package/dist/lib/components/Tabs.svelte +125 -0
- package/dist/lib/components/Tabs.svelte.d.ts +19 -0
- package/dist/lib/components/Textarea.svelte +54 -0
- package/dist/lib/components/Textarea.svelte.d.ts +16 -0
- package/dist/lib/components/Toast.svelte +116 -0
- package/dist/lib/components/Toast.svelte.d.ts +12 -0
- package/dist/lib/components/ToastContainer.svelte +56 -0
- package/dist/lib/components/ToastContainer.svelte.d.ts +8 -0
- package/dist/lib/components/Tooltip.svelte +55 -0
- package/dist/lib/components/Tooltip.svelte.d.ts +18 -0
- package/dist/lib/components/layout/AppShell.svelte +82 -0
- package/dist/lib/components/layout/AppShell.svelte.d.ts +44 -0
- package/dist/lib/components/layout/DashboardLayout.svelte +248 -0
- package/dist/lib/components/layout/DashboardLayout.svelte.d.ts +62 -0
- package/dist/lib/components/layout/Footer.svelte +130 -0
- package/dist/lib/components/layout/Footer.svelte.d.ts +32 -0
- package/dist/lib/components/layout/FormPageLayout.svelte +92 -0
- package/dist/lib/components/layout/FormPageLayout.svelte.d.ts +33 -0
- package/dist/lib/components/layout/Header.svelte +94 -0
- package/dist/lib/components/layout/Header.svelte.d.ts +30 -0
- package/dist/lib/components/layout/PublicLayout.svelte +180 -0
- package/dist/lib/components/layout/PublicLayout.svelte.d.ts +39 -0
- package/dist/lib/components/layout/QuickLinks.svelte +112 -0
- package/dist/lib/components/layout/QuickLinks.svelte.d.ts +27 -0
- package/dist/lib/components/layout/Sidebar.svelte +243 -0
- package/dist/lib/components/layout/Sidebar.svelte.d.ts +48 -0
- package/dist/lib/composables/index.d.ts +8 -0
- package/dist/lib/composables/index.js +10 -0
- package/dist/lib/composables/useAsync.svelte.d.ts +102 -0
- package/dist/lib/composables/useAsync.svelte.js +210 -0
- package/dist/lib/composables/useForm.svelte.d.ts +123 -0
- package/dist/lib/composables/useForm.svelte.js +245 -0
- package/dist/lib/index.d.ts +65 -0
- package/dist/lib/index.js +83 -0
- package/dist/lib/performance.d.ts +79 -0
- package/dist/lib/performance.js +170 -0
- package/dist/lib/schemas/auth.d.ts +410 -0
- package/dist/lib/schemas/auth.js +216 -0
- package/dist/lib/schemas/common.d.ts +267 -0
- package/dist/lib/schemas/common.js +268 -0
- package/dist/lib/schemas/index.d.ts +24 -0
- package/dist/lib/schemas/index.js +32 -0
- package/dist/lib/stores/sidebar.svelte.d.ts +25 -0
- package/dist/lib/stores/sidebar.svelte.js +38 -0
- package/dist/lib/stores/theme.svelte.d.ts +72 -0
- package/dist/lib/stores/theme.svelte.js +150 -0
- package/dist/lib/stores/toast.svelte.d.ts +62 -0
- package/dist/lib/stores/toast.svelte.js +93 -0
- package/dist/lib/types/components.d.ts +85 -0
- package/dist/lib/types/components.js +7 -0
- package/dist/lib/types/layout.d.ts +258 -0
- package/dist/lib/types/layout.js +7 -0
- package/dist/lib/utils.d.ts +6 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/validation.d.ts +101 -0
- package/dist/lib/validation.js +170 -0
- package/package.json +56 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Validation Schemas
|
|
3
|
+
*
|
|
4
|
+
* Reusable Zod schemas for common data types and validation patterns.
|
|
5
|
+
* These can be composed with other schemas or used standalone.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* Non-empty string
|
|
10
|
+
*/
|
|
11
|
+
export declare const nonEmptyString: z.ZodString;
|
|
12
|
+
/**
|
|
13
|
+
* Trimmed non-empty string (strips whitespace)
|
|
14
|
+
*/
|
|
15
|
+
export declare const trimmedString: z.ZodString;
|
|
16
|
+
/**
|
|
17
|
+
* Optional string (empty string treated as undefined)
|
|
18
|
+
*/
|
|
19
|
+
export declare const optionalString: z.ZodOptional<z.ZodEffects<z.ZodString, string | undefined, string>>;
|
|
20
|
+
/**
|
|
21
|
+
* URL validation
|
|
22
|
+
*/
|
|
23
|
+
export declare const urlSchema: z.ZodString;
|
|
24
|
+
/**
|
|
25
|
+
* Optional URL
|
|
26
|
+
*/
|
|
27
|
+
export declare const optionalUrlSchema: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
28
|
+
/**
|
|
29
|
+
* Slug validation (URL-friendly string)
|
|
30
|
+
*/
|
|
31
|
+
export declare const slugSchema: z.ZodString;
|
|
32
|
+
/**
|
|
33
|
+
* Positive integer
|
|
34
|
+
*/
|
|
35
|
+
export declare const positiveInt: z.ZodNumber;
|
|
36
|
+
/**
|
|
37
|
+
* Non-negative integer (0 or greater)
|
|
38
|
+
*/
|
|
39
|
+
export declare const nonNegativeInt: z.ZodNumber;
|
|
40
|
+
/**
|
|
41
|
+
* Percentage (0-100)
|
|
42
|
+
*/
|
|
43
|
+
export declare const percentageSchema: z.ZodNumber;
|
|
44
|
+
/**
|
|
45
|
+
* Price/currency (positive, 2 decimal places)
|
|
46
|
+
*/
|
|
47
|
+
export declare const priceSchema: z.ZodNumber;
|
|
48
|
+
/**
|
|
49
|
+
* String that parses to a number
|
|
50
|
+
*/
|
|
51
|
+
export declare const numericString: z.ZodEffects<z.ZodString, number, string>;
|
|
52
|
+
/**
|
|
53
|
+
* ISO date string
|
|
54
|
+
*/
|
|
55
|
+
export declare const isoDateSchema: z.ZodString;
|
|
56
|
+
/**
|
|
57
|
+
* Date string in YYYY-MM-DD format
|
|
58
|
+
*/
|
|
59
|
+
export declare const dateStringSchema: z.ZodString;
|
|
60
|
+
/**
|
|
61
|
+
* Time string in HH:MM format
|
|
62
|
+
*/
|
|
63
|
+
export declare const timeStringSchema: z.ZodString;
|
|
64
|
+
/**
|
|
65
|
+
* Future date validation
|
|
66
|
+
*/
|
|
67
|
+
export declare const futureDateSchema: z.ZodEffects<z.ZodDate, Date, Date>;
|
|
68
|
+
/**
|
|
69
|
+
* Past date validation
|
|
70
|
+
*/
|
|
71
|
+
export declare const pastDateSchema: z.ZodEffects<z.ZodDate, Date, Date>;
|
|
72
|
+
/**
|
|
73
|
+
* Non-empty array
|
|
74
|
+
*/
|
|
75
|
+
export declare function nonEmptyArray<T extends z.ZodTypeAny>(schema: T): z.ZodArray<T, "many">;
|
|
76
|
+
/**
|
|
77
|
+
* Unique array (no duplicates)
|
|
78
|
+
*/
|
|
79
|
+
export declare function uniqueArray<T extends z.ZodTypeAny>(schema: T, message?: string): z.ZodEffects<z.ZodArray<T, "many">, T["_output"][], T["_input"][]>;
|
|
80
|
+
/**
|
|
81
|
+
* Array with max length
|
|
82
|
+
*/
|
|
83
|
+
export declare function maxLengthArray<T extends z.ZodTypeAny>(schema: T, max: number): z.ZodArray<T, "many">;
|
|
84
|
+
/**
|
|
85
|
+
* ID field (string, typically UUID or similar)
|
|
86
|
+
*/
|
|
87
|
+
export declare const idSchema: z.ZodString;
|
|
88
|
+
/**
|
|
89
|
+
* UUID validation
|
|
90
|
+
*/
|
|
91
|
+
export declare const uuidSchema: z.ZodString;
|
|
92
|
+
/**
|
|
93
|
+
* Pagination parameters
|
|
94
|
+
*/
|
|
95
|
+
export declare const paginationSchema: z.ZodObject<{
|
|
96
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
97
|
+
pageSize: z.ZodDefault<z.ZodNumber>;
|
|
98
|
+
sortBy: z.ZodOptional<z.ZodString>;
|
|
99
|
+
sortOrder: z.ZodDefault<z.ZodOptional<z.ZodEnum<["asc", "desc"]>>>;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
page: number;
|
|
102
|
+
pageSize: number;
|
|
103
|
+
sortOrder: "asc" | "desc";
|
|
104
|
+
sortBy?: string | undefined;
|
|
105
|
+
}, {
|
|
106
|
+
page?: number | undefined;
|
|
107
|
+
pageSize?: number | undefined;
|
|
108
|
+
sortBy?: string | undefined;
|
|
109
|
+
sortOrder?: "asc" | "desc" | undefined;
|
|
110
|
+
}>;
|
|
111
|
+
export type PaginationParams = z.infer<typeof paginationSchema>;
|
|
112
|
+
/**
|
|
113
|
+
* Search/filter parameters
|
|
114
|
+
*/
|
|
115
|
+
export declare const searchParamsSchema: z.ZodObject<{
|
|
116
|
+
query: z.ZodOptional<z.ZodString>;
|
|
117
|
+
filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
118
|
+
}, "strip", z.ZodTypeAny, {
|
|
119
|
+
query?: string | undefined;
|
|
120
|
+
filters?: Record<string, unknown> | undefined;
|
|
121
|
+
}, {
|
|
122
|
+
query?: string | undefined;
|
|
123
|
+
filters?: Record<string, unknown> | undefined;
|
|
124
|
+
}>;
|
|
125
|
+
export type SearchParams = z.infer<typeof searchParamsSchema>;
|
|
126
|
+
/**
|
|
127
|
+
* File size validation (in bytes)
|
|
128
|
+
*/
|
|
129
|
+
export declare function maxFileSize(maxBytes: number, message?: string): z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>;
|
|
130
|
+
/**
|
|
131
|
+
* File type validation
|
|
132
|
+
*/
|
|
133
|
+
export declare function allowedFileTypes(types: string[], message?: string): z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>;
|
|
134
|
+
/**
|
|
135
|
+
* Image file validation
|
|
136
|
+
*/
|
|
137
|
+
export declare const imageFileSchema: z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>;
|
|
138
|
+
/**
|
|
139
|
+
* Phone number (flexible international format)
|
|
140
|
+
*/
|
|
141
|
+
export declare const phoneNumberSchema: z.ZodString;
|
|
142
|
+
/**
|
|
143
|
+
* Postal/ZIP code (flexible format)
|
|
144
|
+
*/
|
|
145
|
+
export declare const postalCodeSchema: z.ZodString;
|
|
146
|
+
export declare const addressSchema: z.ZodObject<{
|
|
147
|
+
street: z.ZodString;
|
|
148
|
+
street2: z.ZodOptional<z.ZodString>;
|
|
149
|
+
city: z.ZodString;
|
|
150
|
+
state: z.ZodOptional<z.ZodString>;
|
|
151
|
+
postalCode: z.ZodString;
|
|
152
|
+
country: z.ZodString;
|
|
153
|
+
}, "strip", z.ZodTypeAny, {
|
|
154
|
+
country: string;
|
|
155
|
+
street: string;
|
|
156
|
+
city: string;
|
|
157
|
+
postalCode: string;
|
|
158
|
+
street2?: string | undefined;
|
|
159
|
+
state?: string | undefined;
|
|
160
|
+
}, {
|
|
161
|
+
country: string;
|
|
162
|
+
street: string;
|
|
163
|
+
city: string;
|
|
164
|
+
postalCode: string;
|
|
165
|
+
street2?: string | undefined;
|
|
166
|
+
state?: string | undefined;
|
|
167
|
+
}>;
|
|
168
|
+
export type Address = z.infer<typeof addressSchema>;
|
|
169
|
+
/**
|
|
170
|
+
* Create a schema with custom error message
|
|
171
|
+
*/
|
|
172
|
+
export declare function withMessage<T extends z.ZodTypeAny>(schema: T, message: string): z.ZodEffects<T, any, any>;
|
|
173
|
+
/**
|
|
174
|
+
* Make all fields in a schema optional
|
|
175
|
+
*/
|
|
176
|
+
export declare function makePartial<T extends z.ZodRawShape>(schema: z.ZodObject<T>): z.ZodObject<{ [k in keyof T]: z.ZodOptional<T[k]>; }, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<{ [k in keyof T]: z.ZodOptional<T[k]>; }>, any> extends infer T_1 ? { [k_1 in keyof T_1]: T_1[k_1]; } : never, z.baseObjectInputType<{ [k in keyof T]: z.ZodOptional<T[k]>; }> extends infer T_2 ? { [k_2 in keyof T_2]: T_2[k_2]; } : never>;
|
|
177
|
+
/**
|
|
178
|
+
* Helper to create a pick object for schema.pick()
|
|
179
|
+
* Use: schema.pick(pickKeys(['field1', 'field2']))
|
|
180
|
+
*/
|
|
181
|
+
export declare function pickKeys<K extends string>(keys: K[]): Record<K, true>;
|
|
182
|
+
/**
|
|
183
|
+
* Helper to create an omit object for schema.omit()
|
|
184
|
+
* Use: schema.omit(omitKeys(['field1', 'field2']))
|
|
185
|
+
*/
|
|
186
|
+
export declare function omitKeys<K extends string>(keys: K[]): Record<K, true>;
|
|
187
|
+
/**
|
|
188
|
+
* Standard API response schema
|
|
189
|
+
*/
|
|
190
|
+
export declare function apiResponseSchema<T extends z.ZodTypeAny>(dataSchema: T): z.ZodObject<{
|
|
191
|
+
success: z.ZodBoolean;
|
|
192
|
+
data: z.ZodOptional<T>;
|
|
193
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
194
|
+
code: z.ZodString;
|
|
195
|
+
message: z.ZodString;
|
|
196
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
197
|
+
}, "strip", z.ZodTypeAny, {
|
|
198
|
+
message: string;
|
|
199
|
+
code: string;
|
|
200
|
+
details?: Record<string, unknown> | undefined;
|
|
201
|
+
}, {
|
|
202
|
+
message: string;
|
|
203
|
+
code: string;
|
|
204
|
+
details?: Record<string, unknown> | undefined;
|
|
205
|
+
}>>;
|
|
206
|
+
}, "strip", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<{
|
|
207
|
+
success: z.ZodBoolean;
|
|
208
|
+
data: z.ZodOptional<T>;
|
|
209
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
210
|
+
code: z.ZodString;
|
|
211
|
+
message: z.ZodString;
|
|
212
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
213
|
+
}, "strip", z.ZodTypeAny, {
|
|
214
|
+
message: string;
|
|
215
|
+
code: string;
|
|
216
|
+
details?: Record<string, unknown> | undefined;
|
|
217
|
+
}, {
|
|
218
|
+
message: string;
|
|
219
|
+
code: string;
|
|
220
|
+
details?: Record<string, unknown> | undefined;
|
|
221
|
+
}>>;
|
|
222
|
+
}>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<{
|
|
223
|
+
success: z.ZodBoolean;
|
|
224
|
+
data: z.ZodOptional<T>;
|
|
225
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
226
|
+
code: z.ZodString;
|
|
227
|
+
message: z.ZodString;
|
|
228
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
229
|
+
}, "strip", z.ZodTypeAny, {
|
|
230
|
+
message: string;
|
|
231
|
+
code: string;
|
|
232
|
+
details?: Record<string, unknown> | undefined;
|
|
233
|
+
}, {
|
|
234
|
+
message: string;
|
|
235
|
+
code: string;
|
|
236
|
+
details?: Record<string, unknown> | undefined;
|
|
237
|
+
}>>;
|
|
238
|
+
}> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
239
|
+
/**
|
|
240
|
+
* Paginated response schema
|
|
241
|
+
*/
|
|
242
|
+
export declare function paginatedResponseSchema<T extends z.ZodTypeAny>(itemSchema: T): z.ZodObject<{
|
|
243
|
+
items: z.ZodArray<T, "many">;
|
|
244
|
+
total: z.ZodNumber;
|
|
245
|
+
page: z.ZodNumber;
|
|
246
|
+
pageSize: z.ZodNumber;
|
|
247
|
+
totalPages: z.ZodNumber;
|
|
248
|
+
}, "strip", z.ZodTypeAny, {
|
|
249
|
+
items: T["_output"][];
|
|
250
|
+
page: number;
|
|
251
|
+
pageSize: number;
|
|
252
|
+
total: number;
|
|
253
|
+
totalPages: number;
|
|
254
|
+
}, {
|
|
255
|
+
items: T["_input"][];
|
|
256
|
+
page: number;
|
|
257
|
+
pageSize: number;
|
|
258
|
+
total: number;
|
|
259
|
+
totalPages: number;
|
|
260
|
+
}>;
|
|
261
|
+
export type PaginatedResponse<T> = {
|
|
262
|
+
items: T[];
|
|
263
|
+
total: number;
|
|
264
|
+
page: number;
|
|
265
|
+
pageSize: number;
|
|
266
|
+
totalPages: number;
|
|
267
|
+
};
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Validation Schemas
|
|
3
|
+
*
|
|
4
|
+
* Reusable Zod schemas for common data types and validation patterns.
|
|
5
|
+
* These can be composed with other schemas or used standalone.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// String Validators
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Non-empty string
|
|
13
|
+
*/
|
|
14
|
+
export const nonEmptyString = z.string().min(1, 'This field is required');
|
|
15
|
+
/**
|
|
16
|
+
* Trimmed non-empty string (strips whitespace)
|
|
17
|
+
*/
|
|
18
|
+
export const trimmedString = z.string().trim().min(1, 'This field is required');
|
|
19
|
+
/**
|
|
20
|
+
* Optional string (empty string treated as undefined)
|
|
21
|
+
*/
|
|
22
|
+
export const optionalString = z
|
|
23
|
+
.string()
|
|
24
|
+
.transform((val) => (val === '' ? undefined : val))
|
|
25
|
+
.optional();
|
|
26
|
+
/**
|
|
27
|
+
* URL validation
|
|
28
|
+
*/
|
|
29
|
+
export const urlSchema = z.string().url('Please enter a valid URL');
|
|
30
|
+
/**
|
|
31
|
+
* Optional URL
|
|
32
|
+
*/
|
|
33
|
+
export const optionalUrlSchema = z
|
|
34
|
+
.string()
|
|
35
|
+
.url('Please enter a valid URL')
|
|
36
|
+
.optional()
|
|
37
|
+
.or(z.literal(''));
|
|
38
|
+
/**
|
|
39
|
+
* Slug validation (URL-friendly string)
|
|
40
|
+
*/
|
|
41
|
+
export const slugSchema = z
|
|
42
|
+
.string()
|
|
43
|
+
.min(1, 'Slug is required')
|
|
44
|
+
.max(100, 'Slug must be at most 100 characters')
|
|
45
|
+
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'Slug must be lowercase with hyphens only');
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Number Validators
|
|
48
|
+
// ============================================================================
|
|
49
|
+
/**
|
|
50
|
+
* Positive integer
|
|
51
|
+
*/
|
|
52
|
+
export const positiveInt = z.number().int().positive('Must be a positive number');
|
|
53
|
+
/**
|
|
54
|
+
* Non-negative integer (0 or greater)
|
|
55
|
+
*/
|
|
56
|
+
export const nonNegativeInt = z.number().int().min(0, 'Must be 0 or greater');
|
|
57
|
+
/**
|
|
58
|
+
* Percentage (0-100)
|
|
59
|
+
*/
|
|
60
|
+
export const percentageSchema = z
|
|
61
|
+
.number()
|
|
62
|
+
.min(0, 'Must be at least 0')
|
|
63
|
+
.max(100, 'Must be at most 100');
|
|
64
|
+
/**
|
|
65
|
+
* Price/currency (positive, 2 decimal places)
|
|
66
|
+
*/
|
|
67
|
+
export const priceSchema = z
|
|
68
|
+
.number()
|
|
69
|
+
.positive('Price must be positive')
|
|
70
|
+
.multipleOf(0.01, 'Price must have at most 2 decimal places');
|
|
71
|
+
/**
|
|
72
|
+
* String that parses to a number
|
|
73
|
+
*/
|
|
74
|
+
export const numericString = z
|
|
75
|
+
.string()
|
|
76
|
+
.regex(/^-?\d+\.?\d*$/, 'Must be a valid number')
|
|
77
|
+
.transform((val) => parseFloat(val));
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// Date/Time Validators
|
|
80
|
+
// ============================================================================
|
|
81
|
+
/**
|
|
82
|
+
* ISO date string
|
|
83
|
+
*/
|
|
84
|
+
export const isoDateSchema = z.string().datetime('Please enter a valid date');
|
|
85
|
+
/**
|
|
86
|
+
* Date string in YYYY-MM-DD format
|
|
87
|
+
*/
|
|
88
|
+
export const dateStringSchema = z
|
|
89
|
+
.string()
|
|
90
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, 'Please enter a valid date (YYYY-MM-DD)');
|
|
91
|
+
/**
|
|
92
|
+
* Time string in HH:MM format
|
|
93
|
+
*/
|
|
94
|
+
export const timeStringSchema = z
|
|
95
|
+
.string()
|
|
96
|
+
.regex(/^([01]?\d|2[0-3]):[0-5]\d$/, 'Please enter a valid time (HH:MM)');
|
|
97
|
+
/**
|
|
98
|
+
* Future date validation
|
|
99
|
+
*/
|
|
100
|
+
export const futureDateSchema = z.coerce.date().refine((date) => date > new Date(), {
|
|
101
|
+
message: 'Date must be in the future',
|
|
102
|
+
});
|
|
103
|
+
/**
|
|
104
|
+
* Past date validation
|
|
105
|
+
*/
|
|
106
|
+
export const pastDateSchema = z.coerce.date().refine((date) => date < new Date(), {
|
|
107
|
+
message: 'Date must be in the past',
|
|
108
|
+
});
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Array Validators
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Non-empty array
|
|
114
|
+
*/
|
|
115
|
+
export function nonEmptyArray(schema) {
|
|
116
|
+
return z.array(schema).min(1, 'At least one item is required');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Unique array (no duplicates)
|
|
120
|
+
*/
|
|
121
|
+
export function uniqueArray(schema, message = 'Duplicate values not allowed') {
|
|
122
|
+
return z.array(schema).refine((items) => new Set(items).size === items.length, { message });
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Array with max length
|
|
126
|
+
*/
|
|
127
|
+
export function maxLengthArray(schema, max) {
|
|
128
|
+
return z.array(schema).max(max, `Maximum ${max} items allowed`);
|
|
129
|
+
}
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// Object Validators
|
|
132
|
+
// ============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* ID field (string, typically UUID or similar)
|
|
135
|
+
*/
|
|
136
|
+
export const idSchema = z.string().min(1, 'ID is required');
|
|
137
|
+
/**
|
|
138
|
+
* UUID validation
|
|
139
|
+
*/
|
|
140
|
+
export const uuidSchema = z.string().uuid('Please enter a valid UUID');
|
|
141
|
+
/**
|
|
142
|
+
* Pagination parameters
|
|
143
|
+
*/
|
|
144
|
+
export const paginationSchema = z.object({
|
|
145
|
+
page: z.number().int().min(1).default(1),
|
|
146
|
+
pageSize: z.number().int().min(1).max(100).default(20),
|
|
147
|
+
sortBy: z.string().optional(),
|
|
148
|
+
sortOrder: z.enum(['asc', 'desc']).optional().default('asc'),
|
|
149
|
+
});
|
|
150
|
+
/**
|
|
151
|
+
* Search/filter parameters
|
|
152
|
+
*/
|
|
153
|
+
export const searchParamsSchema = z.object({
|
|
154
|
+
query: z.string().optional(),
|
|
155
|
+
filters: z.record(z.unknown()).optional(),
|
|
156
|
+
});
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// File Validators
|
|
159
|
+
// ============================================================================
|
|
160
|
+
/**
|
|
161
|
+
* File size validation (in bytes)
|
|
162
|
+
*/
|
|
163
|
+
export function maxFileSize(maxBytes, message) {
|
|
164
|
+
return z.instanceof(File).refine((file) => file.size <= maxBytes, {
|
|
165
|
+
message: message || `File must be smaller than ${Math.round(maxBytes / 1024 / 1024)}MB`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* File type validation
|
|
170
|
+
*/
|
|
171
|
+
export function allowedFileTypes(types, message) {
|
|
172
|
+
return z.instanceof(File).refine((file) => types.includes(file.type), {
|
|
173
|
+
message: message || `File must be one of: ${types.join(', ')}`,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Image file validation
|
|
178
|
+
*/
|
|
179
|
+
export const imageFileSchema = z
|
|
180
|
+
.instanceof(File)
|
|
181
|
+
.refine((file) => file.type.startsWith('image/'), { message: 'File must be an image' });
|
|
182
|
+
// ============================================================================
|
|
183
|
+
// Contact Validators
|
|
184
|
+
// ============================================================================
|
|
185
|
+
/**
|
|
186
|
+
* Phone number (flexible international format)
|
|
187
|
+
*/
|
|
188
|
+
export const phoneNumberSchema = z
|
|
189
|
+
.string()
|
|
190
|
+
.regex(/^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/, 'Please enter a valid phone number');
|
|
191
|
+
/**
|
|
192
|
+
* Postal/ZIP code (flexible format)
|
|
193
|
+
*/
|
|
194
|
+
export const postalCodeSchema = z
|
|
195
|
+
.string()
|
|
196
|
+
.min(3, 'Postal code must be at least 3 characters')
|
|
197
|
+
.max(10, 'Postal code must be at most 10 characters');
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Address Schema
|
|
200
|
+
// ============================================================================
|
|
201
|
+
export const addressSchema = z.object({
|
|
202
|
+
street: z.string().min(1, 'Street address is required'),
|
|
203
|
+
street2: z.string().optional(),
|
|
204
|
+
city: z.string().min(1, 'City is required'),
|
|
205
|
+
state: z.string().optional(),
|
|
206
|
+
postalCode: postalCodeSchema,
|
|
207
|
+
country: z.string().min(2, 'Country is required'),
|
|
208
|
+
});
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// Utility Functions
|
|
211
|
+
// ============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Create a schema with custom error message
|
|
214
|
+
*/
|
|
215
|
+
export function withMessage(schema, message) {
|
|
216
|
+
return schema.refine(() => true, { message });
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Make all fields in a schema optional
|
|
220
|
+
*/
|
|
221
|
+
export function makePartial(schema) {
|
|
222
|
+
return schema.partial();
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Helper to create a pick object for schema.pick()
|
|
226
|
+
* Use: schema.pick(pickKeys(['field1', 'field2']))
|
|
227
|
+
*/
|
|
228
|
+
export function pickKeys(keys) {
|
|
229
|
+
return keys.reduce((acc, key) => ({ ...acc, [key]: true }), {});
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Helper to create an omit object for schema.omit()
|
|
233
|
+
* Use: schema.omit(omitKeys(['field1', 'field2']))
|
|
234
|
+
*/
|
|
235
|
+
export function omitKeys(keys) {
|
|
236
|
+
return keys.reduce((acc, key) => ({ ...acc, [key]: true }), {});
|
|
237
|
+
}
|
|
238
|
+
// ============================================================================
|
|
239
|
+
// API Response Wrappers
|
|
240
|
+
// ============================================================================
|
|
241
|
+
/**
|
|
242
|
+
* Standard API response schema
|
|
243
|
+
*/
|
|
244
|
+
export function apiResponseSchema(dataSchema) {
|
|
245
|
+
return z.object({
|
|
246
|
+
success: z.boolean(),
|
|
247
|
+
data: dataSchema.optional(),
|
|
248
|
+
error: z
|
|
249
|
+
.object({
|
|
250
|
+
code: z.string(),
|
|
251
|
+
message: z.string(),
|
|
252
|
+
details: z.record(z.unknown()).optional(),
|
|
253
|
+
})
|
|
254
|
+
.optional(),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Paginated response schema
|
|
259
|
+
*/
|
|
260
|
+
export function paginatedResponseSchema(itemSchema) {
|
|
261
|
+
return z.object({
|
|
262
|
+
items: z.array(itemSchema),
|
|
263
|
+
total: z.number().int().min(0),
|
|
264
|
+
page: z.number().int().min(1),
|
|
265
|
+
pageSize: z.number().int().min(1),
|
|
266
|
+
totalPages: z.number().int().min(0),
|
|
267
|
+
});
|
|
268
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Schemas
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all Zod schemas for authentication and common validation patterns.
|
|
5
|
+
* Also re-exports Zod itself for convenience.
|
|
6
|
+
*/
|
|
7
|
+
export { z } from 'zod';
|
|
8
|
+
export { emailSchema, passwordSchema, loginPasswordSchema, usernameSchema, fullNameSchema, phoneSchema, mfaCodeSchema, totpSecretSchema, } from './auth.js';
|
|
9
|
+
export { loginSchema, registerSchema, forgotPasswordSchema, resetPasswordSchema, changePasswordSchema, mfaVerifySchema, mfaSetupSchema, profileUpdateSchema, emailChangeSchema, } from './auth.js';
|
|
10
|
+
export type { LoginFormData, RegisterFormData, ForgotPasswordFormData, ResetPasswordFormData, ChangePasswordFormData, MfaVerifyFormData, MfaSetupFormData, ProfileUpdateFormData, EmailChangeFormData, } from './auth.js';
|
|
11
|
+
export { userSchema, authTokensSchema, loginResponseSchema } from './auth.js';
|
|
12
|
+
export type { User, AuthTokens, LoginResponse } from './auth.js';
|
|
13
|
+
export { nonEmptyString, trimmedString, optionalString, urlSchema, optionalUrlSchema, slugSchema, } from './common.js';
|
|
14
|
+
export { positiveInt, nonNegativeInt, percentageSchema, priceSchema, numericString, } from './common.js';
|
|
15
|
+
export { isoDateSchema, dateStringSchema, timeStringSchema, futureDateSchema, pastDateSchema, } from './common.js';
|
|
16
|
+
export { nonEmptyArray, uniqueArray, maxLengthArray } from './common.js';
|
|
17
|
+
export { idSchema, uuidSchema, paginationSchema, searchParamsSchema } from './common.js';
|
|
18
|
+
export type { PaginationParams, SearchParams } from './common.js';
|
|
19
|
+
export { maxFileSize, allowedFileTypes, imageFileSchema } from './common.js';
|
|
20
|
+
export { phoneNumberSchema, postalCodeSchema, addressSchema } from './common.js';
|
|
21
|
+
export type { Address } from './common.js';
|
|
22
|
+
export { withMessage, makePartial, pickKeys, omitKeys } from './common.js';
|
|
23
|
+
export { apiResponseSchema, paginatedResponseSchema } from './common.js';
|
|
24
|
+
export type { PaginatedResponse } from './common.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Schemas
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all Zod schemas for authentication and common validation patterns.
|
|
5
|
+
* Also re-exports Zod itself for convenience.
|
|
6
|
+
*/
|
|
7
|
+
// Re-export Zod for convenience
|
|
8
|
+
export { z } from 'zod';
|
|
9
|
+
// Auth schemas - field validators
|
|
10
|
+
export { emailSchema, passwordSchema, loginPasswordSchema, usernameSchema, fullNameSchema, phoneSchema, mfaCodeSchema, totpSecretSchema, } from './auth.js';
|
|
11
|
+
// Auth schemas - form schemas
|
|
12
|
+
export { loginSchema, registerSchema, forgotPasswordSchema, resetPasswordSchema, changePasswordSchema, mfaVerifySchema, mfaSetupSchema, profileUpdateSchema, emailChangeSchema, } from './auth.js';
|
|
13
|
+
// Auth schemas - API response types
|
|
14
|
+
export { userSchema, authTokensSchema, loginResponseSchema } from './auth.js';
|
|
15
|
+
// Common schemas - string validators
|
|
16
|
+
export { nonEmptyString, trimmedString, optionalString, urlSchema, optionalUrlSchema, slugSchema, } from './common.js';
|
|
17
|
+
// Common schemas - number validators
|
|
18
|
+
export { positiveInt, nonNegativeInt, percentageSchema, priceSchema, numericString, } from './common.js';
|
|
19
|
+
// Common schemas - date validators
|
|
20
|
+
export { isoDateSchema, dateStringSchema, timeStringSchema, futureDateSchema, pastDateSchema, } from './common.js';
|
|
21
|
+
// Common schemas - array validators
|
|
22
|
+
export { nonEmptyArray, uniqueArray, maxLengthArray } from './common.js';
|
|
23
|
+
// Common schemas - object validators
|
|
24
|
+
export { idSchema, uuidSchema, paginationSchema, searchParamsSchema } from './common.js';
|
|
25
|
+
// Common schemas - file validators
|
|
26
|
+
export { maxFileSize, allowedFileTypes, imageFileSchema } from './common.js';
|
|
27
|
+
// Common schemas - contact validators
|
|
28
|
+
export { phoneNumberSchema, postalCodeSchema, addressSchema } from './common.js';
|
|
29
|
+
// Common schemas - utility functions
|
|
30
|
+
export { withMessage, makePartial, pickKeys, omitKeys } from './common.js';
|
|
31
|
+
// Common schemas - API response wrappers
|
|
32
|
+
export { apiResponseSchema, paginatedResponseSchema } from './common.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar Store - Svelte 5 runes-based state management for sidebar
|
|
3
|
+
*/
|
|
4
|
+
declare class SidebarStore {
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
isMobile: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Toggle the sidebar open/closed state
|
|
9
|
+
*/
|
|
10
|
+
toggle(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Open the sidebar
|
|
13
|
+
*/
|
|
14
|
+
open(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Close the sidebar
|
|
17
|
+
*/
|
|
18
|
+
close(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Set mobile mode
|
|
21
|
+
*/
|
|
22
|
+
setMobile(isMobile: boolean): void;
|
|
23
|
+
}
|
|
24
|
+
export declare const sidebarStore: SidebarStore;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar Store - Svelte 5 runes-based state management for sidebar
|
|
3
|
+
*/
|
|
4
|
+
class SidebarStore {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.isOpen = $state(true);
|
|
7
|
+
this.isMobile = $state(false);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Toggle the sidebar open/closed state
|
|
11
|
+
*/
|
|
12
|
+
toggle() {
|
|
13
|
+
this.isOpen = !this.isOpen;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Open the sidebar
|
|
17
|
+
*/
|
|
18
|
+
open() {
|
|
19
|
+
this.isOpen = true;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Close the sidebar
|
|
23
|
+
*/
|
|
24
|
+
close() {
|
|
25
|
+
this.isOpen = false;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Set mobile mode
|
|
29
|
+
*/
|
|
30
|
+
setMobile(isMobile) {
|
|
31
|
+
this.isMobile = isMobile;
|
|
32
|
+
// Auto-close sidebar on mobile
|
|
33
|
+
if (isMobile) {
|
|
34
|
+
this.isOpen = false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export const sidebarStore = new SidebarStore();
|