@questpie/admin 3.3.0 → 3.4.1

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 (90) hide show
  1. package/README.md +4 -6
  2. package/dist/client/blocks/block-renderer.d.mts +2 -2
  3. package/dist/client/builder/admin-types.d.mts +3 -3
  4. package/dist/client/builder/types/action-types.d.mts +1 -1
  5. package/dist/client/builder/types/collection-types.d.mts +59 -2
  6. package/dist/client/modules/admin.d.mts +3 -0
  7. package/dist/client/modules/admin.mjs +3 -0
  8. package/dist/client/preview/block-scope-context.d.mts +2 -2
  9. package/dist/client/preview/preview-banner.d.mts +2 -2
  10. package/dist/client/preview/preview-field.d.mts +4 -4
  11. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  12. package/dist/client/views/auth/auth-layout.d.mts +3 -3
  13. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  14. package/dist/client/views/auth/setup-form.d.mts +2 -2
  15. package/dist/client/views/collection/list-view.mjs +830 -0
  16. package/dist/client/views/collection/outline.mjs +363 -0
  17. package/dist/client/views/collection/table-view.mjs +6 -3
  18. package/dist/client/views/layout/admin-layout.d.mts +15 -1
  19. package/dist/client/views/layout/admin-layout.mjs +95 -31
  20. package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
  21. package/dist/client/views/pages/dashboard-page.d.mts +2 -2
  22. package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
  23. package/dist/client/views/pages/invite-page.d.mts +2 -2
  24. package/dist/client/views/pages/login-page.d.mts +2 -2
  25. package/dist/client.d.mts +6 -6
  26. package/dist/components/rich-text/rich-text-renderer.d.mts +2 -2
  27. package/dist/factories.d.mts +21 -0
  28. package/dist/factories.mjs +11 -0
  29. package/dist/fields.d.mts +4 -0
  30. package/dist/fields.mjs +5 -0
  31. package/dist/index.d.mts +6 -6
  32. package/dist/modules/admin.d.mts +10 -0
  33. package/dist/modules/admin.mjs +9 -0
  34. package/dist/modules/audit.d.mts +5 -0
  35. package/dist/modules/audit.mjs +5 -0
  36. package/dist/server/adapters/index.d.mts +2 -0
  37. package/dist/server/adapters/nextjs.d.mts +1 -0
  38. package/dist/server/augmentation/form-layout.d.mts +57 -2
  39. package/dist/server/augmentation/index.d.mts +3 -1
  40. package/dist/server/augmentation/shell.d.mts +48 -0
  41. package/dist/server/augmentation.d.mts +2 -1
  42. package/dist/server/auth-helpers.d.mts +1 -0
  43. package/dist/server/codegen/admin-client-template.mjs +11 -4
  44. package/dist/server/fields/blocks.d.mts +9 -2
  45. package/dist/server/fields/blocks.mjs +1 -1
  46. package/dist/server/fields/index.d.mts +2 -2
  47. package/dist/server/fields/index.mjs +2 -2
  48. package/dist/server/fields/rich-text.d.mts +9 -2
  49. package/dist/server/fields/rich-text.mjs +1 -1
  50. package/dist/server/modules/admin/.generated/module.d.mts +24 -19
  51. package/dist/server/modules/admin/.generated/module.mjs +5 -1
  52. package/dist/server/modules/admin/.generated/registries.d.mts +6 -4
  53. package/dist/server/modules/admin/client/.generated/module.d.mts +70 -70
  54. package/dist/server/modules/admin/client/.generated/module.mjs +3 -1
  55. package/dist/server/modules/admin/client/views/collection-form.d.mts +6 -0
  56. package/dist/server/modules/admin/client/views/collection-table.d.mts +6 -0
  57. package/dist/server/modules/admin/client/views/global-form.d.mts +6 -0
  58. package/dist/server/modules/admin/client/views/list-view.d.mts +6 -0
  59. package/dist/server/modules/admin/client/views/list-view.mjs +10 -0
  60. package/dist/server/modules/admin/collections/account.d.mts +50 -50
  61. package/dist/server/modules/admin/collections/admin-locks.d.mts +54 -54
  62. package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
  63. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
  64. package/dist/server/modules/admin/collections/apikey.d.mts +68 -68
  65. package/dist/server/modules/admin/collections/session.d.mts +42 -42
  66. package/dist/server/modules/admin/collections/user.d.mts +14 -14
  67. package/dist/server/modules/admin/collections/verification.d.mts +23 -23
  68. package/dist/server/modules/admin/dto/admin-config.dto.mjs +17 -0
  69. package/dist/server/modules/admin/index.d.mts +30 -31
  70. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -17
  71. package/dist/server/modules/admin/routes/admin-config.mjs +21 -5
  72. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  73. package/dist/server/modules/admin/routes/execute-action.mjs +18 -12
  74. package/dist/server/modules/admin/routes/i18n-helpers.d.mts +4 -0
  75. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  76. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  77. package/dist/server/modules/admin/routes/route-helpers.mjs +36 -1
  78. package/dist/server/modules/admin/routes/setup.d.mts +7 -14
  79. package/dist/server/modules/admin/routes/setup.mjs +16 -3
  80. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  81. package/dist/server/modules/admin/views/list-view.d.mts +8 -0
  82. package/dist/server/modules/admin/views/list-view.mjs +7 -0
  83. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
  84. package/dist/server/modules/audit/collections/audit-log.d.mts +7 -2
  85. package/dist/server/modules/audit/index.d.mts +1 -1
  86. package/dist/server/plugin.d.mts +1 -1
  87. package/dist/server/plugin.mjs +28 -28
  88. package/dist/server.d.mts +7 -4
  89. package/dist/server.mjs +7 -7
  90. package/package.json +13 -3
@@ -1,5 +1,5 @@
1
- import { introspectBlocks } from "../block/introspection.mjs";
2
1
  import { resolveDashboardCallback, resolveSidebarCallback } from "../../../proxy-factories.mjs";
2
+ import { introspectBlocks } from "../block/introspection.mjs";
3
3
  import { adminConfigDTOSchema } from "../dto/admin-config.dto.mjs";
4
4
  import { getAccessContext, getAdminConfig as getAdminConfig$1, getApp, getAppState, getCollectionState, getGlobalState } from "./route-helpers.mjs";
5
5
  import { z } from "zod";
@@ -21,6 +21,21 @@ import { executeAccessRule, route } from "questpie";
21
21
  * // { dashboard: {...}, sidebar: {...}, collections: {...}, globals: {...} }
22
22
  * ```
23
23
  */
24
+ function isPlainRecord(value) {
25
+ if (value === null || typeof value !== "object") return false;
26
+ const proto = Object.getPrototypeOf(value);
27
+ return proto === Object.prototype || proto === null;
28
+ }
29
+ function stripUndefinedDeep(value) {
30
+ if (Array.isArray(value)) return value.filter((item) => item !== void 0).map((item) => stripUndefinedDeep(item));
31
+ if (!isPlainRecord(value)) return value;
32
+ const result = {};
33
+ for (const [key, child] of Object.entries(value)) {
34
+ if (child === void 0) continue;
35
+ result[key] = stripUndefinedDeep(child);
36
+ }
37
+ return result;
38
+ }
24
39
  /**
25
40
  * Check if the current user has read access to a collection or global.
26
41
  * Returns true if accessible, false if denied.
@@ -468,7 +483,7 @@ async function processDashboardItems(items, accessibleCollections, accessCtx) {
468
483
  if (action.action?.type === "create") return accessibleCollections.has(action.action.collection);
469
484
  return true;
470
485
  });
471
- const { loader: loader$1, access: access$1, filterFn: filterFn$1, ...serializable$1 } = widget;
486
+ const { loader: loader$1, access: _access$1, filterFn: _filterFn$1, ...serializable$1 } = widget;
472
487
  if (loader$1) serializable$1.hasLoader = true;
473
488
  if (serializable$1.label && !serializable$1.title) serializable$1.title = serializable$1.label;
474
489
  result.push({
@@ -478,7 +493,7 @@ async function processDashboardItems(items, accessibleCollections, accessCtx) {
478
493
  });
479
494
  continue;
480
495
  }
481
- const { loader, access, filterFn, ...serializable } = widget;
496
+ const { loader, access: _access, filterFn: _filterFn, ...serializable } = widget;
482
497
  if (loader) serializable.hasLoader = true;
483
498
  if (serializable.label && !serializable.title) serializable.title = serializable.label;
484
499
  result.push(serializable);
@@ -497,7 +512,7 @@ const getAdminConfigOutputSchema = adminConfigDTOSchema;
497
512
  * ```ts title="questpie/server/config/admin.ts"
498
513
  * import { adminConfig } from "#questpie/factories";
499
514
  *
500
- * export default adminConfig({
515
+ * export const config = adminConfig({
501
516
  * dashboard: { items: [] },
502
517
  * sidebar: { sections: [], items: [] },
503
518
  * });
@@ -527,6 +542,7 @@ const getAdminConfig = route().post().schema(getAdminConfigSchema).outputSchema(
527
542
  defaultCollection: uploadCollections.length === 1 ? uploadCollections[0] : void 0
528
543
  };
529
544
  if (adminCfg.branding) response.branding = adminCfg.branding;
545
+ if (adminCfg.shell) response.shell = adminCfg.shell;
530
546
  if (adminCfg.dashboard) {
531
547
  let dashboard;
532
548
  if (isLegacyDashboardConfig(adminCfg.dashboard)) dashboard = adminCfg.dashboard;
@@ -555,7 +571,7 @@ const getAdminConfig = route().post().schema(getAdminConfigSchema).outputSchema(
555
571
  if (appState.blocks && Object.keys(appState.blocks).length > 0) response.blocks = introspectBlocks(appState.blocks);
556
572
  response.collections = filteredCollectionsMeta;
557
573
  response.globals = filteredGlobalsMeta;
558
- return response;
574
+ return stripUndefinedDeep(response);
559
575
  });
560
576
  /**
561
577
  * Admin config route handlers.
@@ -1,7 +1,7 @@
1
1
  import { ServerActionDefinition, ServerActionResult } from "../../../augmentation/actions.mjs";
2
2
  import "../../../augmentation.mjs";
3
3
  import { App } from "./route-helpers.mjs";
4
- import * as questpie121 from "questpie";
4
+ import * as questpie143 from "questpie";
5
5
 
6
6
  //#region src/server/modules/admin/routes/execute-action.d.ts
7
7
 
@@ -56,37 +56,37 @@ declare function executeAction(app: App, request: ExecuteActionRequest, session?
56
56
  * });
57
57
  * ```
58
58
  */
59
- declare const executeActionFn: questpie121.JsonRouteDefinition<{
59
+ declare const executeActionFn: questpie143.JsonRouteDefinition<{
60
60
  collection: string;
61
61
  actionId: string;
62
62
  itemId?: string | undefined;
63
63
  itemIds?: string[] | undefined;
64
64
  data?: Record<string, unknown> | undefined;
65
65
  locale?: string | undefined;
66
- }, any, questpie121.JsonRouteParams>;
66
+ }, any, questpie143.JsonRouteParams>;
67
67
  /**
68
68
  * Get actions configuration for a collection.
69
69
  * Returns action definitions without handlers for client rendering.
70
70
  */
71
- declare const getActionsConfigFn: questpie121.JsonRouteDefinition<{
71
+ declare const getActionsConfigFn: questpie143.JsonRouteDefinition<{
72
72
  collection: string;
73
- }, any, questpie121.JsonRouteParams>;
73
+ }, any, questpie143.JsonRouteParams>;
74
74
  /**
75
75
  * QUESTPIE functions for action execution.
76
76
  * These are registered on the `adminModule`.
77
77
  */
78
78
  declare const actionFunctions: {
79
- executeAction: questpie121.JsonRouteDefinition<{
79
+ executeAction: questpie143.JsonRouteDefinition<{
80
80
  collection: string;
81
81
  actionId: string;
82
82
  itemId?: string | undefined;
83
83
  itemIds?: string[] | undefined;
84
84
  data?: Record<string, unknown> | undefined;
85
85
  locale?: string | undefined;
86
- }, any, questpie121.JsonRouteParams>;
87
- getActionsConfig: questpie121.JsonRouteDefinition<{
86
+ }, any, questpie143.JsonRouteParams>;
87
+ getActionsConfig: questpie143.JsonRouteDefinition<{
88
88
  collection: string;
89
- }, any, questpie121.JsonRouteParams>;
89
+ }, any, questpie143.JsonRouteParams>;
90
90
  };
91
91
  //#endregion
92
92
  export { ExecuteActionRequest, ExecuteActionResponse, actionFunctions, executeAction, executeActionFn, getActionsConfig, getActionsConfigFn };
@@ -1,4 +1,4 @@
1
- import { getApp, getAppState, getSession } from "./route-helpers.mjs";
1
+ import { getApp, getCollection, getCollectionCrud, getCollectionCruds, getGlobalCruds, getSession } from "./route-helpers.mjs";
2
2
  import { translateAdminMessage } from "./i18n-helpers.mjs";
3
3
  import { z } from "zod";
4
4
  import { route } from "questpie";
@@ -26,7 +26,7 @@ import { route } from "questpie";
26
26
  * Returns action definitions without handlers (for client-side rendering).
27
27
  */
28
28
  function getActionsConfig(app, collectionSlug) {
29
- const collection$1 = getAppState(app).collections?.[collectionSlug];
29
+ const collection$1 = getCollection(app, collectionSlug);
30
30
  if (!collection$1) return null;
31
31
  const actionsConfig = (collection$1.state || collection$1).adminActions;
32
32
  if (!actionsConfig) return {
@@ -98,7 +98,7 @@ function serializeActionFormFields(fields) {
98
98
  */
99
99
  async function executeAction(app, request, session) {
100
100
  const { collection: collectionSlug, actionId, itemId, itemIds, data, locale } = request;
101
- const collection$1 = getAppState(app).collections?.[collectionSlug];
101
+ const collection$1 = getCollection(app, collectionSlug);
102
102
  const t = (key, params) => translateAdminMessage(locale, key, params);
103
103
  if (!collection$1) return {
104
104
  success: false,
@@ -148,8 +148,8 @@ async function executeAction(app, request, session) {
148
148
  itemId,
149
149
  itemIds,
150
150
  auth: appRec.auth,
151
- collections: appRec.api?.collections,
152
- globals: appRec.api?.globals,
151
+ collections: getCollectionCruds(app),
152
+ globals: getGlobalCruds(app),
153
153
  db: appRec.db,
154
154
  session,
155
155
  locale
@@ -177,7 +177,7 @@ async function executeBuiltinAction(app, params) {
177
177
  const { collectionSlug, actionId, itemId, itemIds, data, locale } = params;
178
178
  const t = (key, messageParams) => translateAdminMessage(locale, key, messageParams);
179
179
  const appRec = app;
180
- const collectionCrud = appRec.api?.collections?.[collectionSlug];
180
+ const collectionCrud = getCollectionCrud(app, collectionSlug);
181
181
  const crudContext = {
182
182
  db: appRec.db,
183
183
  session: params.session,
@@ -186,7 +186,7 @@ async function executeBuiltinAction(app, params) {
186
186
  try {
187
187
  switch (actionId) {
188
188
  case "create": {
189
- const result = await appRec.create(collectionSlug, data || {});
189
+ const result = collectionCrud?.create ? await collectionCrud.create(data || {}, crudContext) : await appRec.create(collectionSlug, data || {});
190
190
  return {
191
191
  success: true,
192
192
  result: {
@@ -207,7 +207,11 @@ async function executeBuiltinAction(app, params) {
207
207
  toast: { message: t("action.itemIdRequired.save") }
208
208
  }
209
209
  };
210
- await appRec.update(collectionSlug, itemId, data || {});
210
+ if (collectionCrud?.updateById) await collectionCrud.updateById({
211
+ id: itemId,
212
+ data: data || {}
213
+ }, crudContext);
214
+ else await appRec.update(collectionSlug, itemId, data || {});
211
215
  return {
212
216
  success: true,
213
217
  result: {
@@ -224,7 +228,8 @@ async function executeBuiltinAction(app, params) {
224
228
  toast: { message: t("action.itemIdRequired.delete") }
225
229
  }
226
230
  };
227
- await appRec.delete(collectionSlug, itemId);
231
+ if (collectionCrud?.deleteById) await collectionCrud.deleteById({ id: itemId }, crudContext);
232
+ else await appRec.delete(collectionSlug, itemId);
228
233
  return {
229
234
  success: true,
230
235
  result: {
@@ -244,7 +249,8 @@ async function executeBuiltinAction(app, params) {
244
249
  toast: { message: t("action.itemIdsRequired.bulkDelete") }
245
250
  }
246
251
  };
247
- await Promise.all(itemIds.map((id) => appRec.delete(collectionSlug, id)));
252
+ if (collectionCrud?.deleteById) await Promise.all(itemIds.map((id) => collectionCrud.deleteById({ id }, crudContext)));
253
+ else await Promise.all(itemIds.map((id) => appRec.delete(collectionSlug, id)));
248
254
  return {
249
255
  success: true,
250
256
  result: {
@@ -314,7 +320,7 @@ async function executeBuiltinAction(app, params) {
314
320
  toast: { message: t("action.itemIdRequired.duplicate") }
315
321
  }
316
322
  };
317
- const original = await appRec.findById(collectionSlug, itemId);
323
+ const original = collectionCrud?.findOne ? await collectionCrud.findOne({ where: { id: itemId } }, crudContext) : await appRec.findById(collectionSlug, itemId);
318
324
  if (!original) return {
319
325
  success: false,
320
326
  result: {
@@ -323,7 +329,7 @@ async function executeBuiltinAction(app, params) {
323
329
  }
324
330
  };
325
331
  const { id, createdAt, updatedAt, ...duplicateData } = original;
326
- const duplicated = await appRec.create(collectionSlug, duplicateData);
332
+ const duplicated = collectionCrud?.create ? await collectionCrud.create(duplicateData, crudContext) : await appRec.create(collectionSlug, duplicateData);
327
333
  return {
328
334
  success: true,
329
335
  result: {
@@ -0,0 +1,4 @@
1
+ //#region src/server/modules/admin/routes/i18n-helpers.d.ts
2
+ declare function translateAdminMessage(locale: string | undefined, key: string, params?: Record<string, unknown>): string;
3
+ //#endregion
4
+ export { translateAdminMessage };
@@ -1,4 +1,4 @@
1
- import * as questpie141 from "questpie";
1
+ import * as questpie73 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/preview.d.ts
4
4
 
@@ -25,13 +25,13 @@ interface PreviewTokenPayload {
25
25
  * @returns Object with preview functions
26
26
  */
27
27
  declare function createPreviewFunctions(secret?: PreviewSecretSource): {
28
- mintPreviewToken: questpie141.JsonRouteDefinition<{
28
+ mintPreviewToken: questpie73.JsonRouteDefinition<{
29
29
  path: string;
30
30
  ttlMs?: number | undefined;
31
- }, any, questpie141.JsonRouteParams>;
32
- verifyPreviewToken: questpie141.JsonRouteDefinition<{
31
+ }, any, questpie73.JsonRouteParams>;
32
+ verifyPreviewToken: questpie73.JsonRouteDefinition<{
33
33
  token: string;
34
- }, any, questpie141.JsonRouteParams>;
34
+ }, any, questpie73.JsonRouteParams>;
35
35
  };
36
36
  /**
37
37
  * Verify a preview token without RPC.
@@ -68,18 +68,18 @@ declare function createPreviewTokenVerifier(secret: string): (token: string) =>
68
68
  * Used by the `adminModule` to register preview RPC functions.
69
69
  */
70
70
  declare const previewFunctions: {
71
- getPreviewUrl: questpie141.JsonRouteDefinition<{
71
+ getPreviewUrl: questpie73.JsonRouteDefinition<{
72
72
  collection: string;
73
73
  record: Record<string, unknown>;
74
74
  locale?: string | undefined;
75
- }, any, questpie141.JsonRouteParams>;
76
- mintPreviewToken: questpie141.JsonRouteDefinition<{
75
+ }, any, questpie73.JsonRouteParams>;
76
+ mintPreviewToken: questpie73.JsonRouteDefinition<{
77
77
  path: string;
78
78
  ttlMs?: number | undefined;
79
- }, any, questpie141.JsonRouteParams>;
80
- verifyPreviewToken: questpie141.JsonRouteDefinition<{
79
+ }, any, questpie73.JsonRouteParams>;
80
+ verifyPreviewToken: questpie73.JsonRouteDefinition<{
81
81
  token: string;
82
- }, any, questpie141.JsonRouteParams>;
82
+ }, any, questpie73.JsonRouteParams>;
83
83
  };
84
84
  //#endregion
85
85
  export { PreviewTokenPayload, createPreviewFunctions, createPreviewTokenVerifier, previewFunctions, verifyPreviewTokenDirect };
@@ -1,4 +1,4 @@
1
- import * as questpie113 from "questpie";
1
+ import * as questpie83 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/reactive.d.ts
4
4
 
@@ -13,7 +13,7 @@ import * as questpie113 from "questpie";
13
13
  * Batch reactive endpoint.
14
14
  * Executes multiple reactive handlers in a single request.
15
15
  */
16
- declare const batchReactive: questpie113.JsonRouteDefinition<{
16
+ declare const batchReactive: questpie83.JsonRouteDefinition<{
17
17
  collection: string;
18
18
  type: "collection" | "global";
19
19
  requests: {
@@ -27,12 +27,12 @@ declare const batchReactive: questpie113.JsonRouteDefinition<{
27
27
  }[];
28
28
  formData?: Record<string, unknown> | undefined;
29
29
  prevData?: Record<string, unknown> | null | undefined;
30
- }, any, questpie113.JsonRouteParams>;
30
+ }, any, questpie83.JsonRouteParams>;
31
31
  /**
32
32
  * Dynamic options endpoint.
33
33
  * Fetches options for select/relation fields with search and pagination.
34
34
  */
35
- declare const fieldOptions: questpie113.JsonRouteDefinition<{
35
+ declare const fieldOptions: questpie83.JsonRouteDefinition<{
36
36
  collection: string;
37
37
  type: "collection" | "global";
38
38
  field: string;
@@ -41,12 +41,12 @@ declare const fieldOptions: questpie113.JsonRouteDefinition<{
41
41
  page: number;
42
42
  limit: number;
43
43
  siblingData?: Record<string, unknown> | null | undefined;
44
- }, any, questpie113.JsonRouteParams>;
44
+ }, any, questpie83.JsonRouteParams>;
45
45
  /**
46
46
  * Reactive functions bundle.
47
47
  */
48
48
  declare const reactiveFunctions: {
49
- readonly batchReactive: questpie113.JsonRouteDefinition<{
49
+ readonly batchReactive: questpie83.JsonRouteDefinition<{
50
50
  collection: string;
51
51
  type: "collection" | "global";
52
52
  requests: {
@@ -60,8 +60,8 @@ declare const reactiveFunctions: {
60
60
  }[];
61
61
  formData?: Record<string, unknown> | undefined;
62
62
  prevData?: Record<string, unknown> | null | undefined;
63
- }, any, questpie113.JsonRouteParams>;
64
- readonly fieldOptions: questpie113.JsonRouteDefinition<{
63
+ }, any, questpie83.JsonRouteParams>;
64
+ readonly fieldOptions: questpie83.JsonRouteDefinition<{
65
65
  collection: string;
66
66
  type: "collection" | "global";
67
67
  field: string;
@@ -70,7 +70,7 @@ declare const reactiveFunctions: {
70
70
  page: number;
71
71
  limit: number;
72
72
  siblingData?: Record<string, unknown> | null | undefined;
73
- }, any, questpie113.JsonRouteParams>;
73
+ }, any, questpie83.JsonRouteParams>;
74
74
  };
75
75
  //#endregion
76
76
  export { batchReactive, fieldOptions, reactiveFunctions };
@@ -60,6 +60,41 @@ function getAdminConfig(app) {
60
60
  return getAppState(app).config?.admin || {};
61
61
  }
62
62
  /**
63
+ * Get registered collection definitions from the current or legacy app shape.
64
+ */
65
+ function getCollections(app) {
66
+ const appRec = app;
67
+ if (typeof appRec.getCollections === "function") return appRec.getCollections();
68
+ return getAppState(app).collections ?? {};
69
+ }
70
+ /**
71
+ * Get a registered collection definition by slug.
72
+ */
73
+ function getCollection(app, collectionSlug) {
74
+ return getCollections(app)[collectionSlug];
75
+ }
76
+ /**
77
+ * Get collection CRUD APIs from the current or legacy app shape.
78
+ */
79
+ function getCollectionCrud(app, collectionSlug) {
80
+ const appRec = app;
81
+ return appRec.collections?.[collectionSlug] ?? appRec.api?.collections?.[collectionSlug] ?? appRec._api?.collections?.[collectionSlug];
82
+ }
83
+ /**
84
+ * Get all collection CRUD APIs from the current or legacy app shape.
85
+ */
86
+ function getCollectionCruds(app) {
87
+ const appRec = app;
88
+ return appRec.collections ?? appRec.api?.collections ?? appRec._api?.collections;
89
+ }
90
+ /**
91
+ * Get all global CRUD APIs from the current or legacy app shape.
92
+ */
93
+ function getGlobalCruds(app) {
94
+ const appRec = app;
95
+ return appRec.globals ?? appRec.api?.globals ?? appRec._api?.globals;
96
+ }
97
+ /**
63
98
  * Build a ReactiveServerContext from route handler context.
64
99
  */
65
100
  function buildServerContext(ctx) {
@@ -73,4 +108,4 @@ function buildServerContext(ctx) {
73
108
  }
74
109
 
75
110
  //#endregion
76
- export { buildServerContext, getAccessContext, getAdminConfig, getApp, getAppState, getCollectionState, getGlobalState, getLocale, getSession };
111
+ export { buildServerContext, getAccessContext, getAdminConfig, getApp, getAppState, getCollection, getCollectionCrud, getCollectionCruds, getCollectionState, getGlobalCruds, getGlobalState, getLocale, getSession };
@@ -1,14 +1,7 @@
1
- import * as questpie129 from "questpie";
1
+ import * as questpie91 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/setup.d.ts
4
4
 
5
- /**
6
- * Setup Functions
7
- *
8
- * Built-in functions for bootstrapping the first admin user.
9
- * Solves the chicken-and-egg problem where invitation-based systems
10
- * need an existing admin to create the first invitation.
11
- */
12
5
  /**
13
6
  * Check if setup is required (no admin users exist in the system).
14
7
  *
@@ -20,7 +13,7 @@ import * as questpie129 from "questpie";
20
13
  * }
21
14
  * ```
22
15
  */
23
- declare const isSetupRequired: questpie129.JsonRouteDefinition<Record<string, never>, any, questpie129.JsonRouteParams>;
16
+ declare const isSetupRequired: questpie91.JsonRouteDefinition<Record<string, never>, any, questpie91.JsonRouteParams>;
24
17
  /**
25
18
  * Create the first admin user in the system.
26
19
  * This function only works when no admin users exist (setup mode).
@@ -43,21 +36,21 @@ declare const isSetupRequired: questpie129.JsonRouteDefinition<Record<string, ne
43
36
  * }
44
37
  * ```
45
38
  */
46
- declare const createFirstAdmin: questpie129.JsonRouteDefinition<{
39
+ declare const createFirstAdmin: questpie91.JsonRouteDefinition<{
47
40
  email: string;
48
41
  password: string;
49
42
  name: string;
50
- }, any, questpie129.JsonRouteParams>;
43
+ }, any, questpie91.JsonRouteParams>;
51
44
  /**
52
45
  * Bundle of setup-related functions.
53
46
  */
54
47
  declare const setupFunctions: {
55
- readonly isSetupRequired: questpie129.JsonRouteDefinition<Record<string, never>, any, questpie129.JsonRouteParams>;
56
- readonly createFirstAdmin: questpie129.JsonRouteDefinition<{
48
+ readonly isSetupRequired: questpie91.JsonRouteDefinition<Record<string, never>, any, questpie91.JsonRouteParams>;
49
+ readonly createFirstAdmin: questpie91.JsonRouteDefinition<{
57
50
  email: string;
58
51
  password: string;
59
52
  name: string;
60
- }, any, questpie129.JsonRouteParams>;
53
+ }, any, questpie91.JsonRouteParams>;
61
54
  };
62
55
  //#endregion
63
56
  export { createFirstAdmin, isSetupRequired, setupFunctions };
@@ -28,6 +28,17 @@ const createFirstAdminOutputSchema = z.object({
28
28
  }).optional(),
29
29
  error: z.string().optional()
30
30
  });
31
+ const adminUserContractMessage = "QUESTPIE Admin requires the canonical Better Auth \"user\" collection from adminModule/starterModule. The current \"user\" collection is missing required admin auth fields. Do not replace collection(\"user\") from scratch; merge starterModule.collections.user or adminModule.collections.user and extend it.";
32
+ function getAdminUserTableContract(userCollection) {
33
+ const table = userCollection?.table;
34
+ const missing = [
35
+ "id",
36
+ "role",
37
+ "emailVerified"
38
+ ].filter((field$1) => !table?.[field$1]);
39
+ if (missing.length > 0) throw new Error(`${adminUserContractMessage} Missing field(s): ${missing.join(", ")}.`);
40
+ return table;
41
+ }
31
42
  /**
32
43
  * Check if setup is required (no admin users exist in the system).
33
44
  *
@@ -42,7 +53,8 @@ const createFirstAdminOutputSchema = z.object({
42
53
  const isSetupRequired = route().post().schema(isSetupRequiredSchema).outputSchema(isSetupRequiredOutputSchema).handler(async (ctx) => {
43
54
  const app = getApp(ctx);
44
55
  const userCollection = app.getCollectionConfig("user");
45
- return { required: (await app.db.select({ count: sql$1`count(*)::int` }).from(userCollection.table).where(eq(userCollection.table.role, "admin")))[0].count === 0 };
56
+ const userTable = getAdminUserTableContract(userCollection);
57
+ return { required: (await app.db.select({ count: sql$1`count(*)::int` }).from(userCollection.table).where(eq(userTable.role, "admin")))[0].count === 0 };
46
58
  });
47
59
  /**
48
60
  * Create the first admin user in the system.
@@ -72,7 +84,8 @@ const createFirstAdmin = route().post().schema(createFirstAdminSchema).outputSch
72
84
  const t = (key, params) => translateAdminMessage(locale, key, params);
73
85
  const input = ctx.input;
74
86
  const userCollection = app.getCollectionConfig("user");
75
- if ((await app.db.select({ count: sql$1`count(*)::int` }).from(userCollection.table).where(eq(userCollection.table.role, "admin")))[0].count > 0) return {
87
+ const userTable = getAdminUserTableContract(userCollection);
88
+ if ((await app.db.select({ count: sql$1`count(*)::int` }).from(userCollection.table).where(eq(userTable.role, "admin")))[0].count > 0) return {
76
89
  success: false,
77
90
  error: t("auth.setupAlreadyCompleted")
78
91
  };
@@ -89,7 +102,7 @@ const createFirstAdmin = route().post().schema(createFirstAdminSchema).outputSch
89
102
  await app.db.update(userCollection.table).set({
90
103
  role: "admin",
91
104
  emailVerified: true
92
- }).where(eq(userCollection.table.id, signUpResult.user.id));
105
+ }).where(eq(userTable.id, signUpResult.user.id));
93
106
  return {
94
107
  success: true,
95
108
  user: {
@@ -1,4 +1,4 @@
1
- import * as questpie137 from "questpie";
1
+ import * as questpie69 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/widget-data.d.ts
4
4
 
@@ -20,13 +20,13 @@ import * as questpie137 from "questpie";
20
20
  * const data = await client.routes.fetchWidgetData({ widgetId: "my-widget" });
21
21
  * ```
22
22
  */
23
- declare const fetchWidgetData: questpie137.JsonRouteDefinition<{
23
+ declare const fetchWidgetData: questpie69.JsonRouteDefinition<{
24
24
  widgetId: string;
25
- }, any, questpie137.JsonRouteParams>;
25
+ }, any, questpie69.JsonRouteParams>;
26
26
  declare const widgetDataFunctions: {
27
- readonly fetchWidgetData: questpie137.JsonRouteDefinition<{
27
+ readonly fetchWidgetData: questpie69.JsonRouteDefinition<{
28
28
  widgetId: string;
29
- }, any, questpie137.JsonRouteParams>;
29
+ }, any, questpie69.JsonRouteParams>;
30
30
  };
31
31
  //#endregion
32
32
  export { fetchWidgetData, widgetDataFunctions };
@@ -0,0 +1,8 @@
1
+ import { ListViewConfig } from "../../../augmentation/form-layout.mjs";
2
+ import { ViewDefinition } from "../../../augmentation/views.mjs";
3
+ import "../../../augmentation.mjs";
4
+
5
+ //#region src/server/modules/admin/views/list-view.d.ts
6
+ declare const _default: ViewDefinition<"list-view", "list", ListViewConfig>;
7
+ //#endregion
8
+ export { _default };
@@ -0,0 +1,7 @@
1
+ import { view } from "../../../registry-helpers.mjs";
2
+
3
+ //#region src/server/modules/admin/views/list-view.ts
4
+ var list_view_default = view("list-view", { kind: "list" });
5
+
6
+ //#endregion
7
+ export { list_view_default as default };
@@ -1,8 +1,8 @@
1
1
  import { FilterOperator, FilterRule, SortConfig, ViewConfiguration } from "../../../../shared/types/saved-views.types.mjs";
2
2
  import * as questpie_shared16 from "questpie/shared";
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";
3
+ import * as questpie115 from "questpie";
4
+ import * as questpie_src_server_modules_core_fields_email_js2 from "questpie/src/server/modules/core/fields/email.js";
5
+ import * as questpie_src_server_modules_core_fields_json_js2 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
 
@@ -31,22 +31,22 @@ import * as drizzle_orm5 from "drizzle-orm";
31
31
  * });
32
32
  * ```
33
33
  */
34
- declare const savedViewsCollection: questpie69.CollectionBuilder<questpie_shared16.Override<questpie_shared16.Override<questpie69.EmptyCollectionState<"admin_saved_views", undefined, {
35
- readonly text: typeof questpie69.text;
36
- readonly textarea: typeof questpie69.textarea;
37
- readonly email: typeof questpie_src_server_modules_core_fields_email_js1.email;
38
- readonly url: typeof questpie69.url;
39
- readonly number: typeof questpie69.number;
40
- readonly boolean: typeof questpie69.boolean;
41
- readonly date: typeof questpie69.date;
42
- readonly datetime: typeof questpie69.datetime;
43
- readonly time: typeof questpie69.time;
44
- readonly select: typeof questpie69.select;
45
- readonly upload: typeof questpie69.upload;
46
- readonly relation: typeof questpie69.relation;
47
- readonly object: typeof questpie69.object;
48
- readonly json: typeof questpie_src_server_modules_core_fields_json_js1.json;
49
- readonly from: typeof questpie69.from;
34
+ declare const savedViewsCollection: questpie115.CollectionBuilder<questpie_shared16.Override<questpie_shared16.Override<questpie115.EmptyCollectionState<"admin_saved_views", undefined, {
35
+ readonly text: typeof questpie115.text;
36
+ readonly textarea: typeof questpie115.textarea;
37
+ readonly email: typeof questpie_src_server_modules_core_fields_email_js2.email;
38
+ readonly url: typeof questpie115.url;
39
+ readonly number: typeof questpie115.number;
40
+ readonly boolean: typeof questpie115.boolean;
41
+ readonly date: typeof questpie115.date;
42
+ readonly datetime: typeof questpie115.datetime;
43
+ readonly time: typeof questpie115.time;
44
+ readonly select: typeof questpie115.select;
45
+ readonly upload: typeof questpie115.upload;
46
+ readonly relation: typeof questpie115.relation;
47
+ readonly object: typeof questpie115.object;
48
+ readonly json: typeof questpie_src_server_modules_core_fields_json_js2.json;
49
+ readonly from: typeof questpie115.from;
50
50
  }>, {
51
51
  fields: {
52
52
  readonly userId: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
@@ -57,31 +57,31 @@ declare const savedViewsCollection: questpie69.CollectionBuilder<questpie_shared
57
57
  };
58
58
  localized: readonly string[];
59
59
  fieldDefinitions: {
60
- readonly userId: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
60
+ readonly userId: questpie115.FieldWithMethods<Omit<questpie115.TextFieldState, "notNull" | "column"> & {
61
61
  notNull: true;
62
62
  column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
63
63
  } & {
64
64
  label: questpie_shared16.I18nText;
65
- }, questpie69.TextFieldMethods>;
66
- readonly collectionName: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
65
+ }, questpie115.TextFieldMethods>;
66
+ readonly collectionName: questpie115.FieldWithMethods<Omit<questpie115.TextFieldState, "notNull" | "column"> & {
67
67
  notNull: true;
68
68
  column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
69
69
  } & {
70
70
  label: questpie_shared16.I18nText;
71
- }, questpie69.TextFieldMethods>;
72
- readonly name: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
71
+ }, questpie115.TextFieldMethods>;
72
+ readonly name: questpie115.FieldWithMethods<Omit<questpie115.TextFieldState, "notNull" | "column"> & {
73
73
  notNull: true;
74
74
  column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
75
75
  } & {
76
76
  label: questpie_shared16.I18nText;
77
- }, questpie69.TextFieldMethods>;
78
- readonly configuration: questpie69.Field<Omit<questpie69.JsonFieldState, "notNull" | "column"> & {
77
+ }, questpie115.TextFieldMethods>;
78
+ readonly configuration: questpie115.Field<Omit<questpie115.JsonFieldState, "notNull" | "column"> & {
79
79
  notNull: true;
80
80
  column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgJsonbBuilder>;
81
81
  } & {
82
82
  label: questpie_shared16.I18nText;
83
83
  }>;
84
- readonly isDefault: questpie69.Field<Omit<questpie69.BooleanFieldState, "column" | "hasDefault"> & {
84
+ readonly isDefault: questpie115.Field<Omit<questpie115.BooleanFieldState, "column" | "hasDefault"> & {
85
85
  hasDefault: true;
86
86
  column: drizzle_orm5.HasDefault<drizzle_orm_pg_core22.PgBooleanBuilder>;
87
87
  } & {
@@ -7,7 +7,12 @@ import * as drizzle_orm0 from "drizzle-orm";
7
7
  import * as questpie_src_server_fields_operators_builtin_js0 from "questpie/src/server/fields/operators/builtin.js";
8
8
 
9
9
  //#region src/server/modules/audit/collections/audit-log.d.ts
10
-
10
+ /**
11
+ * The collection slug used by the audit log.
12
+ * Exported so hooks and jobs can reference the collection dynamically
13
+ * instead of hardcoding the name.
14
+ */
15
+ declare const AUDIT_LOG_COLLECTION: "admin_audit_log";
11
16
  /**
12
17
  * Audit Log Collection
13
18
  *
@@ -213,4 +218,4 @@ declare const auditLogCollection: questpie21.CollectionBuilder<questpie_shared0.
213
218
  })[];
214
219
  }>>;
215
220
  //#endregion
216
- export { auditLogCollection };
221
+ export { AUDIT_LOG_COLLECTION, auditLogCollection };
@@ -1,3 +1,3 @@
1
- import { auditLogCollection } from "./collections/audit-log.mjs";
1
+ import { AUDIT_LOG_COLLECTION, auditLogCollection } from "./collections/audit-log.mjs";
2
2
  import { AuditModule, _module } from "./.generated/module.mjs";
3
3
  import { AuditActorType, AuditContext, LogAuditEntryOptions, logAuditEntry } from "./log-audit-entry.mjs";