@marktiderman/genesis-ui 1.1.0 → 1.2.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/dist/{chunk-X7KMF6NH.js → chunk-IP6TMT3D.js} +3 -3
- package/dist/{chunk-X7KMF6NH.js.map → chunk-IP6TMT3D.js.map} +1 -1
- package/dist/{chunk-MUQLZFUR.js → chunk-NPNADZHM.js} +11 -5
- package/dist/chunk-NPNADZHM.js.map +1 -0
- package/dist/{chunk-CLK7JBZJ.js → chunk-QLCDAFS7.js} +2 -2
- package/dist/chunk-QLCDAFS7.js.map +1 -0
- package/dist/{chunk-6V4GJUE3.js → chunk-QSXVL5UB.js} +4 -3
- package/dist/chunk-QSXVL5UB.js.map +1 -0
- package/dist/{chunk-AIODTBWP.js → chunk-T5VX5DYO.js} +3 -2
- package/dist/chunk-T5VX5DYO.js.map +1 -0
- package/dist/chunk-YETMISCE.js +23 -0
- package/dist/chunk-YETMISCE.js.map +1 -0
- package/dist/components/data/index.d.ts +4 -6
- package/dist/components/data/index.js +14 -17
- package/dist/components/data/index.js.map +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/form-field.js +2 -2
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +3 -3
- package/dist/hooks/use-resource-page.d.ts +2 -2
- package/dist/hooks/use-resource-page.js +1 -1
- package/dist/index.js +26 -26
- package/dist/{use-resource-page-BzvUM8de.d.ts → use-resource-page-B-CFcikK.d.ts} +1 -1
- package/package.json +6 -2
- package/dist/chunk-4HUKJSKC.js +0 -51
- package/dist/chunk-4HUKJSKC.js.map +0 -1
- package/dist/chunk-6V4GJUE3.js.map +0 -1
- package/dist/chunk-A5WHNNXJ.js +0 -22
- package/dist/chunk-A5WHNNXJ.js.map +0 -1
- package/dist/chunk-AIODTBWP.js.map +0 -1
- package/dist/chunk-CLK7JBZJ.js.map +0 -1
- package/dist/chunk-F2JB7YFF.js +0 -341
- package/dist/chunk-F2JB7YFF.js.map +0 -1
- package/dist/chunk-IKIFQILN.js +0 -124
- package/dist/chunk-IKIFQILN.js.map +0 -1
- package/dist/chunk-JEECTX26.js +0 -20
- package/dist/chunk-JEECTX26.js.map +0 -1
- package/dist/chunk-MUQLZFUR.js.map +0 -1
- package/dist/chunk-W64GERJW.js +0 -22
- package/dist/chunk-W64GERJW.js.map +0 -1
- package/dist/hooks/use-one.d.ts +0 -18
- package/dist/hooks/use-one.js +0 -4
- package/dist/hooks/use-one.js.map +0 -1
- package/dist/hooks/use-resource-form.d.ts +0 -37
- package/dist/hooks/use-resource-form.js +0 -7
- package/dist/hooks/use-resource-form.js.map +0 -1
- package/dist/hooks/use-resource.d.ts +0 -46
- package/dist/hooks/use-resource.js +0 -4
- package/dist/hooks/use-resource.js.map +0 -1
- package/dist/hooks/use-wizard.d.ts +0 -25
- package/dist/hooks/use-wizard.js +0 -3
- package/dist/hooks/use-wizard.js.map +0 -1
- package/dist/types-HIZY7zxO.d.ts +0 -61
package/dist/chunk-F2JB7YFF.js
DELETED
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { titleCase } from './chunk-CLK7JBZJ.js';
|
|
3
|
-
import { useOne } from './chunk-A5WHNNXJ.js';
|
|
4
|
-
import { useDataProvider } from './chunk-JEECTX26.js';
|
|
5
|
-
import { useMemo, useEffect, useCallback } from 'react';
|
|
6
|
-
import { useForm } from 'react-hook-form';
|
|
7
|
-
import { zodResolver } from '@hookform/resolvers/zod';
|
|
8
|
-
import { z } from 'zod';
|
|
9
|
-
import { useQueryClient } from '@tanstack/react-query';
|
|
10
|
-
|
|
11
|
-
function inferFieldType(value) {
|
|
12
|
-
if (typeof value === "boolean") return "switch";
|
|
13
|
-
if (typeof value === "number") return "number";
|
|
14
|
-
if (typeof value === "string") {
|
|
15
|
-
if (/^\d{4}-\d{2}-\d{2}/.test(value)) return "date";
|
|
16
|
-
if (value.includes("@") && value.includes(".")) return "email";
|
|
17
|
-
if (/^https?:\/\//.test(value)) return "url";
|
|
18
|
-
if (value.length > 100) return "textarea";
|
|
19
|
-
}
|
|
20
|
-
return "text";
|
|
21
|
-
}
|
|
22
|
-
function inferSelectFromData(key, allData) {
|
|
23
|
-
if (!allData || allData.length === 0) return null;
|
|
24
|
-
const uniqueValues = /* @__PURE__ */ new Set();
|
|
25
|
-
for (const row of allData) {
|
|
26
|
-
const v = row[key];
|
|
27
|
-
if (typeof v === "string" && v.length > 0) uniqueValues.add(v);
|
|
28
|
-
}
|
|
29
|
-
if (uniqueValues.size > 0 && uniqueValues.size <= 10) {
|
|
30
|
-
return {
|
|
31
|
-
type: "select",
|
|
32
|
-
options: Array.from(uniqueValues).sort().map((v) => ({ value: v, label: v }))
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
function defaultPlaceholder(key, type) {
|
|
38
|
-
switch (type) {
|
|
39
|
-
case "email":
|
|
40
|
-
return "name@example.com";
|
|
41
|
-
case "url":
|
|
42
|
-
return "https://...";
|
|
43
|
-
case "number":
|
|
44
|
-
return "0";
|
|
45
|
-
case "date":
|
|
46
|
-
return "YYYY-MM-DD";
|
|
47
|
-
case "textarea":
|
|
48
|
-
return `Enter ${titleCase(key).toLowerCase()}...`;
|
|
49
|
-
default:
|
|
50
|
-
return `Enter ${titleCase(key).toLowerCase()}`;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function resolveFields(fields, data, allData) {
|
|
54
|
-
if (fields && fields.length > 0) {
|
|
55
|
-
return fields.map((f) => {
|
|
56
|
-
const inferred = f.type ?? (data ? inferFieldType(data[f.key]) : "text");
|
|
57
|
-
return {
|
|
58
|
-
...f,
|
|
59
|
-
label: f.label ?? titleCase(f.key),
|
|
60
|
-
type: inferred,
|
|
61
|
-
placeholder: f.placeholder ?? defaultPlaceholder(f.key, inferred),
|
|
62
|
-
required: f.required ?? (inferred !== "switch" && inferred !== "checkbox" && inferred !== "hidden")
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
if (!data) return [];
|
|
67
|
-
return Object.keys(data).filter((key) => key !== "id" && key !== "created_at" && key !== "updated_at").map((key) => {
|
|
68
|
-
if (typeof data[key] === "string") {
|
|
69
|
-
const selectInfo = inferSelectFromData(key, allData);
|
|
70
|
-
if (selectInfo) {
|
|
71
|
-
return {
|
|
72
|
-
key,
|
|
73
|
-
label: titleCase(key),
|
|
74
|
-
type: selectInfo.type,
|
|
75
|
-
options: selectInfo.options,
|
|
76
|
-
placeholder: `Select ${titleCase(key).toLowerCase()}...`,
|
|
77
|
-
required: true
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const inferred = inferFieldType(data[key]);
|
|
82
|
-
return {
|
|
83
|
-
key,
|
|
84
|
-
label: titleCase(key),
|
|
85
|
-
type: inferred,
|
|
86
|
-
placeholder: defaultPlaceholder(key, inferred),
|
|
87
|
-
required: inferred !== "switch" && inferred !== "checkbox" && inferred !== "hidden"
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
function buildSchema(fields) {
|
|
92
|
-
const shape = {};
|
|
93
|
-
for (const field of fields) {
|
|
94
|
-
const fieldType = field.type ?? "text";
|
|
95
|
-
if (field.hidden || fieldType === "hidden") continue;
|
|
96
|
-
if (fieldType === "file" || fieldType === "image") {
|
|
97
|
-
shape[field.key] = field.required !== false ? z.any() : z.any().optional();
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
switch (fieldType) {
|
|
101
|
-
case "number": {
|
|
102
|
-
let schema = z.number({ message: "Must be a number" });
|
|
103
|
-
if (field.min != null) schema = schema.min(field.min);
|
|
104
|
-
if (field.max != null) schema = schema.max(field.max);
|
|
105
|
-
shape[field.key] = field.required !== false ? schema : schema.optional();
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
case "array": {
|
|
109
|
-
if (field.arrayFields) {
|
|
110
|
-
const itemShape = {};
|
|
111
|
-
for (const sub of field.arrayFields) {
|
|
112
|
-
const subType = sub.type ?? "text";
|
|
113
|
-
if (subType === "number") {
|
|
114
|
-
let s = z.number({ message: "Must be a number" });
|
|
115
|
-
if (sub.min != null) s = s.min(sub.min);
|
|
116
|
-
if (sub.max != null) s = s.max(sub.max);
|
|
117
|
-
itemShape[sub.key] = sub.required !== false ? s : s.optional();
|
|
118
|
-
} else if (subType === "switch" || subType === "checkbox") {
|
|
119
|
-
itemShape[sub.key] = z.boolean().optional();
|
|
120
|
-
} else {
|
|
121
|
-
let s = z.string();
|
|
122
|
-
if (sub.required !== false) {
|
|
123
|
-
s = s.min(1, `${sub.label ?? titleCase(sub.key)} is required`);
|
|
124
|
-
}
|
|
125
|
-
if (subType === "email") s = s.email("Invalid email address");
|
|
126
|
-
if (subType === "url") s = s.url("Invalid URL");
|
|
127
|
-
itemShape[sub.key] = sub.required === false ? s.optional().or(z.literal("")) : s;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
let arraySchema = z.array(z.object(itemShape));
|
|
131
|
-
if (field.arrayMin != null) arraySchema = arraySchema.min(field.arrayMin, `Minimum ${field.arrayMin} items required`);
|
|
132
|
-
if (field.arrayMax != null) arraySchema = arraySchema.max(field.arrayMax, `Maximum ${field.arrayMax} items allowed`);
|
|
133
|
-
shape[field.key] = arraySchema;
|
|
134
|
-
}
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
case "switch":
|
|
138
|
-
case "checkbox": {
|
|
139
|
-
shape[field.key] = z.boolean().optional();
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
default: {
|
|
143
|
-
let schema = z.string();
|
|
144
|
-
if (field.required !== false) {
|
|
145
|
-
schema = schema.min(1, `${field.label ?? titleCase(field.key)} is required`);
|
|
146
|
-
}
|
|
147
|
-
if (fieldType === "email") {
|
|
148
|
-
schema = schema.email("Invalid email address");
|
|
149
|
-
}
|
|
150
|
-
if (fieldType === "url") {
|
|
151
|
-
schema = schema.url("Invalid URL");
|
|
152
|
-
}
|
|
153
|
-
shape[field.key] = field.required === false ? schema.optional().or(z.literal("")) : schema;
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return z.object(shape).passthrough();
|
|
159
|
-
}
|
|
160
|
-
function buildArrayItemDefaults(arrayFields) {
|
|
161
|
-
const defaults = {};
|
|
162
|
-
for (const sub of arrayFields) {
|
|
163
|
-
const subType = sub.type ?? "text";
|
|
164
|
-
if (subType === "number") defaults[sub.key] = void 0;
|
|
165
|
-
else if (subType === "switch" || subType === "checkbox") defaults[sub.key] = false;
|
|
166
|
-
else defaults[sub.key] = sub.defaultValue ?? "";
|
|
167
|
-
}
|
|
168
|
-
return defaults;
|
|
169
|
-
}
|
|
170
|
-
function buildDefaults(fields, data, action, prefillFromUrl) {
|
|
171
|
-
const defaults = {};
|
|
172
|
-
for (const field of fields) {
|
|
173
|
-
if (data && field.key in data) {
|
|
174
|
-
defaults[field.key] = data[field.key];
|
|
175
|
-
} else if (field.defaultValue !== void 0) {
|
|
176
|
-
defaults[field.key] = field.defaultValue;
|
|
177
|
-
} else {
|
|
178
|
-
const fieldType = field.type ?? "text";
|
|
179
|
-
switch (fieldType) {
|
|
180
|
-
case "array":
|
|
181
|
-
defaults[field.key] = field.arrayMin ? Array.from(
|
|
182
|
-
{ length: field.arrayMin },
|
|
183
|
-
() => buildArrayItemDefaults(field.arrayFields ?? [])
|
|
184
|
-
) : [];
|
|
185
|
-
break;
|
|
186
|
-
case "number":
|
|
187
|
-
defaults[field.key] = void 0;
|
|
188
|
-
break;
|
|
189
|
-
case "switch":
|
|
190
|
-
case "checkbox":
|
|
191
|
-
defaults[field.key] = false;
|
|
192
|
-
break;
|
|
193
|
-
default:
|
|
194
|
-
defaults[field.key] = "";
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (typeof window !== "undefined" && action === "create" && prefillFromUrl !== false) {
|
|
200
|
-
const params = new URLSearchParams(window.location.search);
|
|
201
|
-
for (const field of fields) {
|
|
202
|
-
const val = params.get(field.key);
|
|
203
|
-
if (val != null) {
|
|
204
|
-
defaults[field.key] = field.type === "number" ? Number(val) : val;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return defaults;
|
|
209
|
-
}
|
|
210
|
-
function useResourceForm(options) {
|
|
211
|
-
const {
|
|
212
|
-
resource,
|
|
213
|
-
action,
|
|
214
|
-
id,
|
|
215
|
-
initialData,
|
|
216
|
-
fields: fieldsProp,
|
|
217
|
-
listData,
|
|
218
|
-
onSuccess,
|
|
219
|
-
onError,
|
|
220
|
-
prefillFromUrl = true,
|
|
221
|
-
validationMode,
|
|
222
|
-
autosave
|
|
223
|
-
} = options;
|
|
224
|
-
const autosaveEnabled = !!autosave;
|
|
225
|
-
const debounceMs = typeof autosave === "object" ? autosave.debounceMs ?? 1e3 : 1e3;
|
|
226
|
-
const provider = useDataProvider();
|
|
227
|
-
const queryClient = useQueryClient();
|
|
228
|
-
const needsFetch = action === "edit" && !initialData && !!id;
|
|
229
|
-
const fetchResult = useOne(
|
|
230
|
-
resource,
|
|
231
|
-
needsFetch ? id : void 0,
|
|
232
|
-
{ enabled: needsFetch }
|
|
233
|
-
);
|
|
234
|
-
const fetchedData = fetchResult.data ?? void 0;
|
|
235
|
-
const effectiveData = initialData ?? fetchedData;
|
|
236
|
-
const isLoading = needsFetch && fetchResult.isLoading;
|
|
237
|
-
const resolvedFields = useMemo(
|
|
238
|
-
() => resolveFields(fieldsProp, effectiveData, listData),
|
|
239
|
-
[fieldsProp, effectiveData, listData]
|
|
240
|
-
);
|
|
241
|
-
const schema = useMemo(
|
|
242
|
-
() => buildSchema(resolvedFields),
|
|
243
|
-
[resolvedFields]
|
|
244
|
-
);
|
|
245
|
-
const defaultValues = useMemo(() => {
|
|
246
|
-
const defaults = buildDefaults(resolvedFields, effectiveData, action, prefillFromUrl);
|
|
247
|
-
if (autosaveEnabled && action === "create" && typeof window !== "undefined") {
|
|
248
|
-
const key = `genesis-draft:${resource}:new`;
|
|
249
|
-
const saved = localStorage.getItem(key);
|
|
250
|
-
if (saved) {
|
|
251
|
-
try {
|
|
252
|
-
const draft = JSON.parse(saved);
|
|
253
|
-
Object.assign(defaults, draft);
|
|
254
|
-
} catch {
|
|
255
|
-
console.warn(`[useResourceForm] Corrupt draft for "${resource}", removing`);
|
|
256
|
-
localStorage.removeItem(key);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return defaults;
|
|
261
|
-
}, [resolvedFields, effectiveData, action, prefillFromUrl, autosaveEnabled, resource]);
|
|
262
|
-
const resolver = useMemo(
|
|
263
|
-
() => zodResolver(schema),
|
|
264
|
-
[schema]
|
|
265
|
-
);
|
|
266
|
-
const form = useForm({
|
|
267
|
-
resolver,
|
|
268
|
-
defaultValues,
|
|
269
|
-
values: action === "edit" ? defaultValues : void 0,
|
|
270
|
-
mode: validationMode ?? "onBlur",
|
|
271
|
-
reValidateMode: "onChange",
|
|
272
|
-
shouldUnregister: true
|
|
273
|
-
});
|
|
274
|
-
useEffect(() => {
|
|
275
|
-
if (!autosaveEnabled || action !== "create") return;
|
|
276
|
-
const key = `genesis-draft:${resource}:new`;
|
|
277
|
-
let timer;
|
|
278
|
-
const subscription = form.watch((values) => {
|
|
279
|
-
clearTimeout(timer);
|
|
280
|
-
timer = setTimeout(() => {
|
|
281
|
-
try {
|
|
282
|
-
localStorage.setItem(key, JSON.stringify(values));
|
|
283
|
-
} catch {
|
|
284
|
-
}
|
|
285
|
-
}, debounceMs);
|
|
286
|
-
});
|
|
287
|
-
return () => {
|
|
288
|
-
clearTimeout(timer);
|
|
289
|
-
subscription.unsubscribe();
|
|
290
|
-
};
|
|
291
|
-
}, [autosaveEnabled, resource, action, form, debounceMs]);
|
|
292
|
-
const handleSubmit = useCallback(
|
|
293
|
-
async (formData) => {
|
|
294
|
-
try {
|
|
295
|
-
let result;
|
|
296
|
-
if (action === "create") {
|
|
297
|
-
const res = await provider.create(resource, { data: formData });
|
|
298
|
-
result = res.data;
|
|
299
|
-
} else {
|
|
300
|
-
const recordId = id ?? String(effectiveData?.id ?? "");
|
|
301
|
-
if (!recordId) {
|
|
302
|
-
throw new Error("Cannot update record: no ID available. Provide an id prop or ensure the record has an id field.");
|
|
303
|
-
}
|
|
304
|
-
const res = await provider.update(resource, { id: recordId, data: formData });
|
|
305
|
-
result = res.data;
|
|
306
|
-
}
|
|
307
|
-
if (autosaveEnabled && action === "create") {
|
|
308
|
-
localStorage.removeItem(`genesis-draft:${resource}:new`);
|
|
309
|
-
}
|
|
310
|
-
await queryClient.invalidateQueries({ queryKey: [resource] });
|
|
311
|
-
onSuccess?.(result);
|
|
312
|
-
} catch (err) {
|
|
313
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
314
|
-
if (onError) {
|
|
315
|
-
onError(error);
|
|
316
|
-
} else {
|
|
317
|
-
console.error(`[useResourceForm] ${action} failed for "${resource}":`, error);
|
|
318
|
-
form.setError("root", { message: error.message });
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
[action, provider, resource, id, effectiveData, queryClient, onSuccess, onError, autosaveEnabled]
|
|
323
|
-
);
|
|
324
|
-
const onSubmit = useCallback(
|
|
325
|
-
(e) => form.handleSubmit(handleSubmit)(e),
|
|
326
|
-
[form, handleSubmit]
|
|
327
|
-
);
|
|
328
|
-
const isSaving = form.formState.isSubmitting;
|
|
329
|
-
return {
|
|
330
|
-
form,
|
|
331
|
-
resolvedFields,
|
|
332
|
-
onSubmit,
|
|
333
|
-
handleSave: handleSubmit,
|
|
334
|
-
isSaving,
|
|
335
|
-
isLoading
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
export { buildArrayItemDefaults, useResourceForm };
|
|
340
|
-
//# sourceMappingURL=chunk-F2JB7YFF.js.map
|
|
341
|
-
//# sourceMappingURL=chunk-F2JB7YFF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-resource-form.ts"],"names":[],"mappings":"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","file":"chunk-F2JB7YFF.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { useMemo, useCallback, useEffect } from \"react\";\nimport { useForm, type UseFormReturn, type Resolver } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { z } from \"zod\";\nimport { useOne } from \"./use-one\";\nimport { useDataProvider } from \"../provider/context\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { titleCase } from \"./use-resource-page\";\nimport type { ResourceFormFieldDef, FieldType } from \"../components/data/ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UseResourceFormOptions {\n resource: string;\n action: \"create\" | \"edit\";\n id?: string;\n initialData?: Record<string, unknown>;\n fields?: ResourceFormFieldDef[];\n /** Full dataset used to auto-detect select fields from unique values. */\n listData?: Record<string, unknown>[];\n onSuccess?: (data: Record<string, unknown>) => void;\n onError?: (error: Error) => void;\n /** Pre-fill create form defaults from URL query params. Default true. */\n prefillFromUrl?: boolean;\n /** Validation trigger mode. Default \"onBlur\". */\n validationMode?: \"onBlur\" | \"onChange\" | \"onSubmit\";\n /** Enable autosave drafts to localStorage for create mode. */\n autosave?: boolean | { debounceMs?: number };\n}\n\nexport interface UseResourceFormReturn {\n form: UseFormReturn<Record<string, unknown>>;\n resolvedFields: ResourceFormFieldDef[];\n onSubmit: (e?: React.BaseSyntheticEvent) => Promise<void>;\n /** Raw save handler — use with form.handleSubmit(handleSave, onInvalid). */\n handleSave: (data: Record<string, unknown>) => Promise<void>;\n isSaving: boolean;\n isLoading: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Infer a field type from a value */\nfunction inferFieldType(value: unknown): FieldType {\n if (typeof value === \"boolean\") return \"switch\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"string\") {\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(value)) return \"date\";\n if (value.includes(\"@\") && value.includes(\".\")) return \"email\";\n if (/^https?:\\/\\//.test(value)) return \"url\";\n if (value.length > 100) return \"textarea\";\n }\n return \"text\";\n}\n\n/** Try to infer a select field from unique values across the full dataset */\nfunction inferSelectFromData(\n key: string,\n allData: Record<string, unknown>[] | undefined,\n): { type: \"select\"; options: { value: string; label: string }[] } | null {\n if (!allData || allData.length === 0) return null;\n const uniqueValues = new Set<string>();\n for (const row of allData) {\n const v = row[key];\n if (typeof v === \"string\" && v.length > 0) uniqueValues.add(v);\n }\n if (uniqueValues.size > 0 && uniqueValues.size <= 10) {\n return {\n type: \"select\" as const,\n options: Array.from(uniqueValues)\n .sort()\n .map((v) => ({ value: v, label: v })),\n };\n }\n return null;\n}\n\n/** Generate a sensible placeholder for an auto-inferred field */\nfunction defaultPlaceholder(key: string, type: FieldType): string {\n switch (type) {\n case \"email\": return \"name@example.com\";\n case \"url\": return \"https://...\";\n case \"number\": return \"0\";\n case \"date\": return \"YYYY-MM-DD\";\n case \"textarea\": return `Enter ${titleCase(key).toLowerCase()}...`;\n default: return `Enter ${titleCase(key).toLowerCase()}`;\n }\n}\n\n/** Resolve fields from data keys when none provided */\nfunction resolveFields(\n fields: ResourceFormFieldDef[] | undefined,\n data: Record<string, unknown> | undefined,\n allData?: Record<string, unknown>[],\n): ResourceFormFieldDef[] {\n if (fields && fields.length > 0) {\n return fields.map((f) => {\n const inferred = f.type ?? (data ? inferFieldType(data[f.key]) : \"text\");\n return {\n ...f,\n label: f.label ?? titleCase(f.key),\n type: inferred,\n placeholder: f.placeholder ?? defaultPlaceholder(f.key, inferred),\n required: f.required ?? (inferred !== \"switch\" && inferred !== \"checkbox\" && inferred !== \"hidden\"),\n };\n });\n }\n\n if (!data) return [];\n\n return Object.keys(data)\n .filter((key) => key !== \"id\" && key !== \"created_at\" && key !== \"updated_at\")\n .map((key) => {\n // Check for select-like field first (string with few unique values)\n if (typeof data[key] === \"string\") {\n const selectInfo = inferSelectFromData(key, allData);\n if (selectInfo) {\n return {\n key,\n label: titleCase(key),\n type: selectInfo.type,\n options: selectInfo.options,\n placeholder: `Select ${titleCase(key).toLowerCase()}...`,\n required: true,\n };\n }\n }\n\n const inferred = inferFieldType(data[key]);\n return {\n key,\n label: titleCase(key),\n type: inferred,\n placeholder: defaultPlaceholder(key, inferred),\n required: inferred !== \"switch\" && inferred !== \"checkbox\" && inferred !== \"hidden\",\n };\n });\n}\n\n/** Build a zod schema from resolved fields */\nfunction buildSchema(fields: ResourceFormFieldDef[]) {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n const fieldType = field.type ?? \"text\";\n\n if (field.hidden || fieldType === \"hidden\") continue;\n\n // File/image fields store File objects — skip string validation\n if (fieldType === \"file\" || fieldType === \"image\") {\n shape[field.key] = field.required !== false ? z.any() : z.any().optional();\n continue;\n }\n\n switch (fieldType) {\n case \"number\": {\n let schema = z.number({ message: \"Must be a number\" });\n if (field.min != null) schema = schema.min(field.min);\n if (field.max != null) schema = schema.max(field.max);\n shape[field.key] = field.required !== false\n ? schema\n : schema.optional();\n break;\n }\n case \"array\": {\n if (field.arrayFields) {\n const itemShape: Record<string, z.ZodTypeAny> = {};\n for (const sub of field.arrayFields) {\n const subType = sub.type ?? \"text\";\n if (subType === \"number\") {\n let s = z.number({ message: \"Must be a number\" });\n if (sub.min != null) s = s.min(sub.min);\n if (sub.max != null) s = s.max(sub.max);\n itemShape[sub.key] = sub.required !== false ? s : s.optional();\n } else if (subType === \"switch\" || subType === \"checkbox\") {\n itemShape[sub.key] = z.boolean().optional();\n } else {\n let s = z.string();\n if (sub.required !== false) {\n s = s.min(1, `${sub.label ?? titleCase(sub.key)} is required`);\n }\n if (subType === \"email\") s = s.email(\"Invalid email address\");\n if (subType === \"url\") s = s.url(\"Invalid URL\");\n itemShape[sub.key] = sub.required === false ? s.optional().or(z.literal(\"\")) : s;\n }\n }\n let arraySchema: z.ZodTypeAny = z.array(z.object(itemShape));\n if (field.arrayMin != null) arraySchema = (arraySchema as z.ZodArray<z.ZodTypeAny>).min(field.arrayMin, `Minimum ${field.arrayMin} items required`);\n if (field.arrayMax != null) arraySchema = (arraySchema as z.ZodArray<z.ZodTypeAny>).max(field.arrayMax, `Maximum ${field.arrayMax} items allowed`);\n shape[field.key] = arraySchema;\n }\n break;\n }\n case \"switch\":\n case \"checkbox\": {\n shape[field.key] = z.boolean().optional();\n break;\n }\n default: {\n // text, email, url, textarea, date, select\n let schema = z.string();\n if (field.required !== false) {\n schema = schema.min(1, `${field.label ?? titleCase(field.key)} is required`);\n }\n if (fieldType === \"email\") {\n schema = schema.email(\"Invalid email address\");\n }\n if (fieldType === \"url\") {\n schema = schema.url(\"Invalid URL\");\n }\n shape[field.key] = field.required === false\n ? schema.optional().or(z.literal(\"\"))\n : schema;\n break;\n }\n }\n }\n\n return z.object(shape).passthrough();\n}\n\n/** Build default values for a single array item from its sub-field definitions */\nexport function buildArrayItemDefaults(\n arrayFields: ResourceFormFieldDef[],\n): Record<string, unknown> {\n const defaults: Record<string, unknown> = {};\n for (const sub of arrayFields) {\n const subType = sub.type ?? \"text\";\n if (subType === \"number\") defaults[sub.key] = undefined;\n else if (subType === \"switch\" || subType === \"checkbox\") defaults[sub.key] = false;\n else defaults[sub.key] = sub.defaultValue ?? \"\";\n }\n return defaults;\n}\n\n/** Build default values from fields and existing data */\nfunction buildDefaults(\n fields: ResourceFormFieldDef[],\n data: Record<string, unknown> | undefined,\n action: \"create\" | \"edit\",\n prefillFromUrl: boolean,\n): Record<string, unknown> {\n const defaults: Record<string, unknown> = {};\n for (const field of fields) {\n if (data && field.key in data) {\n defaults[field.key] = data[field.key];\n } else if (field.defaultValue !== undefined) {\n defaults[field.key] = field.defaultValue;\n } else {\n const fieldType = field.type ?? \"text\";\n switch (fieldType) {\n case \"array\":\n defaults[field.key] = field.arrayMin\n ? Array.from({ length: field.arrayMin }, () =>\n buildArrayItemDefaults(field.arrayFields ?? []),\n )\n : [];\n break;\n case \"number\":\n defaults[field.key] = undefined;\n break;\n case \"switch\":\n case \"checkbox\":\n defaults[field.key] = false;\n break;\n default:\n defaults[field.key] = \"\";\n break;\n }\n }\n }\n\n // URL pre-fill for create mode\n if (typeof window !== \"undefined\" && action === \"create\" && prefillFromUrl !== false) {\n const params = new URLSearchParams(window.location.search);\n for (const field of fields) {\n const val = params.get(field.key);\n if (val != null) {\n defaults[field.key] = field.type === \"number\" ? Number(val) : val;\n }\n }\n }\n\n return defaults;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useResourceForm(options: UseResourceFormOptions): UseResourceFormReturn {\n const {\n resource,\n action,\n id,\n initialData,\n fields: fieldsProp,\n listData,\n onSuccess,\n onError,\n prefillFromUrl = true,\n validationMode,\n autosave,\n } = options;\n\n const autosaveEnabled = !!autosave;\n const debounceMs = typeof autosave === \"object\" ? autosave.debounceMs ?? 1000 : 1000;\n\n const provider = useDataProvider();\n const queryClient = useQueryClient();\n\n // Fetch record for edit mode when no initialData\n const needsFetch = action === \"edit\" && !initialData && !!id;\n const fetchResult = useOne<Record<string, unknown>>(\n resource,\n needsFetch ? id : undefined,\n { enabled: needsFetch },\n );\n\n const fetchedData = fetchResult.data ?? undefined;\n const effectiveData = initialData ?? fetchedData;\n const isLoading = needsFetch && fetchResult.isLoading;\n\n // Resolve fields\n const resolvedFields = useMemo(\n () => resolveFields(fieldsProp, effectiveData, listData),\n [fieldsProp, effectiveData, listData],\n );\n\n // Build schema\n const schema = useMemo(\n () => buildSchema(resolvedFields),\n [resolvedFields],\n );\n\n // Build defaults (with optional draft restoration)\n const defaultValues = useMemo(() => {\n const defaults = buildDefaults(resolvedFields, effectiveData, action, prefillFromUrl);\n if (autosaveEnabled && action === \"create\" && typeof window !== \"undefined\") {\n const key = `genesis-draft:${resource}:new`;\n const saved = localStorage.getItem(key);\n if (saved) {\n try {\n const draft = JSON.parse(saved);\n Object.assign(defaults, draft);\n } catch {\n console.warn(`[useResourceForm] Corrupt draft for \"${resource}\", removing`);\n localStorage.removeItem(key);\n }\n }\n }\n return defaults;\n }, [resolvedFields, effectiveData, action, prefillFromUrl, autosaveEnabled, resource]);\n\n // Form\n // Cast the resolver because zod v4's passthrough() produces `unknown` for input,\n // but react-hook-form expects FieldValues (Record<string, any>).\n const resolver = useMemo(\n () => zodResolver(schema) as unknown as Resolver<Record<string, unknown>>,\n [schema],\n );\n\n const form = useForm<Record<string, unknown>>({\n resolver,\n defaultValues,\n values: action === \"edit\" ? defaultValues : undefined,\n mode: validationMode ?? \"onBlur\",\n reValidateMode: \"onChange\",\n shouldUnregister: true,\n });\n\n // Autosave effect — persist form values to localStorage for create mode\n useEffect(() => {\n if (!autosaveEnabled || action !== \"create\") return;\n const key = `genesis-draft:${resource}:new`;\n let timer: ReturnType<typeof setTimeout>;\n\n const subscription = form.watch((values) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n try {\n localStorage.setItem(key, JSON.stringify(values));\n } catch {\n // Quota exceeded or private browsing — autosave is best-effort\n }\n }, debounceMs);\n });\n\n return () => {\n clearTimeout(timer);\n subscription.unsubscribe();\n };\n }, [autosaveEnabled, resource, action, form, debounceMs]);\n\n // Submit handler\n const handleSubmit = useCallback(\n async (formData: Record<string, unknown>) => {\n try {\n let result: Record<string, unknown>;\n if (action === \"create\") {\n const res = await provider.create<Record<string, unknown>>(resource, { data: formData });\n result = res.data;\n } else {\n const recordId = id ?? String((effectiveData as Record<string, unknown>)?.id ?? \"\");\n if (!recordId) {\n throw new Error(\"Cannot update record: no ID available. Provide an id prop or ensure the record has an id field.\");\n }\n const res = await provider.update<Record<string, unknown>>(resource, { id: recordId, data: formData });\n result = res.data;\n }\n // Clear draft on successful save\n if (autosaveEnabled && action === \"create\") {\n localStorage.removeItem(`genesis-draft:${resource}:new`);\n }\n // Invalidate queries to refresh data\n await queryClient.invalidateQueries({ queryKey: [resource] });\n onSuccess?.(result);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (onError) {\n onError(error);\n } else {\n console.error(`[useResourceForm] ${action} failed for \"${resource}\":`, error);\n form.setError(\"root\", { message: error.message });\n }\n }\n },\n [action, provider, resource, id, effectiveData, queryClient, onSuccess, onError, autosaveEnabled],\n );\n\n const onSubmit = useCallback(\n (e?: React.BaseSyntheticEvent) => form.handleSubmit(handleSubmit)(e),\n [form, handleSubmit],\n );\n\n const isSaving = form.formState.isSubmitting;\n\n return {\n form,\n resolvedFields,\n onSubmit,\n handleSave: handleSubmit,\n isSaving,\n isLoading,\n };\n}\n"]}
|
package/dist/chunk-IKIFQILN.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useDataProvider } from './chunk-JEECTX26.js';
|
|
3
|
-
import { useState, useCallback, useMemo } from 'react';
|
|
4
|
-
import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
5
|
-
|
|
6
|
-
function useResource(resource, options = {}) {
|
|
7
|
-
const {
|
|
8
|
-
defaultSort,
|
|
9
|
-
defaultFilters,
|
|
10
|
-
defaultPerPage = 25,
|
|
11
|
-
select,
|
|
12
|
-
searchFields: searchFieldsOption,
|
|
13
|
-
enabled = true,
|
|
14
|
-
onCreateSuccess,
|
|
15
|
-
onUpdateSuccess,
|
|
16
|
-
onDeleteSuccess,
|
|
17
|
-
onError
|
|
18
|
-
} = options;
|
|
19
|
-
const provider = useDataProvider();
|
|
20
|
-
const queryClient = useQueryClient();
|
|
21
|
-
const [sort, setSort] = useState(defaultSort);
|
|
22
|
-
const [filters, setFilters] = useState(defaultFilters ?? []);
|
|
23
|
-
const [page, setPage] = useState(1);
|
|
24
|
-
const [perPage, setPerPageRaw] = useState(defaultPerPage);
|
|
25
|
-
const [searchQuery, setSearchQuery] = useState("");
|
|
26
|
-
const setPerPage = useCallback((value) => {
|
|
27
|
-
setPerPageRaw(value);
|
|
28
|
-
setPage(1);
|
|
29
|
-
}, []);
|
|
30
|
-
const setSearch = useCallback((query) => {
|
|
31
|
-
setSearchQuery(query);
|
|
32
|
-
setPage(1);
|
|
33
|
-
}, []);
|
|
34
|
-
const params = useMemo(() => {
|
|
35
|
-
const p = {
|
|
36
|
-
pagination: { page, perPage },
|
|
37
|
-
sort,
|
|
38
|
-
filters: filters.length > 0 ? filters : void 0,
|
|
39
|
-
select
|
|
40
|
-
};
|
|
41
|
-
if (searchQuery && searchFieldsOption && searchFieldsOption.length > 0) {
|
|
42
|
-
p.search = { query: searchQuery, fields: searchFieldsOption };
|
|
43
|
-
}
|
|
44
|
-
return p;
|
|
45
|
-
}, [page, perPage, sort, filters, select, searchQuery, searchFieldsOption]);
|
|
46
|
-
const listQueryKey = useMemo(
|
|
47
|
-
() => [resource, "list", params],
|
|
48
|
-
[resource, params]
|
|
49
|
-
);
|
|
50
|
-
const list = useQuery({
|
|
51
|
-
queryKey: listQueryKey,
|
|
52
|
-
queryFn: () => provider.getList(resource, params),
|
|
53
|
-
enabled
|
|
54
|
-
});
|
|
55
|
-
const invalidateResource = useCallback(
|
|
56
|
-
() => queryClient.invalidateQueries({ queryKey: [resource] }),
|
|
57
|
-
[queryClient, resource]
|
|
58
|
-
);
|
|
59
|
-
const createMutation = useMutation({
|
|
60
|
-
mutationFn: async (data) => {
|
|
61
|
-
const result = await provider.create(resource, { data });
|
|
62
|
-
return result.data;
|
|
63
|
-
},
|
|
64
|
-
onSuccess: (data) => {
|
|
65
|
-
invalidateResource();
|
|
66
|
-
onCreateSuccess?.(data);
|
|
67
|
-
},
|
|
68
|
-
onError
|
|
69
|
-
});
|
|
70
|
-
const updateMutation = useMutation({
|
|
71
|
-
mutationFn: async ({ id, data }) => {
|
|
72
|
-
const result = await provider.update(resource, { id, data });
|
|
73
|
-
return result.data;
|
|
74
|
-
},
|
|
75
|
-
onSuccess: (data) => {
|
|
76
|
-
invalidateResource();
|
|
77
|
-
onUpdateSuccess?.(data);
|
|
78
|
-
},
|
|
79
|
-
onError
|
|
80
|
-
});
|
|
81
|
-
const deleteMutation = useMutation({
|
|
82
|
-
mutationFn: async (id) => {
|
|
83
|
-
await provider.deleteOne(resource, { id });
|
|
84
|
-
},
|
|
85
|
-
onSuccess: () => {
|
|
86
|
-
invalidateResource();
|
|
87
|
-
onDeleteSuccess?.();
|
|
88
|
-
},
|
|
89
|
-
onError
|
|
90
|
-
});
|
|
91
|
-
const create = useCallback(
|
|
92
|
-
(data) => createMutation.mutateAsync(data),
|
|
93
|
-
[createMutation]
|
|
94
|
-
);
|
|
95
|
-
const update = useCallback(
|
|
96
|
-
(id, data) => updateMutation.mutateAsync({ id, data }),
|
|
97
|
-
[updateMutation]
|
|
98
|
-
);
|
|
99
|
-
const remove = useCallback(
|
|
100
|
-
(id) => deleteMutation.mutateAsync(id),
|
|
101
|
-
[deleteMutation]
|
|
102
|
-
);
|
|
103
|
-
const isMutating = createMutation.isPending || updateMutation.isPending || deleteMutation.isPending;
|
|
104
|
-
return {
|
|
105
|
-
list,
|
|
106
|
-
params,
|
|
107
|
-
setSort,
|
|
108
|
-
setFilters,
|
|
109
|
-
setPage,
|
|
110
|
-
setPerPage,
|
|
111
|
-
setSearch,
|
|
112
|
-
create,
|
|
113
|
-
update,
|
|
114
|
-
remove,
|
|
115
|
-
isMutating,
|
|
116
|
-
createMutation,
|
|
117
|
-
updateMutation,
|
|
118
|
-
deleteMutation
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export { useResource };
|
|
123
|
-
//# sourceMappingURL=chunk-IKIFQILN.js.map
|
|
124
|
-
//# sourceMappingURL=chunk-IKIFQILN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-resource.ts"],"names":[],"mappings":"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","file":"chunk-IKIFQILN.js","sourcesContent":["\"use client\";\n\nimport { useState, useCallback, useMemo } from \"react\";\nimport {\n useQuery,\n useMutation,\n useQueryClient,\n type UseQueryResult,\n type UseMutationResult,\n} from \"@tanstack/react-query\";\nimport { useDataProvider } from \"../provider/context\";\nimport type {\n Identifier,\n SortParam,\n FilterParam,\n ListParams,\n ListResult,\n} from \"../provider/types\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface UseResourceOptions<T> {\n defaultSort?: SortParam;\n defaultFilters?: FilterParam[];\n defaultPerPage?: number;\n /** Supabase select/join syntax, e.g. \"*, author:profiles(name)\". */\n select?: string;\n /** Fields to search across when setSearch is called. Required for server-side search. */\n searchFields?: string[];\n /** Disable auto-fetching. */\n enabled?: boolean;\n onCreateSuccess?: (data: T) => void;\n onUpdateSuccess?: (data: T) => void;\n onDeleteSuccess?: () => void;\n onError?: (error: Error) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Return type\n// ---------------------------------------------------------------------------\n\nexport interface UseResourceReturn<T> {\n /** TanStack Query result for the list query. */\n list: UseQueryResult<ListResult<T>>;\n /** Current list params (pagination, sort, filters, search). */\n params: ListParams;\n setSort: (sort: SortParam) => void;\n setFilters: (filters: FilterParam[]) => void;\n setPage: (page: number) => void;\n setPerPage: (perPage: number) => void;\n setSearch: (query: string) => void;\n /** Create a new record. Returns the created item. */\n create: (data: Partial<T>) => Promise<T>;\n /** Update an existing record by id. Returns the updated item. */\n update: (id: Identifier, data: Partial<T>) => Promise<T>;\n /** Delete a record by id. */\n remove: (id: Identifier) => Promise<void>;\n /** True when any mutation is in-flight. */\n isMutating: boolean;\n createMutation: UseMutationResult<T, Error, Partial<T>>;\n updateMutation: UseMutationResult<T, Error, { id: Identifier; data: Partial<T> }>;\n deleteMutation: UseMutationResult<void, Error, Identifier>;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useResource<T = Record<string, unknown>>(\n resource: string,\n options: UseResourceOptions<T> = {},\n): UseResourceReturn<T> {\n const {\n defaultSort,\n defaultFilters,\n defaultPerPage = 25,\n select,\n searchFields: searchFieldsOption,\n enabled = true,\n onCreateSuccess,\n onUpdateSuccess,\n onDeleteSuccess,\n onError,\n } = options;\n\n const provider = useDataProvider();\n const queryClient = useQueryClient();\n\n // -------------------------------------------------------------------------\n // State\n // -------------------------------------------------------------------------\n\n const [sort, setSort] = useState<SortParam | undefined>(defaultSort);\n const [filters, setFilters] = useState<FilterParam[]>(defaultFilters ?? []);\n const [page, setPage] = useState(1);\n const [perPage, setPerPageRaw] = useState(defaultPerPage);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const setPerPage = useCallback((value: number) => {\n setPerPageRaw(value);\n setPage(1);\n }, []);\n\n const setSearch = useCallback((query: string) => {\n setSearchQuery(query);\n setPage(1);\n }, []);\n\n // -------------------------------------------------------------------------\n // Params\n // -------------------------------------------------------------------------\n\n const params = useMemo<ListParams>(() => {\n const p: ListParams = {\n pagination: { page, perPage },\n sort,\n filters: filters.length > 0 ? filters : undefined,\n select,\n };\n if (searchQuery && searchFieldsOption && searchFieldsOption.length > 0) {\n p.search = { query: searchQuery, fields: searchFieldsOption };\n }\n return p;\n }, [page, perPage, sort, filters, select, searchQuery, searchFieldsOption]);\n\n // -------------------------------------------------------------------------\n // List query\n // -------------------------------------------------------------------------\n\n const listQueryKey = useMemo(\n () => [resource, \"list\", params] as const,\n [resource, params],\n );\n\n const list = useQuery<ListResult<T>>({\n queryKey: listQueryKey,\n queryFn: () => provider.getList<T>(resource, params),\n enabled,\n });\n\n // -------------------------------------------------------------------------\n // Mutations\n // -------------------------------------------------------------------------\n\n const invalidateResource = useCallback(\n () => queryClient.invalidateQueries({ queryKey: [resource] }),\n [queryClient, resource],\n );\n\n const createMutation = useMutation<T, Error, Partial<T>>({\n mutationFn: async (data) => {\n const result = await provider.create<T>(resource, { data });\n return result.data;\n },\n onSuccess: (data) => {\n invalidateResource();\n onCreateSuccess?.(data);\n },\n onError,\n });\n\n const updateMutation = useMutation<\n T,\n Error,\n { id: Identifier; data: Partial<T> }\n >({\n mutationFn: async ({ id, data }) => {\n const result = await provider.update<T>(resource, { id, data });\n return result.data;\n },\n onSuccess: (data) => {\n invalidateResource();\n onUpdateSuccess?.(data);\n },\n onError,\n });\n\n const deleteMutation = useMutation<void, Error, Identifier>({\n mutationFn: async (id) => {\n await provider.deleteOne(resource, { id });\n },\n onSuccess: () => {\n invalidateResource();\n onDeleteSuccess?.();\n },\n onError,\n });\n\n // -------------------------------------------------------------------------\n // Convenience wrappers\n // -------------------------------------------------------------------------\n\n const create = useCallback(\n (data: Partial<T>) => createMutation.mutateAsync(data),\n [createMutation],\n );\n\n const update = useCallback(\n (id: Identifier, data: Partial<T>) =>\n updateMutation.mutateAsync({ id, data }),\n [updateMutation],\n );\n\n const remove = useCallback(\n (id: Identifier) => deleteMutation.mutateAsync(id),\n [deleteMutation],\n );\n\n const isMutating =\n createMutation.isPending ||\n updateMutation.isPending ||\n deleteMutation.isPending;\n\n return {\n list,\n params,\n setSort,\n setFilters,\n setPage,\n setPerPage,\n setSearch,\n create,\n update,\n remove,\n isMutating,\n createMutation,\n updateMutation,\n deleteMutation,\n };\n}\n"]}
|
package/dist/chunk-JEECTX26.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { createContext, useContext } from 'react';
|
|
3
|
-
import '@tanstack/react-query';
|
|
4
|
-
import 'react/jsx-runtime';
|
|
5
|
-
|
|
6
|
-
// src/provider/context.tsx
|
|
7
|
-
var DataProviderContext = createContext(null);
|
|
8
|
-
function useDataProvider() {
|
|
9
|
-
const ctx = useContext(DataProviderContext);
|
|
10
|
-
if (!ctx) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
"useDataProvider must be used inside <DataProviderRoot> or <GenesisProvider>. Wrap your app (or the relevant subtree) in one of these providers."
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
return ctx;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { useDataProvider };
|
|
19
|
-
//# sourceMappingURL=chunk-JEECTX26.js.map
|
|
20
|
-
//# sourceMappingURL=chunk-JEECTX26.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/context.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,mBAAA,GAAsB,cAAmC,IAAI,CAAA;AAuB5D,SAAS,eAAA,GAAgC;AAC9C,EAAA,MAAM,GAAA,GAAM,WAAW,mBAAmB,CAAA;AAC1C,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT","file":"chunk-JEECTX26.js","sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type { DataProvider } from \"./types\";\nimport { createMockProvider, type MockProviderOptions } from \"./mock-provider\";\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst DataProviderContext = createContext<DataProvider | null>(null);\n\n// ---------------------------------------------------------------------------\n// DataProviderRoot — thin context wrapper\n// ---------------------------------------------------------------------------\n\nexport interface DataProviderRootProps {\n provider: DataProvider;\n children: ReactNode;\n}\n\nexport function DataProviderRoot({ provider, children }: DataProviderRootProps) {\n return (\n <DataProviderContext.Provider value={provider}>\n {children}\n </DataProviderContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useDataProvider(): DataProvider {\n const ctx = useContext(DataProviderContext);\n if (!ctx) {\n throw new Error(\n \"useDataProvider must be used inside <DataProviderRoot> or <GenesisProvider>. \" +\n \"Wrap your app (or the relevant subtree) in one of these providers.\",\n );\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// GenesisProvider — convenience wrapper\n// ---------------------------------------------------------------------------\n\ntype Row = Record<string, unknown>;\n\nexport interface GenesisProviderProps {\n children: ReactNode;\n /** Pass a ready-made DataProvider. Mutually exclusive with `mock`. */\n provider?: DataProvider;\n /** Pass mock datasets. Creates a MockProvider internally. */\n mock?: {\n datasets: Record<string, Row[]>;\n options?: MockProviderOptions;\n };\n}\n\nexport function GenesisProvider({\n children,\n provider,\n mock,\n}: GenesisProviderProps) {\n // Build provider from mock datasets when no explicit provider is given.\n const resolvedProvider = useMemo(() => {\n if (provider) return provider;\n if (mock) return createMockProvider(mock.datasets, mock.options);\n throw new Error(\n \"<GenesisProvider> requires either a `provider` or `mock` prop.\",\n );\n }, [provider, mock]);\n\n // Internal QueryClient with sensible defaults.\n const queryClient = useMemo(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n },\n },\n }),\n [],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <DataProviderRoot provider={resolvedProvider}>\n {children}\n </DataProviderRoot>\n </QueryClientProvider>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/badge.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,8LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,uDAAA;AAAA,QACF,SAAA,EACE,2DAAA;AAAA,QACF,WAAA,EACE,+DAAA;AAAA,QACF,OAAA,EAAS,iBAAA;AAAA,QACT,OAAA,EACE,kEAAA;AAAA,QACF,OAAA,EACE,kEAAA;AAAA,QACF,IAAA,EAAM,yDAAA;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ;AAMA,SAAS,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,GAAG,OAAM,EAAe;AAC3D,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAE3E","file":"chunk-MUQLZFUR.js","sourcesContent":["import * as React from \"react\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { cn } from \"../../utils\";\n\nconst badgeVariants = cva(\n \"inline-flex w-fit items-center whitespace-nowrap rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground\",\n destructive:\n \"border-transparent bg-destructive text-destructive-foreground\",\n outline: \"text-foreground\",\n success:\n \"border-transparent bg-success/15 text-success dark:bg-success/20\",\n warning:\n \"border-transparent bg-warning/15 text-warning dark:bg-warning/20\",\n info: \"border-transparent bg-info/15 text-info dark:bg-info/20\",\n muted: \"border-transparent bg-muted text-muted-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props} />\n );\n}\n\nexport { Badge, badgeVariants };\n"]}
|
package/dist/chunk-W64GERJW.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { cn } from './chunk-NZ5WBA4R.js';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { jsx } from 'react/jsx-runtime';
|
|
4
|
-
|
|
5
|
-
var Textarea = React.forwardRef(({ className, ...props }, ref) => {
|
|
6
|
-
return /* @__PURE__ */ jsx(
|
|
7
|
-
"textarea",
|
|
8
|
-
{
|
|
9
|
-
className: cn(
|
|
10
|
-
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
11
|
-
className
|
|
12
|
-
),
|
|
13
|
-
ref,
|
|
14
|
-
...props
|
|
15
|
-
}
|
|
16
|
-
);
|
|
17
|
-
});
|
|
18
|
-
Textarea.displayName = "Textarea";
|
|
19
|
-
|
|
20
|
-
export { Textarea };
|
|
21
|
-
//# sourceMappingURL=chunk-W64GERJW.js.map
|
|
22
|
-
//# sourceMappingURL=chunk-W64GERJW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/textarea.tsx"],"names":[],"mappings":";;;;AAGA,IAAM,QAAA,GAAiB,iBAGrB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAClC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,mTAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,GAAA;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-W64GERJW.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n"]}
|
package/dist/hooks/use-one.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
-
import { I as Identifier } from '../types-HIZY7zxO.js';
|
|
3
|
-
|
|
4
|
-
interface UseOneOptions {
|
|
5
|
-
/** Supabase select/join syntax, e.g. "*, author:profiles(name)". */
|
|
6
|
-
select?: string;
|
|
7
|
-
/** Defaults to `!!id` — won't fetch when id is falsy. */
|
|
8
|
-
enabled?: boolean;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Fetch a single record by id, powered by TanStack Query.
|
|
12
|
-
*
|
|
13
|
-
* Returns the full `UseQueryResult<T>` with the data unwrapped from the
|
|
14
|
-
* provider's `GetOneResult` wrapper.
|
|
15
|
-
*/
|
|
16
|
-
declare function useOne<T = Record<string, unknown>>(resource: string, id: Identifier | undefined | null, options?: UseOneOptions): UseQueryResult<T>;
|
|
17
|
-
|
|
18
|
-
export { type UseOneOptions, useOne };
|
package/dist/hooks/use-one.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"use-one.js"}
|