sveltekit-admin 0.2.0 → 0.5.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.
Files changed (72) hide show
  1. package/README.md +80 -2
  2. package/dist/index.d.ts +2 -7
  3. package/dist/index.js +2 -13
  4. package/dist/server/auth.d.ts +7 -0
  5. package/dist/server/auth.js +19 -0
  6. package/dist/server/data.d.ts +38 -0
  7. package/dist/server/data.js +116 -0
  8. package/dist/server/handler.d.ts +123 -4
  9. package/dist/server/handler.js +590 -819
  10. package/dist/server/introspection/parser.d.ts +19 -12
  11. package/dist/server/introspection/parser.js +71 -61
  12. package/dist/server/introspection/relations.d.ts +49 -0
  13. package/dist/server/introspection/relations.js +128 -0
  14. package/dist/server/query/filterDetection.d.ts +71 -0
  15. package/dist/server/query/filterDetection.js +153 -0
  16. package/dist/server/query/listQuery.d.ts +89 -0
  17. package/dist/server/query/listQuery.js +428 -0
  18. package/dist/server/query/urls.d.ts +33 -0
  19. package/dist/server/query/urls.js +58 -0
  20. package/dist/server/router.d.ts +6 -0
  21. package/dist/server/router.js +27 -0
  22. package/dist/server/views/Dashboard.svelte +29 -0
  23. package/dist/server/views/Dashboard.svelte.d.ts +15 -0
  24. package/dist/server/views/FieldInput.svelte +63 -0
  25. package/dist/server/views/FieldInput.svelte.d.ts +9 -0
  26. package/dist/server/views/Form.svelte +127 -0
  27. package/dist/server/views/Form.svelte.d.ts +12 -0
  28. package/dist/server/views/Layout.svelte +78 -0
  29. package/dist/server/views/Layout.svelte.d.ts +13 -0
  30. package/dist/server/views/List.svelte +240 -0
  31. package/dist/server/views/List.svelte.d.ts +27 -0
  32. package/dist/server/views/ListFilters.svelte +257 -0
  33. package/dist/server/views/ListFilters.svelte.d.ts +18 -0
  34. package/dist/server/views/ModelCard.svelte +11 -0
  35. package/dist/server/views/ModelCard.svelte.d.ts +8 -0
  36. package/dist/server/views/NotFound.svelte +7 -0
  37. package/dist/server/views/NotFound.svelte.d.ts +7 -0
  38. package/dist/server/views/RelatedBlock.svelte +74 -0
  39. package/dist/server/views/RelatedBlock.svelte.d.ts +11 -0
  40. package/dist/server/views/RelationCheckboxes.svelte +53 -0
  41. package/dist/server/views/RelationCheckboxes.svelte.d.ts +9 -0
  42. package/dist/server/views/RelationSelect.svelte +53 -0
  43. package/dist/server/views/RelationSelect.svelte.d.ts +12 -0
  44. package/dist/server/views/StatCard.svelte +18 -0
  45. package/dist/server/views/StatCard.svelte.d.ts +8 -0
  46. package/dist/server/views/html.d.ts +5 -0
  47. package/dist/server/views/html.js +41 -0
  48. package/dist/server/views/theme.d.ts +1 -0
  49. package/dist/server/views/theme.js +484 -0
  50. package/dist/server/views/types.d.ts +57 -0
  51. package/dist/server/views/types.js +1 -0
  52. package/package.json +24 -26
  53. package/dist/admin.d.ts +0 -227
  54. package/dist/admin.js +0 -369
  55. package/dist/components/AdminForm.svelte +0 -423
  56. package/dist/components/AdminForm.svelte.d.ts +0 -30
  57. package/dist/components/AdminLayout.svelte +0 -328
  58. package/dist/components/AdminLayout.svelte.d.ts +0 -20
  59. package/dist/components/DataTable.svelte +0 -573
  60. package/dist/components/DataTable.svelte.d.ts +0 -25
  61. package/dist/components/index.d.ts +0 -3
  62. package/dist/components/index.js +0 -3
  63. package/dist/server/auth/guard.d.ts +0 -36
  64. package/dist/server/auth/guard.js +0 -38
  65. package/dist/server/auth/index.d.ts +0 -1
  66. package/dist/server/auth/index.js +0 -1
  67. package/dist/server/crud/index.d.ts +0 -1
  68. package/dist/server/crud/index.js +0 -1
  69. package/dist/server/crud/operations.d.ts +0 -87
  70. package/dist/server/crud/operations.js +0 -276
  71. package/dist/server/introspection/index.d.ts +0 -1
  72. package/dist/server/introspection/index.js +0 -1
@@ -1,87 +0,0 @@
1
- /**
2
- * CRUD Operations Generator
3
- * Creates type-safe Prisma operations for admin panel
4
- */
5
- import type { PrismaModel } from '../introspection/parser.js';
6
- export interface ListOptions {
7
- page?: number;
8
- perPage?: number;
9
- search?: string;
10
- searchFields?: string[];
11
- orderBy?: string;
12
- orderDir?: 'asc' | 'desc';
13
- filters?: Record<string, unknown>;
14
- }
15
- export interface ListResult<T> {
16
- items: T[];
17
- total: number;
18
- page: number;
19
- perPage: number;
20
- totalPages: number;
21
- }
22
- /**
23
- * Build a Prisma where clause for searching
24
- */
25
- export declare function buildSearchWhere(search: string | undefined, searchFields: string[], model: PrismaModel): Record<string, unknown> | undefined;
26
- /**
27
- * Build filter conditions from query params
28
- */
29
- export declare function buildFilterWhere(filters: Record<string, unknown> | undefined, model: PrismaModel): Record<string, unknown>;
30
- /**
31
- * Create list operation config
32
- */
33
- export declare function createListOperation(model: PrismaModel): {
34
- modelName: string;
35
- searchableFields: string[];
36
- defaultOrderBy: string;
37
- execute<T>(prisma: {
38
- [key: string]: {
39
- findMany: Function;
40
- count: Function;
41
- };
42
- }, options?: ListOptions): Promise<ListResult<T>>;
43
- };
44
- /**
45
- * Create get single record operation
46
- */
47
- export declare function createGetOperation(model: PrismaModel): {
48
- modelName: string;
49
- execute<T>(prisma: {
50
- [key: string]: {
51
- findUnique: Function;
52
- };
53
- }, id: string | number): Promise<T | null>;
54
- };
55
- /**
56
- * Create create operation
57
- */
58
- export declare function createCreateOperation(model: PrismaModel): {
59
- modelName: string;
60
- execute<T>(prisma: {
61
- [key: string]: {
62
- create: Function;
63
- };
64
- }, data: Record<string, unknown>): Promise<T>;
65
- };
66
- /**
67
- * Create update operation
68
- */
69
- export declare function createUpdateOperation(model: PrismaModel): {
70
- modelName: string;
71
- execute<T>(prisma: {
72
- [key: string]: {
73
- update: Function;
74
- };
75
- }, id: string | number, data: Record<string, unknown>): Promise<T>;
76
- };
77
- /**
78
- * Create delete operation
79
- */
80
- export declare function createDeleteOperation(model: PrismaModel): {
81
- modelName: string;
82
- execute(prisma: {
83
- [key: string]: {
84
- delete: Function;
85
- };
86
- }, id: string | number): Promise<void>;
87
- };
@@ -1,276 +0,0 @@
1
- /**
2
- * CRUD Operations Generator
3
- * Creates type-safe Prisma operations for admin panel
4
- */
5
- /**
6
- * Build a Prisma where clause for searching
7
- */
8
- export function buildSearchWhere(search, searchFields, model) {
9
- if (!search || searchFields.length === 0)
10
- return undefined;
11
- const stringFields = searchFields.filter(fieldName => {
12
- const field = model.fields.find(f => f.name === fieldName);
13
- return field?.type === 'String';
14
- });
15
- if (stringFields.length === 0)
16
- return undefined;
17
- return {
18
- OR: stringFields.map(field => ({
19
- [field]: {
20
- contains: search,
21
- mode: 'insensitive'
22
- }
23
- }))
24
- };
25
- }
26
- /**
27
- * Build filter conditions from query params
28
- */
29
- export function buildFilterWhere(filters, model) {
30
- if (!filters)
31
- return {};
32
- const where = {};
33
- for (const [key, value] of Object.entries(filters)) {
34
- if (value === undefined || value === null || value === '')
35
- continue;
36
- const field = model.fields.find(f => f.name === key);
37
- if (!field)
38
- continue;
39
- // Handle different field types
40
- switch (field.type) {
41
- case 'String':
42
- where[key] = { contains: String(value), mode: 'insensitive' };
43
- break;
44
- case 'Int':
45
- case 'Float':
46
- case 'Decimal':
47
- case 'BigInt':
48
- where[key] = Number(value);
49
- break;
50
- case 'Boolean':
51
- where[key] = value === 'true' || value === true;
52
- break;
53
- case 'DateTime':
54
- // Support date range filters
55
- if (typeof value === 'object' && value !== null) {
56
- const dateFilter = {};
57
- if ('from' in value)
58
- dateFilter.gte = new Date(value.from);
59
- if ('to' in value)
60
- dateFilter.lte = new Date(value.to);
61
- where[key] = dateFilter;
62
- }
63
- else {
64
- where[key] = new Date(String(value));
65
- }
66
- break;
67
- default:
68
- // For enums and relations
69
- where[key] = value;
70
- }
71
- }
72
- return where;
73
- }
74
- /**
75
- * Create list operation config
76
- */
77
- export function createListOperation(model) {
78
- const searchableFields = model.fields
79
- .filter(f => f.type === 'String' && !f.relation)
80
- .map(f => f.name);
81
- return {
82
- modelName: model.name,
83
- searchableFields,
84
- defaultOrderBy: model.primaryKey || 'id',
85
- async execute(prisma, options = {}) {
86
- const { page = 1, perPage = 20, search, searchFields = searchableFields, orderBy = model.primaryKey || 'id', orderDir = 'desc', filters } = options;
87
- const modelKey = model.name.charAt(0).toLowerCase() + model.name.slice(1);
88
- const prismaModel = prisma[modelKey];
89
- if (!prismaModel) {
90
- throw new Error(`Model ${model.name} not found in Prisma client`);
91
- }
92
- // Build where clause
93
- const searchWhere = buildSearchWhere(search, searchFields, model);
94
- const filterWhere = buildFilterWhere(filters, model);
95
- const where = {
96
- ...filterWhere,
97
- ...(searchWhere ? searchWhere : {})
98
- };
99
- // Build include for relations (limit depth)
100
- const include = buildInclude(model);
101
- // Execute queries
102
- const [items, total] = await Promise.all([
103
- prismaModel.findMany({
104
- where,
105
- include,
106
- orderBy: { [orderBy]: orderDir },
107
- skip: (page - 1) * perPage,
108
- take: perPage
109
- }),
110
- prismaModel.count({ where })
111
- ]);
112
- return {
113
- items: items,
114
- total,
115
- page,
116
- perPage,
117
- totalPages: Math.ceil(total / perPage)
118
- };
119
- }
120
- };
121
- }
122
- /**
123
- * Create get single record operation
124
- */
125
- export function createGetOperation(model) {
126
- return {
127
- modelName: model.name,
128
- async execute(prisma, id) {
129
- const modelKey = model.name.charAt(0).toLowerCase() + model.name.slice(1);
130
- const prismaModel = prisma[modelKey];
131
- if (!prismaModel) {
132
- throw new Error(`Model ${model.name} not found in Prisma client`);
133
- }
134
- const primaryKey = model.primaryKey || 'id';
135
- const include = buildInclude(model);
136
- // Convert ID to correct type
137
- const pkField = model.fields.find(f => f.name === primaryKey);
138
- const typedId = pkField?.type === 'Int' ? parseInt(String(id)) : id;
139
- return prismaModel.findUnique({
140
- where: { [primaryKey]: typedId },
141
- include
142
- });
143
- }
144
- };
145
- }
146
- /**
147
- * Create create operation
148
- */
149
- export function createCreateOperation(model) {
150
- return {
151
- modelName: model.name,
152
- async execute(prisma, data) {
153
- const modelKey = model.name.charAt(0).toLowerCase() + model.name.slice(1);
154
- const prismaModel = prisma[modelKey];
155
- if (!prismaModel) {
156
- throw new Error(`Model ${model.name} not found in Prisma client`);
157
- }
158
- // Process data - handle relations
159
- const processedData = processInputData(data, model);
160
- return prismaModel.create({
161
- data: processedData
162
- });
163
- }
164
- };
165
- }
166
- /**
167
- * Create update operation
168
- */
169
- export function createUpdateOperation(model) {
170
- return {
171
- modelName: model.name,
172
- async execute(prisma, id, data) {
173
- const modelKey = model.name.charAt(0).toLowerCase() + model.name.slice(1);
174
- const prismaModel = prisma[modelKey];
175
- if (!prismaModel) {
176
- throw new Error(`Model ${model.name} not found in Prisma client`);
177
- }
178
- const primaryKey = model.primaryKey || 'id';
179
- const pkField = model.fields.find(f => f.name === primaryKey);
180
- const typedId = pkField?.type === 'Int' ? parseInt(String(id)) : id;
181
- // Process data - handle relations
182
- const processedData = processInputData(data, model);
183
- return prismaModel.update({
184
- where: { [primaryKey]: typedId },
185
- data: processedData
186
- });
187
- }
188
- };
189
- }
190
- /**
191
- * Create delete operation
192
- */
193
- export function createDeleteOperation(model) {
194
- return {
195
- modelName: model.name,
196
- async execute(prisma, id) {
197
- const modelKey = model.name.charAt(0).toLowerCase() + model.name.slice(1);
198
- const prismaModel = prisma[modelKey];
199
- if (!prismaModel) {
200
- throw new Error(`Model ${model.name} not found in Prisma client`);
201
- }
202
- const primaryKey = model.primaryKey || 'id';
203
- const pkField = model.fields.find(f => f.name === primaryKey);
204
- const typedId = pkField?.type === 'Int' ? parseInt(String(id)) : id;
205
- await prismaModel.delete({
206
- where: { [primaryKey]: typedId }
207
- });
208
- }
209
- };
210
- }
211
- /**
212
- * Build include object for relations
213
- */
214
- function buildInclude(model) {
215
- const include = {};
216
- for (const field of model.fields) {
217
- if (field.relation && !field.isList) {
218
- // Only include single relations, not lists (for performance)
219
- include[field.name] = true;
220
- }
221
- }
222
- return Object.keys(include).length > 0 ? include : undefined;
223
- }
224
- /**
225
- * Process input data for create/update
226
- */
227
- function processInputData(data, model) {
228
- const processed = {};
229
- for (const field of model.fields) {
230
- // Skip auto-generated fields
231
- if (field.isId || field.isCreatedAt || field.isUpdatedAt)
232
- continue;
233
- const value = data[field.name];
234
- // Skip undefined values
235
- if (value === undefined)
236
- continue;
237
- // Handle relations
238
- if (field.relation?.fields) {
239
- // This is the "owning" side of a relation with foreign key
240
- // User provides the related ID directly
241
- const fkField = field.relation.fields[0];
242
- if (data[fkField] !== undefined) {
243
- processed[fkField] = data[fkField];
244
- }
245
- continue;
246
- }
247
- // Handle type conversions
248
- if (value !== null && value !== '') {
249
- switch (field.type) {
250
- case 'Int':
251
- case 'BigInt':
252
- processed[field.name] = parseInt(String(value));
253
- break;
254
- case 'Float':
255
- case 'Decimal':
256
- processed[field.name] = parseFloat(String(value));
257
- break;
258
- case 'Boolean':
259
- processed[field.name] = value === true || value === 'true' || value === 'on';
260
- break;
261
- case 'DateTime':
262
- processed[field.name] = new Date(String(value));
263
- break;
264
- case 'Json':
265
- processed[field.name] = typeof value === 'string' ? JSON.parse(value) : value;
266
- break;
267
- default:
268
- processed[field.name] = value;
269
- }
270
- }
271
- else if (!field.isRequired) {
272
- processed[field.name] = null;
273
- }
274
- }
275
- return processed;
276
- }
@@ -1 +0,0 @@
1
- export * from './parser.js';
@@ -1 +0,0 @@
1
- export * from './parser.js';