@questpie/admin 1.1.1 → 3.0.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/README.md +256 -488
- package/dist/augmentation.d.mts +414 -0
- package/dist/client/blocks/block-renderer.d.mts +45 -0
- package/dist/client/blocks/block-renderer.mjs +105 -0
- package/dist/client/blocks/index.d.mts +2 -0
- package/dist/client/blocks/types.d.mts +68 -0
- package/dist/client/blocks/types.mjs +19 -0
- package/dist/client/builder/admin-types.d.mts +40 -0
- package/dist/client/builder/admin.d.mts +110 -0
- package/dist/client/builder/admin.mjs +151 -0
- package/dist/client/builder/field/field.d.mts +51 -0
- package/dist/client/builder/field/field.mjs +37 -0
- package/dist/client/builder/index.d.mts +31 -0
- package/dist/client/builder/page/page.d.mts +24 -0
- package/dist/client/builder/page/page.mjs +31 -0
- package/dist/client/builder/registry.d.mts +50 -0
- package/dist/client/builder/types/action-registry.mjs +276 -0
- package/dist/client/builder/types/action-types.d.mts +226 -0
- package/dist/client/builder/types/collection-types.mjs +10 -0
- package/dist/client/builder/types/common.d.mts +46 -0
- package/dist/client/builder/types/field-types.d.mts +592 -0
- package/dist/client/builder/types/field-types.mjs +18 -0
- package/dist/client/builder/types/ui-config.d.mts +158 -0
- package/dist/client/builder/types/widget-types.d.mts +562 -0
- package/dist/client/builder/validation.d.mts +33 -0
- package/dist/client/builder/validation.mjs +227 -0
- package/dist/client/builder/view/view.d.mts +49 -0
- package/dist/client/builder/view/view.mjs +27 -0
- package/dist/client/builder/widget/widget.d.mts +27 -0
- package/dist/client/builder/widget/widget.mjs +21 -0
- package/dist/client/components/actions/action-button.mjs +245 -0
- package/dist/client/components/actions/action-dialog.mjs +559 -0
- package/dist/client/components/actions/confirmation-dialog.mjs +201 -0
- package/dist/client/components/actions/header-actions.mjs +210 -0
- package/dist/client/components/admin-link.d.mts +66 -0
- package/dist/client/components/admin-link.mjs +171 -0
- package/dist/client/components/auth/auth-guard.d.mts +50 -0
- package/dist/client/components/auth/auth-guard.mjs +60 -0
- package/dist/client/components/auth/auth-loading.d.mts +35 -0
- package/dist/client/components/auth/auth-loading.mjs +55 -0
- package/dist/client/components/blocks/block-canvas.mjs +159 -0
- package/dist/client/components/blocks/block-editor-context.mjs +125 -0
- package/dist/client/components/blocks/block-editor-layout.mjs +199 -0
- package/dist/client/components/blocks/block-editor-provider.mjs +235 -0
- package/dist/client/components/blocks/block-fields-renderer.mjs +240 -0
- package/dist/client/components/blocks/block-insert-button.mjs +189 -0
- package/dist/client/components/blocks/block-item-menu.mjs +363 -0
- package/dist/client/components/blocks/block-item.mjs +434 -0
- package/dist/client/components/blocks/block-library-sidebar.mjs +285 -0
- package/dist/client/components/blocks/block-tree.mjs +103 -0
- package/dist/client/components/blocks/block-type-icon.mjs +95 -0
- package/dist/client/components/blocks/utils/tree-utils.mjs +185 -0
- package/dist/client/components/component-renderer.d.mts +114 -0
- package/dist/client/components/component-renderer.mjs +258 -0
- package/dist/client/components/error-boundary.mjs +144 -0
- package/dist/client/components/fields/array-field.mjs +506 -0
- package/dist/client/components/fields/asset-preview-field.mjs +159 -0
- package/dist/client/components/fields/blocks-field/blocks-field.mjs +209 -0
- package/dist/client/components/fields/boolean-field.mjs +77 -0
- package/dist/client/components/fields/date-field.mjs +76 -0
- package/dist/client/components/fields/datetime-field.mjs +74 -0
- package/dist/client/components/fields/email-field.mjs +67 -0
- package/dist/client/components/fields/field-utils.mjs +64 -0
- package/dist/client/components/fields/field-wrapper.mjs +124 -0
- package/dist/client/components/fields/json-field.mjs +461 -0
- package/dist/client/components/fields/locale-badge.mjs +25 -0
- package/dist/client/components/fields/number-field.mjs +73 -0
- package/dist/client/components/fields/object-array-field.mjs +707 -0
- package/dist/client/components/fields/object-field.mjs +686 -0
- package/dist/client/components/fields/relation/displays/cards-display.mjs +254 -0
- package/dist/client/components/fields/relation/displays/chips-display.mjs +173 -0
- package/dist/client/components/fields/relation/displays/grid-display.mjs +209 -0
- package/dist/client/components/fields/relation/displays/list-display.mjs +247 -0
- package/dist/client/components/fields/relation/displays/table-display.mjs +309 -0
- package/dist/client/components/fields/relation/displays/types.mjs +72 -0
- package/dist/client/components/fields/relation/relation-items-display.mjs +143 -0
- package/dist/client/components/fields/relation-field.mjs +161 -0
- package/dist/client/components/fields/relation-picker.mjs +296 -0
- package/dist/client/components/fields/relation-select.mjs +232 -0
- package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +105 -0
- package/dist/client/components/fields/rich-text-editor/extensions.mjs +144 -0
- package/dist/client/components/fields/rich-text-editor/image-popover.mjs +221 -0
- package/dist/client/components/fields/rich-text-editor/index.mjs +520 -0
- package/dist/client/components/fields/rich-text-editor/link-popover.mjs +85 -0
- package/dist/client/components/fields/rich-text-editor/presets.mjs +123 -0
- package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +188 -0
- package/dist/client/components/fields/rich-text-editor/table-controls.mjs +433 -0
- package/dist/client/components/fields/rich-text-editor/toolbar.mjs +541 -0
- package/dist/client/components/fields/rich-text-editor/types.mjs +30 -0
- package/dist/client/components/fields/rich-text-editor/utils.mjs +50 -0
- package/dist/client/components/fields/rich-text-field.mjs +64 -0
- package/dist/client/components/fields/select-field.mjs +88 -0
- package/dist/client/components/fields/text-field.mjs +72 -0
- package/dist/client/components/fields/textarea-field.mjs +71 -0
- package/dist/client/components/fields/time-field.mjs +67 -0
- package/dist/client/components/fields/upload-field.mjs +621 -0
- package/dist/client/components/filter-builder/columns-tab.mjs +325 -0
- package/dist/client/components/filter-builder/filter-builder-sheet.mjs +456 -0
- package/dist/client/components/filter-builder/filters-tab.mjs +663 -0
- package/dist/client/components/filter-builder/saved-views-tab.mjs +278 -0
- package/dist/client/components/history-sidebar.mjs +496 -0
- package/dist/client/components/layout/field-layout-renderer.mjs +301 -0
- package/dist/client/components/locale-switcher.mjs +251 -0
- package/dist/client/components/media/media-grid.mjs +314 -0
- package/dist/client/components/media/media-picker-dialog.mjs +563 -0
- package/dist/client/components/preview/live-preview-mode.mjs +503 -0
- package/dist/client/components/preview/preview-pane.mjs +388 -0
- package/dist/client/components/primitives/asset-preview.mjs +771 -0
- package/dist/client/components/primitives/checkbox-input.mjs +59 -0
- package/dist/client/components/primitives/date-input.mjs +461 -0
- package/dist/client/components/primitives/dropzone.mjs +368 -0
- package/dist/client/components/primitives/number-input.mjs +117 -0
- package/dist/client/components/primitives/select-multi.mjs +590 -0
- package/dist/client/components/primitives/select-single.mjs +473 -0
- package/dist/client/components/primitives/text-input.mjs +45 -0
- package/dist/client/components/primitives/textarea-input.mjs +43 -0
- package/dist/client/components/primitives/time-input.mjs +145 -0
- package/dist/client/components/primitives/toggle-input.mjs +51 -0
- package/dist/client/components/primitives/types.mjs +12 -0
- package/dist/client/components/sheets/resource-sheet.mjs +86 -0
- package/dist/client/components/ui/accordion.mjs +169 -0
- package/dist/client/components/ui/alert.mjs +85 -0
- package/dist/client/components/ui/badge.mjs +76 -0
- package/dist/client/components/ui/button.mjs +84 -0
- package/dist/client/components/ui/card.mjs +206 -0
- package/dist/client/components/ui/checkbox.mjs +82 -0
- package/dist/client/components/ui/command.mjs +239 -0
- package/dist/client/components/ui/dialog.mjs +296 -0
- package/dist/client/components/ui/drawer.mjs +278 -0
- package/dist/client/components/ui/dropdown-menu.mjs +315 -0
- package/dist/client/components/ui/empty-state.mjs +99 -0
- package/dist/client/components/ui/field.mjs +354 -0
- package/dist/client/components/ui/input-group.mjs +201 -0
- package/dist/client/components/ui/input.mjs +46 -0
- package/dist/client/components/ui/kbd.mjs +53 -0
- package/dist/client/components/ui/label.mjs +45 -0
- package/dist/client/components/ui/popover.mjs +176 -0
- package/dist/client/components/ui/responsive-dialog.mjs +308 -0
- package/dist/client/components/ui/search-input.mjs +139 -0
- package/dist/client/components/ui/select.mjs +325 -0
- package/dist/client/components/ui/separator.mjs +47 -0
- package/dist/client/components/ui/sheet.mjs +280 -0
- package/dist/client/components/ui/sidebar.mjs +774 -0
- package/dist/client/components/ui/skeleton.mjs +40 -0
- package/dist/client/components/ui/sonner.d.mts +13 -0
- package/dist/client/components/ui/sonner.mjs +85 -0
- package/dist/client/components/ui/spinner.mjs +52 -0
- package/dist/client/components/ui/switch.mjs +58 -0
- package/dist/client/components/ui/table.mjs +276 -0
- package/dist/client/components/ui/tabs.mjs +160 -0
- package/dist/client/components/ui/textarea.mjs +40 -0
- package/dist/client/components/ui/toolbar.mjs +136 -0
- package/dist/client/components/ui/tooltip.mjs +146 -0
- package/dist/client/components/widgets/chart-widget.mjs +582 -0
- package/dist/client/components/widgets/progress-widget.mjs +200 -0
- package/dist/client/components/widgets/quick-actions-widget.mjs +209 -0
- package/dist/client/components/widgets/recent-items-widget.mjs +196 -0
- package/dist/client/components/widgets/stats-widget.mjs +261 -0
- package/dist/client/components/widgets/table-widget.mjs +273 -0
- package/dist/client/components/widgets/timeline-widget.mjs +279 -0
- package/dist/client/components/widgets/value-widget.mjs +312 -0
- package/dist/client/components/widgets/widget-skeletons.mjs +427 -0
- package/dist/client/contexts/breadcrumb-context.mjs +60 -0
- package/dist/client/contexts/focus-context.d.mts +87 -0
- package/dist/client/contexts/focus-context.mjs +250 -0
- package/dist/client/hooks/typed-hooks.d.mts +110 -0
- package/dist/client/hooks/typed-hooks.mjs +888 -0
- package/dist/client/hooks/use-action.mjs +329 -0
- package/dist/client/hooks/use-admin-config.mjs +69 -0
- package/dist/client/hooks/use-admin-preferences.mjs +171 -0
- package/dist/client/hooks/use-admin-routes.mjs +130 -0
- package/dist/client/hooks/use-audit-history.mjs +157 -0
- package/dist/client/hooks/use-auth.d.mts +97 -0
- package/dist/{use-auth-BoLmWtmU.mjs → client/hooks/use-auth.mjs} +9 -10
- package/dist/client/hooks/use-collection-fields.mjs +71 -0
- package/dist/client/hooks/use-collection-meta.mjs +153 -0
- package/dist/client/hooks/use-collection-schema.mjs +90 -0
- package/dist/client/hooks/use-collection-validation.mjs +88 -0
- package/dist/client/hooks/use-collection.d.mts +96 -0
- package/dist/client/hooks/use-collection.mjs +673 -0
- package/dist/client/hooks/use-current-user.d.mts +60 -0
- package/dist/client/hooks/use-current-user.mjs +79 -0
- package/dist/client/hooks/use-field-hooks.mjs +199 -0
- package/dist/client/hooks/use-field-options.d.mts +57 -0
- package/dist/client/hooks/use-field-options.mjs +269 -0
- package/dist/client/hooks/use-global-fields.mjs +58 -0
- package/dist/client/hooks/use-global-meta.mjs +105 -0
- package/dist/client/hooks/use-global-schema.mjs +53 -0
- package/dist/client/hooks/use-global.d.mts +51 -0
- package/dist/client/hooks/use-global.mjs +284 -0
- package/dist/client/hooks/use-locks.mjs +452 -0
- package/dist/client/hooks/use-media-query.d.mts +22 -0
- package/dist/client/hooks/use-media-query.mjs +81 -0
- package/dist/client/hooks/use-prefill-params.mjs +47 -0
- package/dist/client/hooks/use-questpie-query-options.mjs +50 -0
- package/dist/client/hooks/use-reactive-fields.d.mts +78 -0
- package/dist/client/hooks/use-reactive-fields.mjs +201 -0
- package/dist/client/hooks/use-realtime-highlight.mjs +158 -0
- package/dist/client/hooks/use-saved-views.mjs +140 -0
- package/dist/client/hooks/use-search-param-toggle.d.mts +12 -0
- package/dist/client/hooks/use-search-param-toggle.mjs +115 -0
- package/dist/client/hooks/use-search.mjs +258 -0
- package/dist/client/hooks/use-server-actions.mjs +191 -0
- package/dist/client/hooks/use-server-validation.mjs +291 -0
- package/dist/client/hooks/use-server-widget-data.d.mts +25 -0
- package/dist/client/hooks/use-server-widget-data.mjs +65 -0
- package/dist/client/hooks/use-setup-status.d.mts +38 -0
- package/dist/client/hooks/use-setup-status.mjs +62 -0
- package/dist/client/hooks/use-sidebar-search-param.d.mts +9 -0
- package/dist/client/hooks/use-sidebar-search-param.mjs +104 -0
- package/dist/client/hooks/use-transition-stage.mjs +125 -0
- package/dist/client/hooks/use-upload-collection.mjs +31 -0
- package/dist/client/hooks/use-upload.mjs +209 -0
- package/dist/client/hooks/use-validation-error-map.mjs +57 -0
- package/dist/client/hooks/use-view-state.mjs +479 -0
- package/dist/client/i18n/hooks.mjs +284 -0
- package/dist/client/i18n/intl-cache.mjs +64 -0
- package/dist/client/i18n/messages.mjs +6 -0
- package/dist/client/i18n/simple.d.mts +21 -0
- package/dist/client/i18n/simple.mjs +156 -0
- package/dist/client/i18n/types.d.mts +109 -0
- package/dist/client/lib/cookies.mjs +9 -0
- package/dist/client/lib/events.mjs +5 -0
- package/dist/client/lib/render-profiler.mjs +51 -0
- package/dist/client/lib/utils.mjs +23 -0
- package/dist/client/preview/block-scope-context.d.mts +73 -0
- package/dist/client/preview/block-scope-context.mjs +116 -0
- package/dist/client/preview/index.d.mts +5 -0
- package/dist/client/preview/preview-banner.d.mts +45 -0
- package/dist/client/preview/preview-banner.mjs +134 -0
- package/dist/client/preview/preview-field.d.mts +107 -0
- package/dist/client/preview/preview-field.mjs +227 -0
- package/dist/client/preview/types.d.mts +114 -0
- package/dist/client/preview/types.mjs +20 -0
- package/dist/client/preview/use-collection-preview.d.mts +70 -0
- package/dist/client/preview/use-collection-preview.mjs +163 -0
- package/dist/client/runtime/content-locales-provider.d.mts +1 -0
- package/dist/client/runtime/content-locales-provider.mjs +136 -0
- package/dist/client/runtime/index.d.mts +5 -0
- package/dist/client/runtime/index.mjs +6 -0
- package/dist/client/runtime/locale-scope.d.mts +2 -0
- package/dist/client/runtime/locale-scope.mjs +108 -0
- package/dist/client/runtime/provider.d.mts +203 -0
- package/dist/client/runtime/provider.mjs +393 -0
- package/dist/client/runtime/routes.d.mts +49 -0
- package/dist/client/runtime/routes.mjs +91 -0
- package/dist/client/runtime/translations-provider.mjs +242 -0
- package/dist/client/scope/index.d.mts +3 -0
- package/dist/client/scope/picker.d.mts +53 -0
- package/dist/client/scope/picker.mjs +395 -0
- package/dist/client/scope/provider.d.mts +103 -0
- package/dist/client/scope/provider.mjs +167 -0
- package/dist/client/scope/types.d.mts +111 -0
- package/dist/client/styles/index.css +344 -188
- package/dist/client/utils/auto-expand-fields.mjs +83 -0
- package/dist/client/utils/build-field-definitions-from-schema.mjs +259 -0
- package/dist/client/utils/dependency-tracker.mjs +61 -0
- package/dist/client/utils/detect-relations.mjs +45 -0
- package/dist/client/utils/locale-to-flag.d.mts +119 -0
- package/dist/client/utils/locale-to-flag.mjs +129 -0
- package/dist/client/utils/routes.mjs +195 -0
- package/dist/client/views/auth/accept-invite-form.d.mts +72 -0
- package/dist/client/views/auth/accept-invite-form.mjs +473 -0
- package/dist/client/views/auth/auth-layout.d.mts +43 -0
- package/dist/client/views/auth/auth-layout.mjs +116 -0
- package/dist/client/views/auth/forgot-password-form.d.mts +58 -0
- package/dist/client/views/auth/forgot-password-form.mjs +386 -0
- package/dist/client/views/auth/invite-form.mjs +497 -0
- package/dist/client/views/auth/login-form.d.mts +75 -0
- package/dist/client/views/auth/login-form.mjs +387 -0
- package/dist/client/views/auth/reset-password-form.d.mts +65 -0
- package/dist/client/views/auth/reset-password-form.mjs +515 -0
- package/dist/client/views/auth/setup-form.d.mts +60 -0
- package/dist/client/views/auth/setup-form.mjs +526 -0
- package/dist/client/views/collection/auto-form-fields.mjs +873 -0
- package/dist/client/views/collection/bulk-action-toolbar.mjs +480 -0
- package/dist/client/views/collection/cells/complex-cells.mjs +746 -0
- package/dist/client/views/collection/cells/primitive-cells.mjs +395 -0
- package/dist/client/views/collection/cells/relation-cells.mjs +260 -0
- package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +509 -0
- package/dist/client/views/collection/cells/shared/cell-helpers.mjs +125 -0
- package/dist/client/views/collection/cells/shared/relation-chip.mjs +121 -0
- package/dist/client/views/collection/cells/upload-cells.mjs +28 -0
- package/dist/client/views/collection/columns/build-columns.mjs +195 -0
- package/dist/client/views/collection/columns/column-defaults.mjs +123 -0
- package/dist/client/views/collection/field-context.mjs +126 -0
- package/dist/client/views/collection/field-renderer.mjs +368 -0
- package/dist/client/views/collection/form-view.mjs +1566 -0
- package/dist/client/views/collection/table-view.mjs +832 -0
- package/dist/client/views/collection/view-skeletons.mjs +215 -0
- package/dist/client/views/common/global-search.mjs +700 -0
- package/dist/client/views/dashboard/dashboard-grid.mjs +881 -0
- package/dist/client/views/dashboard/dashboard-widget.mjs +265 -0
- package/dist/client/views/dashboard/widget-card.mjs +372 -0
- package/dist/client/views/globals/global-form-view.mjs +1306 -0
- package/dist/client/views/layout/admin-layout-provider.d.mts +137 -0
- package/dist/client/views/layout/admin-layout-provider.mjs +193 -0
- package/dist/client/views/layout/admin-layout.d.mts +133 -0
- package/dist/client/views/layout/admin-layout.mjs +302 -0
- package/dist/client/views/layout/admin-router.d.mts +93 -0
- package/dist/client/views/layout/admin-router.mjs +1254 -0
- package/dist/client/views/layout/admin-sidebar.d.mts +99 -0
- package/dist/client/views/layout/admin-sidebar.mjs +1379 -0
- package/dist/client/views/layout/admin-topbar.mjs +236 -0
- package/dist/client/views/pages/accept-invite-page.d.mts +66 -0
- package/dist/client/views/pages/accept-invite-page.mjs +349 -0
- package/dist/client/views/pages/dashboard-page.d.mts +43 -0
- package/dist/client/views/pages/dashboard-page.mjs +84 -0
- package/dist/client/views/pages/forgot-password-page.d.mts +56 -0
- package/dist/client/views/pages/forgot-password-page.mjs +152 -0
- package/dist/client/views/pages/invite-page.d.mts +70 -0
- package/dist/client/views/pages/invite-page.mjs +161 -0
- package/dist/client/views/pages/login-page.d.mts +69 -0
- package/dist/client/views/pages/login-page.mjs +193 -0
- package/dist/client/views/pages/reset-password-page.d.mts +63 -0
- package/dist/client/views/pages/reset-password-page.mjs +257 -0
- package/dist/client/views/pages/setup-page.d.mts +61 -0
- package/dist/client/views/pages/setup-page.mjs +156 -0
- package/dist/client-module.d.mts +3 -0
- package/dist/client-module.mjs +3 -0
- package/dist/client.d.mts +99 -3
- package/dist/client.mjs +52 -12
- package/dist/components/rich-text/index.d.mts +1 -0
- package/dist/components/rich-text/rich-text-renderer.d.mts +103 -0
- package/dist/components/rich-text/rich-text-renderer.mjs +237 -0
- package/dist/index.d.mts +59 -3
- package/dist/index.mjs +52 -12
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.mjs +3 -0
- package/dist/server/adapters/nextjs.d.mts +120 -0
- package/dist/server/adapters/nextjs.mjs +110 -0
- package/dist/server/adapters/tanstack.d.mts +132 -0
- package/dist/server/adapters/tanstack.mjs +89 -0
- package/dist/server/augmentation/actions.d.mts +279 -0
- package/dist/server/augmentation/common.d.mts +76 -0
- package/dist/server/augmentation/dashboard.d.mts +547 -0
- package/dist/server/augmentation/form-layout.d.mts +303 -0
- package/dist/server/augmentation/index.d.mts +44 -0
- package/dist/server/augmentation/index.mjs +10 -0
- package/dist/server/augmentation/sidebar.d.mts +181 -0
- package/dist/server/augmentation/views.d.mts +237 -0
- package/dist/server/augmentation.d.mts +7 -0
- package/dist/server/block/index.d.mts +4 -0
- package/dist/server/codegen/admin-client-template.mjs +93 -0
- package/dist/server/codegen/projection-validator.mjs +67 -0
- package/dist/server/fields/blocks.d.mts +71 -0
- package/dist/server/fields/blocks.mjs +151 -0
- package/dist/server/fields/index.d.mts +15 -0
- package/dist/server/fields/index.mjs +15 -0
- package/dist/server/fields/rich-text.d.mts +68 -0
- package/dist/server/fields/rich-text.mjs +147 -0
- package/dist/server/i18n/index.mjs +43 -0
- package/dist/server/i18n/messages/cs.mjs +461 -0
- package/dist/server/i18n/messages/de.mjs +461 -0
- package/dist/server/i18n/messages/en.mjs +707 -0
- package/dist/server/i18n/messages/es.mjs +461 -0
- package/dist/server/i18n/messages/fr.mjs +461 -0
- package/dist/server/i18n/messages/index.mjs +23 -0
- package/dist/server/i18n/messages/pl.mjs +461 -0
- package/dist/server/i18n/messages/pt.mjs +464 -0
- package/dist/server/i18n/messages/sk.mjs +689 -0
- package/dist/server/modules/admin/.generated/module.d.mts +52 -0
- package/dist/server/modules/admin/.generated/module.mjs +78 -0
- package/dist/server/modules/admin/.generated/registries.d.mts +22 -0
- package/dist/server/modules/admin/auth-helpers.d.mts +142 -0
- package/dist/server/modules/admin/auth-helpers.mjs +107 -0
- package/dist/server/modules/admin/block/block-builder.d.mts +383 -0
- package/dist/server/modules/admin/block/block-builder.mjs +315 -0
- package/dist/server/modules/admin/block/index.d.mts +3 -0
- package/dist/server/modules/admin/block/introspection.d.mts +89 -0
- package/dist/server/modules/admin/block/introspection.mjs +100 -0
- package/dist/server/modules/admin/block/prefetch.d.mts +78 -0
- package/dist/server/modules/admin/block/prefetch.mjs +241 -0
- package/dist/server/modules/admin/client/.generated/module.d.mts +94 -0
- package/dist/server/modules/admin/client/.generated/module.mjs +91 -0
- package/dist/server/modules/admin/client/components/badge.d.mts +1 -0
- package/dist/server/modules/admin/client/components/icon.d.mts +1 -0
- package/dist/server/modules/admin/client/fields/array.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/array.mjs +12 -0
- package/dist/server/modules/admin/client/fields/assetPreview.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/assetPreview.mjs +18 -0
- package/dist/server/modules/admin/client/fields/blocks.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/blocks.mjs +12 -0
- package/dist/server/modules/admin/client/fields/boolean.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/boolean.mjs +12 -0
- package/dist/server/modules/admin/client/fields/date.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/date.mjs +12 -0
- package/dist/server/modules/admin/client/fields/datetime.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/datetime.mjs +12 -0
- package/dist/server/modules/admin/client/fields/email.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/email.mjs +12 -0
- package/dist/server/modules/admin/client/fields/json.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/json.mjs +11 -0
- package/dist/server/modules/admin/client/fields/number.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/number.mjs +12 -0
- package/dist/server/modules/admin/client/fields/object.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/object.mjs +12 -0
- package/dist/server/modules/admin/client/fields/relation.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/relation.mjs +12 -0
- package/dist/server/modules/admin/client/fields/richText.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/richText.mjs +11 -0
- package/dist/server/modules/admin/client/fields/select.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/select.mjs +12 -0
- package/dist/server/modules/admin/client/fields/text.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/text.mjs +12 -0
- package/dist/server/modules/admin/client/fields/textarea.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/textarea.mjs +12 -0
- package/dist/server/modules/admin/client/fields/time.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/time.mjs +12 -0
- package/dist/server/modules/admin/client/fields/upload.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/upload.mjs +12 -0
- package/dist/server/modules/admin/client/fields/url.d.mts +6 -0
- package/dist/server/modules/admin/client/fields/url.mjs +12 -0
- package/dist/server/modules/admin/client/index.d.mts +1 -0
- package/dist/server/modules/admin/client/pages/dashboard.d.mts +6 -0
- package/dist/server/modules/admin/client/pages/dashboard.mjs +11 -0
- package/dist/server/modules/admin/client/pages/forgotPassword.d.mts +6 -0
- package/dist/server/modules/admin/client/pages/forgotPassword.mjs +11 -0
- package/dist/server/modules/admin/client/pages/login.d.mts +6 -0
- package/dist/server/modules/admin/client/pages/login.mjs +11 -0
- package/dist/server/modules/admin/client/pages/resetPassword.d.mts +6 -0
- package/dist/server/modules/admin/client/pages/resetPassword.mjs +11 -0
- package/dist/server/modules/admin/client/pages/setup.d.mts +6 -0
- package/dist/server/modules/admin/client/pages/setup.mjs +11 -0
- package/dist/server/modules/admin/client/views/collection-form.mjs +10 -0
- package/dist/server/modules/admin/client/views/collection-table.mjs +10 -0
- package/dist/server/modules/admin/client/views/global-form.mjs +10 -0
- package/dist/server/modules/admin/client/widgets/chart.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/chart.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/progress.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/progress.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/quickActions.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/quickActions.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/recentItems.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/recentItems.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/stats.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/stats.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/table.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/table.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/timeline.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/timeline.mjs +7 -0
- package/dist/server/modules/admin/client/widgets/value.d.mts +6 -0
- package/dist/server/modules/admin/client/widgets/value.mjs +7 -0
- package/dist/server/modules/admin/collections/account.d.mts +77 -0
- package/dist/server/modules/admin/collections/account.mjs +23 -0
- package/dist/server/modules/admin/collections/admin-locks.d.mts +90 -0
- package/dist/server/modules/admin/collections/admin-locks.mjs +16 -0
- package/dist/server/modules/admin/collections/admin-preferences.d.mts +69 -0
- package/dist/server/modules/admin/collections/admin-preferences.mjs +16 -0
- package/dist/server/modules/admin/collections/admin-saved-views.d.mts +83 -0
- package/dist/server/modules/admin/collections/admin-saved-views.mjs +16 -0
- package/dist/server/modules/admin/collections/apikey.d.mts +99 -0
- package/dist/server/modules/admin/collections/apikey.mjs +15 -0
- package/dist/server/modules/admin/collections/assets.d.mts +72 -0
- package/dist/server/modules/admin/collections/assets.mjs +71 -0
- package/dist/server/modules/admin/collections/session.d.mts +69 -0
- package/dist/server/modules/admin/collections/session.mjs +15 -0
- package/dist/server/modules/admin/collections/user.d.mts +85 -0
- package/dist/server/modules/admin/collections/user.mjs +204 -0
- package/dist/server/modules/admin/collections/verification.d.mts +63 -0
- package/dist/server/modules/admin/collections/verification.mjs +15 -0
- package/dist/server/modules/admin/components/badge.d.mts +10 -0
- package/dist/server/modules/admin/components/badge.mjs +10 -0
- package/dist/server/modules/admin/components/icon.d.mts +9 -0
- package/dist/server/modules/admin/components/icon.mjs +11 -0
- package/dist/server/modules/admin/config/admin.mjs +34 -0
- package/dist/server/modules/admin/dto/admin-config.dto.mjs +102 -0
- package/dist/server/modules/admin/factories.mjs +172 -0
- package/dist/server/modules/admin/index.d.mts +1093 -0
- package/dist/server/modules/admin/index.mjs +26 -0
- package/dist/server/modules/admin/modules.mjs +11 -0
- package/dist/server/modules/admin/plugin.mjs +13 -0
- package/dist/server/modules/admin/routes/admin-config.d.mts +28 -0
- package/dist/server/modules/admin/routes/admin-config.mjs +552 -0
- package/dist/server/modules/admin/routes/execute-action.d.mts +92 -0
- package/dist/server/modules/admin/routes/execute-action.mjs +433 -0
- package/dist/server/modules/admin/routes/locales.d.mts +18 -0
- package/dist/server/modules/admin/routes/locales.mjs +69 -0
- package/dist/server/modules/admin/routes/preview.d.mts +80 -0
- package/dist/server/modules/admin/routes/preview.mjs +230 -0
- package/dist/server/modules/admin/routes/reactive.d.mts +74 -0
- package/dist/server/modules/admin/routes/reactive.mjs +350 -0
- package/dist/server/modules/admin/routes/route-helpers.d.mts +23 -0
- package/dist/server/modules/admin/routes/route-helpers.mjs +76 -0
- package/dist/server/modules/admin/routes/setup.d.mts +63 -0
- package/dist/server/modules/admin/routes/setup.mjs +114 -0
- package/dist/server/modules/admin/routes/translations.d.mts +26 -0
- package/dist/server/modules/admin/routes/translations.mjs +114 -0
- package/dist/server/modules/admin/routes/widget-data.d.mts +32 -0
- package/dist/server/modules/admin/routes/widget-data.mjs +62 -0
- package/dist/server/modules/admin/views/form.d.mts +8 -0
- package/dist/server/modules/admin/views/form.mjs +7 -0
- package/dist/server/modules/admin/views/global-form.d.mts +8 -0
- package/dist/server/modules/admin/views/global-form.mjs +7 -0
- package/dist/server/modules/admin/views/table.d.mts +8 -0
- package/dist/server/modules/admin/views/table.mjs +7 -0
- package/dist/server/modules/admin-preferences/collections/admin-preferences.mjs +37 -0
- package/dist/server/modules/admin-preferences/collections/locks.collection.mjs +55 -0
- package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +99 -0
- package/dist/server/modules/admin-preferences/collections/saved-views.mjs +38 -0
- package/dist/server/modules/audit/.generated/module.d.mts +60 -0
- package/dist/server/modules/audit/.generated/module.mjs +30 -0
- package/dist/server/modules/audit/collections/audit-log.d.mts +214 -0
- package/dist/server/modules/audit/collections/audit-log.mjs +107 -0
- package/dist/server/modules/audit/config/admin.mjs +21 -0
- package/dist/server/modules/audit/config/app.mjs +262 -0
- package/dist/server/modules/audit/index.d.mts +2 -0
- package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +13 -0
- package/dist/server/modules/audit/jobs/audit-cleanup.mjs +28 -0
- package/dist/server/plugin.d.mts +26 -0
- package/dist/server/plugin.mjs +385 -0
- package/dist/server/proxy-factories.d.mts +85 -0
- package/dist/server/proxy-factories.mjs +302 -0
- package/dist/server/registry-helpers.d.mts +83 -0
- package/dist/server/registry-helpers.mjs +104 -0
- package/dist/server.d.mts +33 -250
- package/dist/server.mjs +22 -832
- package/dist/shared/preview-utils.d.mts +53 -0
- package/dist/{preview-utils-BKQ9-TMa.mjs → shared/preview-utils.mjs} +2 -3
- package/dist/{saved-views.types-BMsz5mCy.d.mts → shared/types/saved-views.types.d.mts} +7 -2
- package/dist/shared.d.mts +3 -57
- package/dist/shared.mjs +1 -1
- package/package.json +56 -51
- package/skills/questpie-admin/SKILL.md +397 -0
- package/skills/questpie-admin/blocks/SKILL.md +305 -0
- package/skills/questpie-admin/custom-ui/SKILL.md +307 -0
- package/skills/questpie-admin/views/SKILL.md +442 -0
- package/dist/auth-layout-M8K8_q5R.mjs +0 -181
- package/dist/auth-layout-M8K8_q5R.mjs.map +0 -1
- package/dist/bulk-upload-dialog-D7w7W1Hl.mjs +0 -273
- package/dist/bulk-upload-dialog-D7w7W1Hl.mjs.map +0 -1
- package/dist/card-BKHjBQfw.mjs +0 -58
- package/dist/card-BKHjBQfw.mjs.map +0 -1
- package/dist/client-D1DqawtP.d.mts +0 -13403
- package/dist/client-D1DqawtP.d.mts.map +0 -1
- package/dist/client-njX1rZmi.mjs +0 -22612
- package/dist/client-njX1rZmi.mjs.map +0 -1
- package/dist/content-locales-provider-BXvuIgfg.mjs +0 -1650
- package/dist/content-locales-provider-BXvuIgfg.mjs.map +0 -1
- package/dist/dashboard-page-B4PGEdc2.mjs +0 -2500
- package/dist/dashboard-page-B4PGEdc2.mjs.map +0 -1
- package/dist/dashboard-page-mCY0pgZv.mjs +0 -3
- package/dist/dropzone-Do3awXKd.mjs +0 -634
- package/dist/dropzone-Do3awXKd.mjs.map +0 -1
- package/dist/forgot-password-page-Bcp-An4Y.mjs +0 -221
- package/dist/forgot-password-page-Bcp-An4Y.mjs.map +0 -1
- package/dist/forgot-password-page-CEwsdLwn.mjs +0 -3
- package/dist/index-B4H3amCD.d.mts +0 -2753
- package/dist/index-B4H3amCD.d.mts.map +0 -1
- package/dist/login-page-BUnpCbCa.mjs +0 -3
- package/dist/login-page-CP4gA-dl.mjs +0 -298
- package/dist/login-page-CP4gA-dl.mjs.map +0 -1
- package/dist/preview-utils-BKQ9-TMa.mjs.map +0 -1
- package/dist/reset-password-page-BqfDmLxA.mjs +0 -281
- package/dist/reset-password-page-BqfDmLxA.mjs.map +0 -1
- package/dist/reset-password-page-CufHz3h3.mjs +0 -3
- package/dist/runtime-6VZM878K.mjs +0 -69
- package/dist/runtime-6VZM878K.mjs.map +0 -1
- package/dist/saved-views.types-BMsz5mCy.d.mts.map +0 -1
- package/dist/server.d.mts.map +0 -1
- package/dist/server.mjs.map +0 -1
- package/dist/setup-page-BNNzt_Z6.mjs +0 -3
- package/dist/setup-page-YAP_fzqh.mjs +0 -264
- package/dist/setup-page-YAP_fzqh.mjs.map +0 -1
- package/dist/shared.d.mts.map +0 -1
- package/dist/use-auth-BoLmWtmU.mjs.map +0 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { getApp, getCollectionState, getSession } from "./route-helpers.mjs";
|
|
2
|
+
import { getPreviewSecret } from "../../../../shared/preview-utils.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { ApiError, route } from "questpie";
|
|
5
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
6
|
+
|
|
7
|
+
//#region src/server/modules/admin/routes/preview.ts
|
|
8
|
+
/**
|
|
9
|
+
* Preview Functions - Server-side
|
|
10
|
+
*
|
|
11
|
+
* RPC functions for draft mode preview.
|
|
12
|
+
* Handles token minting for secure, shareable preview links.
|
|
13
|
+
*
|
|
14
|
+
* Browser-safe utilities (isDraftMode, createDraftModeCookie, etc.) are in @questpie/admin/shared
|
|
15
|
+
*/
|
|
16
|
+
function base64UrlEncode(input) {
|
|
17
|
+
return (Buffer.isBuffer(input) ? input : Buffer.from(input)).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
18
|
+
}
|
|
19
|
+
function base64UrlDecode(input) {
|
|
20
|
+
let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
21
|
+
const padding = base64.length % 4;
|
|
22
|
+
if (padding) base64 += "=".repeat(4 - padding);
|
|
23
|
+
return Buffer.from(base64, "base64").toString("utf8");
|
|
24
|
+
}
|
|
25
|
+
const mintPreviewTokenSchema = z.object({
|
|
26
|
+
path: z.string().min(1, "Path is required"),
|
|
27
|
+
ttlMs: z.number().positive().optional()
|
|
28
|
+
});
|
|
29
|
+
const mintPreviewTokenOutputSchema = z.object({
|
|
30
|
+
token: z.string(),
|
|
31
|
+
expiresAt: z.number()
|
|
32
|
+
});
|
|
33
|
+
const verifyPreviewTokenSchema = z.object({ token: z.string() });
|
|
34
|
+
const verifyPreviewTokenOutputSchema = z.object({
|
|
35
|
+
valid: z.boolean(),
|
|
36
|
+
path: z.string().optional(),
|
|
37
|
+
error: z.string().optional()
|
|
38
|
+
});
|
|
39
|
+
const DEFAULT_TTL_MS = 3600 * 1e3;
|
|
40
|
+
/**
|
|
41
|
+
* Create preview-related RPC functions.
|
|
42
|
+
*
|
|
43
|
+
* @param secret - Secret key for signing tokens
|
|
44
|
+
* @returns Object with preview functions
|
|
45
|
+
*/
|
|
46
|
+
function createPreviewFunctions(secret) {
|
|
47
|
+
const signPayload = (payload) => {
|
|
48
|
+
return base64UrlEncode(createHmac("sha256", secret).update(payload).digest());
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
mintPreviewToken: route().post().schema(mintPreviewTokenSchema).outputSchema(mintPreviewTokenOutputSchema).handler(async (ctx) => {
|
|
52
|
+
const { input } = ctx;
|
|
53
|
+
if (!getSession(ctx)) throw ApiError.unauthorized("Admin session required");
|
|
54
|
+
const { path, ttlMs = DEFAULT_TTL_MS } = input;
|
|
55
|
+
const expiresAt = Date.now() + ttlMs;
|
|
56
|
+
const payload = {
|
|
57
|
+
path,
|
|
58
|
+
exp: expiresAt
|
|
59
|
+
};
|
|
60
|
+
const encodedPayload = base64UrlEncode(JSON.stringify(payload));
|
|
61
|
+
return {
|
|
62
|
+
token: `${encodedPayload}.${signPayload(encodedPayload)}`,
|
|
63
|
+
expiresAt
|
|
64
|
+
};
|
|
65
|
+
}),
|
|
66
|
+
verifyPreviewToken: route().post().schema(verifyPreviewTokenSchema).outputSchema(verifyPreviewTokenOutputSchema).handler(async ({ input }) => {
|
|
67
|
+
const { token } = input;
|
|
68
|
+
const [encodedPayload, signature] = token.split(".");
|
|
69
|
+
if (!encodedPayload || !signature) return {
|
|
70
|
+
valid: false,
|
|
71
|
+
error: "Invalid token format"
|
|
72
|
+
};
|
|
73
|
+
const expectedSignature = signPayload(encodedPayload);
|
|
74
|
+
const signatureBuffer = Uint8Array.from(Buffer.from(signature));
|
|
75
|
+
const expectedBuffer = Uint8Array.from(Buffer.from(expectedSignature));
|
|
76
|
+
if (signatureBuffer.length !== expectedBuffer.length) return {
|
|
77
|
+
valid: false,
|
|
78
|
+
error: "Invalid signature"
|
|
79
|
+
};
|
|
80
|
+
if (!timingSafeEqual(signatureBuffer, expectedBuffer)) return {
|
|
81
|
+
valid: false,
|
|
82
|
+
error: "Invalid signature"
|
|
83
|
+
};
|
|
84
|
+
try {
|
|
85
|
+
const payload = JSON.parse(base64UrlDecode(encodedPayload));
|
|
86
|
+
if (!payload?.exp || typeof payload.exp !== "number") return {
|
|
87
|
+
valid: false,
|
|
88
|
+
error: "Invalid payload"
|
|
89
|
+
};
|
|
90
|
+
if (payload.exp < Date.now()) return {
|
|
91
|
+
valid: false,
|
|
92
|
+
error: "Token expired"
|
|
93
|
+
};
|
|
94
|
+
if (!payload.path || typeof payload.path !== "string") return {
|
|
95
|
+
valid: false,
|
|
96
|
+
error: "Invalid path"
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
valid: true,
|
|
100
|
+
path: payload.path
|
|
101
|
+
};
|
|
102
|
+
} catch {
|
|
103
|
+
return {
|
|
104
|
+
valid: false,
|
|
105
|
+
error: "Invalid payload"
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Verify a preview token without RPC.
|
|
113
|
+
* Used directly in route handlers where RPC is not available.
|
|
114
|
+
*
|
|
115
|
+
* @param token - The preview token to verify
|
|
116
|
+
* @param secret - The secret used to sign the token
|
|
117
|
+
* @returns The payload if valid, null otherwise
|
|
118
|
+
*/
|
|
119
|
+
function verifyPreviewTokenDirect(token, secret) {
|
|
120
|
+
const [encodedPayload, signature] = token.split(".");
|
|
121
|
+
if (!encodedPayload || !signature) return null;
|
|
122
|
+
const expectedSignature = base64UrlEncode(createHmac("sha256", secret).update(encodedPayload).digest());
|
|
123
|
+
const signatureBuffer = Uint8Array.from(Buffer.from(signature));
|
|
124
|
+
const expectedBuffer = Uint8Array.from(Buffer.from(expectedSignature));
|
|
125
|
+
if (signatureBuffer.length !== expectedBuffer.length) return null;
|
|
126
|
+
if (!timingSafeEqual(signatureBuffer, expectedBuffer)) return null;
|
|
127
|
+
try {
|
|
128
|
+
const payload = JSON.parse(base64UrlDecode(encodedPayload));
|
|
129
|
+
if (!payload?.exp || typeof payload.exp !== "number") return null;
|
|
130
|
+
if (payload.exp < Date.now()) return null;
|
|
131
|
+
if (!payload.path || typeof payload.path !== "string") return null;
|
|
132
|
+
return payload;
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create a preview token verifier with bound secret.
|
|
139
|
+
* Use this in route handlers to avoid passing secret repeatedly.
|
|
140
|
+
*
|
|
141
|
+
* @param secret - The secret used to sign tokens (optional, uses env if not provided)
|
|
142
|
+
* @returns A verify function that only needs the token
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* // Create once at module level
|
|
147
|
+
* const verifyPreviewToken = createPreviewTokenVerifier();
|
|
148
|
+
*
|
|
149
|
+
* // Use in route handler
|
|
150
|
+
* const payload = verifyPreviewToken(token);
|
|
151
|
+
* if (!payload) {
|
|
152
|
+
* return new Response("Invalid token", { status: 401 });
|
|
153
|
+
* }
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
function createPreviewTokenVerifier(secret) {
|
|
157
|
+
const resolvedSecret = secret ?? getPreviewSecret();
|
|
158
|
+
return (token) => {
|
|
159
|
+
return verifyPreviewTokenDirect(token, resolvedSecret);
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const getPreviewUrlSchema = z.object({
|
|
163
|
+
collection: z.string().min(1, "Collection name is required"),
|
|
164
|
+
record: z.record(z.string(), z.unknown()),
|
|
165
|
+
locale: z.string().optional()
|
|
166
|
+
});
|
|
167
|
+
const getPreviewUrlOutputSchema = z.object({
|
|
168
|
+
url: z.string().nullable(),
|
|
169
|
+
error: z.string().optional()
|
|
170
|
+
});
|
|
171
|
+
/**
|
|
172
|
+
* Get preview URL for a collection record.
|
|
173
|
+
*
|
|
174
|
+
* Calls the server-side url() function from the collection's .preview() config.
|
|
175
|
+
* This is needed because url() is a function that cannot be serialized to JSON.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* const { url } = await client.routes.getPreviewUrl({
|
|
180
|
+
* collection: "pages",
|
|
181
|
+
* record: { slug: "about", title: "About Us" },
|
|
182
|
+
* locale: "en",
|
|
183
|
+
* });
|
|
184
|
+
* // Returns: "/about?preview=true"
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
const getPreviewUrl = route().post().schema(getPreviewUrlSchema).outputSchema(getPreviewUrlOutputSchema).handler(async (ctx) => {
|
|
188
|
+
const { input } = ctx;
|
|
189
|
+
if (!getSession(ctx)) return {
|
|
190
|
+
url: null,
|
|
191
|
+
error: "Unauthorized: Admin session required"
|
|
192
|
+
};
|
|
193
|
+
const { collection: collectionName, record, locale } = input;
|
|
194
|
+
const collection$1 = getApp(ctx).getCollections()[collectionName];
|
|
195
|
+
if (!collection$1) return {
|
|
196
|
+
url: null,
|
|
197
|
+
error: `Collection '${collectionName}' not found`
|
|
198
|
+
};
|
|
199
|
+
const previewConfig = getCollectionState(collection$1).adminPreview;
|
|
200
|
+
if (!previewConfig?.url) return {
|
|
201
|
+
url: null,
|
|
202
|
+
error: "No preview URL configured for this collection"
|
|
203
|
+
};
|
|
204
|
+
if (previewConfig.enabled === false) return {
|
|
205
|
+
url: null,
|
|
206
|
+
error: "Preview is disabled for this collection"
|
|
207
|
+
};
|
|
208
|
+
try {
|
|
209
|
+
return { url: previewConfig.url({
|
|
210
|
+
record,
|
|
211
|
+
locale
|
|
212
|
+
}) };
|
|
213
|
+
} catch (err) {
|
|
214
|
+
return {
|
|
215
|
+
url: null,
|
|
216
|
+
error: `Failed to generate preview URL: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
/**
|
|
221
|
+
* Default preview functions bundle with env-based secret.
|
|
222
|
+
* Used by the `adminModule` to register preview RPC functions.
|
|
223
|
+
*/
|
|
224
|
+
const previewFunctions = {
|
|
225
|
+
...createPreviewFunctions(getPreviewSecret()),
|
|
226
|
+
getPreviewUrl
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
//#endregion
|
|
230
|
+
export { createPreviewFunctions, createPreviewTokenVerifier, previewFunctions, verifyPreviewTokenDirect };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as questpie105 from "questpie";
|
|
2
|
+
|
|
3
|
+
//#region src/server/modules/admin/routes/reactive.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Reactive Field RPC Endpoints
|
|
7
|
+
*
|
|
8
|
+
* Provides server-side execution of reactive field handlers:
|
|
9
|
+
* - /reactive: Batch endpoint for compute, hidden, readOnly, disabled
|
|
10
|
+
* - /options: Dynamic options for select/relation fields
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Batch reactive endpoint.
|
|
14
|
+
* Executes multiple reactive handlers in a single request.
|
|
15
|
+
*/
|
|
16
|
+
declare const batchReactive: questpie105.JsonRouteDefinition<{
|
|
17
|
+
collection: string;
|
|
18
|
+
type: "collection" | "global";
|
|
19
|
+
requests: {
|
|
20
|
+
field: string;
|
|
21
|
+
type: "hidden" | "readOnly" | "disabled" | "compute";
|
|
22
|
+
formData?: Record<string, unknown> | undefined;
|
|
23
|
+
siblingData?: Record<string, unknown> | null | undefined;
|
|
24
|
+
prevData?: Record<string, unknown> | null | undefined;
|
|
25
|
+
prevSiblingData?: Record<string, unknown> | null | undefined;
|
|
26
|
+
}[];
|
|
27
|
+
formData?: Record<string, unknown> | undefined;
|
|
28
|
+
prevData?: Record<string, unknown> | null | undefined;
|
|
29
|
+
}, any>;
|
|
30
|
+
/**
|
|
31
|
+
* Dynamic options endpoint.
|
|
32
|
+
* Fetches options for select/relation fields with search and pagination.
|
|
33
|
+
*/
|
|
34
|
+
declare const fieldOptions: questpie105.JsonRouteDefinition<{
|
|
35
|
+
collection: string;
|
|
36
|
+
type: "collection" | "global";
|
|
37
|
+
field: string;
|
|
38
|
+
formData: Record<string, unknown>;
|
|
39
|
+
search: string;
|
|
40
|
+
page: number;
|
|
41
|
+
limit: number;
|
|
42
|
+
siblingData?: Record<string, unknown> | null | undefined;
|
|
43
|
+
}, any>;
|
|
44
|
+
/**
|
|
45
|
+
* Reactive functions bundle.
|
|
46
|
+
*/
|
|
47
|
+
declare const reactiveFunctions: {
|
|
48
|
+
readonly batchReactive: questpie105.JsonRouteDefinition<{
|
|
49
|
+
collection: string;
|
|
50
|
+
type: "collection" | "global";
|
|
51
|
+
requests: {
|
|
52
|
+
field: string;
|
|
53
|
+
type: "hidden" | "readOnly" | "disabled" | "compute";
|
|
54
|
+
formData?: Record<string, unknown> | undefined;
|
|
55
|
+
siblingData?: Record<string, unknown> | null | undefined;
|
|
56
|
+
prevData?: Record<string, unknown> | null | undefined;
|
|
57
|
+
prevSiblingData?: Record<string, unknown> | null | undefined;
|
|
58
|
+
}[];
|
|
59
|
+
formData?: Record<string, unknown> | undefined;
|
|
60
|
+
prevData?: Record<string, unknown> | null | undefined;
|
|
61
|
+
}, any>;
|
|
62
|
+
readonly fieldOptions: questpie105.JsonRouteDefinition<{
|
|
63
|
+
collection: string;
|
|
64
|
+
type: "collection" | "global";
|
|
65
|
+
field: string;
|
|
66
|
+
formData: Record<string, unknown>;
|
|
67
|
+
search: string;
|
|
68
|
+
page: number;
|
|
69
|
+
limit: number;
|
|
70
|
+
siblingData?: Record<string, unknown> | null | undefined;
|
|
71
|
+
}, any>;
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
export { batchReactive, fieldOptions, reactiveFunctions };
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { buildServerContext, getApp } from "./route-helpers.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { ApiError, route } from "questpie";
|
|
4
|
+
|
|
5
|
+
//#region src/server/modules/admin/routes/reactive.ts
|
|
6
|
+
/**
|
|
7
|
+
* Build ReactiveContext from request data.
|
|
8
|
+
*/
|
|
9
|
+
function buildReactiveContext(formData, siblingData, prevData, prevSiblingData, serverCtx) {
|
|
10
|
+
return {
|
|
11
|
+
data: formData,
|
|
12
|
+
sibling: siblingData || {},
|
|
13
|
+
prev: {
|
|
14
|
+
data: prevData || formData,
|
|
15
|
+
sibling: prevSiblingData || siblingData || {}
|
|
16
|
+
},
|
|
17
|
+
ctx: serverCtx
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build OptionsContext from request data.
|
|
22
|
+
*/
|
|
23
|
+
function buildOptionsContext(formData, siblingData, search, page, limit, serverCtx) {
|
|
24
|
+
return {
|
|
25
|
+
data: formData,
|
|
26
|
+
sibling: siblingData || {},
|
|
27
|
+
search,
|
|
28
|
+
page,
|
|
29
|
+
limit,
|
|
30
|
+
ctx: serverCtx
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get collection builder by name.
|
|
35
|
+
*/
|
|
36
|
+
function getCollection(app, collectionName) {
|
|
37
|
+
const collection$1 = app.getCollections()[collectionName];
|
|
38
|
+
if (!collection$1) throw ApiError.notFound("Collection", collectionName);
|
|
39
|
+
return collection$1;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get global builder by name.
|
|
43
|
+
*/
|
|
44
|
+
function getGlobal(app, globalName) {
|
|
45
|
+
const global = app.getGlobals()[globalName];
|
|
46
|
+
if (!global) throw ApiError.notFound("Global", globalName);
|
|
47
|
+
return global;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get entity (collection or global) builder by name and type.
|
|
51
|
+
*/
|
|
52
|
+
function getEntity(app, entityName, type) {
|
|
53
|
+
if (type === "global") return getGlobal(app, entityName);
|
|
54
|
+
return getCollection(app, entityName);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get field definition from collection or global.
|
|
58
|
+
*/
|
|
59
|
+
function getFieldDefinition(app, entityName, fieldPath, type = "collection") {
|
|
60
|
+
const fieldDefinitions = getEntity(app, entityName, type).state.fieldDefinitions || {};
|
|
61
|
+
const parts = fieldPath.split(".");
|
|
62
|
+
let currentDefs = fieldDefinitions;
|
|
63
|
+
let fieldDef = null;
|
|
64
|
+
for (let i = 0; i < parts.length; i++) {
|
|
65
|
+
const part = parts[i];
|
|
66
|
+
if (/^\d+$/.test(part)) continue;
|
|
67
|
+
if (currentDefs[part]) {
|
|
68
|
+
fieldDef = currentDefs[part];
|
|
69
|
+
if (fieldDef.getNestedFields) currentDefs = fieldDef.getNestedFields();
|
|
70
|
+
else if (fieldDef._state?.innerField) {
|
|
71
|
+
const ofField = fieldDef._state.innerField;
|
|
72
|
+
if (ofField?.getNestedFields) currentDefs = ofField.getNestedFields();
|
|
73
|
+
}
|
|
74
|
+
} else throw ApiError.notFound("Field", `${part} in path '${fieldPath}'`);
|
|
75
|
+
}
|
|
76
|
+
if (!fieldDef) {
|
|
77
|
+
const entityType = type === "global" ? "Global" : "Collection";
|
|
78
|
+
throw ApiError.notFound(`${entityType} field`, `${entityName}.${fieldPath}`);
|
|
79
|
+
}
|
|
80
|
+
return fieldDef;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Remove numeric indices from nested field paths.
|
|
84
|
+
*/
|
|
85
|
+
function normalizeFieldPath(fieldPath) {
|
|
86
|
+
return fieldPath.split(".").filter((part) => !/^\d+$/.test(part)).join(".");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate candidate field paths for matching form entries.
|
|
90
|
+
*/
|
|
91
|
+
function getFieldPathCandidates(fieldPath) {
|
|
92
|
+
const normalized = normalizeFieldPath(fieldPath);
|
|
93
|
+
const candidates = new Set([normalized]);
|
|
94
|
+
const parts = normalized.split(".");
|
|
95
|
+
if (parts.length > 1) {
|
|
96
|
+
const leaf = parts[parts.length - 1];
|
|
97
|
+
if (leaf) candidates.add(leaf);
|
|
98
|
+
}
|
|
99
|
+
return candidates;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Find a reactive field entry in form layout items recursively.
|
|
103
|
+
*/
|
|
104
|
+
function findReactiveFieldEntryInLayoutItems(items, fieldCandidates) {
|
|
105
|
+
if (!Array.isArray(items)) return null;
|
|
106
|
+
for (const item of items) {
|
|
107
|
+
if (!item || typeof item !== "object") continue;
|
|
108
|
+
const entry = item;
|
|
109
|
+
if (typeof entry.field === "string" && fieldCandidates.has(entry.field)) return entry;
|
|
110
|
+
if (entry.type === "section") {
|
|
111
|
+
const found = findReactiveFieldEntryInLayoutItems(entry.fields, fieldCandidates);
|
|
112
|
+
if (found) return found;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (entry.type === "tabs") {
|
|
116
|
+
const found = findReactiveFieldEntryInTabs(entry.tabs, fieldCandidates);
|
|
117
|
+
if (found) return found;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Find a reactive field entry in form sections.
|
|
124
|
+
*/
|
|
125
|
+
function findReactiveFieldEntryInSections(sections, fieldCandidates) {
|
|
126
|
+
if (!Array.isArray(sections)) return null;
|
|
127
|
+
for (const section of sections) {
|
|
128
|
+
if (!section || typeof section !== "object") continue;
|
|
129
|
+
const found = findReactiveFieldEntryInLayoutItems(section.fields, fieldCandidates);
|
|
130
|
+
if (found) return found;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Find a reactive field entry in form tabs.
|
|
136
|
+
*/
|
|
137
|
+
function findReactiveFieldEntryInTabs(tabs, fieldCandidates) {
|
|
138
|
+
if (!Array.isArray(tabs)) return null;
|
|
139
|
+
for (const tab of tabs) {
|
|
140
|
+
if (!tab || typeof tab !== "object") continue;
|
|
141
|
+
const tabConfig = tab;
|
|
142
|
+
const fromFields = findReactiveFieldEntryInLayoutItems(tabConfig.fields, fieldCandidates);
|
|
143
|
+
if (fromFields) return fromFields;
|
|
144
|
+
const fromSections = findReactiveFieldEntryInSections(tabConfig.sections, fieldCandidates);
|
|
145
|
+
if (fromSections) return fromSections;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Find field entry config from collection form configuration.
|
|
151
|
+
*/
|
|
152
|
+
function findReactiveFieldEntry(formConfig, fieldPath) {
|
|
153
|
+
if (!formConfig || typeof formConfig !== "object") return null;
|
|
154
|
+
const fieldCandidates = getFieldPathCandidates(fieldPath);
|
|
155
|
+
const form = formConfig;
|
|
156
|
+
const fromFields = findReactiveFieldEntryInLayoutItems(form.fields, fieldCandidates);
|
|
157
|
+
if (fromFields) return fromFields;
|
|
158
|
+
const fromSections = findReactiveFieldEntryInSections(form.sections, fieldCandidates);
|
|
159
|
+
if (fromSections) return fromSections;
|
|
160
|
+
const fromTabs = findReactiveFieldEntryInTabs(form.tabs, fieldCandidates);
|
|
161
|
+
if (fromTabs) return fromTabs;
|
|
162
|
+
if (form.sidebar && typeof form.sidebar === "object") {
|
|
163
|
+
const sidebar = form.sidebar;
|
|
164
|
+
return findReactiveFieldEntryInLayoutItems(sidebar.fields, fieldCandidates);
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get reactive handler from collection/global form config.
|
|
170
|
+
*/
|
|
171
|
+
function getReactiveHandler(app, entityName, fieldPath, handlerType, type = "collection") {
|
|
172
|
+
const formConfig = getEntity(app, entityName, type).state.adminForm;
|
|
173
|
+
const fieldEntry = findReactiveFieldEntry(formConfig, fieldPath);
|
|
174
|
+
if (!fieldEntry) return null;
|
|
175
|
+
const handlerConfig = fieldEntry[handlerType];
|
|
176
|
+
if (!handlerConfig || typeof handlerConfig === "boolean") return null;
|
|
177
|
+
if (typeof handlerConfig === "function") return handlerConfig;
|
|
178
|
+
if (typeof handlerConfig === "object" && handlerConfig !== null && "handler" in handlerConfig && typeof handlerConfig.handler === "function") return handlerConfig.handler;
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get options handler from field config.
|
|
183
|
+
*/
|
|
184
|
+
function getOptionsHandler(fieldDef) {
|
|
185
|
+
const options = fieldDef._state?.options;
|
|
186
|
+
if (!options) return null;
|
|
187
|
+
if (typeof options === "object" && "handler" in options) return options.handler;
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Single reactive request in a batch.
|
|
192
|
+
*/
|
|
193
|
+
const reactiveRequestSchema = z.object({
|
|
194
|
+
field: z.string(),
|
|
195
|
+
type: z.enum([
|
|
196
|
+
"hidden",
|
|
197
|
+
"readOnly",
|
|
198
|
+
"disabled",
|
|
199
|
+
"compute"
|
|
200
|
+
]),
|
|
201
|
+
formData: z.record(z.string(), z.unknown()).optional(),
|
|
202
|
+
siblingData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
203
|
+
prevData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
204
|
+
prevSiblingData: z.record(z.string(), z.unknown()).nullable().optional()
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* Batch reactive request.
|
|
208
|
+
*/
|
|
209
|
+
const batchReactiveInputSchema = z.object({
|
|
210
|
+
collection: z.string(),
|
|
211
|
+
type: z.enum(["collection", "global"]).default("collection"),
|
|
212
|
+
formData: z.record(z.string(), z.unknown()).optional(),
|
|
213
|
+
prevData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
214
|
+
requests: z.array(reactiveRequestSchema)
|
|
215
|
+
});
|
|
216
|
+
/**
|
|
217
|
+
* Single reactive result.
|
|
218
|
+
*/
|
|
219
|
+
const reactiveResultSchema = z.object({
|
|
220
|
+
field: z.string(),
|
|
221
|
+
type: z.enum([
|
|
222
|
+
"hidden",
|
|
223
|
+
"readOnly",
|
|
224
|
+
"disabled",
|
|
225
|
+
"compute"
|
|
226
|
+
]),
|
|
227
|
+
value: z.unknown(),
|
|
228
|
+
error: z.string().optional()
|
|
229
|
+
});
|
|
230
|
+
/**
|
|
231
|
+
* Batch reactive response.
|
|
232
|
+
*/
|
|
233
|
+
const batchReactiveOutputSchema = z.object({ results: z.array(reactiveResultSchema) });
|
|
234
|
+
/**
|
|
235
|
+
* Options request.
|
|
236
|
+
*/
|
|
237
|
+
const optionsInputSchema = z.object({
|
|
238
|
+
collection: z.string(),
|
|
239
|
+
type: z.enum(["collection", "global"]).default("collection"),
|
|
240
|
+
field: z.string(),
|
|
241
|
+
formData: z.record(z.string(), z.unknown()),
|
|
242
|
+
siblingData: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
243
|
+
search: z.string().default(""),
|
|
244
|
+
page: z.number().int().min(0).default(0),
|
|
245
|
+
limit: z.number().int().min(1).max(100).default(20)
|
|
246
|
+
});
|
|
247
|
+
/**
|
|
248
|
+
* Options response.
|
|
249
|
+
*/
|
|
250
|
+
const optionsOutputSchema = z.object({
|
|
251
|
+
options: z.array(z.object({
|
|
252
|
+
value: z.union([z.string(), z.number()]),
|
|
253
|
+
label: z.union([z.string(), z.record(z.string(), z.string())])
|
|
254
|
+
})),
|
|
255
|
+
hasMore: z.boolean().optional(),
|
|
256
|
+
total: z.number().optional()
|
|
257
|
+
});
|
|
258
|
+
/**
|
|
259
|
+
* Batch reactive endpoint.
|
|
260
|
+
* Executes multiple reactive handlers in a single request.
|
|
261
|
+
*/
|
|
262
|
+
const batchReactive = route().post().schema(batchReactiveInputSchema).outputSchema(batchReactiveOutputSchema).handler(async (ctx) => {
|
|
263
|
+
const app = getApp(ctx);
|
|
264
|
+
const { collection: entityName, type: entityType, requests, formData: sharedFormData, prevData: sharedPrevData } = ctx.input;
|
|
265
|
+
const serverCtx = buildServerContext(ctx);
|
|
266
|
+
return { results: await Promise.all(requests.map(async (request) => {
|
|
267
|
+
const { field: field$1, type, formData, siblingData, prevData, prevSiblingData } = request;
|
|
268
|
+
const resolvedFormData = formData ?? sharedFormData ?? {};
|
|
269
|
+
const resolvedPrevData = prevData ?? sharedPrevData ?? null;
|
|
270
|
+
try {
|
|
271
|
+
getFieldDefinition(app, entityName, field$1, entityType);
|
|
272
|
+
const handler = getReactiveHandler(app, entityName, field$1, type, entityType);
|
|
273
|
+
if (!handler) return {
|
|
274
|
+
field: field$1,
|
|
275
|
+
type,
|
|
276
|
+
value: void 0,
|
|
277
|
+
error: `No ${type} handler found for field '${field$1}'`
|
|
278
|
+
};
|
|
279
|
+
return {
|
|
280
|
+
field: field$1,
|
|
281
|
+
type,
|
|
282
|
+
value: await handler(buildReactiveContext(resolvedFormData, siblingData, resolvedPrevData, prevSiblingData, serverCtx))
|
|
283
|
+
};
|
|
284
|
+
} catch (error) {
|
|
285
|
+
return {
|
|
286
|
+
field: field$1,
|
|
287
|
+
type,
|
|
288
|
+
value: void 0,
|
|
289
|
+
error: error instanceof Error ? error.message : String(error)
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
})) };
|
|
293
|
+
});
|
|
294
|
+
/**
|
|
295
|
+
* Dynamic options endpoint.
|
|
296
|
+
* Fetches options for select/relation fields with search and pagination.
|
|
297
|
+
*/
|
|
298
|
+
const fieldOptions = route().post().schema(optionsInputSchema).outputSchema(optionsOutputSchema).handler(async (ctx) => {
|
|
299
|
+
const app = getApp(ctx);
|
|
300
|
+
const { collection: entityName, type: entityType, field: field$1, formData, siblingData, search, page, limit } = ctx.input;
|
|
301
|
+
const serverCtx = buildServerContext(ctx);
|
|
302
|
+
try {
|
|
303
|
+
const fieldDef = getFieldDefinition(app, entityName, field$1, entityType);
|
|
304
|
+
const handler = getOptionsHandler(fieldDef);
|
|
305
|
+
if (!handler) {
|
|
306
|
+
const fieldOptions$1 = fieldDef._state?.options;
|
|
307
|
+
if (Array.isArray(fieldOptions$1)) {
|
|
308
|
+
let options = fieldOptions$1;
|
|
309
|
+
if (search) {
|
|
310
|
+
const searchLower = search.toLowerCase();
|
|
311
|
+
options = options.filter((opt) => {
|
|
312
|
+
return (typeof opt.label === "string" ? opt.label : Object.values(opt.label).join(" ")).toLowerCase().includes(searchLower);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
const start = page * limit;
|
|
316
|
+
return {
|
|
317
|
+
options: options.slice(start, start + limit),
|
|
318
|
+
hasMore: start + limit < options.length,
|
|
319
|
+
total: options.length
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
options: [],
|
|
324
|
+
hasMore: false
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
const result = await handler(buildOptionsContext(formData, siblingData, search, page, limit, serverCtx));
|
|
328
|
+
return {
|
|
329
|
+
options: result.options || [],
|
|
330
|
+
hasMore: result.hasMore,
|
|
331
|
+
total: result.total
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.error(`Error fetching options for ${entityName}.${field$1}:`, error);
|
|
335
|
+
return {
|
|
336
|
+
options: [],
|
|
337
|
+
hasMore: false
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
/**
|
|
342
|
+
* Reactive functions bundle.
|
|
343
|
+
*/
|
|
344
|
+
const reactiveFunctions = {
|
|
345
|
+
batchReactive,
|
|
346
|
+
fieldOptions
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
//#endregion
|
|
350
|
+
export { batchReactive, fieldOptions, reactiveFunctions };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Questpie } from "questpie";
|
|
2
|
+
|
|
3
|
+
//#region src/server/modules/admin/routes/route-helpers.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Minimal typed shape for route handler context.
|
|
7
|
+
* The actual context is `JsonRouteHandlerArgs<T>` which extends `AppContext`,
|
|
8
|
+
* but AppContext is empty in the admin package (augmented by user's codegen).
|
|
9
|
+
*
|
|
10
|
+
* These helpers safely extract the known properties at runtime.
|
|
11
|
+
* Uses Record<string, any> base to accept JsonRouteHandlerArgs without index signature issues.
|
|
12
|
+
*/
|
|
13
|
+
type RouteHandlerContext = Record<string, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Typed app instance type used throughout admin routes.
|
|
16
|
+
*/
|
|
17
|
+
type App = Questpie<any>;
|
|
18
|
+
/**
|
|
19
|
+
* Get typed Questpie app instance from route handler context.
|
|
20
|
+
*/
|
|
21
|
+
declare function getApp(ctx: RouteHandlerContext): App;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { App, getApp };
|