@questpie/admin 3.0.9 → 3.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/augmentation.d.mts +39 -0
- package/dist/client/builder/page/page.d.mts +29 -1
- package/dist/client/builder/types/field-types.d.mts +10 -14
- package/dist/client/components/fields/relation-picker.mjs +2 -2
- package/dist/client/components/fields/relation-select.mjs +3 -3
- package/dist/client/hooks/use-audit-history.mjs +10 -17
- package/dist/client/hooks/use-reactive-prop.mjs +308 -0
- package/dist/client/hooks/use-transition-stage.mjs +34 -41
- package/dist/client/preview/block-scope-context.d.mts +2 -2
- package/dist/client/preview/preview-banner.d.mts +2 -2
- package/dist/client/preview/preview-field.d.mts +4 -4
- package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
- package/dist/client/views/auth/auth-layout.d.mts +3 -3
- package/dist/client/views/auth/reset-password-form.d.mts +2 -2
- package/dist/client/views/auth/setup-form.d.mts +2 -2
- package/dist/client/views/collection/field-renderer.mjs +59 -134
- package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
- package/dist/client/views/pages/invite-page.d.mts +2 -2
- package/dist/client/views/pages/login-page.d.mts +2 -2
- package/dist/client/views/pages/reset-password-page.d.mts +2 -2
- package/dist/client/views/pages/setup-page.d.mts +2 -2
- package/dist/client.d.mts +2 -1
- package/dist/client.mjs +2 -1
- package/dist/components/rich-text/rich-text-renderer.d.mts +2 -2
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/server/augmentation/form-layout.d.mts +48 -4
- package/dist/server/augmentation/index.d.mts +1 -1
- package/dist/server/augmentation.d.mts +1 -1
- package/dist/server/modules/admin/collections/admin-locks.d.mts +54 -54
- package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
- package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
- package/dist/server/modules/admin/collections/apikey.d.mts +68 -68
- package/dist/server/modules/admin/collections/assets.d.mts +20 -20
- package/dist/server/modules/admin/collections/session.d.mts +42 -42
- package/dist/server/modules/admin/collections/user.d.mts +32 -32
- package/dist/server/modules/admin/collections/verification.d.mts +32 -32
- package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
- package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
- package/dist/server/modules/admin/routes/preview.d.mts +11 -11
- package/dist/server/modules/admin/routes/reactive.d.mts +13 -11
- package/dist/server/modules/admin/routes/reactive.mjs +75 -11
- package/dist/server/modules/admin/routes/setup.d.mts +7 -7
- package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
- package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
- package/package.json +4 -4
|
@@ -179,6 +179,49 @@ function getReactiveHandler(app, entityName, fieldPath, handlerType, type = "col
|
|
|
179
179
|
return null;
|
|
180
180
|
}
|
|
181
181
|
/**
|
|
182
|
+
* Coerce a `function | { handler }` config-like value to the underlying
|
|
183
|
+
* handler function. Returns `null` for static values.
|
|
184
|
+
*/
|
|
185
|
+
function unwrapHandler(value) {
|
|
186
|
+
if (typeof value === "function") return value;
|
|
187
|
+
if (value !== null && typeof value === "object" && "handler" in value && typeof value.handler === "function") return value.handler;
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get a reactive prop handler. Resolution chain (first hit wins):
|
|
192
|
+
*
|
|
193
|
+
* 1. **Layout-level** `state.adminForm.fields[*].props[propPath]`
|
|
194
|
+
* (per-instance `.form()` override)
|
|
195
|
+
* 2. **Field-level** `state.fieldDefinitions[fieldPath]._state.extensions.admin[propPath]`
|
|
196
|
+
* (default attached to the field via `f.<x>().admin({ ... })`)
|
|
197
|
+
*
|
|
198
|
+
* The wire-side counterpart is the `ReactivePropPlaceholder` introspection
|
|
199
|
+
* emits for function values in either location.
|
|
200
|
+
*/
|
|
201
|
+
function getReactivePropHandler(app, entityName, fieldPath, propPath, type = "collection") {
|
|
202
|
+
const formConfig = getEntity(app, entityName, type).state.adminForm;
|
|
203
|
+
const fieldEntry = findReactiveFieldEntry(formConfig, fieldPath);
|
|
204
|
+
if (fieldEntry) {
|
|
205
|
+
const props = fieldEntry.props;
|
|
206
|
+
if (props && typeof props === "object") {
|
|
207
|
+
const layoutHandler = unwrapHandler(props[propPath]);
|
|
208
|
+
if (layoutHandler) return layoutHandler;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
let fieldDef;
|
|
212
|
+
try {
|
|
213
|
+
fieldDef = getFieldDefinition(app, entityName, fieldPath, type);
|
|
214
|
+
} catch {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const adminMeta = fieldDef._state?.extensions?.admin;
|
|
218
|
+
if (adminMeta && typeof adminMeta === "object") {
|
|
219
|
+
const fieldHandler = unwrapHandler(adminMeta[propPath]);
|
|
220
|
+
if (fieldHandler) return fieldHandler;
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
182
225
|
* Get options handler from field config.
|
|
183
226
|
*/
|
|
184
227
|
function getOptionsHandler(fieldDef) {
|
|
@@ -196,8 +239,10 @@ const reactiveRequestSchema = z.object({
|
|
|
196
239
|
"hidden",
|
|
197
240
|
"readOnly",
|
|
198
241
|
"disabled",
|
|
199
|
-
"compute"
|
|
242
|
+
"compute",
|
|
243
|
+
"prop"
|
|
200
244
|
]),
|
|
245
|
+
propPath: z.string().optional(),
|
|
201
246
|
formData: z.record(z.string(), z.unknown()).optional(),
|
|
202
247
|
siblingData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
203
248
|
prevData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
@@ -222,8 +267,10 @@ const reactiveResultSchema = z.object({
|
|
|
222
267
|
"hidden",
|
|
223
268
|
"readOnly",
|
|
224
269
|
"disabled",
|
|
225
|
-
"compute"
|
|
270
|
+
"compute",
|
|
271
|
+
"prop"
|
|
226
272
|
]),
|
|
273
|
+
propPath: z.string().optional(),
|
|
227
274
|
value: z.unknown(),
|
|
228
275
|
error: z.string().optional()
|
|
229
276
|
});
|
|
@@ -264,27 +311,44 @@ const batchReactive = route().post().schema(batchReactiveInputSchema).outputSche
|
|
|
264
311
|
const { collection: entityName, type: entityType, requests, formData: sharedFormData, prevData: sharedPrevData } = ctx.input;
|
|
265
312
|
const serverCtx = buildServerContext(ctx);
|
|
266
313
|
return { results: await Promise.all(requests.map(async (request) => {
|
|
267
|
-
const { field: field$1, type, formData, siblingData, prevData, prevSiblingData } = request;
|
|
314
|
+
const { field: field$1, type, propPath, formData, siblingData, prevData, prevSiblingData } = request;
|
|
268
315
|
const resolvedFormData = formData ?? sharedFormData ?? {};
|
|
269
316
|
const resolvedPrevData = prevData ?? sharedPrevData ?? null;
|
|
270
317
|
try {
|
|
271
318
|
getFieldDefinition(app, entityName, field$1, entityType);
|
|
272
|
-
|
|
273
|
-
if (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
319
|
+
let handler;
|
|
320
|
+
if (type === "prop") {
|
|
321
|
+
if (!propPath) return {
|
|
322
|
+
field: field$1,
|
|
323
|
+
type,
|
|
324
|
+
value: void 0,
|
|
325
|
+
error: "propPath is required when type === 'prop'"
|
|
326
|
+
};
|
|
327
|
+
handler = getReactivePropHandler(app, entityName, field$1, propPath, entityType);
|
|
328
|
+
} else handler = getReactiveHandler(app, entityName, field$1, type, entityType);
|
|
329
|
+
if (!handler) {
|
|
330
|
+
const what = type === "prop" ? `prop '${propPath}'` : `${type} handler`;
|
|
331
|
+
return {
|
|
332
|
+
field: field$1,
|
|
333
|
+
type,
|
|
334
|
+
...propPath ? { propPath } : {},
|
|
335
|
+
value: void 0,
|
|
336
|
+
error: `No ${what} found for field '${field$1}'`
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
const reactiveCtx = buildReactiveContext(resolvedFormData, siblingData, resolvedPrevData, prevSiblingData, serverCtx);
|
|
340
|
+
const value = await handler(reactiveCtx);
|
|
279
341
|
return {
|
|
280
342
|
field: field$1,
|
|
281
343
|
type,
|
|
282
|
-
|
|
344
|
+
...propPath ? { propPath } : {},
|
|
345
|
+
value
|
|
283
346
|
};
|
|
284
347
|
} catch (error) {
|
|
285
348
|
return {
|
|
286
349
|
field: field$1,
|
|
287
350
|
type,
|
|
351
|
+
...propPath ? { propPath } : {},
|
|
288
352
|
value: void 0,
|
|
289
353
|
error: error instanceof Error ? error.message : String(error)
|
|
290
354
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as questpie139 from "questpie";
|
|
2
2
|
|
|
3
3
|
//#region src/server/modules/admin/routes/setup.d.ts
|
|
4
4
|
|
|
@@ -20,7 +20,7 @@ import * as questpie143 from "questpie";
|
|
|
20
20
|
* }
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
declare const isSetupRequired:
|
|
23
|
+
declare const isSetupRequired: questpie139.JsonRouteDefinition<Record<string, never>, any, questpie139.JsonRouteParams>;
|
|
24
24
|
/**
|
|
25
25
|
* Create the first admin user in the system.
|
|
26
26
|
* This function only works when no admin users exist (setup mode).
|
|
@@ -43,21 +43,21 @@ declare const isSetupRequired: questpie143.JsonRouteDefinition<Record<string, ne
|
|
|
43
43
|
* }
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
declare const createFirstAdmin:
|
|
46
|
+
declare const createFirstAdmin: questpie139.JsonRouteDefinition<{
|
|
47
47
|
email: string;
|
|
48
48
|
password: string;
|
|
49
49
|
name: string;
|
|
50
|
-
}, any,
|
|
50
|
+
}, any, questpie139.JsonRouteParams>;
|
|
51
51
|
/**
|
|
52
52
|
* Bundle of setup-related functions.
|
|
53
53
|
*/
|
|
54
54
|
declare const setupFunctions: {
|
|
55
|
-
readonly isSetupRequired:
|
|
56
|
-
readonly createFirstAdmin:
|
|
55
|
+
readonly isSetupRequired: questpie139.JsonRouteDefinition<Record<string, never>, any, questpie139.JsonRouteParams>;
|
|
56
|
+
readonly createFirstAdmin: questpie139.JsonRouteDefinition<{
|
|
57
57
|
email: string;
|
|
58
58
|
password: string;
|
|
59
59
|
name: string;
|
|
60
|
-
}, any,
|
|
60
|
+
}, any, questpie139.JsonRouteParams>;
|
|
61
61
|
};
|
|
62
62
|
//#endregion
|
|
63
63
|
export { createFirstAdmin, isSetupRequired, setupFunctions };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as questpie147 from "questpie";
|
|
2
2
|
|
|
3
3
|
//#region src/server/modules/admin/routes/widget-data.d.ts
|
|
4
4
|
|
|
@@ -20,13 +20,13 @@ import * as questpie131 from "questpie";
|
|
|
20
20
|
* const data = await client.routes.fetchWidgetData({ widgetId: "my-widget" });
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
-
declare const fetchWidgetData:
|
|
23
|
+
declare const fetchWidgetData: questpie147.JsonRouteDefinition<{
|
|
24
24
|
widgetId: string;
|
|
25
|
-
}, any,
|
|
25
|
+
}, any, questpie147.JsonRouteParams>;
|
|
26
26
|
declare const widgetDataFunctions: {
|
|
27
|
-
readonly fetchWidgetData:
|
|
27
|
+
readonly fetchWidgetData: questpie147.JsonRouteDefinition<{
|
|
28
28
|
widgetId: string;
|
|
29
|
-
}, any,
|
|
29
|
+
}, any, questpie147.JsonRouteParams>;
|
|
30
30
|
};
|
|
31
31
|
//#endregion
|
|
32
32
|
export { fetchWidgetData, widgetDataFunctions };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { FilterOperator, FilterRule, SortConfig, ViewConfiguration } from "../../../../shared/types/saved-views.types.mjs";
|
|
2
2
|
import * as questpie_shared15 from "questpie/shared";
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
3
|
+
import * as questpie69 from "questpie";
|
|
4
|
+
import * as questpie_src_server_modules_core_fields_email_js1 from "questpie/src/server/modules/core/fields/email.js";
|
|
5
|
+
import * as questpie_src_server_modules_core_fields_json_js1 from "questpie/src/server/modules/core/fields/json.js";
|
|
6
6
|
import * as drizzle_orm_pg_core22 from "drizzle-orm/pg-core";
|
|
7
7
|
import * as drizzle_orm5 from "drizzle-orm";
|
|
8
8
|
|
|
@@ -33,22 +33,22 @@ import * as drizzle_orm5 from "drizzle-orm";
|
|
|
33
33
|
* });
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
|
-
declare const savedViewsCollection:
|
|
37
|
-
readonly text: typeof
|
|
38
|
-
readonly textarea: typeof
|
|
39
|
-
readonly email: typeof
|
|
40
|
-
readonly url: typeof
|
|
41
|
-
readonly number: typeof
|
|
42
|
-
readonly boolean: typeof
|
|
43
|
-
readonly date: typeof
|
|
44
|
-
readonly datetime: typeof
|
|
45
|
-
readonly time: typeof
|
|
46
|
-
readonly select: typeof
|
|
47
|
-
readonly upload: typeof
|
|
48
|
-
readonly relation: typeof
|
|
49
|
-
readonly object: typeof
|
|
50
|
-
readonly json: typeof
|
|
51
|
-
readonly from: typeof
|
|
36
|
+
declare const savedViewsCollection: questpie69.CollectionBuilder<questpie_shared15.Override<questpie_shared15.Override<questpie69.EmptyCollectionState<"admin_saved_views", undefined, {
|
|
37
|
+
readonly text: typeof questpie69.text;
|
|
38
|
+
readonly textarea: typeof questpie69.textarea;
|
|
39
|
+
readonly email: typeof questpie_src_server_modules_core_fields_email_js1.email;
|
|
40
|
+
readonly url: typeof questpie69.url;
|
|
41
|
+
readonly number: typeof questpie69.number;
|
|
42
|
+
readonly boolean: typeof questpie69.boolean;
|
|
43
|
+
readonly date: typeof questpie69.date;
|
|
44
|
+
readonly datetime: typeof questpie69.datetime;
|
|
45
|
+
readonly time: typeof questpie69.time;
|
|
46
|
+
readonly select: typeof questpie69.select;
|
|
47
|
+
readonly upload: typeof questpie69.upload;
|
|
48
|
+
readonly relation: typeof questpie69.relation;
|
|
49
|
+
readonly object: typeof questpie69.object;
|
|
50
|
+
readonly json: typeof questpie_src_server_modules_core_fields_json_js1.json;
|
|
51
|
+
readonly from: typeof questpie69.from;
|
|
52
52
|
}>, {
|
|
53
53
|
fields: {
|
|
54
54
|
readonly userId: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
|
|
@@ -59,31 +59,31 @@ declare const savedViewsCollection: questpie93.CollectionBuilder<questpie_shared
|
|
|
59
59
|
};
|
|
60
60
|
localized: readonly string[];
|
|
61
61
|
fieldDefinitions: {
|
|
62
|
-
readonly userId:
|
|
62
|
+
readonly userId: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
|
|
63
63
|
notNull: true;
|
|
64
64
|
column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
|
|
65
65
|
} & {
|
|
66
66
|
label: questpie_shared15.I18nText;
|
|
67
|
-
},
|
|
68
|
-
readonly collectionName:
|
|
67
|
+
}, questpie69.TextFieldMethods>;
|
|
68
|
+
readonly collectionName: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
|
|
69
69
|
notNull: true;
|
|
70
70
|
column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
|
|
71
71
|
} & {
|
|
72
72
|
label: questpie_shared15.I18nText;
|
|
73
|
-
},
|
|
74
|
-
readonly name:
|
|
73
|
+
}, questpie69.TextFieldMethods>;
|
|
74
|
+
readonly name: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
|
|
75
75
|
notNull: true;
|
|
76
76
|
column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
|
|
77
77
|
} & {
|
|
78
78
|
label: questpie_shared15.I18nText;
|
|
79
|
-
},
|
|
80
|
-
readonly configuration:
|
|
79
|
+
}, questpie69.TextFieldMethods>;
|
|
80
|
+
readonly configuration: questpie69.Field<Omit<questpie69.JsonFieldState, "notNull" | "column"> & {
|
|
81
81
|
notNull: true;
|
|
82
82
|
column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgJsonbBuilder>;
|
|
83
83
|
} & {
|
|
84
84
|
label: questpie_shared15.I18nText;
|
|
85
85
|
}>;
|
|
86
|
-
readonly isDefault:
|
|
86
|
+
readonly isDefault: questpie69.Field<Omit<questpie69.BooleanFieldState, "column" | "hasDefault"> & {
|
|
87
87
|
hasDefault: true;
|
|
88
88
|
column: drizzle_orm5.HasDefault<drizzle_orm_pg_core22.PgBooleanBuilder>;
|
|
89
89
|
} & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@questpie/admin",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/questpie/questpie.git",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"dev": "tsdown --watch",
|
|
50
50
|
"build": "tsdown",
|
|
51
51
|
"check-types": "tsc --noEmit",
|
|
52
|
-
"test": "bun test test/",
|
|
52
|
+
"test": "bun test --max-concurrency=1 test/",
|
|
53
53
|
"test:watch": "bun test --watch test/",
|
|
54
54
|
"questpie:generate": "bun x questpie generate --verbose"
|
|
55
55
|
},
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
|
63
63
|
"@hookform/resolvers": "^5.1.0",
|
|
64
64
|
"@iconify/react": "^6.0.2",
|
|
65
|
-
"@questpie/tanstack-query": "^3.0
|
|
65
|
+
"@questpie/tanstack-query": "^3.2.0",
|
|
66
66
|
"@tailwindcss/vite": "^4.0.6",
|
|
67
67
|
"@tiptap/core": "^2.x",
|
|
68
68
|
"@tiptap/extension-character-count": "^2.x",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"date-fns": "^4.1.0",
|
|
89
89
|
"lowlight": "^3.x",
|
|
90
90
|
"next-themes": "^0.4.6",
|
|
91
|
-
"questpie": "^3.0
|
|
91
|
+
"questpie": "^3.2.0",
|
|
92
92
|
"react-day-picker": "^9.12.0",
|
|
93
93
|
"react-hook-form": "^7.54.0",
|
|
94
94
|
"react-resizable-panels": "^4.4.2",
|