convex-cms 0.0.2 → 0.0.3
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/admin-dist/nitro.json +15 -0
- package/admin-dist/public/assets/CmsEmptyState-CRswfTzk.js +5 -0
- package/admin-dist/public/assets/CmsPageHeader-CirpXndm.js +1 -0
- package/admin-dist/public/assets/CmsStatusBadge-CbEUpQu-.js +1 -0
- package/admin-dist/public/assets/CmsToolbar-BI2nZOXp.js +1 -0
- package/admin-dist/public/assets/ContentEntryEditor-CBeCyK_m.js +4 -0
- package/admin-dist/public/assets/ErrorState-BIVaWmom.js +1 -0
- package/admin-dist/public/assets/TaxonomyFilter-ChaY6Y_x.js +1 -0
- package/admin-dist/public/assets/_contentTypeId-DQ8k_Rvw.js +1 -0
- package/admin-dist/public/assets/_entryId-CKU_glsK.js +1 -0
- package/admin-dist/public/assets/alert-BXjTqrwQ.js +1 -0
- package/admin-dist/public/assets/badge-hvUOzpVZ.js +1 -0
- package/admin-dist/public/assets/circle-check-big-CF_pR17r.js +1 -0
- package/admin-dist/public/assets/command-DU82cJlt.js +1 -0
- package/admin-dist/public/assets/content-_LXl3pp7.js +1 -0
- package/admin-dist/public/assets/content-types-KjxaXGxY.js +2 -0
- package/admin-dist/public/assets/globals-CS6BZ0zp.css +1 -0
- package/admin-dist/public/assets/index-DNGIZHL-.js +1 -0
- package/admin-dist/public/assets/label-KNtpL71g.js +1 -0
- package/admin-dist/public/assets/link-2-Bw2aI4V4.js +1 -0
- package/admin-dist/public/assets/list-sYepHjt_.js +1 -0
- package/admin-dist/public/assets/main-CKj5yfEi.js +97 -0
- package/admin-dist/public/assets/media-Bkrkffm7.js +1 -0
- package/admin-dist/public/assets/new._contentTypeId-C3LstjNs.js +1 -0
- package/admin-dist/public/assets/plus-DUn8v_Xf.js +1 -0
- package/admin-dist/public/assets/rotate-ccw-DJEoHcRI.js +1 -0
- package/admin-dist/public/assets/scroll-area-DfIlT0in.js +1 -0
- package/admin-dist/public/assets/search-MuAUDJKR.js +1 -0
- package/admin-dist/public/assets/select-BD29IXCI.js +1 -0
- package/admin-dist/public/assets/settings-DmMyn_6A.js +1 -0
- package/admin-dist/public/assets/switch-h3Rrnl5i.js +1 -0
- package/admin-dist/public/assets/tabs-imc8h-Dp.js +1 -0
- package/admin-dist/public/assets/taxonomies-dAsrT65H.js +1 -0
- package/admin-dist/public/assets/textarea-BTy7nwzR.js +1 -0
- package/admin-dist/public/assets/trash-SAWKZZHv.js +1 -0
- package/admin-dist/public/assets/triangle-alert-E52Vfeuh.js +1 -0
- package/admin-dist/public/assets/useBreadcrumbLabel-BECBMCzM.js +1 -0
- package/admin-dist/public/assets/usePermissions-Basjs9BT.js +1 -0
- package/admin-dist/public/favicon.ico +0 -0
- package/admin-dist/server/_chunks/_libs/@date-fns/tz.mjs +217 -0
- package/admin-dist/server/_chunks/_libs/@floating-ui/core.mjs +719 -0
- package/admin-dist/server/_chunks/_libs/@floating-ui/dom.mjs +622 -0
- package/admin-dist/server/_chunks/_libs/@floating-ui/react-dom.mjs +292 -0
- package/admin-dist/server/_chunks/_libs/@floating-ui/utils.mjs +320 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/number.mjs +6 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/primitive.mjs +11 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-arrow.mjs +23 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-avatar.mjs +119 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-checkbox.mjs +270 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-collection.mjs +69 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-compose-refs.mjs +39 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-context.mjs +137 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-dialog.mjs +325 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-direction.mjs +9 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-dismissable-layer.mjs +210 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-dropdown-menu.mjs +253 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-guards.mjs +29 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-focus-scope.mjs +206 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-id.mjs +14 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-label.mjs +23 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-menu.mjs +812 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-popover.mjs +300 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-popper.mjs +286 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-portal.mjs +16 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-presence.mjs +128 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-primitive.mjs +141 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-roving-focus.mjs +224 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-scroll-area.mjs +721 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-select.mjs +1163 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-separator.mjs +28 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-slot.mjs +601 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-switch.mjs +152 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-tabs.mjs +189 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-callback-ref.mjs +11 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-controllable-state.mjs +69 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-effect-event.mjs +1 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-escape-keydown.mjs +17 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-is-hydrated.mjs +15 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-layout-effect.mjs +6 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-previous.mjs +14 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-use-size.mjs +39 -0
- package/admin-dist/server/_chunks/_libs/@radix-ui/react-visually-hidden.mjs +33 -0
- package/admin-dist/server/_chunks/_libs/@tanstack/history.mjs +409 -0
- package/admin-dist/server/_chunks/_libs/@tanstack/react-router.mjs +1711 -0
- package/admin-dist/server/_chunks/_libs/@tanstack/react-store.mjs +56 -0
- package/admin-dist/server/_chunks/_libs/@tanstack/router-core.mjs +4829 -0
- package/admin-dist/server/_chunks/_libs/@tanstack/store.mjs +134 -0
- package/admin-dist/server/_chunks/_libs/react-dom.mjs +10781 -0
- package/admin-dist/server/_chunks/_libs/react.mjs +513 -0
- package/admin-dist/server/_libs/aria-hidden.mjs +122 -0
- package/admin-dist/server/_libs/class-variance-authority.mjs +44 -0
- package/admin-dist/server/_libs/clsx.mjs +16 -0
- package/admin-dist/server/_libs/cmdk.mjs +315 -0
- package/admin-dist/server/_libs/convex.mjs +4841 -0
- package/admin-dist/server/_libs/cookie-es.mjs +58 -0
- package/admin-dist/server/_libs/croner.mjs +1 -0
- package/admin-dist/server/_libs/crossws.mjs +1 -0
- package/admin-dist/server/_libs/date-fns.mjs +1716 -0
- package/admin-dist/server/_libs/detect-node-es.mjs +1 -0
- package/admin-dist/server/_libs/get-nonce.mjs +9 -0
- package/admin-dist/server/_libs/h3-v2.mjs +277 -0
- package/admin-dist/server/_libs/h3.mjs +401 -0
- package/admin-dist/server/_libs/hookable.mjs +1 -0
- package/admin-dist/server/_libs/isbot.mjs +20 -0
- package/admin-dist/server/_libs/lucide-react.mjs +850 -0
- package/admin-dist/server/_libs/ohash.mjs +1 -0
- package/admin-dist/server/_libs/react-day-picker.mjs +2201 -0
- package/admin-dist/server/_libs/react-remove-scroll-bar.mjs +82 -0
- package/admin-dist/server/_libs/react-remove-scroll.mjs +328 -0
- package/admin-dist/server/_libs/react-style-singleton.mjs +69 -0
- package/admin-dist/server/_libs/rou3.mjs +8 -0
- package/admin-dist/server/_libs/seroval-plugins.mjs +58 -0
- package/admin-dist/server/_libs/seroval.mjs +1765 -0
- package/admin-dist/server/_libs/srvx.mjs +719 -0
- package/admin-dist/server/_libs/tailwind-merge.mjs +3010 -0
- package/admin-dist/server/_libs/tiny-invariant.mjs +12 -0
- package/admin-dist/server/_libs/tiny-warning.mjs +5 -0
- package/admin-dist/server/_libs/tslib.mjs +39 -0
- package/admin-dist/server/_libs/ufo.mjs +54 -0
- package/admin-dist/server/_libs/unctx.mjs +1 -0
- package/admin-dist/server/_libs/unstorage.mjs +1 -0
- package/admin-dist/server/_libs/use-callback-ref.mjs +66 -0
- package/admin-dist/server/_libs/use-sidecar.mjs +106 -0
- package/admin-dist/server/_libs/use-sync-external-store.mjs +139 -0
- package/admin-dist/server/_libs/zod.mjs +4223 -0
- package/admin-dist/server/_ssr/CmsEmptyState-DU7-7-mV.mjs +290 -0
- package/admin-dist/server/_ssr/CmsPageHeader-CseW0AHm.mjs +24 -0
- package/admin-dist/server/_ssr/CmsStatusBadge-B_pi4KCp.mjs +127 -0
- package/admin-dist/server/_ssr/CmsToolbar-X75ex6ek.mjs +49 -0
- package/admin-dist/server/_ssr/ContentEntryEditor-CepusRsA.mjs +3720 -0
- package/admin-dist/server/_ssr/ErrorState-cI-bKLez.mjs +89 -0
- package/admin-dist/server/_ssr/TaxonomyFilter-Bwrq0-cz.mjs +188 -0
- package/admin-dist/server/_ssr/_contentTypeId-BqYKEcLr.mjs +379 -0
- package/admin-dist/server/_ssr/_entryId-CRfnqeDf.mjs +161 -0
- package/admin-dist/server/_ssr/_tanstack-start-manifest_v-BwDlABVk.mjs +4 -0
- package/admin-dist/server/_ssr/alert-CVt45UUP.mjs +92 -0
- package/admin-dist/server/_ssr/badge-6BsP37vG.mjs +125 -0
- package/admin-dist/server/_ssr/command-fy8epIKf.mjs +128 -0
- package/admin-dist/server/_ssr/config.server-D7JHDcDv.mjs +117 -0
- package/admin-dist/server/_ssr/content-B5RhL7uW.mjs +532 -0
- package/admin-dist/server/_ssr/content-types-BIOqCQYN.mjs +1166 -0
- package/admin-dist/server/_ssr/index-DHSHDPt1.mjs +193 -0
- package/admin-dist/server/_ssr/index.mjs +1275 -0
- package/admin-dist/server/_ssr/label-C8Dko1j7.mjs +22 -0
- package/admin-dist/server/_ssr/media-CSx3XttC.mjs +1832 -0
- package/admin-dist/server/_ssr/new._contentTypeId-DzanEZQM.mjs +144 -0
- package/admin-dist/server/_ssr/router-DDWcF-kt.mjs +1556 -0
- package/admin-dist/server/_ssr/scroll-area-bjPYwhXN.mjs +59 -0
- package/admin-dist/server/_ssr/select-BUhDDf4T.mjs +142 -0
- package/admin-dist/server/_ssr/settings-DAsxnw2q.mjs +348 -0
- package/admin-dist/server/_ssr/start-HYkvq4Ni.mjs +4 -0
- package/admin-dist/server/_ssr/switch-BgyRtQ1Z.mjs +31 -0
- package/admin-dist/server/_ssr/tabs-DzMdRB1A.mjs +628 -0
- package/admin-dist/server/_ssr/taxonomies-C8j8g5Q5.mjs +915 -0
- package/admin-dist/server/_ssr/textarea-9jNeYJSc.mjs +18 -0
- package/admin-dist/server/_ssr/trash-DYMxwhZB.mjs +291 -0
- package/admin-dist/server/_ssr/useBreadcrumbLabel-FNSAr2Ha.mjs +16 -0
- package/admin-dist/server/_ssr/usePermissions-BJGGahrJ.mjs +68 -0
- package/admin-dist/server/favicon.ico +0 -0
- package/admin-dist/server/index.mjs +627 -0
- package/dist/cli/index.js +0 -0
- package/dist/client/admin-config.d.ts +0 -1
- package/dist/client/admin-config.d.ts.map +1 -1
- package/dist/client/admin-config.js +0 -1
- package/dist/client/admin-config.js.map +1 -1
- package/dist/client/adminApi.d.ts.map +1 -1
- package/dist/client/agentTools.d.ts +1237 -135
- package/dist/client/agentTools.d.ts.map +1 -1
- package/dist/client/agentTools.js +33 -9
- package/dist/client/agentTools.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +9 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/mediaAssets.d.ts +35 -0
- package/dist/component/mediaAssets.d.ts.map +1 -1
- package/dist/component/mediaAssets.js +81 -0
- package/dist/component/mediaAssets.js.map +1 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -1
- package/dist/test.js.map +1 -1
- package/package.json +9 -5
- package/dist/component/auditLog.d.ts +0 -410
- package/dist/component/auditLog.d.ts.map +0 -1
- package/dist/component/auditLog.js +0 -607
- package/dist/component/auditLog.js.map +0 -1
- package/dist/component/types.d.ts +0 -4
- package/dist/component/types.d.ts.map +0 -1
- package/dist/component/types.js +0 -2
- package/dist/component/types.js.map +0 -1
- package/src/cli/commands/admin.ts +0 -104
- package/src/cli/index.ts +0 -21
- package/src/cli/utils/detectConvexUrl.ts +0 -54
- package/src/cli/utils/openBrowser.ts +0 -16
- package/src/client/admin-config.ts +0 -138
- package/src/client/adminApi.ts +0 -942
- package/src/client/agentTools.ts +0 -1311
- package/src/client/argTypes.ts +0 -316
- package/src/client/field-types.ts +0 -187
- package/src/client/index.ts +0 -1301
- package/src/client/queryBuilder.ts +0 -1100
- package/src/client/schema/codegen.ts +0 -500
- package/src/client/schema/defineContentType.ts +0 -501
- package/src/client/schema/index.ts +0 -169
- package/src/client/schema/schemaDrift.ts +0 -574
- package/src/client/schema/typedClient.ts +0 -688
- package/src/client/schema/types.ts +0 -666
- package/src/client/types.ts +0 -723
- package/src/client/workflows.ts +0 -141
- package/src/client/wrapper.ts +0 -4304
- package/src/component/_generated/api.ts +0 -140
- package/src/component/_generated/component.ts +0 -5029
- package/src/component/_generated/dataModel.ts +0 -60
- package/src/component/_generated/server.ts +0 -156
- package/src/component/authorization.ts +0 -647
- package/src/component/authorizationHooks.ts +0 -668
- package/src/component/bulkOperations.ts +0 -687
- package/src/component/contentEntries.ts +0 -1976
- package/src/component/contentEntryMutations.ts +0 -1223
- package/src/component/contentEntryValidation.ts +0 -707
- package/src/component/contentLock.ts +0 -550
- package/src/component/contentTypeMigration.ts +0 -1064
- package/src/component/contentTypeMutations.ts +0 -969
- package/src/component/contentTypes.ts +0 -346
- package/src/component/convex.config.ts +0 -44
- package/src/component/documentTypes.ts +0 -240
- package/src/component/eventEmitter.ts +0 -485
- package/src/component/exportImport.ts +0 -1169
- package/src/component/index.ts +0 -491
- package/src/component/lib/deepReferenceResolver.ts +0 -999
- package/src/component/lib/errors.ts +0 -816
- package/src/component/lib/index.ts +0 -145
- package/src/component/lib/mediaReferenceResolver.ts +0 -495
- package/src/component/lib/metadataExtractor.ts +0 -792
- package/src/component/lib/mutationAuth.ts +0 -199
- package/src/component/lib/queries.ts +0 -79
- package/src/component/lib/ragContentChunker.ts +0 -1371
- package/src/component/lib/referenceResolver.ts +0 -430
- package/src/component/lib/slugGenerator.ts +0 -262
- package/src/component/lib/slugUniqueness.ts +0 -333
- package/src/component/lib/softDelete.ts +0 -44
- package/src/component/localeFallbackChain.ts +0 -673
- package/src/component/localeFields.ts +0 -896
- package/src/component/mediaAssetMutations.ts +0 -725
- package/src/component/mediaAssets.ts +0 -932
- package/src/component/mediaFolderMutations.ts +0 -1046
- package/src/component/mediaUploadMutations.ts +0 -224
- package/src/component/mediaVariantMutations.ts +0 -900
- package/src/component/mediaVariants.ts +0 -793
- package/src/component/ragContentIndexer.ts +0 -1067
- package/src/component/rateLimitHooks.ts +0 -572
- package/src/component/roles.ts +0 -1360
- package/src/component/scheduledPublish.ts +0 -358
- package/src/component/schema.ts +0 -617
- package/src/component/taxonomies.ts +0 -949
- package/src/component/taxonomyMutations.ts +0 -1210
- package/src/component/trash.ts +0 -724
- package/src/component/userContext.ts +0 -898
- package/src/component/validation.ts +0 -1388
- package/src/component/validators.ts +0 -949
- package/src/component/versionMutations.ts +0 -392
- package/src/component/webhookTrigger.ts +0 -1922
- package/src/react/index.ts +0 -898
- package/src/test.ts +0 -1580
package/src/client/types.ts
DELETED
|
@@ -1,723 +0,0 @@
|
|
|
1
|
-
/** TypeScript type definitions for the Convex CMS component. */
|
|
2
|
-
|
|
3
|
-
import type { Infer } from "convex/values";
|
|
4
|
-
import type {
|
|
5
|
-
MediaVariant as MediaVariantType,
|
|
6
|
-
ContentVersion as ContentVersionType,
|
|
7
|
-
StringifyIds,
|
|
8
|
-
} from "../component/documentTypes.js";
|
|
9
|
-
import * as validators from "../component/validators.js";
|
|
10
|
-
import * as schema from "../component/schema.js";
|
|
11
|
-
import type { ContentStatus } from "../component/validators.js";
|
|
12
|
-
import type { FieldTypeDefinition } from "./field-types.js";
|
|
13
|
-
import type { WorkflowConfig } from "./workflows.js";
|
|
14
|
-
|
|
15
|
-
// --- Component Configuration ---
|
|
16
|
-
|
|
17
|
-
/** Locale code following IETF BCP 47 format */
|
|
18
|
-
export type LocaleCode = string;
|
|
19
|
-
|
|
20
|
-
/** Feature flags for enabling/disabling CMS capabilities */
|
|
21
|
-
export interface FeatureFlags {
|
|
22
|
-
/** @default true */
|
|
23
|
-
versioning?: boolean;
|
|
24
|
-
/** @default true */
|
|
25
|
-
scheduling?: boolean;
|
|
26
|
-
/** @default false */
|
|
27
|
-
localization?: boolean;
|
|
28
|
-
/** @default true */
|
|
29
|
-
mediaManagement?: boolean;
|
|
30
|
-
/** @default true */
|
|
31
|
-
contentLocking?: boolean;
|
|
32
|
-
/** @default true - when disabled, deletions are permanent */
|
|
33
|
-
softDelete?: boolean;
|
|
34
|
-
/** @default true */
|
|
35
|
-
searchIndexing?: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// --- Convex Context Types ---
|
|
39
|
-
|
|
40
|
-
import type { GenericMutationCtx, GenericDataModel } from "convex/server";
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Convex context for CMS authorization hooks (Pick pattern per Convex docs).
|
|
44
|
-
* Cast to your app's MutationCtx in hook implementations for full type safety.
|
|
45
|
-
*/
|
|
46
|
-
export type CmsHookContext = Pick<
|
|
47
|
-
GenericMutationCtx<GenericDataModel>,
|
|
48
|
-
"db" | "auth" | "runMutation" | "runQuery"
|
|
49
|
-
>;
|
|
50
|
-
|
|
51
|
-
// --- User Role Hook Types ---
|
|
52
|
-
|
|
53
|
-
export interface GetUserRoleContext {
|
|
54
|
-
userId: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// --- Authorization Hook Types ---
|
|
58
|
-
|
|
59
|
-
export type CmsOperation =
|
|
60
|
-
| "contentTypes.create" | "contentTypes.update" | "contentTypes.delete" | "contentTypes.read"
|
|
61
|
-
| "contentEntries.create" | "contentEntries.update" | "contentEntries.delete" | "contentEntries.read"
|
|
62
|
-
| "contentEntries.publish" | "contentEntries.unpublish" | "contentEntries.restore" | "contentEntries.schedule"
|
|
63
|
-
| "mediaItems.create" | "mediaItems.update" | "mediaItems.delete" | "mediaItems.read" | "mediaItems.move"
|
|
64
|
-
| "versions.read" | "versions.rollback";
|
|
65
|
-
|
|
66
|
-
/** Context passed to authorization hooks */
|
|
67
|
-
export interface AuthorizationHookContext {
|
|
68
|
-
/** Convex context for database/auth access */
|
|
69
|
-
ctx: CmsHookContext;
|
|
70
|
-
operation: CmsOperation;
|
|
71
|
-
userId?: string;
|
|
72
|
-
role?: string | null;
|
|
73
|
-
resourceId?: string;
|
|
74
|
-
resourceOwnerId?: string;
|
|
75
|
-
contentTypeId?: string;
|
|
76
|
-
contentTypeName?: string;
|
|
77
|
-
operationData?: Record<string, unknown>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export interface AuthorizationHookResult {
|
|
81
|
-
allowed: boolean;
|
|
82
|
-
reason?: string;
|
|
83
|
-
/** Modified data to use instead of original (allows hooks to transform input) */
|
|
84
|
-
modifiedData?: Record<string, unknown>;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** Extends AuthorizationHookContext with the default RBAC decision */
|
|
88
|
-
export interface AuthorizeHookContext extends AuthorizationHookContext {
|
|
89
|
-
defaultDecision: {
|
|
90
|
-
allowed: boolean;
|
|
91
|
-
reason?: string;
|
|
92
|
-
/** Possible: 'NO_ROLE', 'UNKNOWN_ROLE', 'PERMISSION_DENIED', 'OWNERSHIP_REQUIRED' */
|
|
93
|
-
code?: string;
|
|
94
|
-
grantedScope?: "all" | "own";
|
|
95
|
-
ownershipVerified?: boolean;
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Hook called AFTER RBAC check. Can override RBAC decisions based on custom logic.
|
|
101
|
-
* Receives context.defaultDecision showing what RBAC decided.
|
|
102
|
-
*/
|
|
103
|
-
export type AuthorizeHook = (
|
|
104
|
-
context: AuthorizeHookContext
|
|
105
|
-
) => Promise<AuthorizationHookResult> | AuthorizationHookResult;
|
|
106
|
-
|
|
107
|
-
/** Hook for custom permission logic beyond built-in RBAC */
|
|
108
|
-
export type AuthorizationHook = (
|
|
109
|
-
context: AuthorizationHookContext
|
|
110
|
-
) => Promise<AuthorizationHookResult> | AuthorizationHookResult;
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Authorization hooks configuration.
|
|
114
|
-
*
|
|
115
|
-
* Hook execution order:
|
|
116
|
-
* 1. beforeRbac (can skip RBAC)
|
|
117
|
-
* 2. RBAC check (if not skipped)
|
|
118
|
-
* 3. authorize (receives RBAC decision, can override)
|
|
119
|
-
* 4. afterRbac (only if authorize allowed)
|
|
120
|
-
* 5. operationHooks (only if afterRbac allowed)
|
|
121
|
-
* 6. onDeny (if any step denied)
|
|
122
|
-
*/
|
|
123
|
-
export interface AuthorizationHooks {
|
|
124
|
-
/** Runs before RBAC. Return {allowed: false} for early rejection, or {allowed: true, skipRbac: true} to bypass RBAC */
|
|
125
|
-
beforeRbac?: AuthorizationHook;
|
|
126
|
-
/** Runs after RBAC passes. Add restrictions (team membership, quotas, etc.) */
|
|
127
|
-
afterRbac?: AuthorizationHook;
|
|
128
|
-
/** Runs after RBAC regardless of outcome. Can override RBAC decisions. */
|
|
129
|
-
authorize?: AuthorizeHook;
|
|
130
|
-
/** Runs when authorization denied. Return {allowed: true} to override denial */
|
|
131
|
-
onDeny?: AuthorizationHook;
|
|
132
|
-
/** Operation-specific hooks run after general hooks */
|
|
133
|
-
operationHooks?: Partial<Record<CmsOperation, AuthorizationHook>>;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// --- Rate Limiting Hook Types ---
|
|
137
|
-
|
|
138
|
-
export type OperationCategory = "read" | "write" | "publish" | "media" | "admin";
|
|
139
|
-
|
|
140
|
-
export interface RateLimitHookContext {
|
|
141
|
-
operation: CmsOperation;
|
|
142
|
-
operationCategory: OperationCategory;
|
|
143
|
-
userId?: string;
|
|
144
|
-
role?: string | null;
|
|
145
|
-
contentTypeId?: string;
|
|
146
|
-
contentTypeName?: string;
|
|
147
|
-
/** Additional metadata (IP address, session ID, API key, user tier, etc.) */
|
|
148
|
-
metadata?: Record<string, unknown>;
|
|
149
|
-
timestamp: number;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface RateLimitCheckResult {
|
|
153
|
-
allowed: boolean;
|
|
154
|
-
retryAt?: number;
|
|
155
|
-
reason?: string;
|
|
156
|
-
rateLimitInfo?: {
|
|
157
|
-
limitName?: string;
|
|
158
|
-
remaining?: number;
|
|
159
|
-
limit?: number;
|
|
160
|
-
windowMs?: number;
|
|
161
|
-
isSoftLimit?: boolean;
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface RateLimitConsumeResult extends RateLimitCheckResult {
|
|
166
|
-
consumed: boolean;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** Called BEFORE operation to check rate limit (should NOT modify state) */
|
|
170
|
-
export type RateLimitCheckHook = (
|
|
171
|
-
context: RateLimitHookContext
|
|
172
|
-
) => Promise<RateLimitCheckResult> | RateLimitCheckResult;
|
|
173
|
-
|
|
174
|
-
/** Called AFTER check passes to record usage */
|
|
175
|
-
export type RateLimitConsumeHook = (
|
|
176
|
-
context: RateLimitHookContext
|
|
177
|
-
) => Promise<RateLimitConsumeResult> | RateLimitConsumeResult;
|
|
178
|
-
|
|
179
|
-
/** Dynamic rate limit configuration based on user tier, operation, etc. */
|
|
180
|
-
export type RateLimitConfigHook = (
|
|
181
|
-
context: RateLimitHookContext
|
|
182
|
-
) => Promise<RateLimitConfigResult> | RateLimitConfigResult;
|
|
183
|
-
|
|
184
|
-
export interface RateLimitConfigResult {
|
|
185
|
-
enabled: boolean;
|
|
186
|
-
config?: {
|
|
187
|
-
rate: number;
|
|
188
|
-
period: number;
|
|
189
|
-
capacity?: number;
|
|
190
|
-
maxReserved?: number;
|
|
191
|
-
};
|
|
192
|
-
key?: string;
|
|
193
|
-
cost?: number;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Rate limiting hooks configuration.
|
|
198
|
-
* Hook order: getConfig → check → consume (if check passed)
|
|
199
|
-
*/
|
|
200
|
-
export interface RateLimitHooks {
|
|
201
|
-
check?: RateLimitCheckHook;
|
|
202
|
-
consume?: RateLimitConsumeHook;
|
|
203
|
-
getConfig?: RateLimitConfigHook;
|
|
204
|
-
/** @default false */
|
|
205
|
-
skipForAdmin?: boolean;
|
|
206
|
-
excludeOperations?: CmsOperation[];
|
|
207
|
-
excludeCategories?: OperationCategory[];
|
|
208
|
-
/** Override global hooks for specific operations */
|
|
209
|
-
operationHooks?: Partial<
|
|
210
|
-
Record<CmsOperation, {
|
|
211
|
-
check?: RateLimitCheckHook;
|
|
212
|
-
consume?: RateLimitConsumeHook;
|
|
213
|
-
getConfig?: RateLimitConfigHook;
|
|
214
|
-
}>
|
|
215
|
-
>;
|
|
216
|
-
onRateLimited?: (context: RateLimitHookContext, result: RateLimitCheckResult) => void | Promise<void>;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export type GetUserRoleResult = string | null;
|
|
220
|
-
|
|
221
|
-
/** Maps user IDs to CMS roles ('admin', 'editor', 'author', 'viewer', or custom) */
|
|
222
|
-
export type GetUserRoleHook = (
|
|
223
|
-
ctx: CmsHookContext,
|
|
224
|
-
context: GetUserRoleContext
|
|
225
|
-
) => Promise<GetUserRoleResult> | GetUserRoleResult;
|
|
226
|
-
|
|
227
|
-
// --- Configuration Types ---
|
|
228
|
-
|
|
229
|
-
/** Minimal CMS configuration - just provide getUserRole hook */
|
|
230
|
-
export interface CmsConfig {
|
|
231
|
-
getUserRole: GetUserRoleHook;
|
|
232
|
-
/** @default "en" */
|
|
233
|
-
defaultLocale?: LocaleCode;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** CMS configuration with feature flags */
|
|
237
|
-
export interface CmsConfigWithFeatures extends CmsConfig {
|
|
238
|
-
features?: FeatureFlags;
|
|
239
|
-
supportedLocales?: LocaleCode[];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/** Full CMS configuration with hooks, custom roles, and advanced options */
|
|
243
|
-
export interface FullCmsConfig extends CmsConfigWithFeatures {
|
|
244
|
-
authorizationHooks?: AuthorizationHooks;
|
|
245
|
-
rateLimitHooks?: RateLimitHooks;
|
|
246
|
-
customRoles?: Array<CustomRoleInput>;
|
|
247
|
-
/** @default false */
|
|
248
|
-
skipRbac?: boolean;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/** Development-only config - WARNING: Never use in production! */
|
|
252
|
-
export interface CmsDevConfig {
|
|
253
|
-
/** Bypasses all authorization - only for local development */
|
|
254
|
-
permissiveMode: true;
|
|
255
|
-
/** @default "en" */
|
|
256
|
-
defaultLocale?: LocaleCode;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export type SimplifiedCmsConfig =
|
|
260
|
-
| CmsConfig
|
|
261
|
-
| CmsConfigWithFeatures
|
|
262
|
-
| FullCmsConfig
|
|
263
|
-
| CmsDevConfig;
|
|
264
|
-
|
|
265
|
-
/** Full CMS component configuration. For simpler setups, use CmsConfig or CmsConfigWithFeatures. */
|
|
266
|
-
export interface ComponentConfig {
|
|
267
|
-
/** @default "en" */
|
|
268
|
-
defaultLocale?: LocaleCode;
|
|
269
|
-
/** @default ["en"] */
|
|
270
|
-
supportedLocales?: LocaleCode[];
|
|
271
|
-
/** Locale fallback chains (e.g., "es-MX": ["es-ES", "en-US"]) */
|
|
272
|
-
localeFallbackChains?: Record<LocaleCode, LocaleCode[]>;
|
|
273
|
-
/** Auto-generate fallback chains from BCP 47 hierarchy. @default true */
|
|
274
|
-
autoGenerateLocaleFallbacks?: boolean;
|
|
275
|
-
features?: FeatureFlags;
|
|
276
|
-
/** @default 50 (0 for unlimited) */
|
|
277
|
-
maxVersionsPerEntry?: number;
|
|
278
|
-
/** @default 300000 (5 minutes) */
|
|
279
|
-
lockDurationMs?: number;
|
|
280
|
-
/** @default 52428800 (50MB) */
|
|
281
|
-
maxMediaFileSize?: number;
|
|
282
|
-
getUserRole?: GetUserRoleHook;
|
|
283
|
-
authorizationHooks?: AuthorizationHooks;
|
|
284
|
-
rateLimitHooks?: RateLimitHooks;
|
|
285
|
-
/** Skip built-in RBAC (use authorizationHooks instead). @default false */
|
|
286
|
-
skipRbac?: boolean;
|
|
287
|
-
/** WARNING: Never enable in production! @default false */
|
|
288
|
-
permissiveMode?: boolean;
|
|
289
|
-
/** Validate hooks at init time instead of runtime */
|
|
290
|
-
requireHooks?: Array<"getUserRole" | "authorizationHooks" | "rateLimitHooks">;
|
|
291
|
-
customRoles?: Array<CustomRoleInput>;
|
|
292
|
-
/** Content type schema for type-safe access */
|
|
293
|
-
schema?: ContentSchemaConfig;
|
|
294
|
-
/** Custom field type definitions (extends built-in types) */
|
|
295
|
-
fieldTypes?: FieldTypeDefinition[];
|
|
296
|
-
/** Custom workflow configuration (replaces default draft/published/archived/scheduled) */
|
|
297
|
-
workflow?: WorkflowConfig;
|
|
298
|
-
/** Per-content-type workflow overrides */
|
|
299
|
-
contentTypeWorkflows?: Record<string, WorkflowConfig>;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
export type ContentSchemaConfig = {
|
|
303
|
-
definitions: Record<string, ContentTypeDefinitionBase>;
|
|
304
|
-
getDefinition(name: string): ContentTypeDefinitionBase | undefined;
|
|
305
|
-
getContentTypeNames(): string[];
|
|
306
|
-
hasContentType(name: string): boolean;
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
export interface ContentTypeDefinitionBase {
|
|
310
|
-
readonly name: string;
|
|
311
|
-
readonly validator: unknown;
|
|
312
|
-
readonly meta: {
|
|
313
|
-
displayName: string;
|
|
314
|
-
description?: string;
|
|
315
|
-
titleField?: string;
|
|
316
|
-
slugField?: string;
|
|
317
|
-
singleton?: boolean;
|
|
318
|
-
};
|
|
319
|
-
readonly _type: "content_type_definition";
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
export interface CustomRoleInput {
|
|
323
|
-
name: string;
|
|
324
|
-
displayName: string;
|
|
325
|
-
description: string;
|
|
326
|
-
permissions: CustomPermission[];
|
|
327
|
-
isSystem?: boolean;
|
|
328
|
-
extendsRole?: string;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export interface CustomRoleDefinition {
|
|
332
|
-
name: string;
|
|
333
|
-
displayName: string;
|
|
334
|
-
description: string;
|
|
335
|
-
permissions: CustomPermission[];
|
|
336
|
-
isSystem: boolean;
|
|
337
|
-
extendsRole?: string;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
export interface CustomPermission {
|
|
341
|
-
resource: "contentTypes" | "contentEntries" | "mediaItems" | "settings";
|
|
342
|
-
action: "create" | "read" | "update" | "delete" | "publish" | "unpublish" | "restore" | "manage" | "move";
|
|
343
|
-
scope?: "all" | "own";
|
|
344
|
-
contentTypes?: string[];
|
|
345
|
-
excludeContentTypes?: string[];
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/** Configuration with all defaults applied */
|
|
349
|
-
export type ResolvedComponentConfig = Required<Omit<ComponentConfig, "getUserRole" | "authorizationHooks" | "rateLimitHooks" | "localeFallbackChains" | "customRoles" | "requireHooks" | "schema" | "fieldTypes" | "workflow" | "contentTypeWorkflows">> & {
|
|
350
|
-
getUserRole?: GetUserRoleHook;
|
|
351
|
-
authorizationHooks?: AuthorizationHooks;
|
|
352
|
-
rateLimitHooks?: RateLimitHooks;
|
|
353
|
-
localeFallbackChains: Record<LocaleCode, LocaleCode[]>;
|
|
354
|
-
customRoles: Record<string, CustomRoleDefinition>;
|
|
355
|
-
requireHooks: Array<"getUserRole" | "authorizationHooks" | "rateLimitHooks">;
|
|
356
|
-
schema?: ContentSchemaConfig;
|
|
357
|
-
fieldTypes?: FieldTypeDefinition[];
|
|
358
|
-
workflow?: WorkflowConfig;
|
|
359
|
-
contentTypeWorkflows?: Record<string, WorkflowConfig>;
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
export const DEFAULT_CONFIG: Omit<ResolvedComponentConfig, "getUserRole" | "authorizationHooks" | "rateLimitHooks"> = {
|
|
363
|
-
defaultLocale: "en",
|
|
364
|
-
supportedLocales: ["en"],
|
|
365
|
-
localeFallbackChains: {},
|
|
366
|
-
autoGenerateLocaleFallbacks: true,
|
|
367
|
-
features: {
|
|
368
|
-
versioning: true,
|
|
369
|
-
scheduling: true,
|
|
370
|
-
localization: false,
|
|
371
|
-
mediaManagement: true,
|
|
372
|
-
contentLocking: true,
|
|
373
|
-
softDelete: true,
|
|
374
|
-
searchIndexing: true,
|
|
375
|
-
},
|
|
376
|
-
maxVersionsPerEntry: 50,
|
|
377
|
-
lockDurationMs: 300000, // 5 minutes
|
|
378
|
-
maxMediaFileSize: 52428800, // 50MB
|
|
379
|
-
skipRbac: false,
|
|
380
|
-
permissiveMode: false,
|
|
381
|
-
customRoles: {},
|
|
382
|
-
requireHooks: [],
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
export type RequiredHookName = "getUserRole" | "authorizationHooks" | "rateLimitHooks";
|
|
386
|
-
|
|
387
|
-
/** Thrown when requireHooks validation fails at init time */
|
|
388
|
-
export class MissingHookError extends Error {
|
|
389
|
-
readonly hookName: RequiredHookName;
|
|
390
|
-
readonly suggestion: string;
|
|
391
|
-
readonly affectedMethods: string[];
|
|
392
|
-
|
|
393
|
-
constructor(hookName: RequiredHookName) {
|
|
394
|
-
const hookInfo = HOOK_INFO[hookName];
|
|
395
|
-
super(`Missing required hook: ${hookName}. ${hookInfo.suggestion}`);
|
|
396
|
-
this.name = "MissingHookError";
|
|
397
|
-
this.hookName = hookName;
|
|
398
|
-
this.suggestion = hookInfo.suggestion;
|
|
399
|
-
this.affectedMethods = hookInfo.affectedMethods;
|
|
400
|
-
Object.setPrototypeOf(this, MissingHookError.prototype);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/** Thrown when mutation attempted without getUserRole configured (and not in permissiveMode) */
|
|
405
|
-
export class AuthorizationNotConfiguredError extends Error {
|
|
406
|
-
readonly operation: string;
|
|
407
|
-
readonly suggestion: string;
|
|
408
|
-
|
|
409
|
-
constructor(operation: string) {
|
|
410
|
-
super(
|
|
411
|
-
`Authorization not configured for operation "${operation}". ` +
|
|
412
|
-
"Configure a getUserRole hook in createCmsClient options, or set permissiveMode: true for development."
|
|
413
|
-
);
|
|
414
|
-
this.name = "AuthorizationNotConfiguredError";
|
|
415
|
-
this.operation = operation;
|
|
416
|
-
this.suggestion =
|
|
417
|
-
"Add getUserRole hook: createCmsClient(api, { getUserRole: async (ctx, { userId }) => getUserRoleFromDb(userId) })";
|
|
418
|
-
Object.setPrototypeOf(this, AuthorizationNotConfiguredError.prototype);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const HOOK_INFO: Record<RequiredHookName, { suggestion: string; affectedMethods: string[] }> = {
|
|
423
|
-
getUserRole: {
|
|
424
|
-
suggestion: "Configure a getUserRole function in createCmsClient options to map user IDs to CMS roles.",
|
|
425
|
-
affectedMethods: [
|
|
426
|
-
"getUserRole()",
|
|
427
|
-
"hasPermissionForUser()",
|
|
428
|
-
"hasContentTypePermissionForUser()",
|
|
429
|
-
"getPermittedContentTypesForUser()",
|
|
430
|
-
"canUserPerformOnResource()",
|
|
431
|
-
"requireUserCanPerformOnResource()",
|
|
432
|
-
],
|
|
433
|
-
},
|
|
434
|
-
authorizationHooks: {
|
|
435
|
-
suggestion: "Configure authorizationHooks in createCmsClient options (beforeRbac, afterRbac, authorize, onDeny, or operationHooks).",
|
|
436
|
-
affectedMethods: [
|
|
437
|
-
"authorize()",
|
|
438
|
-
"requireAuthorization()",
|
|
439
|
-
],
|
|
440
|
-
},
|
|
441
|
-
rateLimitHooks: {
|
|
442
|
-
suggestion: "Configure rateLimitHooks.check in createCmsClient options to implement rate limiting.",
|
|
443
|
-
affectedMethods: [
|
|
444
|
-
"Rate-limited CMS operations",
|
|
445
|
-
],
|
|
446
|
-
},
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
/** @throws MissingHookError if a required hook is not configured */
|
|
450
|
-
export function validateRequiredHooks(config?: ComponentConfig): void {
|
|
451
|
-
const requireHooks = config?.requireHooks ?? [];
|
|
452
|
-
|
|
453
|
-
for (const hookName of requireHooks) {
|
|
454
|
-
switch (hookName) {
|
|
455
|
-
case "getUserRole":
|
|
456
|
-
if (!config?.getUserRole) {
|
|
457
|
-
throw new MissingHookError("getUserRole");
|
|
458
|
-
}
|
|
459
|
-
break;
|
|
460
|
-
|
|
461
|
-
case "authorizationHooks": {
|
|
462
|
-
if (!config?.authorizationHooks) {
|
|
463
|
-
throw new MissingHookError("authorizationHooks");
|
|
464
|
-
}
|
|
465
|
-
// Check that at least one hook is configured
|
|
466
|
-
const hooks = config.authorizationHooks;
|
|
467
|
-
const hasHook = !!(
|
|
468
|
-
hooks.beforeRbac ||
|
|
469
|
-
hooks.afterRbac ||
|
|
470
|
-
hooks.authorize ||
|
|
471
|
-
hooks.onDeny ||
|
|
472
|
-
(hooks.operationHooks && Object.keys(hooks.operationHooks).length > 0)
|
|
473
|
-
);
|
|
474
|
-
if (!hasHook) {
|
|
475
|
-
throw new MissingHookError("authorizationHooks");
|
|
476
|
-
}
|
|
477
|
-
break;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
case "rateLimitHooks":
|
|
481
|
-
if (!config?.rateLimitHooks?.check) {
|
|
482
|
-
throw new MissingHookError("rateLimitHooks");
|
|
483
|
-
}
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
export function resolveConfig(config?: ComponentConfig): ResolvedComponentConfig {
|
|
490
|
-
// Build custom roles record from array, ensuring isSystem defaults to false
|
|
491
|
-
const customRolesRecord: Record<string, CustomRoleDefinition> = {};
|
|
492
|
-
if (config?.customRoles) {
|
|
493
|
-
for (const role of config.customRoles) {
|
|
494
|
-
customRolesRecord[role.name] = {
|
|
495
|
-
...role,
|
|
496
|
-
isSystem: role.isSystem ?? false, // Default isSystem to false
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return {
|
|
502
|
-
defaultLocale: config?.defaultLocale ?? DEFAULT_CONFIG.defaultLocale,
|
|
503
|
-
supportedLocales: config?.supportedLocales ?? DEFAULT_CONFIG.supportedLocales,
|
|
504
|
-
localeFallbackChains: config?.localeFallbackChains ?? DEFAULT_CONFIG.localeFallbackChains,
|
|
505
|
-
autoGenerateLocaleFallbacks: config?.autoGenerateLocaleFallbacks ?? DEFAULT_CONFIG.autoGenerateLocaleFallbacks,
|
|
506
|
-
features: {
|
|
507
|
-
...DEFAULT_CONFIG.features,
|
|
508
|
-
...config?.features,
|
|
509
|
-
},
|
|
510
|
-
maxVersionsPerEntry: config?.maxVersionsPerEntry ?? DEFAULT_CONFIG.maxVersionsPerEntry,
|
|
511
|
-
lockDurationMs: config?.lockDurationMs ?? DEFAULT_CONFIG.lockDurationMs,
|
|
512
|
-
maxMediaFileSize: config?.maxMediaFileSize ?? DEFAULT_CONFIG.maxMediaFileSize,
|
|
513
|
-
skipRbac: config?.skipRbac ?? DEFAULT_CONFIG.skipRbac,
|
|
514
|
-
permissiveMode: config?.permissiveMode ?? DEFAULT_CONFIG.permissiveMode,
|
|
515
|
-
getUserRole: config?.getUserRole,
|
|
516
|
-
authorizationHooks: config?.authorizationHooks,
|
|
517
|
-
rateLimitHooks: config?.rateLimitHooks,
|
|
518
|
-
customRoles: customRolesRecord,
|
|
519
|
-
requireHooks: config?.requireHooks ?? DEFAULT_CONFIG.requireHooks,
|
|
520
|
-
schema: config?.schema,
|
|
521
|
-
fieldTypes: config?.fieldTypes,
|
|
522
|
-
workflow: config?.workflow,
|
|
523
|
-
contentTypeWorkflows: config?.contentTypeWorkflows,
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// --- Field Types ---
|
|
528
|
-
|
|
529
|
-
export type { FieldType } from "../component/validators.js";
|
|
530
|
-
|
|
531
|
-
export type FieldOptions = StringifyIds<
|
|
532
|
-
| Infer<typeof schema.textFieldDefinitionValidator>["options"]
|
|
533
|
-
| Infer<typeof schema.numberFieldDefinitionValidator>["options"]
|
|
534
|
-
| Infer<typeof schema.booleanFieldDefinitionValidator>["options"]
|
|
535
|
-
| Infer<typeof schema.richTextFieldDefinitionValidator>["options"]
|
|
536
|
-
| Infer<typeof schema.mediaFieldDefinitionValidator>["options"]
|
|
537
|
-
| Infer<typeof schema.selectFieldDefinitionValidator>["options"]
|
|
538
|
-
| Infer<typeof schema.tagsFieldDefinitionValidator>["options"]
|
|
539
|
-
| Infer<typeof schema.categoryFieldDefinitionValidator>["options"]
|
|
540
|
-
| Infer<typeof schema.jsonFieldDefinitionValidator>["options"]
|
|
541
|
-
| Infer<typeof schema.referenceFieldDefinitionValidator>["options"]
|
|
542
|
-
| Infer<typeof schema.multiSelectFieldDefinitionValidator>["options"]
|
|
543
|
-
| Infer<typeof schema.dateFieldDefinitionValidator>["options"]
|
|
544
|
-
| Infer<typeof schema.datetimeFieldDefinitionValidator>["options"]
|
|
545
|
-
>;
|
|
546
|
-
|
|
547
|
-
// --- Sort Types ---
|
|
548
|
-
|
|
549
|
-
export type SortDirection = "asc" | "desc";
|
|
550
|
-
|
|
551
|
-
export type SystemSortField =
|
|
552
|
-
| "_creationTime" | "_id" | "firstPublishedAt" | "lastPublishedAt" | "scheduledPublishAt" | "version";
|
|
553
|
-
|
|
554
|
-
/** System field or custom data field (prefix with "data.") */
|
|
555
|
-
export type SortField = SystemSortField | `data.${string}` | string;
|
|
556
|
-
|
|
557
|
-
export interface SortOptions {
|
|
558
|
-
sortField: SortField;
|
|
559
|
-
sortDirection: SortDirection;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// --- Field Filter Types ---
|
|
563
|
-
|
|
564
|
-
export type FilterOperator =
|
|
565
|
-
| "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "contains" | "startsWith" | "endsWith" | "in" | "notIn";
|
|
566
|
-
|
|
567
|
-
export interface FieldFilter {
|
|
568
|
-
field: string;
|
|
569
|
-
operator: FilterOperator;
|
|
570
|
-
value: unknown;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// --- Reference Field Types ---
|
|
574
|
-
|
|
575
|
-
export type SingleReference = string;
|
|
576
|
-
export type MultipleReferences = string[];
|
|
577
|
-
export type ReferenceValue = SingleReference | MultipleReferences;
|
|
578
|
-
|
|
579
|
-
export interface ResolvedReference {
|
|
580
|
-
id: string;
|
|
581
|
-
contentTypeName: string;
|
|
582
|
-
contentTypeDisplayName: string;
|
|
583
|
-
slug: string;
|
|
584
|
-
status: ContentStatus;
|
|
585
|
-
data: Record<string, unknown>;
|
|
586
|
-
exists: boolean;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// --- Deep Reference Resolution Types ---
|
|
590
|
-
|
|
591
|
-
export interface DeepResolveOptions {
|
|
592
|
-
/** @default 1 (0=no resolve, 1=immediate refs, 2+=nested) */
|
|
593
|
-
maxDepth?: number;
|
|
594
|
-
/** @default true */
|
|
595
|
-
resolveMedia?: boolean;
|
|
596
|
-
/** @default true */
|
|
597
|
-
resolveContent?: boolean;
|
|
598
|
-
/** @default false */
|
|
599
|
-
publishedOnly?: boolean;
|
|
600
|
-
/** @default false */
|
|
601
|
-
includeDeleted?: boolean;
|
|
602
|
-
fields?: string[];
|
|
603
|
-
onlyFields?: string[];
|
|
604
|
-
excludeFields?: string[];
|
|
605
|
-
/** @default false - adds _originalId field when true */
|
|
606
|
-
preserveOriginalIds?: boolean;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
export interface ResolvedContentEntry {
|
|
610
|
-
id: string;
|
|
611
|
-
contentTypeName: string;
|
|
612
|
-
contentTypeDisplayName: string;
|
|
613
|
-
slug: string;
|
|
614
|
-
status: ContentStatus;
|
|
615
|
-
data: Record<string, unknown>;
|
|
616
|
-
exists: boolean;
|
|
617
|
-
locale?: string;
|
|
618
|
-
version?: number;
|
|
619
|
-
_circularReferences?: string[];
|
|
620
|
-
_unresolvedReferences?: Record<string, string[]>;
|
|
621
|
-
_originalId?: string;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
export interface BatchResolveResult {
|
|
625
|
-
resolved: ResolvedContentEntry[];
|
|
626
|
-
unresolved: string[];
|
|
627
|
-
circularReferencesDetected: number;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
export type { FieldDefinition } from "../component/documentTypes.js";
|
|
631
|
-
|
|
632
|
-
// --- Content Status ---
|
|
633
|
-
|
|
634
|
-
export type { ContentStatus } from "../component/validators.js";
|
|
635
|
-
|
|
636
|
-
// --- Media Types ---
|
|
637
|
-
|
|
638
|
-
export type { MediaType, VariantType, VariantStatus } from "../component/validators.js";
|
|
639
|
-
export type MediaVariant = MediaVariantType;
|
|
640
|
-
export type MediaVariantWithUrl = MediaVariant & { url: string | null };
|
|
641
|
-
|
|
642
|
-
// --- Document Types ---
|
|
643
|
-
|
|
644
|
-
export type {
|
|
645
|
-
ContentType,
|
|
646
|
-
ContentEntry,
|
|
647
|
-
ContentVersion,
|
|
648
|
-
MediaAsset,
|
|
649
|
-
MediaFolder,
|
|
650
|
-
MediaVariant as MediaVariantDoc,
|
|
651
|
-
Taxonomy,
|
|
652
|
-
TaxonomyTerm,
|
|
653
|
-
} from "../component/documentTypes.js";
|
|
654
|
-
|
|
655
|
-
// --- Version Comparison Types ---
|
|
656
|
-
|
|
657
|
-
export type FieldChangeType = "added" | "removed" | "modified" | "unchanged";
|
|
658
|
-
|
|
659
|
-
export interface FieldChange {
|
|
660
|
-
field: string;
|
|
661
|
-
changeType: FieldChangeType;
|
|
662
|
-
oldValue?: unknown;
|
|
663
|
-
newValue?: unknown;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
export interface VersionComparison {
|
|
667
|
-
fromVersion: ContentVersionType;
|
|
668
|
-
toVersion: ContentVersionType;
|
|
669
|
-
changes: FieldChange[];
|
|
670
|
-
slugChanged: boolean;
|
|
671
|
-
statusChanged: boolean;
|
|
672
|
-
summary: {
|
|
673
|
-
fieldsAdded: number;
|
|
674
|
-
fieldsRemoved: number;
|
|
675
|
-
fieldsModified: number;
|
|
676
|
-
totalChanges: number;
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
export interface VersionHistoryOptions {
|
|
681
|
-
entryId: string;
|
|
682
|
-
publishedOnly?: boolean;
|
|
683
|
-
paginationOpts: PaginationOpts;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// --- Pagination ---
|
|
687
|
-
|
|
688
|
-
/** Standard Convex pagination result (compatible with usePaginatedQuery) */
|
|
689
|
-
export interface PaginationResult<T> {
|
|
690
|
-
page: T[];
|
|
691
|
-
continueCursor: string | null;
|
|
692
|
-
isDone: boolean;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
export interface PaginationOpts {
|
|
696
|
-
numItems: number;
|
|
697
|
-
/** Pass null for first page */
|
|
698
|
-
cursor: string | null;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// --- Query Options ---
|
|
702
|
-
|
|
703
|
-
type ContentQueryArgsBase = StringifyIds<Infer<typeof validators.contentQueryArgs>>;
|
|
704
|
-
|
|
705
|
-
/** Options for querying content entries with pagination */
|
|
706
|
-
export interface ContentQueryOptions extends Omit<ContentQueryArgsBase, 'cursor' | 'limit'> {
|
|
707
|
-
fieldFilters?: FieldFilter[];
|
|
708
|
-
sortField?: SortField;
|
|
709
|
-
sortDirection?: SortDirection;
|
|
710
|
-
paginationOpts: PaginationOpts;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
export type MediaQueryOptions = StringifyIds<Infer<typeof validators.mediaQueryArgs>>;
|
|
714
|
-
|
|
715
|
-
// --- Component API Types ---
|
|
716
|
-
|
|
717
|
-
export interface ComponentApi {
|
|
718
|
-
contentTypes: { create: unknown; update: unknown; delete: unknown; get: unknown; list: unknown };
|
|
719
|
-
contentEntries: { create: unknown; update: unknown; delete: unknown; get: unknown; list: unknown; publish: unknown; unpublish: unknown; schedule: unknown };
|
|
720
|
-
versions: { list: unknown; get: unknown; rollback: unknown };
|
|
721
|
-
mediaItems: { create: unknown; update: unknown; delete: unknown; get: unknown; list: unknown; move: unknown };
|
|
722
|
-
}
|
|
723
|
-
|