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
|
@@ -1,816 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Centralized Error Handling Module
|
|
3
|
-
*
|
|
4
|
-
* Provides structured error codes, error classes, and helper functions
|
|
5
|
-
* for consistent error handling across all mutation files.
|
|
6
|
-
*
|
|
7
|
-
* Error Format:
|
|
8
|
-
* - code: Machine-readable error code (e.g., "CONTENT_TYPE_NOT_FOUND")
|
|
9
|
-
* - category: Error category for routing (e.g., "NOT_FOUND", "DELETED")
|
|
10
|
-
* - message: Human-readable description
|
|
11
|
-
* - context: Additional data for debugging (resource IDs, states, etc.)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// =============================================================================
|
|
15
|
-
// Error Categories
|
|
16
|
-
// =============================================================================
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* High-level error categories for routing and handling.
|
|
20
|
-
*/
|
|
21
|
-
export type ErrorCategory =
|
|
22
|
-
| "NOT_FOUND"
|
|
23
|
-
| "DELETED"
|
|
24
|
-
| "INACTIVE"
|
|
25
|
-
| "STATE_CONFLICT"
|
|
26
|
-
| "VALIDATION"
|
|
27
|
-
| "PERMISSION"
|
|
28
|
-
| "LOCK_CONFLICT"
|
|
29
|
-
| "REFERENCE_CONFLICT"
|
|
30
|
-
| "LIMIT_EXCEEDED"
|
|
31
|
-
| "INTERNAL";
|
|
32
|
-
|
|
33
|
-
// =============================================================================
|
|
34
|
-
// Error Codes
|
|
35
|
-
// =============================================================================
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Content Type Error Codes
|
|
39
|
-
*/
|
|
40
|
-
export const ContentTypeErrorCodes = {
|
|
41
|
-
NOT_FOUND: "CONTENT_TYPE_NOT_FOUND",
|
|
42
|
-
DELETED: "CONTENT_TYPE_DELETED",
|
|
43
|
-
INACTIVE: "CONTENT_TYPE_INACTIVE",
|
|
44
|
-
NAME_INVALID: "CONTENT_TYPE_NAME_INVALID",
|
|
45
|
-
NAME_DUPLICATE: "CONTENT_TYPE_NAME_DUPLICATE",
|
|
46
|
-
FIELD_VALIDATION_FAILED: "CONTENT_TYPE_FIELD_VALIDATION_FAILED",
|
|
47
|
-
SLUG_FIELD_INVALID: "CONTENT_TYPE_SLUG_FIELD_INVALID",
|
|
48
|
-
TITLE_FIELD_INVALID: "CONTENT_TYPE_TITLE_FIELD_INVALID",
|
|
49
|
-
HAS_ENTRIES: "CONTENT_TYPE_HAS_ENTRIES",
|
|
50
|
-
BREAKING_CHANGE: "CONTENT_TYPE_BREAKING_CHANGE",
|
|
51
|
-
} as const;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Content Entry Error Codes
|
|
55
|
-
*/
|
|
56
|
-
export const ContentEntryErrorCodes = {
|
|
57
|
-
NOT_FOUND: "CONTENT_ENTRY_NOT_FOUND",
|
|
58
|
-
DELETED: "CONTENT_ENTRY_DELETED",
|
|
59
|
-
NOT_DELETED: "CONTENT_ENTRY_NOT_DELETED",
|
|
60
|
-
ALREADY_PUBLISHED: "CONTENT_ENTRY_ALREADY_PUBLISHED",
|
|
61
|
-
NOT_PUBLISHED: "CONTENT_ENTRY_NOT_PUBLISHED",
|
|
62
|
-
ARCHIVED: "CONTENT_ENTRY_ARCHIVED",
|
|
63
|
-
VALIDATION_FAILED: "CONTENT_ENTRY_VALIDATION_FAILED",
|
|
64
|
-
SLUG_CONFLICT: "CONTENT_ENTRY_SLUG_CONFLICT",
|
|
65
|
-
LOCKED: "CONTENT_ENTRY_LOCKED",
|
|
66
|
-
CREATE_FAILED: "CONTENT_ENTRY_CREATE_FAILED",
|
|
67
|
-
UPDATE_FAILED: "CONTENT_ENTRY_UPDATE_FAILED",
|
|
68
|
-
} as const;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Media Asset Error Codes
|
|
72
|
-
*/
|
|
73
|
-
export const MediaAssetErrorCodes = {
|
|
74
|
-
NOT_FOUND: "MEDIA_ASSET_NOT_FOUND",
|
|
75
|
-
DELETED: "MEDIA_ASSET_DELETED",
|
|
76
|
-
NOT_DELETED: "MEDIA_ASSET_NOT_DELETED",
|
|
77
|
-
HAS_REFERENCES: "MEDIA_ASSET_HAS_REFERENCES",
|
|
78
|
-
CREATE_FAILED: "MEDIA_ASSET_CREATE_FAILED",
|
|
79
|
-
UPDATE_FAILED: "MEDIA_ASSET_UPDATE_FAILED",
|
|
80
|
-
UPLOAD_INVALID: "MEDIA_ASSET_UPLOAD_INVALID",
|
|
81
|
-
} as const;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Media Folder Error Codes
|
|
85
|
-
*/
|
|
86
|
-
export const MediaFolderErrorCodes = {
|
|
87
|
-
NOT_FOUND: "MEDIA_FOLDER_NOT_FOUND",
|
|
88
|
-
DELETED: "MEDIA_FOLDER_DELETED",
|
|
89
|
-
NOT_DELETED: "MEDIA_FOLDER_NOT_DELETED",
|
|
90
|
-
NAME_INVALID: "MEDIA_FOLDER_NAME_INVALID",
|
|
91
|
-
NAME_DUPLICATE: "MEDIA_FOLDER_NAME_DUPLICATE",
|
|
92
|
-
DEPTH_EXCEEDED: "MEDIA_FOLDER_DEPTH_EXCEEDED",
|
|
93
|
-
PATH_TOO_LONG: "MEDIA_FOLDER_PATH_TOO_LONG",
|
|
94
|
-
HAS_CONTENTS: "MEDIA_FOLDER_HAS_CONTENTS",
|
|
95
|
-
CIRCULAR_MOVE: "MEDIA_FOLDER_CIRCULAR_MOVE",
|
|
96
|
-
PARENT_DELETED: "MEDIA_FOLDER_PARENT_DELETED",
|
|
97
|
-
CREATE_FAILED: "MEDIA_FOLDER_CREATE_FAILED",
|
|
98
|
-
} as const;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Version Error Codes
|
|
102
|
-
*/
|
|
103
|
-
export const VersionErrorCodes = {
|
|
104
|
-
NOT_FOUND: "VERSION_NOT_FOUND",
|
|
105
|
-
ENTRY_NOT_FOUND: "VERSION_ENTRY_NOT_FOUND",
|
|
106
|
-
ENTRY_DELETED: "VERSION_ENTRY_DELETED",
|
|
107
|
-
MISMATCH: "VERSION_MISMATCH",
|
|
108
|
-
ROLLBACK_FAILED: "VERSION_ROLLBACK_FAILED",
|
|
109
|
-
} as const;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* General Error Codes
|
|
113
|
-
*/
|
|
114
|
-
export const GeneralErrorCodes = {
|
|
115
|
-
BATCH_SIZE_EXCEEDED: "BATCH_SIZE_EXCEEDED",
|
|
116
|
-
PERMISSION_DENIED: "PERMISSION_DENIED",
|
|
117
|
-
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
118
|
-
} as const;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Union type of all error codes from all categories.
|
|
122
|
-
* Use the specific error code objects (ContentTypeErrorCodes, etc.) to access values.
|
|
123
|
-
*/
|
|
124
|
-
export type ErrorCode =
|
|
125
|
-
| (typeof ContentTypeErrorCodes)[keyof typeof ContentTypeErrorCodes]
|
|
126
|
-
| (typeof ContentEntryErrorCodes)[keyof typeof ContentEntryErrorCodes]
|
|
127
|
-
| (typeof MediaAssetErrorCodes)[keyof typeof MediaAssetErrorCodes]
|
|
128
|
-
| (typeof MediaFolderErrorCodes)[keyof typeof MediaFolderErrorCodes]
|
|
129
|
-
| (typeof VersionErrorCodes)[keyof typeof VersionErrorCodes]
|
|
130
|
-
| (typeof GeneralErrorCodes)[keyof typeof GeneralErrorCodes];
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Combined object containing all error codes for reference.
|
|
134
|
-
* Note: Due to key collisions (e.g., NOT_FOUND exists in multiple categories),
|
|
135
|
-
* use the specific error code objects for accessing values in code.
|
|
136
|
-
* This object is primarily useful for listing all possible error code values.
|
|
137
|
-
*/
|
|
138
|
-
export const ErrorCodes = {
|
|
139
|
-
// Content Type Errors
|
|
140
|
-
CONTENT_TYPE_NOT_FOUND: ContentTypeErrorCodes.NOT_FOUND,
|
|
141
|
-
CONTENT_TYPE_DELETED: ContentTypeErrorCodes.DELETED,
|
|
142
|
-
CONTENT_TYPE_INACTIVE: ContentTypeErrorCodes.INACTIVE,
|
|
143
|
-
CONTENT_TYPE_NAME_INVALID: ContentTypeErrorCodes.NAME_INVALID,
|
|
144
|
-
CONTENT_TYPE_NAME_DUPLICATE: ContentTypeErrorCodes.NAME_DUPLICATE,
|
|
145
|
-
CONTENT_TYPE_FIELD_VALIDATION_FAILED: ContentTypeErrorCodes.FIELD_VALIDATION_FAILED,
|
|
146
|
-
CONTENT_TYPE_SLUG_FIELD_INVALID: ContentTypeErrorCodes.SLUG_FIELD_INVALID,
|
|
147
|
-
CONTENT_TYPE_TITLE_FIELD_INVALID: ContentTypeErrorCodes.TITLE_FIELD_INVALID,
|
|
148
|
-
CONTENT_TYPE_HAS_ENTRIES: ContentTypeErrorCodes.HAS_ENTRIES,
|
|
149
|
-
CONTENT_TYPE_BREAKING_CHANGE: ContentTypeErrorCodes.BREAKING_CHANGE,
|
|
150
|
-
// Content Entry Errors
|
|
151
|
-
CONTENT_ENTRY_NOT_FOUND: ContentEntryErrorCodes.NOT_FOUND,
|
|
152
|
-
CONTENT_ENTRY_DELETED: ContentEntryErrorCodes.DELETED,
|
|
153
|
-
CONTENT_ENTRY_NOT_DELETED: ContentEntryErrorCodes.NOT_DELETED,
|
|
154
|
-
CONTENT_ENTRY_ALREADY_PUBLISHED: ContentEntryErrorCodes.ALREADY_PUBLISHED,
|
|
155
|
-
CONTENT_ENTRY_NOT_PUBLISHED: ContentEntryErrorCodes.NOT_PUBLISHED,
|
|
156
|
-
CONTENT_ENTRY_ARCHIVED: ContentEntryErrorCodes.ARCHIVED,
|
|
157
|
-
CONTENT_ENTRY_VALIDATION_FAILED: ContentEntryErrorCodes.VALIDATION_FAILED,
|
|
158
|
-
CONTENT_ENTRY_SLUG_CONFLICT: ContentEntryErrorCodes.SLUG_CONFLICT,
|
|
159
|
-
CONTENT_ENTRY_LOCKED: ContentEntryErrorCodes.LOCKED,
|
|
160
|
-
CONTENT_ENTRY_CREATE_FAILED: ContentEntryErrorCodes.CREATE_FAILED,
|
|
161
|
-
CONTENT_ENTRY_UPDATE_FAILED: ContentEntryErrorCodes.UPDATE_FAILED,
|
|
162
|
-
// Media Asset Errors
|
|
163
|
-
MEDIA_ASSET_NOT_FOUND: MediaAssetErrorCodes.NOT_FOUND,
|
|
164
|
-
MEDIA_ASSET_DELETED: MediaAssetErrorCodes.DELETED,
|
|
165
|
-
MEDIA_ASSET_NOT_DELETED: MediaAssetErrorCodes.NOT_DELETED,
|
|
166
|
-
MEDIA_ASSET_HAS_REFERENCES: MediaAssetErrorCodes.HAS_REFERENCES,
|
|
167
|
-
MEDIA_ASSET_CREATE_FAILED: MediaAssetErrorCodes.CREATE_FAILED,
|
|
168
|
-
MEDIA_ASSET_UPDATE_FAILED: MediaAssetErrorCodes.UPDATE_FAILED,
|
|
169
|
-
MEDIA_ASSET_UPLOAD_INVALID: MediaAssetErrorCodes.UPLOAD_INVALID,
|
|
170
|
-
// Media Folder Errors
|
|
171
|
-
MEDIA_FOLDER_NOT_FOUND: MediaFolderErrorCodes.NOT_FOUND,
|
|
172
|
-
MEDIA_FOLDER_DELETED: MediaFolderErrorCodes.DELETED,
|
|
173
|
-
MEDIA_FOLDER_NOT_DELETED: MediaFolderErrorCodes.NOT_DELETED,
|
|
174
|
-
MEDIA_FOLDER_NAME_INVALID: MediaFolderErrorCodes.NAME_INVALID,
|
|
175
|
-
MEDIA_FOLDER_NAME_DUPLICATE: MediaFolderErrorCodes.NAME_DUPLICATE,
|
|
176
|
-
MEDIA_FOLDER_DEPTH_EXCEEDED: MediaFolderErrorCodes.DEPTH_EXCEEDED,
|
|
177
|
-
MEDIA_FOLDER_PATH_TOO_LONG: MediaFolderErrorCodes.PATH_TOO_LONG,
|
|
178
|
-
MEDIA_FOLDER_HAS_CONTENTS: MediaFolderErrorCodes.HAS_CONTENTS,
|
|
179
|
-
MEDIA_FOLDER_CIRCULAR_MOVE: MediaFolderErrorCodes.CIRCULAR_MOVE,
|
|
180
|
-
MEDIA_FOLDER_PARENT_DELETED: MediaFolderErrorCodes.PARENT_DELETED,
|
|
181
|
-
MEDIA_FOLDER_CREATE_FAILED: MediaFolderErrorCodes.CREATE_FAILED,
|
|
182
|
-
// Version Errors
|
|
183
|
-
VERSION_NOT_FOUND: VersionErrorCodes.NOT_FOUND,
|
|
184
|
-
VERSION_ENTRY_NOT_FOUND: VersionErrorCodes.ENTRY_NOT_FOUND,
|
|
185
|
-
VERSION_ENTRY_DELETED: VersionErrorCodes.ENTRY_DELETED,
|
|
186
|
-
VERSION_MISMATCH: VersionErrorCodes.MISMATCH,
|
|
187
|
-
VERSION_ROLLBACK_FAILED: VersionErrorCodes.ROLLBACK_FAILED,
|
|
188
|
-
// General Errors
|
|
189
|
-
BATCH_SIZE_EXCEEDED: GeneralErrorCodes.BATCH_SIZE_EXCEEDED,
|
|
190
|
-
PERMISSION_DENIED: GeneralErrorCodes.PERMISSION_DENIED,
|
|
191
|
-
INTERNAL_ERROR: GeneralErrorCodes.INTERNAL_ERROR,
|
|
192
|
-
} as const;
|
|
193
|
-
|
|
194
|
-
// =============================================================================
|
|
195
|
-
// Error Context Types
|
|
196
|
-
// =============================================================================
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Context for resource-related errors
|
|
200
|
-
*/
|
|
201
|
-
export interface ResourceErrorContext {
|
|
202
|
-
resourceType: "contentType" | "contentEntry" | "mediaAsset" | "mediaFolder" | "version";
|
|
203
|
-
resourceId?: string;
|
|
204
|
-
resourceName?: string;
|
|
205
|
-
currentState?: string;
|
|
206
|
-
expectedState?: string;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Context for validation errors
|
|
211
|
-
*/
|
|
212
|
-
export interface ValidationErrorContext {
|
|
213
|
-
fields?: Array<{
|
|
214
|
-
field: string;
|
|
215
|
-
message: string;
|
|
216
|
-
code?: string;
|
|
217
|
-
}>;
|
|
218
|
-
details?: string;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Context for lock-related errors
|
|
223
|
-
*/
|
|
224
|
-
export interface LockErrorContext {
|
|
225
|
-
lockedBy?: string;
|
|
226
|
-
lockedAt?: number;
|
|
227
|
-
currentUser?: string;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Context for reference-related errors
|
|
232
|
-
*/
|
|
233
|
-
export interface ReferenceErrorContext {
|
|
234
|
-
referencingResources?: Array<{
|
|
235
|
-
type: string;
|
|
236
|
-
id: string;
|
|
237
|
-
name?: string;
|
|
238
|
-
}>;
|
|
239
|
-
referenceCount?: number;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Union type for all error contexts
|
|
244
|
-
*/
|
|
245
|
-
export type CMSErrorContext =
|
|
246
|
-
| ResourceErrorContext
|
|
247
|
-
| ValidationErrorContext
|
|
248
|
-
| LockErrorContext
|
|
249
|
-
| ReferenceErrorContext
|
|
250
|
-
| Record<string, unknown>;
|
|
251
|
-
|
|
252
|
-
// =============================================================================
|
|
253
|
-
// CMS Error Class
|
|
254
|
-
// =============================================================================
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Custom error class for CMS operations.
|
|
258
|
-
*
|
|
259
|
-
* Provides structured error information including:
|
|
260
|
-
* - Machine-readable error code
|
|
261
|
-
* - Error category for routing
|
|
262
|
-
* - Human-readable message
|
|
263
|
-
* - Additional context for debugging
|
|
264
|
-
*
|
|
265
|
-
* @example
|
|
266
|
-
* ```typescript
|
|
267
|
-
* throw new CMSError(
|
|
268
|
-
* ErrorCodes.CONTENT_TYPE_NOT_FOUND,
|
|
269
|
-
* "NOT_FOUND",
|
|
270
|
-
* `Content type not found: ${id}`,
|
|
271
|
-
* { resourceType: "contentType", resourceId: id }
|
|
272
|
-
* );
|
|
273
|
-
* ```
|
|
274
|
-
*/
|
|
275
|
-
export class CMSError extends Error {
|
|
276
|
-
public readonly code: ErrorCode;
|
|
277
|
-
public readonly category: ErrorCategory;
|
|
278
|
-
public readonly context?: CMSErrorContext;
|
|
279
|
-
|
|
280
|
-
constructor(
|
|
281
|
-
code: ErrorCode,
|
|
282
|
-
category: ErrorCategory,
|
|
283
|
-
message: string,
|
|
284
|
-
context?: CMSErrorContext
|
|
285
|
-
) {
|
|
286
|
-
// Format message to include code for easier debugging
|
|
287
|
-
const formattedMessage = `[${code}] ${message}`;
|
|
288
|
-
super(formattedMessage);
|
|
289
|
-
this.name = "CMSError";
|
|
290
|
-
this.code = code;
|
|
291
|
-
this.category = category;
|
|
292
|
-
this.context = context;
|
|
293
|
-
|
|
294
|
-
// Maintain proper stack trace in V8 environments
|
|
295
|
-
if (Error.captureStackTrace) {
|
|
296
|
-
Error.captureStackTrace(this, CMSError);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Convert error to a plain object for serialization.
|
|
302
|
-
*/
|
|
303
|
-
toJSON(): {
|
|
304
|
-
name: string;
|
|
305
|
-
code: ErrorCode;
|
|
306
|
-
category: ErrorCategory;
|
|
307
|
-
message: string;
|
|
308
|
-
context?: CMSErrorContext;
|
|
309
|
-
} {
|
|
310
|
-
return {
|
|
311
|
-
name: this.name,
|
|
312
|
-
code: this.code,
|
|
313
|
-
category: this.category,
|
|
314
|
-
message: this.message,
|
|
315
|
-
context: this.context,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// =============================================================================
|
|
321
|
-
// Error Factory Functions
|
|
322
|
-
// =============================================================================
|
|
323
|
-
|
|
324
|
-
// -----------------------------------------------------------------------------
|
|
325
|
-
// Content Type Errors
|
|
326
|
-
// -----------------------------------------------------------------------------
|
|
327
|
-
|
|
328
|
-
export function contentTypeNotFound(id: string): CMSError {
|
|
329
|
-
return new CMSError(
|
|
330
|
-
ContentTypeErrorCodes.NOT_FOUND,
|
|
331
|
-
"NOT_FOUND",
|
|
332
|
-
`Content type not found. The content type with ID "${id}" does not exist.`,
|
|
333
|
-
{ resourceType: "contentType", resourceId: id }
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export function contentTypeDeleted(id: string, name?: string): CMSError {
|
|
338
|
-
const identifier = name ? `"${name}" (${id})` : `"${id}"`;
|
|
339
|
-
return new CMSError(
|
|
340
|
-
ContentTypeErrorCodes.DELETED,
|
|
341
|
-
"DELETED",
|
|
342
|
-
`Content type ${identifier} has been deleted. Restore it first to perform this operation.`,
|
|
343
|
-
{ resourceType: "contentType", resourceId: id, resourceName: name, currentState: "deleted" }
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export function contentTypeInactive(id: string, name?: string): CMSError {
|
|
348
|
-
const identifier = name ? `"${name}"` : `"${id}"`;
|
|
349
|
-
return new CMSError(
|
|
350
|
-
ContentTypeErrorCodes.INACTIVE,
|
|
351
|
-
"INACTIVE",
|
|
352
|
-
`Content type ${identifier} is not active. Activate it first to create entries.`,
|
|
353
|
-
{ resourceType: "contentType", resourceId: id, resourceName: name, currentState: "inactive" }
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
export function contentTypeNameInvalid(name: string): CMSError {
|
|
358
|
-
return new CMSError(
|
|
359
|
-
ContentTypeErrorCodes.NAME_INVALID,
|
|
360
|
-
"VALIDATION",
|
|
361
|
-
`Invalid content type name "${name}". Name must start with a lowercase letter and contain only lowercase letters, numbers, and underscores (1-64 characters).`,
|
|
362
|
-
{ details: `Provided name: "${name}"` }
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export function contentTypeNameDuplicate(name: string): CMSError {
|
|
367
|
-
return new CMSError(
|
|
368
|
-
ContentTypeErrorCodes.NAME_DUPLICATE,
|
|
369
|
-
"STATE_CONFLICT",
|
|
370
|
-
`A content type with name "${name}" already exists. Please choose a different name.`,
|
|
371
|
-
{ resourceType: "contentType", resourceName: name }
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export function contentTypeFieldValidationFailed(
|
|
376
|
-
errors: Array<{ fieldName: string; message: string; code?: string }>
|
|
377
|
-
): CMSError {
|
|
378
|
-
const errorMessages = errors.map((e) => `${e.fieldName}: ${e.message}`).join("; ");
|
|
379
|
-
return new CMSError(
|
|
380
|
-
ContentTypeErrorCodes.FIELD_VALIDATION_FAILED,
|
|
381
|
-
"VALIDATION",
|
|
382
|
-
`Invalid field definitions: ${errorMessages}`,
|
|
383
|
-
{ fields: errors.map((e) => ({ field: e.fieldName, message: e.message, code: e.code })) }
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
export function contentTypeSlugFieldInvalid(slugField: string, availableFields: string[]): CMSError {
|
|
388
|
-
return new CMSError(
|
|
389
|
-
ContentTypeErrorCodes.SLUG_FIELD_INVALID,
|
|
390
|
-
"VALIDATION",
|
|
391
|
-
`slugField "${slugField}" does not reference an existing field. Available fields: ${availableFields.join(", ")}`,
|
|
392
|
-
{ details: `Invalid slugField: "${slugField}"` }
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
export function contentTypeTitleFieldInvalid(titleField: string, availableFields: string[]): CMSError {
|
|
397
|
-
return new CMSError(
|
|
398
|
-
ContentTypeErrorCodes.TITLE_FIELD_INVALID,
|
|
399
|
-
"VALIDATION",
|
|
400
|
-
`titleField "${titleField}" does not reference an existing field. Available fields: ${availableFields.join(", ")}`,
|
|
401
|
-
{ details: `Invalid titleField: "${titleField}"` }
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
export function contentTypeHasEntries(id: string, name: string, entryCount: number): CMSError {
|
|
406
|
-
return new CMSError(
|
|
407
|
-
ContentTypeErrorCodes.HAS_ENTRIES,
|
|
408
|
-
"REFERENCE_CONFLICT",
|
|
409
|
-
`Cannot delete content type "${name}": it has ${entryCount} content ${entryCount === 1 ? "entry" : "entries"}. Delete all entries first or use force delete.`,
|
|
410
|
-
{
|
|
411
|
-
resourceType: "contentType",
|
|
412
|
-
resourceId: id,
|
|
413
|
-
resourceName: name,
|
|
414
|
-
referenceCount: entryCount,
|
|
415
|
-
} as ResourceErrorContext & { referenceCount: number }
|
|
416
|
-
);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
export function contentTypeBreakingChange(
|
|
420
|
-
breakingChanges: Array<{ type: string; fieldName: string; message: string; affectedEntriesCount: number }>
|
|
421
|
-
): CMSError {
|
|
422
|
-
const summary = breakingChanges
|
|
423
|
-
.map((bc) => `- ${bc.fieldName}: ${bc.message} (affects ${bc.affectedEntriesCount} entries)`)
|
|
424
|
-
.join("\n");
|
|
425
|
-
return new CMSError(
|
|
426
|
-
ContentTypeErrorCodes.BREAKING_CHANGE,
|
|
427
|
-
"STATE_CONFLICT",
|
|
428
|
-
`Cannot update content type due to breaking changes:\n${summary}\n\nUse allowBreakingChanges: true to force the update.`,
|
|
429
|
-
{ details: summary }
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// -----------------------------------------------------------------------------
|
|
434
|
-
// Content Entry Errors
|
|
435
|
-
// -----------------------------------------------------------------------------
|
|
436
|
-
|
|
437
|
-
export function contentEntryNotFound(id: string): CMSError {
|
|
438
|
-
return new CMSError(
|
|
439
|
-
ContentEntryErrorCodes.NOT_FOUND,
|
|
440
|
-
"NOT_FOUND",
|
|
441
|
-
`Content entry not found. The entry with ID "${id}" does not exist.`,
|
|
442
|
-
{ resourceType: "contentEntry", resourceId: id }
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
export function contentEntryDeleted(id: string): CMSError {
|
|
447
|
-
return new CMSError(
|
|
448
|
-
ContentEntryErrorCodes.DELETED,
|
|
449
|
-
"DELETED",
|
|
450
|
-
`Content entry "${id}" has been deleted. Restore it from trash first to perform this operation.`,
|
|
451
|
-
{ resourceType: "contentEntry", resourceId: id, currentState: "deleted" }
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
export function contentEntryNotDeleted(id: string): CMSError {
|
|
456
|
-
return new CMSError(
|
|
457
|
-
ContentEntryErrorCodes.NOT_DELETED,
|
|
458
|
-
"STATE_CONFLICT",
|
|
459
|
-
`Content entry "${id}" is not deleted. Only deleted entries can be restored.`,
|
|
460
|
-
{ resourceType: "contentEntry", resourceId: id, currentState: "active", expectedState: "deleted" }
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
export function contentEntryAlreadyPublished(id: string): CMSError {
|
|
465
|
-
return new CMSError(
|
|
466
|
-
ContentEntryErrorCodes.ALREADY_PUBLISHED,
|
|
467
|
-
"STATE_CONFLICT",
|
|
468
|
-
`Content entry "${id}" is already published. Use update instead if you want to modify it.`,
|
|
469
|
-
{ resourceType: "contentEntry", resourceId: id, currentState: "published", expectedState: "draft" }
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
export function contentEntryNotPublished(id: string, currentStatus: string): CMSError {
|
|
474
|
-
return new CMSError(
|
|
475
|
-
ContentEntryErrorCodes.NOT_PUBLISHED,
|
|
476
|
-
"STATE_CONFLICT",
|
|
477
|
-
`Content entry "${id}" is not published. Current status: "${currentStatus}". Only published entries can be unpublished.`,
|
|
478
|
-
{ resourceType: "contentEntry", resourceId: id, currentState: currentStatus, expectedState: "published" }
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
export function contentEntryArchived(id: string): CMSError {
|
|
483
|
-
return new CMSError(
|
|
484
|
-
ContentEntryErrorCodes.ARCHIVED,
|
|
485
|
-
"STATE_CONFLICT",
|
|
486
|
-
`Cannot publish archived content entry "${id}". Restore it from archive first.`,
|
|
487
|
-
{ resourceType: "contentEntry", resourceId: id, currentState: "archived" }
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
export function contentEntryValidationFailed(
|
|
492
|
-
errors: Array<{ field: string; message: string }>
|
|
493
|
-
): CMSError {
|
|
494
|
-
const errorMessages = errors.map((e) => `${e.field}: ${e.message}`).join("; ");
|
|
495
|
-
return new CMSError(
|
|
496
|
-
ContentEntryErrorCodes.VALIDATION_FAILED,
|
|
497
|
-
"VALIDATION",
|
|
498
|
-
`Content validation failed: ${errorMessages}`,
|
|
499
|
-
{ fields: errors }
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export function contentEntryLocked(
|
|
504
|
-
entryId: string,
|
|
505
|
-
lockedBy: string,
|
|
506
|
-
lockedAt: number,
|
|
507
|
-
currentUser?: string
|
|
508
|
-
): CMSError {
|
|
509
|
-
const lockedDate = new Date(lockedAt).toISOString();
|
|
510
|
-
return new CMSError(
|
|
511
|
-
ContentEntryErrorCodes.LOCKED,
|
|
512
|
-
"LOCK_CONFLICT",
|
|
513
|
-
`Content entry "${entryId}" is locked by user "${lockedBy}" since ${lockedDate}. Only the lock holder can modify this entry.`,
|
|
514
|
-
{ lockedBy, lockedAt, currentUser }
|
|
515
|
-
);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
export function contentEntryCreateFailed(contentTypeId: string): CMSError {
|
|
519
|
-
return new CMSError(
|
|
520
|
-
ContentEntryErrorCodes.CREATE_FAILED,
|
|
521
|
-
"INTERNAL",
|
|
522
|
-
`Failed to create content entry for content type "${contentTypeId}". The entry was not persisted.`,
|
|
523
|
-
{ resourceType: "contentEntry" }
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
export function contentEntryUpdateFailed(id: string): CMSError {
|
|
528
|
-
return new CMSError(
|
|
529
|
-
ContentEntryErrorCodes.UPDATE_FAILED,
|
|
530
|
-
"INTERNAL",
|
|
531
|
-
`Failed to retrieve content entry "${id}" after update. The update may have failed.`,
|
|
532
|
-
{ resourceType: "contentEntry", resourceId: id }
|
|
533
|
-
);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
// -----------------------------------------------------------------------------
|
|
537
|
-
// Media Asset Errors
|
|
538
|
-
// -----------------------------------------------------------------------------
|
|
539
|
-
|
|
540
|
-
export function mediaAssetNotFound(id: string): CMSError {
|
|
541
|
-
return new CMSError(
|
|
542
|
-
MediaAssetErrorCodes.NOT_FOUND,
|
|
543
|
-
"NOT_FOUND",
|
|
544
|
-
`Media asset not found. The asset with ID "${id}" does not exist.`,
|
|
545
|
-
{ resourceType: "mediaAsset", resourceId: id }
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
export function mediaAssetDeleted(id: string): CMSError {
|
|
550
|
-
return new CMSError(
|
|
551
|
-
MediaAssetErrorCodes.DELETED,
|
|
552
|
-
"DELETED",
|
|
553
|
-
`Media asset "${id}" has been deleted. Restore it first to perform this operation.`,
|
|
554
|
-
{ resourceType: "mediaAsset", resourceId: id, currentState: "deleted" }
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
export function mediaAssetNotDeleted(id: string): CMSError {
|
|
559
|
-
return new CMSError(
|
|
560
|
-
MediaAssetErrorCodes.NOT_DELETED,
|
|
561
|
-
"STATE_CONFLICT",
|
|
562
|
-
`Media asset "${id}" is not deleted. Only deleted assets can be restored.`,
|
|
563
|
-
{ resourceType: "mediaAsset", resourceId: id, currentState: "active", expectedState: "deleted" }
|
|
564
|
-
);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
export function mediaAssetHasReferences(
|
|
568
|
-
id: string,
|
|
569
|
-
references: Array<{ type: string; id: string; name?: string }>
|
|
570
|
-
): CMSError {
|
|
571
|
-
const refSummary = references
|
|
572
|
-
.slice(0, 5)
|
|
573
|
-
.map((r) => `${r.type}: ${r.name || r.id}`)
|
|
574
|
-
.join(", ");
|
|
575
|
-
const moreCount = references.length > 5 ? ` and ${references.length - 5} more` : "";
|
|
576
|
-
return new CMSError(
|
|
577
|
-
MediaAssetErrorCodes.HAS_REFERENCES,
|
|
578
|
-
"REFERENCE_CONFLICT",
|
|
579
|
-
`Cannot delete media asset "${id}": it is referenced by ${references.length} ${references.length === 1 ? "resource" : "resources"} (${refSummary}${moreCount}). Remove references first or use force delete.`,
|
|
580
|
-
{ referencingResources: references, referenceCount: references.length }
|
|
581
|
-
);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
export function mediaAssetCreateFailed(): CMSError {
|
|
585
|
-
return new CMSError(
|
|
586
|
-
MediaAssetErrorCodes.CREATE_FAILED,
|
|
587
|
-
"INTERNAL",
|
|
588
|
-
"Failed to create media asset. The asset was not persisted.",
|
|
589
|
-
{ resourceType: "mediaAsset" }
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
export function mediaAssetUpdateFailed(id: string): CMSError {
|
|
594
|
-
return new CMSError(
|
|
595
|
-
MediaAssetErrorCodes.UPDATE_FAILED,
|
|
596
|
-
"INTERNAL",
|
|
597
|
-
`Failed to retrieve media asset "${id}" after update. The update may have failed.`,
|
|
598
|
-
{ resourceType: "mediaAsset", resourceId: id }
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// -----------------------------------------------------------------------------
|
|
603
|
-
// Media Folder Errors
|
|
604
|
-
// -----------------------------------------------------------------------------
|
|
605
|
-
|
|
606
|
-
export function mediaFolderNotFound(id: string): CMSError {
|
|
607
|
-
return new CMSError(
|
|
608
|
-
MediaFolderErrorCodes.NOT_FOUND,
|
|
609
|
-
"NOT_FOUND",
|
|
610
|
-
`Media folder not found. The folder with ID "${id}" does not exist.`,
|
|
611
|
-
{ resourceType: "mediaFolder", resourceId: id }
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
export function mediaFolderDeleted(id: string): CMSError {
|
|
616
|
-
return new CMSError(
|
|
617
|
-
MediaFolderErrorCodes.DELETED,
|
|
618
|
-
"DELETED",
|
|
619
|
-
`Media folder "${id}" has been deleted. Restore it first to perform this operation.`,
|
|
620
|
-
{ resourceType: "mediaFolder", resourceId: id, currentState: "deleted" }
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
export function mediaFolderNotDeleted(id: string): CMSError {
|
|
625
|
-
return new CMSError(
|
|
626
|
-
MediaFolderErrorCodes.NOT_DELETED,
|
|
627
|
-
"STATE_CONFLICT",
|
|
628
|
-
`Media folder "${id}" is not deleted. Only deleted folders can be restored.`,
|
|
629
|
-
{ resourceType: "mediaFolder", resourceId: id, currentState: "active", expectedState: "deleted" }
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
export function mediaFolderNameInvalid(name: string, reason: string): CMSError {
|
|
634
|
-
return new CMSError(
|
|
635
|
-
MediaFolderErrorCodes.NAME_INVALID,
|
|
636
|
-
"VALIDATION",
|
|
637
|
-
`Invalid folder name "${name}": ${reason}`,
|
|
638
|
-
{ details: reason }
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
export function mediaFolderNameDuplicate(name: string, parentPath?: string): CMSError {
|
|
643
|
-
const location = parentPath ? ` at "${parentPath}"` : " at this location";
|
|
644
|
-
return new CMSError(
|
|
645
|
-
MediaFolderErrorCodes.NAME_DUPLICATE,
|
|
646
|
-
"STATE_CONFLICT",
|
|
647
|
-
`A folder named "${name}" already exists${location}. Please choose a different name.`,
|
|
648
|
-
{ resourceType: "mediaFolder", resourceName: name }
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
export function mediaFolderDepthExceeded(maxDepth: number, currentDepth: number): CMSError {
|
|
653
|
-
return new CMSError(
|
|
654
|
-
MediaFolderErrorCodes.DEPTH_EXCEEDED,
|
|
655
|
-
"LIMIT_EXCEEDED",
|
|
656
|
-
`Cannot create folder: maximum nesting depth of ${maxDepth} exceeded. Current depth would be ${currentDepth}.`,
|
|
657
|
-
{ details: `Max depth: ${maxDepth}, attempted depth: ${currentDepth}` }
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
export function mediaFolderPathTooLong(maxLength: number, pathLength: number): CMSError {
|
|
662
|
-
return new CMSError(
|
|
663
|
-
MediaFolderErrorCodes.PATH_TOO_LONG,
|
|
664
|
-
"LIMIT_EXCEEDED",
|
|
665
|
-
`Cannot create folder: path would exceed maximum length of ${maxLength} characters (would be ${pathLength}).`,
|
|
666
|
-
{ details: `Max length: ${maxLength}, attempted length: ${pathLength}` }
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
export function mediaFolderHasContents(
|
|
671
|
-
id: string,
|
|
672
|
-
folderCount: number,
|
|
673
|
-
assetCount: number
|
|
674
|
-
): CMSError {
|
|
675
|
-
const contents: string[] = [];
|
|
676
|
-
if (folderCount > 0) contents.push(`${folderCount} ${folderCount === 1 ? "subfolder" : "subfolders"}`);
|
|
677
|
-
if (assetCount > 0) contents.push(`${assetCount} ${assetCount === 1 ? "asset" : "assets"}`);
|
|
678
|
-
return new CMSError(
|
|
679
|
-
MediaFolderErrorCodes.HAS_CONTENTS,
|
|
680
|
-
"REFERENCE_CONFLICT",
|
|
681
|
-
`Cannot delete folder "${id}": it contains ${contents.join(" and ")}. Delete contents first or use recursive delete.`,
|
|
682
|
-
{ resourceType: "mediaFolder", resourceId: id }
|
|
683
|
-
);
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
export function mediaFolderCircularMove(id: string): CMSError {
|
|
687
|
-
return new CMSError(
|
|
688
|
-
MediaFolderErrorCodes.CIRCULAR_MOVE,
|
|
689
|
-
"VALIDATION",
|
|
690
|
-
`Cannot move folder "${id}" into itself or one of its descendants. This would create a circular reference.`,
|
|
691
|
-
{ resourceType: "mediaFolder", resourceId: id }
|
|
692
|
-
);
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
export function mediaFolderParentDeleted(id: string, parentId: string): CMSError {
|
|
696
|
-
return new CMSError(
|
|
697
|
-
MediaFolderErrorCodes.PARENT_DELETED,
|
|
698
|
-
"STATE_CONFLICT",
|
|
699
|
-
`Cannot restore folder "${id}": parent folder "${parentId}" is still deleted. Restore the parent folder first.`,
|
|
700
|
-
{ resourceType: "mediaFolder", resourceId: id }
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
export function mediaFolderCreateFailed(): CMSError {
|
|
705
|
-
return new CMSError(
|
|
706
|
-
MediaFolderErrorCodes.CREATE_FAILED,
|
|
707
|
-
"INTERNAL",
|
|
708
|
-
"Failed to create media folder. The folder was not persisted.",
|
|
709
|
-
{ resourceType: "mediaFolder" }
|
|
710
|
-
);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
// -----------------------------------------------------------------------------
|
|
714
|
-
// Version Errors
|
|
715
|
-
// -----------------------------------------------------------------------------
|
|
716
|
-
|
|
717
|
-
export function versionNotFound(entryId: string, versionNumber: number): CMSError {
|
|
718
|
-
return new CMSError(
|
|
719
|
-
VersionErrorCodes.NOT_FOUND,
|
|
720
|
-
"NOT_FOUND",
|
|
721
|
-
`Version ${versionNumber} not found for entry "${entryId}". Check if the version number is correct.`,
|
|
722
|
-
{ resourceType: "version", resourceId: entryId }
|
|
723
|
-
);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
export function versionEntryNotFound(entryId: string): CMSError {
|
|
727
|
-
return new CMSError(
|
|
728
|
-
VersionErrorCodes.ENTRY_NOT_FOUND,
|
|
729
|
-
"NOT_FOUND",
|
|
730
|
-
`Content entry "${entryId}" not found. Cannot create version snapshot for non-existent entry.`,
|
|
731
|
-
{ resourceType: "contentEntry", resourceId: entryId }
|
|
732
|
-
);
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
export function versionEntryDeleted(entryId: string): CMSError {
|
|
736
|
-
return new CMSError(
|
|
737
|
-
VersionErrorCodes.ENTRY_DELETED,
|
|
738
|
-
"DELETED",
|
|
739
|
-
`Content entry "${entryId}" has been deleted. Cannot create version snapshot or rollback deleted entries. Restore the entry first.`,
|
|
740
|
-
{ resourceType: "contentEntry", resourceId: entryId, currentState: "deleted" }
|
|
741
|
-
);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
export function versionMismatch(entryId: string, versionId: string): CMSError {
|
|
745
|
-
return new CMSError(
|
|
746
|
-
VersionErrorCodes.MISMATCH,
|
|
747
|
-
"VALIDATION",
|
|
748
|
-
`Version "${versionId}" does not belong to entry "${entryId}". Ensure you're using the correct version for this entry.`,
|
|
749
|
-
{ resourceType: "version", resourceId: versionId }
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
export function versionRollbackFailed(entryId: string): CMSError {
|
|
754
|
-
return new CMSError(
|
|
755
|
-
VersionErrorCodes.ROLLBACK_FAILED,
|
|
756
|
-
"INTERNAL",
|
|
757
|
-
`Failed to retrieve entry "${entryId}" after rollback. The rollback may have failed.`,
|
|
758
|
-
{ resourceType: "contentEntry", resourceId: entryId }
|
|
759
|
-
);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// -----------------------------------------------------------------------------
|
|
763
|
-
// General Errors
|
|
764
|
-
// -----------------------------------------------------------------------------
|
|
765
|
-
|
|
766
|
-
export function batchSizeExceeded(maxSize: number, requestedSize: number): CMSError {
|
|
767
|
-
return new CMSError(
|
|
768
|
-
GeneralErrorCodes.BATCH_SIZE_EXCEEDED,
|
|
769
|
-
"LIMIT_EXCEEDED",
|
|
770
|
-
`Batch size exceeds limit. Maximum ${maxSize} items per batch, but ${requestedSize} were requested.`,
|
|
771
|
-
{ details: `Max: ${maxSize}, requested: ${requestedSize}` }
|
|
772
|
-
);
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
export function permissionDenied(action: string, resource: string): CMSError {
|
|
776
|
-
return new CMSError(
|
|
777
|
-
GeneralErrorCodes.PERMISSION_DENIED,
|
|
778
|
-
"PERMISSION",
|
|
779
|
-
`Permission denied: you do not have access to ${action} ${resource}.`,
|
|
780
|
-
{ details: `Action: ${action}, resource: ${resource}` }
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
export function internalError(message: string): CMSError {
|
|
785
|
-
return new CMSError(
|
|
786
|
-
GeneralErrorCodes.INTERNAL_ERROR,
|
|
787
|
-
"INTERNAL",
|
|
788
|
-
`Internal error: ${message}`,
|
|
789
|
-
{ details: message }
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// =============================================================================
|
|
794
|
-
// Type Guards
|
|
795
|
-
// =============================================================================
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* Type guard to check if an error is a CMSError.
|
|
799
|
-
*/
|
|
800
|
-
export function isCMSError(error: unknown): error is CMSError {
|
|
801
|
-
return error instanceof CMSError;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* Type guard to check if an error has a specific error code.
|
|
806
|
-
*/
|
|
807
|
-
export function hasErrorCode(error: unknown, code: ErrorCode): boolean {
|
|
808
|
-
return isCMSError(error) && error.code === code;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* Type guard to check if an error is in a specific category.
|
|
813
|
-
*/
|
|
814
|
-
export function isErrorCategory(error: unknown, category: ErrorCategory): boolean {
|
|
815
|
-
return isCMSError(error) && error.category === category;
|
|
816
|
-
}
|