@svadmin/lite 0.3.7 → 0.3.12
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 +19 -13
- package/dist/components/LiteAlert.svelte +19 -0
- package/dist/components/LiteAlert.svelte.d.ts +11 -0
- package/dist/components/LiteArrayField.svelte +60 -0
- package/dist/components/LiteArrayField.svelte.d.ts +17 -0
- package/dist/components/LiteArrayItem.svelte +146 -0
- package/dist/components/LiteArrayItem.svelte.d.ts +13 -0
- package/dist/components/LiteAuditLog.svelte +104 -0
- package/dist/components/LiteAuditLog.svelte.d.ts +23 -0
- package/dist/components/LiteBreadcrumbs.svelte +39 -0
- package/dist/components/LiteBreadcrumbs.svelte.d.ts +16 -0
- package/dist/components/LiteChatDialog.svelte +101 -0
- package/dist/components/LiteChatDialog.svelte.d.ts +20 -0
- package/dist/components/LiteConfirmDialog.svelte +60 -0
- package/dist/components/LiteConfirmDialog.svelte.d.ts +22 -0
- package/dist/components/LiteEmptyState.svelte +39 -0
- package/dist/components/LiteEmptyState.svelte.d.ts +16 -0
- package/dist/components/LiteForm.svelte +165 -0
- package/dist/components/LiteForm.svelte.d.ts +26 -0
- package/dist/components/LiteLayout.svelte +147 -0
- package/dist/components/LiteLayout.svelte.d.ts +19 -0
- package/dist/components/LiteLogin.svelte +41 -0
- package/dist/components/LiteLogin.svelte.d.ts +8 -0
- package/dist/components/LitePagination.svelte +73 -0
- package/dist/components/LitePagination.svelte.d.ts +11 -0
- package/dist/components/LitePermissionMatrix.svelte +147 -0
- package/dist/components/LitePermissionMatrix.svelte.d.ts +32 -0
- package/dist/components/LiteSearch.svelte +41 -0
- package/dist/components/LiteSearch.svelte.d.ts +9 -0
- package/dist/components/LiteShow.svelte +61 -0
- package/dist/components/LiteShow.svelte.d.ts +14 -0
- package/dist/components/LiteShowField.svelte +62 -0
- package/dist/components/LiteShowField.svelte.d.ts +12 -0
- package/dist/components/LiteStatsCard.svelte +70 -0
- package/dist/components/LiteStatsCard.svelte.d.ts +24 -0
- package/dist/components/LiteTable.svelte +132 -0
- package/dist/components/LiteTable.svelte.d.ts +19 -0
- package/dist/components/LiteTabs.svelte +57 -0
- package/dist/components/LiteTabs.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte +26 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte.d.ts +12 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte +33 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteDrawerForm.svelte +42 -0
- package/dist/components/advanced/LiteDrawerForm.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteInlineEdit.svelte +32 -0
- package/dist/components/advanced/LiteInlineEdit.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteModalForm.svelte +44 -0
- package/dist/components/advanced/LiteModalForm.svelte.d.ts +17 -0
- package/dist/components/advanced/LiteToast.svelte +34 -0
- package/dist/components/advanced/LiteToast.svelte.d.ts +14 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte +25 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte.d.ts +13 -0
- package/dist/components/advanced/LiteVirtualTable.svelte +44 -0
- package/dist/components/advanced/LiteVirtualTable.svelte.d.ts +20 -0
- package/dist/components/advanced/index.js +8 -0
- package/dist/components/buttons/LiteCloneButton.svelte +33 -0
- package/dist/components/buttons/LiteCloneButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteCreateButton.svelte +31 -0
- package/dist/components/buttons/LiteCreateButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteDeleteButton.svelte +57 -0
- package/dist/components/buttons/LiteDeleteButton.svelte.d.ts +12 -0
- package/dist/components/buttons/LiteEditButton.svelte +33 -0
- package/dist/components/buttons/LiteEditButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteExportButton.svelte +31 -0
- package/dist/components/buttons/LiteExportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteImportButton.svelte +50 -0
- package/dist/components/buttons/LiteImportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteListButton.svelte +31 -0
- package/dist/components/buttons/LiteListButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteRefreshButton.svelte +34 -0
- package/dist/components/buttons/LiteRefreshButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteSaveButton.svelte +27 -0
- package/dist/components/buttons/LiteSaveButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteShowButton.svelte +33 -0
- package/dist/components/buttons/LiteShowButton.svelte.d.ts +11 -0
- package/dist/components/buttons/index.js +10 -0
- package/dist/components/fields/LiteBooleanField.svelte +42 -0
- package/dist/components/fields/LiteBooleanField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteDateField.svelte +51 -0
- package/dist/components/fields/LiteDateField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteEmailField.svelte +41 -0
- package/dist/components/fields/LiteEmailField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteFileField.svelte +59 -0
- package/dist/components/fields/LiteFileField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteImageField.svelte +57 -0
- package/dist/components/fields/LiteImageField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteJsonField.svelte +43 -0
- package/dist/components/fields/LiteJsonField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMarkdownField.svelte +33 -0
- package/dist/components/fields/LiteMarkdownField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMultiSelectField.svelte +57 -0
- package/dist/components/fields/LiteMultiSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteNumberField.svelte +35 -0
- package/dist/components/fields/LiteNumberField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRelationField.svelte +67 -0
- package/dist/components/fields/LiteRelationField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRichTextField.svelte +44 -0
- package/dist/components/fields/LiteRichTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteSelectField.svelte +47 -0
- package/dist/components/fields/LiteSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTagField.svelte +44 -0
- package/dist/components/fields/LiteTagField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTextField.svelte +35 -0
- package/dist/components/fields/LiteTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteUrlField.svelte +52 -0
- package/dist/components/fields/LiteUrlField.svelte.d.ts +10 -0
- package/dist/components/fields/index.js +15 -0
- package/dist/components/layout/LiteAuthenticated.svelte +23 -0
- package/dist/components/layout/LiteAuthenticated.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCanAccess.svelte +27 -0
- package/dist/components/layout/LiteCanAccess.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte +20 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte.d.ts +7 -0
- package/dist/components/layout/LiteErrorBoundary.svelte +20 -0
- package/dist/components/layout/LiteErrorBoundary.svelte.d.ts +13 -0
- package/dist/components/layout/LiteErrorComponent.svelte +37 -0
- package/dist/components/layout/LiteErrorComponent.svelte.d.ts +9 -0
- package/dist/components/layout/LiteHeader.svelte +19 -0
- package/dist/components/layout/LiteHeader.svelte.d.ts +8 -0
- package/dist/components/layout/LiteNavigateToResource.svelte +25 -0
- package/dist/components/layout/LiteNavigateToResource.svelte.d.ts +7 -0
- package/dist/components/layout/LiteSidebar.svelte +93 -0
- package/dist/components/layout/LiteSidebar.svelte.d.ts +12 -0
- package/dist/components/layout/index.js +8 -0
- package/dist/components/pages/LiteCreatePage.svelte +39 -0
- package/dist/components/pages/LiteCreatePage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteEditPage.svelte +54 -0
- package/dist/components/pages/LiteEditPage.svelte.d.ts +12 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte +60 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteListPage.svelte +81 -0
- package/dist/components/pages/LiteListPage.svelte.d.ts +20 -0
- package/dist/components/pages/LiteProfilePage.svelte +61 -0
- package/dist/components/pages/LiteProfilePage.svelte.d.ts +14 -0
- package/dist/components/pages/LiteRegisterPage.svelte +63 -0
- package/dist/components/pages/LiteRegisterPage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteShowPage.svelte +61 -0
- package/dist/components/pages/LiteShowPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte +51 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte.d.ts +9 -0
- package/dist/components/pages/index.js +8 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte +40 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte.d.ts +15 -0
- package/dist/components/widgets/LiteBarChart.svelte +45 -0
- package/dist/components/widgets/LiteBarChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LiteInsightCard.svelte +31 -0
- package/dist/components/widgets/LiteInsightCard.svelte.d.ts +13 -0
- package/dist/components/widgets/LiteLineChart.svelte +48 -0
- package/dist/components/widgets/LiteLineChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LitePieChart.svelte +44 -0
- package/dist/components/widgets/LitePieChart.svelte.d.ts +17 -0
- package/dist/components/widgets/index.js +5 -0
- package/dist/enhance.js +112 -0
- package/dist/index.d.ts +27 -0
- package/{src/index.ts → dist/index.js} +3 -26
- package/dist/lite.css +817 -0
- package/dist/schema-generator.d.ts +29 -0
- package/dist/schema-generator.js +226 -0
- package/dist/security.d.ts +14 -0
- package/dist/security.js +59 -0
- package/dist/server-adapter.d.ts +111 -0
- package/dist/server-adapter.js +422 -0
- package/package.json +57 -20
- package/src/schema-generator.ts +0 -147
- package/src/server-adapter.ts +0 -307
- /package/{src/components/advanced/index.ts → dist/components/advanced/index.d.ts} +0 -0
- /package/{src/components/buttons/index.ts → dist/components/buttons/index.d.ts} +0 -0
- /package/{src/components/fields/index.ts → dist/components/fields/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/components/pages/index.ts → dist/components/pages/index.d.ts} +0 -0
- /package/{src/components/widgets/index.ts → dist/components/widgets/index.d.ts} +0 -0
package/src/server-adapter.ts
DELETED
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @svadmin/lite — Server Adapter
|
|
3
|
-
*
|
|
4
|
-
* Bridges @svadmin/core DataProvider into SvelteKit server loaders and form actions.
|
|
5
|
-
* All data fetching happens on the server — zero client-side JS required.
|
|
6
|
-
*/
|
|
7
|
-
import type {
|
|
8
|
-
DataProvider, AuthProvider,
|
|
9
|
-
ResourceDefinition, FieldDefinition,
|
|
10
|
-
Sort, Filter,
|
|
11
|
-
} from '@svadmin/core';
|
|
12
|
-
import { redirect, isRedirect, type RequestEvent } from '@sveltejs/kit';
|
|
13
|
-
|
|
14
|
-
// ─── List Loader ──────────────────────────────────────────────
|
|
15
|
-
|
|
16
|
-
export interface ListLoaderResult {
|
|
17
|
-
records: Record<string, unknown>[];
|
|
18
|
-
total: number;
|
|
19
|
-
page: number;
|
|
20
|
-
pageSize: number;
|
|
21
|
-
totalPages: number;
|
|
22
|
-
sort?: string;
|
|
23
|
-
order?: 'asc' | 'desc';
|
|
24
|
-
search?: string;
|
|
25
|
-
resource: ResourceDefinition;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Creates a SvelteKit `load` function that fetches a resource list
|
|
30
|
-
* via the DataProvider. All state is driven by URL search params.
|
|
31
|
-
*/
|
|
32
|
-
export function createListLoader(
|
|
33
|
-
dp: DataProvider,
|
|
34
|
-
resource: ResourceDefinition,
|
|
35
|
-
) {
|
|
36
|
-
return async ({ url }: { url: URL }): Promise<ListLoaderResult> => {
|
|
37
|
-
const page = Math.max(1, Number(url.searchParams.get('page')) || 1);
|
|
38
|
-
const pageSize = resource.pageSize ?? 20;
|
|
39
|
-
const sort = url.searchParams.get('sort') ?? undefined;
|
|
40
|
-
const order = (url.searchParams.get('order') as 'asc' | 'desc') ?? 'asc';
|
|
41
|
-
const search = url.searchParams.get('q') ?? undefined;
|
|
42
|
-
|
|
43
|
-
const sorters: Sort[] = sort ? [{ field: sort, order }] :
|
|
44
|
-
resource.defaultSort ? [resource.defaultSort] : [];
|
|
45
|
-
|
|
46
|
-
const filters: Filter[] = [];
|
|
47
|
-
if (search) {
|
|
48
|
-
const searchable = resource.fields.find((f: FieldDefinition) => f.searchable);
|
|
49
|
-
if (searchable) {
|
|
50
|
-
filters.push({ field: searchable.key, operator: 'contains', value: search });
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const result = await dp.getList({
|
|
55
|
-
resource: resource.name,
|
|
56
|
-
pagination: { current: page, pageSize },
|
|
57
|
-
sorters,
|
|
58
|
-
filters,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
records: result.data as Record<string, unknown>[],
|
|
63
|
-
total: result.total,
|
|
64
|
-
page,
|
|
65
|
-
pageSize,
|
|
66
|
-
totalPages: Math.ceil(result.total / pageSize),
|
|
67
|
-
sort,
|
|
68
|
-
order,
|
|
69
|
-
search,
|
|
70
|
-
resource,
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ─── Detail Loader ────────────────────────────────────────────
|
|
76
|
-
|
|
77
|
-
export function createDetailLoader(
|
|
78
|
-
dp: DataProvider,
|
|
79
|
-
resource: ResourceDefinition,
|
|
80
|
-
) {
|
|
81
|
-
return async ({ params }: { params: { id: string } }) => {
|
|
82
|
-
const result = await dp.getOne({
|
|
83
|
-
resource: resource.name,
|
|
84
|
-
id: params.id,
|
|
85
|
-
});
|
|
86
|
-
return { record: result.data as Record<string, unknown>, resource };
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ─── CRUD Form Actions ────────────────────────────────────────
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Creates SvelteKit form actions for create / update / delete.
|
|
94
|
-
* Works with standard `<form method="POST">` submissions — no JS needed.
|
|
95
|
-
*/
|
|
96
|
-
export function createCrudActions(
|
|
97
|
-
dp: DataProvider,
|
|
98
|
-
resource: ResourceDefinition,
|
|
99
|
-
) {
|
|
100
|
-
const pk = resource.primaryKey ?? 'id';
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
create: async ({ request }: RequestEvent) => {
|
|
104
|
-
const formData = await request.formData();
|
|
105
|
-
const variables = formDataToObject(formData, resource.fields);
|
|
106
|
-
try {
|
|
107
|
-
const result = await dp.create({ resource: resource.name, variables });
|
|
108
|
-
return { success: true, id: (result.data as Record<string, unknown>)[pk] };
|
|
109
|
-
} catch (e) {
|
|
110
|
-
if (isRedirect(e)) throw e;
|
|
111
|
-
return { success: false, error: (e as Error).message, values: variables };
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
update: async ({ request }: RequestEvent) => {
|
|
116
|
-
const formData = await request.formData();
|
|
117
|
-
const id = formData.get('_id') as string;
|
|
118
|
-
formData.delete('_id');
|
|
119
|
-
const variables = formDataToObject(formData, resource.fields);
|
|
120
|
-
try {
|
|
121
|
-
await dp.update({ resource: resource.name, id, variables });
|
|
122
|
-
return { success: true };
|
|
123
|
-
} catch (e) {
|
|
124
|
-
if (isRedirect(e)) throw e;
|
|
125
|
-
return { success: false, error: (e as Error).message, values: variables };
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
delete: async ({ request }: RequestEvent) => {
|
|
130
|
-
const formData = await request.formData();
|
|
131
|
-
const id = formData.get('id') as string;
|
|
132
|
-
const redirectTo = formData.get('redirect') as string | undefined;
|
|
133
|
-
try {
|
|
134
|
-
await dp.deleteOne({ resource: resource.name, id });
|
|
135
|
-
if (redirectTo) throw redirect(303, redirectTo);
|
|
136
|
-
return { success: true };
|
|
137
|
-
} catch (e) {
|
|
138
|
-
if (isRedirect(e)) throw e;
|
|
139
|
-
return { success: false, error: (e as Error).message };
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// ─── Auth Helpers ─────────────────────────────────────────────
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Creates a SvelteKit server hook that checks auth via AuthProvider
|
|
149
|
-
* and redirects unauthenticated users to a login page.
|
|
150
|
-
*/
|
|
151
|
-
export function createAuthGuard(
|
|
152
|
-
authProvider: AuthProvider,
|
|
153
|
-
loginPath = '/lite/login',
|
|
154
|
-
) {
|
|
155
|
-
return async ({ event, resolve }: { event: RequestEvent; resolve: (event: RequestEvent) => Promise<Response> }) => {
|
|
156
|
-
// Skip auth check for the login page itself
|
|
157
|
-
if (event.url.pathname === loginPath) {
|
|
158
|
-
return resolve(event);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Local Lite Session Verify
|
|
162
|
-
const session = event.cookies.get('svadmin-session');
|
|
163
|
-
if (!session) {
|
|
164
|
-
return new Response(null, {
|
|
165
|
-
status: 302,
|
|
166
|
-
headers: { Location: loginPath },
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
const check = await authProvider.check();
|
|
172
|
-
if (!check.authenticated) {
|
|
173
|
-
event.cookies.delete('svadmin-session', { path: '/' });
|
|
174
|
-
return new Response(null, {
|
|
175
|
-
status: 302,
|
|
176
|
-
headers: { Location: loginPath },
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
} catch {
|
|
180
|
-
event.cookies.delete('svadmin-session', { path: '/' });
|
|
181
|
-
return new Response(null, {
|
|
182
|
-
status: 302,
|
|
183
|
-
headers: { Location: loginPath },
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return resolve(event);
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Creates login/logout form actions using AuthProvider.
|
|
192
|
-
*/
|
|
193
|
-
export function createAuthActions(authProvider: AuthProvider) {
|
|
194
|
-
return {
|
|
195
|
-
login: async ({ request, cookies }: RequestEvent) => {
|
|
196
|
-
const formData = await request.formData();
|
|
197
|
-
const params = Object.fromEntries(formData);
|
|
198
|
-
try {
|
|
199
|
-
const result = await authProvider.login(params);
|
|
200
|
-
if (result.success) {
|
|
201
|
-
// Store a session indicator in a cookie
|
|
202
|
-
cookies.set('svadmin-session', 'active', {
|
|
203
|
-
path: '/',
|
|
204
|
-
httpOnly: true,
|
|
205
|
-
sameSite: 'lax',
|
|
206
|
-
maxAge: 60 * 60 * 24 * 7, // 7 days
|
|
207
|
-
});
|
|
208
|
-
throw redirect(303, result.redirectTo ?? '/lite');
|
|
209
|
-
}
|
|
210
|
-
return { success: false, error: result.error?.message ?? 'Login failed' };
|
|
211
|
-
} catch (e) {
|
|
212
|
-
if (isRedirect(e)) throw e;
|
|
213
|
-
return { success: false, error: (e as Error).message };
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
logout: async ({ cookies }: RequestEvent) => {
|
|
218
|
-
try { await authProvider.logout(); } catch { /* ignore */ }
|
|
219
|
-
cookies.delete('svadmin-session', { path: '/' });
|
|
220
|
-
return { success: true };
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ─── UA Detection ─────────────────────────────────────────────
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Detects legacy browsers (IE11) from the User-Agent header.
|
|
229
|
-
*/
|
|
230
|
-
export function isLegacyBrowser(userAgent: string): boolean {
|
|
231
|
-
return /MSIE|Trident|rv:11/.test(userAgent);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Creates a SvelteKit handle hook that auto-redirects legacy browsers to /lite/.
|
|
236
|
-
*/
|
|
237
|
-
export function createLegacyRedirectHook(litePrefix = '/lite') {
|
|
238
|
-
return async ({ event, resolve }: { event: RequestEvent; resolve: (event: RequestEvent) => Promise<Response> }) => {
|
|
239
|
-
const ua = event.request.headers.get('user-agent') ?? '';
|
|
240
|
-
if (isLegacyBrowser(ua) && !event.url.pathname.startsWith(litePrefix)) {
|
|
241
|
-
return new Response(null, {
|
|
242
|
-
status: 302,
|
|
243
|
-
headers: { Location: `${litePrefix}${event.url.pathname}` },
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
return resolve(event);
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// ─── Utilities ────────────────────────────────────────────────
|
|
251
|
-
|
|
252
|
-
function formDataToObject(
|
|
253
|
-
formData: FormData,
|
|
254
|
-
fields: FieldDefinition[],
|
|
255
|
-
): Record<string, unknown> {
|
|
256
|
-
const obj: Record<string, unknown> = {};
|
|
257
|
-
for (const field of fields) {
|
|
258
|
-
if (field.showInForm === false) continue;
|
|
259
|
-
|
|
260
|
-
// Handle array types (like multiselect)
|
|
261
|
-
if (field.type === 'multiselect') {
|
|
262
|
-
const values = formData.getAll(field.key);
|
|
263
|
-
if (values.length > 0) {
|
|
264
|
-
obj[field.key] = values.map(v => String(v));
|
|
265
|
-
}
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const raw = formData.get(field.key);
|
|
270
|
-
if (raw === null) {
|
|
271
|
-
if (field.type === 'boolean') obj[field.key] = false;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Don't coerce File objects, but ignore empty native file inputs
|
|
276
|
-
if (raw instanceof File) {
|
|
277
|
-
if (raw.size > 0 && raw.name !== '') {
|
|
278
|
-
obj[field.key] = raw;
|
|
279
|
-
}
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const strRaw = String(raw);
|
|
284
|
-
|
|
285
|
-
switch (field.type) {
|
|
286
|
-
case 'number':
|
|
287
|
-
obj[field.key] = strRaw === '' ? null : Number(strRaw);
|
|
288
|
-
break;
|
|
289
|
-
case 'boolean':
|
|
290
|
-
obj[field.key] = strRaw === 'on' || strRaw === 'true' || strRaw === '1';
|
|
291
|
-
break;
|
|
292
|
-
case 'tags':
|
|
293
|
-
obj[field.key] = strRaw ? strRaw.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
294
|
-
break;
|
|
295
|
-
case 'json':
|
|
296
|
-
try {
|
|
297
|
-
obj[field.key] = strRaw ? JSON.parse(strRaw) : null;
|
|
298
|
-
} catch {
|
|
299
|
-
obj[field.key] = strRaw; // Let Zod handle validation errors
|
|
300
|
-
}
|
|
301
|
-
break;
|
|
302
|
-
default:
|
|
303
|
-
obj[field.key] = strRaw;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return obj;
|
|
307
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|