@questpie/admin 3.0.5 → 3.0.6

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 (64) hide show
  1. package/README.md +99 -1
  2. package/dist/client/builder/types/field-types.d.mts +11 -0
  3. package/dist/client/components/brand-logo.d.mts +25 -0
  4. package/dist/client/components/brand-logo.mjs +174 -0
  5. package/dist/client/create-admin-client.d.mts +7 -0
  6. package/dist/client/create-admin-client.mjs +25 -0
  7. package/dist/client/hooks/use-brand.d.mts +22 -0
  8. package/dist/client/hooks/use-brand.mjs +52 -0
  9. package/dist/client/runtime/index.mjs +1 -1
  10. package/dist/client/runtime/provider.d.mts +4 -0
  11. package/dist/client/runtime/provider.mjs +38 -8
  12. package/dist/client/styles/base.css +4 -0
  13. package/dist/client/types/admin-config.d.mts +24 -0
  14. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  15. package/dist/client/views/auth/auth-layout.d.mts +8 -3
  16. package/dist/client/views/auth/auth-layout.mjs +116 -102
  17. package/dist/client/views/auth/forgot-password-form.d.mts +2 -2
  18. package/dist/client/views/auth/login-form.d.mts +2 -2
  19. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  20. package/dist/client/views/auth/setup-form.d.mts +2 -2
  21. package/dist/client/views/collection/auto-form-fields.mjs +2 -0
  22. package/dist/client/views/collection/field-renderer.mjs +3 -2
  23. package/dist/client/views/globals/global-form-view.mjs +908 -863
  24. package/dist/client/views/layout/admin-sidebar.mjs +153 -141
  25. package/dist/client/views/pages/accept-invite-page.mjs +122 -144
  26. package/dist/client/views/pages/forgot-password-page.mjs +22 -30
  27. package/dist/client/views/pages/invite-page.mjs +24 -33
  28. package/dist/client/views/pages/login-page.d.mts +2 -2
  29. package/dist/client/views/pages/login-page.mjs +24 -32
  30. package/dist/client/views/pages/reset-password-page.d.mts +2 -2
  31. package/dist/client/views/pages/reset-password-page.mjs +77 -92
  32. package/dist/client/views/pages/setup-page.mjs +31 -39
  33. package/dist/client.d.mts +6 -2
  34. package/dist/client.mjs +5 -2
  35. package/dist/index.d.mts +6 -2
  36. package/dist/index.mjs +5 -2
  37. package/dist/server/augmentation/dashboard.d.mts +23 -5
  38. package/dist/server/augmentation/form-layout.d.mts +10 -0
  39. package/dist/server/augmentation/index.d.mts +1 -1
  40. package/dist/server/augmentation.d.mts +1 -1
  41. package/dist/server/modules/admin/collections/account.d.mts +46 -46
  42. package/dist/server/modules/admin/collections/admin-locks.d.mts +54 -54
  43. package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
  44. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
  45. package/dist/server/modules/admin/collections/apikey.d.mts +68 -68
  46. package/dist/server/modules/admin/collections/assets.d.mts +20 -20
  47. package/dist/server/modules/admin/collections/session.d.mts +42 -42
  48. package/dist/server/modules/admin/collections/user.d.mts +32 -32
  49. package/dist/server/modules/admin/collections/verification.d.mts +32 -32
  50. package/dist/server/modules/admin/dto/admin-config.dto.mjs +19 -1
  51. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  52. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  53. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  54. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  55. package/dist/server/modules/admin/routes/preview.mjs +1 -1
  56. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  57. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  58. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
  59. package/dist/server.d.mts +4 -4
  60. package/dist/shared/preview-utils.d.mts +34 -1
  61. package/dist/shared/preview-utils.mjs +79 -1
  62. package/dist/shared.d.mts +2 -2
  63. package/dist/shared.mjs +2 -2
  64. package/package.json +3 -3
@@ -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 questpie117 from "questpie";
4
+ import * as questpie135 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: questpie117.JsonRouteDefinition<{
59
+ declare const executeActionFn: questpie135.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, questpie117.JsonRouteParams>;
66
+ }, any, questpie135.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: questpie117.JsonRouteDefinition<{
71
+ declare const getActionsConfigFn: questpie135.JsonRouteDefinition<{
72
72
  collection: string;
73
- }, any, questpie117.JsonRouteParams>;
73
+ }, any, questpie135.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: questpie117.JsonRouteDefinition<{
79
+ executeAction: questpie135.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, questpie117.JsonRouteParams>;
87
- getActionsConfig: questpie117.JsonRouteDefinition<{
86
+ }, any, questpie135.JsonRouteParams>;
87
+ getActionsConfig: questpie135.JsonRouteDefinition<{
88
88
  collection: string;
89
- }, any, questpie117.JsonRouteParams>;
89
+ }, any, questpie135.JsonRouteParams>;
90
90
  };
91
91
  //#endregion
92
92
  export { ExecuteActionRequest, ExecuteActionResponse, actionFunctions, executeAction, executeActionFn, getActionsConfig, getActionsConfigFn };
@@ -1,4 +1,4 @@
1
- import * as questpie462 from "questpie";
1
+ import * as questpie268 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/locales.d.ts
4
4
 
@@ -12,7 +12,7 @@ import * as questpie462 from "questpie";
12
12
  * Bundle of locale-related functions.
13
13
  */
14
14
  declare const localeFunctions: {
15
- readonly getContentLocales: questpie462.JsonRouteDefinition<Record<string, never> | undefined, any, questpie462.JsonRouteParams>;
15
+ readonly getContentLocales: questpie268.JsonRouteDefinition<Record<string, never> | undefined, any, questpie268.JsonRouteParams>;
16
16
  };
17
17
  //#endregion
18
18
  export { localeFunctions };
@@ -1,4 +1,4 @@
1
- import * as questpie125 from "questpie";
1
+ import * as questpie117 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/preview.d.ts
4
4
 
@@ -21,13 +21,13 @@ interface PreviewTokenPayload {
21
21
  * @returns Object with preview functions
22
22
  */
23
23
  declare function createPreviewFunctions(secret: string): {
24
- mintPreviewToken: questpie125.JsonRouteDefinition<{
24
+ mintPreviewToken: questpie117.JsonRouteDefinition<{
25
25
  path: string;
26
26
  ttlMs?: number | undefined;
27
- }, any, questpie125.JsonRouteParams>;
28
- verifyPreviewToken: questpie125.JsonRouteDefinition<{
27
+ }, any, questpie117.JsonRouteParams>;
28
+ verifyPreviewToken: questpie117.JsonRouteDefinition<{
29
29
  token: string;
30
- }, any, questpie125.JsonRouteParams>;
30
+ }, any, questpie117.JsonRouteParams>;
31
31
  };
32
32
  /**
33
33
  * Verify a preview token without RPC.
@@ -63,18 +63,18 @@ declare function createPreviewTokenVerifier(secret?: string): (token: string) =>
63
63
  * Used by the `adminModule` to register preview RPC functions.
64
64
  */
65
65
  declare const previewFunctions: {
66
- getPreviewUrl: questpie125.JsonRouteDefinition<{
66
+ getPreviewUrl: questpie117.JsonRouteDefinition<{
67
67
  collection: string;
68
68
  record: Record<string, unknown>;
69
69
  locale?: string | undefined;
70
- }, any, questpie125.JsonRouteParams>;
71
- mintPreviewToken: questpie125.JsonRouteDefinition<{
70
+ }, any, questpie117.JsonRouteParams>;
71
+ mintPreviewToken: questpie117.JsonRouteDefinition<{
72
72
  path: string;
73
73
  ttlMs?: number | undefined;
74
- }, any, questpie125.JsonRouteParams>;
75
- verifyPreviewToken: questpie125.JsonRouteDefinition<{
74
+ }, any, questpie117.JsonRouteParams>;
75
+ verifyPreviewToken: questpie117.JsonRouteDefinition<{
76
76
  token: string;
77
- }, any, questpie125.JsonRouteParams>;
77
+ }, any, questpie117.JsonRouteParams>;
78
78
  };
79
79
  //#endregion
80
80
  export { PreviewTokenPayload, createPreviewFunctions, createPreviewTokenVerifier, previewFunctions, verifyPreviewTokenDirect };
@@ -1,6 +1,6 @@
1
+ import { getPreviewSecret } from "../../../../shared/preview-utils.mjs";
1
2
  import { getApp, getCollectionState, getLocale, getSession } from "./route-helpers.mjs";
2
3
  import { translateAdminMessage } from "./i18n-helpers.mjs";
3
- import { getPreviewSecret } from "../../../../shared/preview-utils.mjs";
4
4
  import { z } from "zod";
5
5
  import { ApiError, route } from "questpie";
6
6
  import { createHmac, timingSafeEqual } from "node:crypto";
@@ -1,4 +1,4 @@
1
- import * as questpie135 from "questpie";
1
+ import * as questpie127 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/reactive.d.ts
4
4
 
@@ -13,7 +13,7 @@ import * as questpie135 from "questpie";
13
13
  * Batch reactive endpoint.
14
14
  * Executes multiple reactive handlers in a single request.
15
15
  */
16
- declare const batchReactive: questpie135.JsonRouteDefinition<{
16
+ declare const batchReactive: questpie127.JsonRouteDefinition<{
17
17
  collection: string;
18
18
  type: "collection" | "global";
19
19
  requests: {
@@ -26,12 +26,12 @@ declare const batchReactive: questpie135.JsonRouteDefinition<{
26
26
  }[];
27
27
  formData?: Record<string, unknown> | undefined;
28
28
  prevData?: Record<string, unknown> | null | undefined;
29
- }, any, questpie135.JsonRouteParams>;
29
+ }, any, questpie127.JsonRouteParams>;
30
30
  /**
31
31
  * Dynamic options endpoint.
32
32
  * Fetches options for select/relation fields with search and pagination.
33
33
  */
34
- declare const fieldOptions: questpie135.JsonRouteDefinition<{
34
+ declare const fieldOptions: questpie127.JsonRouteDefinition<{
35
35
  collection: string;
36
36
  type: "collection" | "global";
37
37
  field: string;
@@ -40,12 +40,12 @@ declare const fieldOptions: questpie135.JsonRouteDefinition<{
40
40
  page: number;
41
41
  limit: number;
42
42
  siblingData?: Record<string, unknown> | null | undefined;
43
- }, any, questpie135.JsonRouteParams>;
43
+ }, any, questpie127.JsonRouteParams>;
44
44
  /**
45
45
  * Reactive functions bundle.
46
46
  */
47
47
  declare const reactiveFunctions: {
48
- readonly batchReactive: questpie135.JsonRouteDefinition<{
48
+ readonly batchReactive: questpie127.JsonRouteDefinition<{
49
49
  collection: string;
50
50
  type: "collection" | "global";
51
51
  requests: {
@@ -58,8 +58,8 @@ declare const reactiveFunctions: {
58
58
  }[];
59
59
  formData?: Record<string, unknown> | undefined;
60
60
  prevData?: Record<string, unknown> | null | undefined;
61
- }, any, questpie135.JsonRouteParams>;
62
- readonly fieldOptions: questpie135.JsonRouteDefinition<{
61
+ }, any, questpie127.JsonRouteParams>;
62
+ readonly fieldOptions: questpie127.JsonRouteDefinition<{
63
63
  collection: string;
64
64
  type: "collection" | "global";
65
65
  field: string;
@@ -68,7 +68,7 @@ declare const reactiveFunctions: {
68
68
  page: number;
69
69
  limit: number;
70
70
  siblingData?: Record<string, unknown> | null | undefined;
71
- }, any, questpie135.JsonRouteParams>;
71
+ }, any, questpie127.JsonRouteParams>;
72
72
  };
73
73
  //#endregion
74
74
  export { batchReactive, fieldOptions, reactiveFunctions };
@@ -1,4 +1,4 @@
1
- import * as questpie464 from "questpie";
1
+ import * as questpie434 from "questpie";
2
2
 
3
3
  //#region src/server/modules/admin/routes/translations.d.ts
4
4
 
@@ -17,10 +17,10 @@ import * as questpie464 from "questpie";
17
17
  * Bundle of translation-related functions.
18
18
  */
19
19
  declare const translationFunctions: {
20
- readonly getAdminTranslations: questpie464.JsonRouteDefinition<{
20
+ readonly getAdminTranslations: questpie434.JsonRouteDefinition<{
21
21
  locale: string;
22
- }, any, questpie464.JsonRouteParams>;
23
- readonly getAdminLocales: questpie464.JsonRouteDefinition<Record<string, never> | undefined, any, questpie464.JsonRouteParams>;
22
+ }, any, questpie434.JsonRouteParams>;
23
+ readonly getAdminLocales: questpie434.JsonRouteDefinition<Record<string, never> | undefined, any, questpie434.JsonRouteParams>;
24
24
  };
25
25
  //#endregion
26
26
  export { translationFunctions };
@@ -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 questpie73 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 questpie89 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
 
@@ -33,22 +33,22 @@ import * as drizzle_orm5 from "drizzle-orm";
33
33
  * });
34
34
  * ```
35
35
  */
36
- declare const savedViewsCollection: questpie73.CollectionBuilder<questpie_shared15.Override<questpie_shared15.Override<questpie73.EmptyCollectionState<"admin_saved_views", undefined, {
37
- readonly text: typeof questpie73.text;
38
- readonly textarea: typeof questpie73.textarea;
39
- readonly email: typeof questpie_src_server_modules_core_fields_email_js1.email;
40
- readonly url: typeof questpie73.url;
41
- readonly number: typeof questpie73.number;
42
- readonly boolean: typeof questpie73.boolean;
43
- readonly date: typeof questpie73.date;
44
- readonly datetime: typeof questpie73.datetime;
45
- readonly time: typeof questpie73.time;
46
- readonly select: typeof questpie73.select;
47
- readonly upload: typeof questpie73.upload;
48
- readonly relation: typeof questpie73.relation;
49
- readonly object: typeof questpie73.object;
50
- readonly json: typeof questpie_src_server_modules_core_fields_json_js1.json;
51
- readonly from: typeof questpie73.from;
36
+ declare const savedViewsCollection: questpie89.CollectionBuilder<questpie_shared15.Override<questpie_shared15.Override<questpie89.EmptyCollectionState<"admin_saved_views", undefined, {
37
+ readonly text: typeof questpie89.text;
38
+ readonly textarea: typeof questpie89.textarea;
39
+ readonly email: typeof questpie_src_server_modules_core_fields_email_js2.email;
40
+ readonly url: typeof questpie89.url;
41
+ readonly number: typeof questpie89.number;
42
+ readonly boolean: typeof questpie89.boolean;
43
+ readonly date: typeof questpie89.date;
44
+ readonly datetime: typeof questpie89.datetime;
45
+ readonly time: typeof questpie89.time;
46
+ readonly select: typeof questpie89.select;
47
+ readonly upload: typeof questpie89.upload;
48
+ readonly relation: typeof questpie89.relation;
49
+ readonly object: typeof questpie89.object;
50
+ readonly json: typeof questpie_src_server_modules_core_fields_json_js2.json;
51
+ readonly from: typeof questpie89.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: questpie73.CollectionBuilder<questpie_shared
59
59
  };
60
60
  localized: readonly string[];
61
61
  fieldDefinitions: {
62
- readonly userId: questpie73.FieldWithMethods<Omit<questpie73.TextFieldState, "notNull" | "column"> & {
62
+ readonly userId: questpie89.FieldWithMethods<Omit<questpie89.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
- }, questpie73.TextFieldMethods>;
68
- readonly collectionName: questpie73.FieldWithMethods<Omit<questpie73.TextFieldState, "notNull" | "column"> & {
67
+ }, questpie89.TextFieldMethods>;
68
+ readonly collectionName: questpie89.FieldWithMethods<Omit<questpie89.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
- }, questpie73.TextFieldMethods>;
74
- readonly name: questpie73.FieldWithMethods<Omit<questpie73.TextFieldState, "notNull" | "column"> & {
73
+ }, questpie89.TextFieldMethods>;
74
+ readonly name: questpie89.FieldWithMethods<Omit<questpie89.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
- }, questpie73.TextFieldMethods>;
80
- readonly configuration: questpie73.Field<Omit<questpie73.JsonFieldState, "notNull" | "column"> & {
79
+ }, questpie89.TextFieldMethods>;
80
+ readonly configuration: questpie89.Field<Omit<questpie89.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: questpie73.Field<Omit<questpie73.BooleanFieldState, "column" | "hasDefault"> & {
86
+ readonly isDefault: questpie89.Field<Omit<questpie89.BooleanFieldState, "column" | "hasDefault"> & {
87
87
  hasDefault: true;
88
88
  column: drizzle_orm5.HasDefault<drizzle_orm_pg_core22.PgBooleanBuilder>;
89
89
  } & {
package/dist/server.d.mts CHANGED
@@ -6,10 +6,6 @@ import { ServerSidebarCollectionItem, ServerSidebarConfig, ServerSidebarDividerI
6
6
  import { ActionsConfigContext, BuiltinActionType, ServerActionContext, ServerActionDefinition, ServerActionDownload, ServerActionEffects, ServerActionError, ServerActionForm, ServerActionFormField, ServerActionHandler, ServerActionRedirect, ServerActionResult, ServerActionSuccess, ServerActionsConfig } from "./server/augmentation/actions.mjs";
7
7
  import { AdminConfigInput, adminConfig } from "./server/augmentation/index.mjs";
8
8
  import "./server/augmentation.mjs";
9
- import { adminPlugin } from "./server/plugin.mjs";
10
- import { AuthSession, GetAdminSessionOptions, RequireAdminAuthOptions, getAdminSession, isAdminUser, requireAdminAuth } from "./server/modules/admin/auth-helpers.mjs";
11
- import { NextAuthMiddlewareOptions, createNextAuthMiddleware, getNextAdminSession } from "./server/adapters/nextjs.mjs";
12
- import { BeforeLoadContext, TanStackAuthGuardOptions, createTanStackAuthGuard, createTanStackSessionLoader } from "./server/adapters/tanstack.mjs";
13
9
  import { BlockNode, BlockValues, BlocksDocument, BlocksFieldMeta } from "./server/fields/blocks.mjs";
14
10
  import { RichTextFeature, RichTextFieldMeta, TipTapDocument, TipTapNode } from "./server/fields/rich-text.mjs";
15
11
  import { adminFields } from "./server/fields/index.mjs";
@@ -17,6 +13,10 @@ import { AnyBlockBuilder, AnyBlockDefinition, BlockBuilder, BlockBuilderState, B
17
13
  import { BlockSchema, getBlocksByCategory, introspectBlock, introspectBlocks } from "./server/modules/admin/block/introspection.mjs";
18
14
  import { BlocksPrefetchContext, createBlocksPrefetchHook, processBlocksDocument, processDocumentBlocksPrefetch } from "./server/modules/admin/block/prefetch.mjs";
19
15
  import "./server/block/index.mjs";
16
+ import { adminPlugin } from "./server/plugin.mjs";
17
+ import { AuthSession, GetAdminSessionOptions, RequireAdminAuthOptions, getAdminSession, isAdminUser, requireAdminAuth } from "./server/modules/admin/auth-helpers.mjs";
18
+ import { NextAuthMiddlewareOptions, createNextAuthMiddleware, getNextAdminSession } from "./server/adapters/nextjs.mjs";
19
+ import { BeforeLoadContext, TanStackAuthGuardOptions, createTanStackAuthGuard, createTanStackSessionLoader } from "./server/adapters/tanstack.mjs";
20
20
  import { ExecuteActionRequest, ExecuteActionResponse, actionFunctions, executeAction, executeActionFn, getActionsConfig, getActionsConfigFn } from "./server/modules/admin/routes/execute-action.mjs";
21
21
  import { PreviewTokenPayload, createPreviewFunctions, createPreviewTokenVerifier, verifyPreviewTokenDirect } from "./server/modules/admin/routes/preview.mjs";
22
22
  import { batchReactive, fieldOptions, reactiveFunctions } from "./server/modules/admin/routes/reactive.mjs";
@@ -10,6 +10,39 @@
10
10
  * Set by /api/preview route, checked by page loaders.
11
11
  */
12
12
  declare const DRAFT_MODE_COOKIE = "__draft_mode";
13
+ /**
14
+ * URL prefix used by the admin SPA when mounted at the conventional
15
+ * `/admin` path. Kept for reference and as a fallback signal for setups
16
+ * that pre-date the header-based detection.
17
+ */
18
+ declare const ADMIN_API_PREFIX = "/admin/api/";
19
+ /**
20
+ * Whether the given request originates from the admin panel.
21
+ *
22
+ * Detection strategy (in order):
23
+ * 1. Presence of the `X-Questpie-Admin` request header — the canonical
24
+ * signal, injected by `createAdminClient` / `withAdminRequestHeader`.
25
+ * 2. URL path starts with {@link ADMIN_API_PREFIX} — fallback for clients
26
+ * that don't inject the header (e.g. pre-3.0.6 admin SDK consumers, or
27
+ * direct `curl` calls to `/admin/api/...`).
28
+ *
29
+ * Use inside collection/global `.access()` rules to grant admin-only
30
+ * scope (e.g. master counselor sees everything in the admin, but stays
31
+ * scoped to their own data on the frontend).
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { isAdminRequest } from "@questpie/admin/shared";
36
+ *
37
+ * .access({
38
+ * read: ({ session, request }) => {
39
+ * if (isAdminRequest(request) && isAdmin(session?.user)) return true;
40
+ * return { createdById: session?.user?.id };
41
+ * },
42
+ * })
43
+ * ```
44
+ */
45
+ declare function isAdminRequest(request?: Request | null): boolean;
13
46
  /**
14
47
  * Check if draft mode is enabled from cookie header.
15
48
  *
@@ -50,4 +83,4 @@ declare function createDraftModeCookie(enabled: boolean, maxAge?: number): strin
50
83
  */
51
84
  declare function getPreviewSecret(): string;
52
85
  //#endregion
53
- export { DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isDraftMode };
86
+ export { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode };
@@ -11,6 +11,84 @@
11
11
  */
12
12
  const DRAFT_MODE_COOKIE = "__draft_mode";
13
13
  /**
14
+ * Header injected by `createAdminClient` (and `withAdminRequestHeader`) on
15
+ * every admin SPA request. Inspected by {@link isAdminRequest} so access
16
+ * rules can branch on caller intent without depending on URL structure.
17
+ */
18
+ const ADMIN_REQUEST_HEADER = "x-questpie-admin";
19
+ /**
20
+ * URL prefix used by the admin SPA when mounted at the conventional
21
+ * `/admin` path. Kept for reference and as a fallback signal for setups
22
+ * that pre-date the header-based detection.
23
+ */
24
+ const ADMIN_API_PREFIX = "/admin/api/";
25
+ /**
26
+ * Whether the given request originates from the admin panel.
27
+ *
28
+ * Detection strategy (in order):
29
+ * 1. Presence of the `X-Questpie-Admin` request header — the canonical
30
+ * signal, injected by `createAdminClient` / `withAdminRequestHeader`.
31
+ * 2. URL path starts with {@link ADMIN_API_PREFIX} — fallback for clients
32
+ * that don't inject the header (e.g. pre-3.0.6 admin SDK consumers, or
33
+ * direct `curl` calls to `/admin/api/...`).
34
+ *
35
+ * Use inside collection/global `.access()` rules to grant admin-only
36
+ * scope (e.g. master counselor sees everything in the admin, but stays
37
+ * scoped to their own data on the frontend).
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { isAdminRequest } from "@questpie/admin/shared";
42
+ *
43
+ * .access({
44
+ * read: ({ session, request }) => {
45
+ * if (isAdminRequest(request) && isAdmin(session?.user)) return true;
46
+ * return { createdById: session?.user?.id };
47
+ * },
48
+ * })
49
+ * ```
50
+ */
51
+ function isAdminRequest(request) {
52
+ if (!request) return false;
53
+ if (request.headers?.get?.(ADMIN_REQUEST_HEADER)) return true;
54
+ try {
55
+ return new URL(request.url).pathname.startsWith(ADMIN_API_PREFIX);
56
+ } catch {
57
+ return false;
58
+ }
59
+ }
60
+ /**
61
+ * Wrap a `fetch` implementation so every outbound request carries the
62
+ * `X-Questpie-Admin` header. Used internally by
63
+ * `createAdminClient` — apps building a custom admin client (or using
64
+ * an alternate HTTP layer) can compose the wrapper themselves.
65
+ *
66
+ * @param baseFetch - The fetch implementation to wrap. Defaults to
67
+ * `globalThis.fetch`.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { createClient } from "questpie/client";
72
+ * import { withAdminRequestHeader } from "@questpie/admin/shared";
73
+ *
74
+ * export const adminCmsClient = createClient<AppConfig>({
75
+ * baseURL: window.location.origin,
76
+ * basePath: "/api",
77
+ * fetch: withAdminRequestHeader(),
78
+ * });
79
+ * ```
80
+ */
81
+ function withAdminRequestHeader(baseFetch = globalThis.fetch) {
82
+ return ((input, init) => {
83
+ const headers = new Headers(init?.headers);
84
+ if (!headers.has(ADMIN_REQUEST_HEADER)) headers.set(ADMIN_REQUEST_HEADER, "1");
85
+ return baseFetch(input, {
86
+ ...init,
87
+ headers
88
+ });
89
+ });
90
+ }
91
+ /**
14
92
  * Check if draft mode is enabled from cookie header.
15
93
  *
16
94
  * @param cookieHeader - The Cookie header value from request
@@ -61,4 +139,4 @@ function getPreviewSecret() {
61
139
  }
62
140
 
63
141
  //#endregion
64
- export { DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isDraftMode };
142
+ export { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode, withAdminRequestHeader };
package/dist/shared.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { FilterOperator, FilterRule, SortConfig, ViewConfiguration } from "./shared/types/saved-views.types.mjs";
2
- import { DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isDraftMode } from "./shared/preview-utils.mjs";
3
- export { DRAFT_MODE_COOKIE, type FilterOperator, type FilterRule, type SortConfig, type ViewConfiguration, createDraftModeCookie, getPreviewSecret, isDraftMode };
2
+ import { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode } from "./shared/preview-utils.mjs";
3
+ export { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, type FilterOperator, type FilterRule, type SortConfig, type ViewConfiguration, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode };
package/dist/shared.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isDraftMode } from "./shared/preview-utils.mjs";
1
+ import { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode } from "./shared/preview-utils.mjs";
2
2
 
3
- export { DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isDraftMode };
3
+ export { ADMIN_API_PREFIX, DRAFT_MODE_COOKIE, createDraftModeCookie, getPreviewSecret, isAdminRequest, isDraftMode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@questpie/admin",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/questpie/questpie.git",
@@ -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.5",
65
+ "@questpie/tanstack-query": "^3.0.6",
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.5",
91
+ "questpie": "^3.0.6",
92
92
  "react-day-picker": "^9.12.0",
93
93
  "react-hook-form": "^7.54.0",
94
94
  "react-resizable-panels": "^4.4.2",