From e8dc5d0689d73201c3e68c9dfd2d349ab6fbd35e Mon Sep 17 00:00:00 2001 From: Khurs Pavel Date: Thu, 30 Apr 2026 20:42:43 +0300 Subject: [PATCH] chore: remove payload-plugin-content-releases from main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin's full development continues in PR #7 (feature/releases-plugin) and is intentionally not yet ready to live on main. This commit removes all references from main so the tree stays clean while the PR is parked open. What is removed: - packages/payload-plugin-content-releases/ — entire package directory (source, tests, README, build/lockfile config). The work is preserved on the feature/releases-plugin branch / PR #7. - apps/dev/package.json — workspace dependency entry. - apps/dev/src/payload.config.ts — import + plugin entry in plugins array. - apps/dev/src/app/(payload)/admin/importMap.js — regenerated via `bun run generate:importmap` (auto-removes orphan plugin entries). - apps/dev/src/payload-types.ts — regenerated via `bun run generate:types` (auto-removes Release / ReleaseItem types). - package.json — restore the simple `multi-semantic-release --ignore-private-packages` script (the `--ignore-packages` workaround is no longer needed once the package itself is gone). - bun.lock — refreshed via `bun install`. What stays untouched: - apps/dev/dev.db — local SQLite state. Orphan releases / release-items tables are harmless and only affect each developer's own machine. - docs/plans/2026-03-26-content-releases-*.md — historical design documents are kept as project history. Verification: - `bun run build` → all 4 remaining published packages build cleanly (apps/dev's own next-build still has unrelated pre-existing libsql / @eslint/eslintrc resolution issues that exist on main today). - `bun run generate:types` and `bun run generate:importmap` both run successfully with no plugin references in the output. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/dev/package.json | 1 - apps/dev/src/app/(payload)/admin/importMap.js | 6 - apps/dev/src/payload-types.ts | 120 +------ apps/dev/src/payload.config.ts | 4 - bun.lock | 297 ++--------------- package.json | 2 +- .../.gitignore | 2 - .../payload-plugin-content-releases/README.md | 229 ------------- .../package.json | 57 ---- .../collections/releaseItems.test.ts | 75 ----- .../__tests__/collections/releases.test.ts | 64 ---- .../endpoints/checkConflicts.test.ts | 54 ---- .../endpoints/previewRollback.test.ts | 66 ---- .../endpoints/publishRelease.test.ts | 77 ----- .../endpoints/rollbackRelease.test.ts | 126 -------- .../__tests__/endpoints/runScheduled.test.ts | 46 --- .../hooks/releaseItemsBeforeChange.test.ts | 113 ------- .../hooks/releasesBeforeChange.test.ts | 76 ----- .../src/__tests__/plugin-endpoints.test.ts | 28 -- .../src/__tests__/plugin-integration.test.ts | 64 ---- .../src/__tests__/plugin-sidebar.test.ts | 47 --- .../src/__tests__/plugin.test.ts | 8 - .../__tests__/publish/detectConflicts.test.ts | 58 ---- .../__tests__/publish/executePublish.test.ts | 136 -------- .../rollback/executeRollback.test.ts | 109 ------- .../rollback/previewRollback.test.ts | 102 ------ .../scheduler/checkScheduledReleases.test.ts | 94 ------ .../src/__tests__/setup.ts | 1 - .../src/__tests__/types.test.ts | 46 --- .../validation/statusTransitions.test.ts | 39 --- .../admin/components/ReleaseActionsField.tsx | 83 ----- .../src/admin/components/ReleaseDrawer.tsx | 303 ------------------ .../admin/components/ReleaseSidebarField.tsx | 137 -------- .../src/admin/components/RollbackButton.tsx | 269 ---------------- .../src/admin/components/TargetDocCell.tsx | 113 ------- .../admin/components/VersionPickerDrawer.tsx | 169 ---------- .../src/client.ts | 3 - .../src/collections/releaseItems.ts | 97 ------ .../src/collections/releases.ts | 113 ------- .../src/constants.ts | 29 -- .../src/endpoints/checkConflicts.ts | 33 -- .../src/endpoints/previewRollback.ts | 46 --- .../src/endpoints/publishRelease.ts | 81 ----- .../src/endpoints/rollbackRelease.ts | 66 ---- .../src/endpoints/runScheduled.ts | 49 --- .../src/hooks/releaseItemsBeforeChange.ts | 54 ---- .../src/hooks/releasesBeforeChange.ts | 28 -- .../src/hooks/releasesBeforeDelete.ts | 22 -- .../src/index.ts | 8 - .../src/plugin.ts | 176 ---------- .../src/publish/detectConflicts.ts | 52 --- .../src/publish/executePublish.ts | 99 ------ .../src/publish/orchestratePublish.ts | 96 ------ .../src/rollback/executeRollback.ts | 65 ---- .../src/rollback/orchestrateRollback.ts | 94 ------ .../src/rollback/previewRollback.ts | 67 ---- .../src/scheduler/checkScheduledReleases.ts | 54 ---- .../src/types.ts | 69 ---- .../src/validation/statusTransitions.ts | 19 -- .../tsconfig.json | 20 -- .../tsup.config.ts | 29 -- .../vitest.config.ts | 10 - 62 files changed, 22 insertions(+), 4678 deletions(-) delete mode 100644 packages/payload-plugin-content-releases/.gitignore delete mode 100644 packages/payload-plugin-content-releases/README.md delete mode 100644 packages/payload-plugin-content-releases/package.json delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/collections/releaseItems.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/collections/releases.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/endpoints/checkConflicts.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/endpoints/previewRollback.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/endpoints/publishRelease.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/endpoints/rollbackRelease.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/endpoints/runScheduled.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/hooks/releaseItemsBeforeChange.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/hooks/releasesBeforeChange.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/plugin-endpoints.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/plugin-integration.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/plugin-sidebar.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/plugin.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/publish/detectConflicts.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/publish/executePublish.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/rollback/executeRollback.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/rollback/previewRollback.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/scheduler/checkScheduledReleases.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/setup.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/types.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/__tests__/validation/statusTransitions.test.ts delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/ReleaseActionsField.tsx delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/ReleaseDrawer.tsx delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/ReleaseSidebarField.tsx delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/RollbackButton.tsx delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/TargetDocCell.tsx delete mode 100644 packages/payload-plugin-content-releases/src/admin/components/VersionPickerDrawer.tsx delete mode 100644 packages/payload-plugin-content-releases/src/client.ts delete mode 100644 packages/payload-plugin-content-releases/src/collections/releaseItems.ts delete mode 100644 packages/payload-plugin-content-releases/src/collections/releases.ts delete mode 100644 packages/payload-plugin-content-releases/src/constants.ts delete mode 100644 packages/payload-plugin-content-releases/src/endpoints/checkConflicts.ts delete mode 100644 packages/payload-plugin-content-releases/src/endpoints/previewRollback.ts delete mode 100644 packages/payload-plugin-content-releases/src/endpoints/publishRelease.ts delete mode 100644 packages/payload-plugin-content-releases/src/endpoints/rollbackRelease.ts delete mode 100644 packages/payload-plugin-content-releases/src/endpoints/runScheduled.ts delete mode 100644 packages/payload-plugin-content-releases/src/hooks/releaseItemsBeforeChange.ts delete mode 100644 packages/payload-plugin-content-releases/src/hooks/releasesBeforeChange.ts delete mode 100644 packages/payload-plugin-content-releases/src/hooks/releasesBeforeDelete.ts delete mode 100644 packages/payload-plugin-content-releases/src/index.ts delete mode 100644 packages/payload-plugin-content-releases/src/plugin.ts delete mode 100644 packages/payload-plugin-content-releases/src/publish/detectConflicts.ts delete mode 100644 packages/payload-plugin-content-releases/src/publish/executePublish.ts delete mode 100644 packages/payload-plugin-content-releases/src/publish/orchestratePublish.ts delete mode 100644 packages/payload-plugin-content-releases/src/rollback/executeRollback.ts delete mode 100644 packages/payload-plugin-content-releases/src/rollback/orchestrateRollback.ts delete mode 100644 packages/payload-plugin-content-releases/src/rollback/previewRollback.ts delete mode 100644 packages/payload-plugin-content-releases/src/scheduler/checkScheduledReleases.ts delete mode 100644 packages/payload-plugin-content-releases/src/types.ts delete mode 100644 packages/payload-plugin-content-releases/src/validation/statusTransitions.ts delete mode 100644 packages/payload-plugin-content-releases/tsconfig.json delete mode 100644 packages/payload-plugin-content-releases/tsup.config.ts delete mode 100644 packages/payload-plugin-content-releases/vitest.config.ts diff --git a/apps/dev/package.json b/apps/dev/package.json index 853a6ec..d633065 100644 --- a/apps/dev/package.json +++ b/apps/dev/package.json @@ -19,7 +19,6 @@ "@focus-reactive/payload-plugin-ab": "workspace:*", "@focus-reactive/payload-plugin-presets": "workspace:*", "@focus-reactive/payload-plugin-comments": "workspace:*", - "@focus-reactive/payload-plugin-content-releases": "workspace:*", "@focus-reactive/payload-plugin-scheduling": "workspace:*", "@payloadcms/db-sqlite": "3.79.0", "@payloadcms/live-preview-react": "3.79.0", diff --git a/apps/dev/src/app/(payload)/admin/importMap.js b/apps/dev/src/app/(payload)/admin/importMap.js index da1ec21..9794fc8 100644 --- a/apps/dev/src/app/(payload)/admin/importMap.js +++ b/apps/dev/src/app/(payload)/admin/importMap.js @@ -2,11 +2,8 @@ import { FieldCommentLabel as FieldCommentLabel_d1361f235be9df6e08bfd730fe68e7c8 import { BlockLabelWithPresets as BlockLabelWithPresets_f0a4a6f21f15d606fa328a5e35f17d11 } from '@focus-reactive/payload-plugin-presets/client' import { BlocksFieldWithPresets as BlocksFieldWithPresets_f0a4a6f21f15d606fa328a5e35f17d11 } from '@focus-reactive/payload-plugin-presets/client' import { VariantsField as VariantsField_1e5bf2338fb8c7d4f6284f3e67c93951 } from '@focus-reactive/payload-plugin-ab/admin/VariantsField' -import { ReleaseSidebarField as ReleaseSidebarField_01ef71babab0d155f9b7e71fc3fd8245 } from '@focus-reactive/payload-plugin-content-releases/client' import { PresetAdminComponentPreview as PresetAdminComponentPreview_f0a4a6f21f15d606fa328a5e35f17d11 } from '@focus-reactive/payload-plugin-presets/client' import { PresetAdminComponentCell as PresetAdminComponentCell_f0a4a6f21f15d606fa328a5e35f17d11 } from '@focus-reactive/payload-plugin-presets/client' -import { ReleaseActionsField as ReleaseActionsField_01ef71babab0d155f9b7e71fc3fd8245 } from '@focus-reactive/payload-plugin-content-releases/client' -import { TargetDocCell as TargetDocCell_01ef71babab0d155f9b7e71fc3fd8245 } from '@focus-reactive/payload-plugin-content-releases/client' import { CommentsHeaderButton as CommentsHeaderButton_30d38dd40c31eff500900a16a2792204 } from '@focus-reactive/payload-plugin-comments/components/CommentsHeaderButton' import { CommentsProviderWrapper as CommentsProviderWrapper_bc62ec20ac2037360812e296d7662f4a } from '@focus-reactive/payload-plugin-comments/providers/CommentsProviderWrapper' import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' @@ -16,11 +13,8 @@ export const importMap = { "@focus-reactive/payload-plugin-presets/client#BlockLabelWithPresets": BlockLabelWithPresets_f0a4a6f21f15d606fa328a5e35f17d11, "@focus-reactive/payload-plugin-presets/client#BlocksFieldWithPresets": BlocksFieldWithPresets_f0a4a6f21f15d606fa328a5e35f17d11, "@focus-reactive/payload-plugin-ab/admin/VariantsField#VariantsField": VariantsField_1e5bf2338fb8c7d4f6284f3e67c93951, - "@focus-reactive/payload-plugin-content-releases/client#ReleaseSidebarField": ReleaseSidebarField_01ef71babab0d155f9b7e71fc3fd8245, "@focus-reactive/payload-plugin-presets/client#PresetAdminComponentPreview": PresetAdminComponentPreview_f0a4a6f21f15d606fa328a5e35f17d11, "@focus-reactive/payload-plugin-presets/client#PresetAdminComponentCell": PresetAdminComponentCell_f0a4a6f21f15d606fa328a5e35f17d11, - "@focus-reactive/payload-plugin-content-releases/client#ReleaseActionsField": ReleaseActionsField_01ef71babab0d155f9b7e71fc3fd8245, - "@focus-reactive/payload-plugin-content-releases/client#TargetDocCell": TargetDocCell_01ef71babab0d155f9b7e71fc3fd8245, "@focus-reactive/payload-plugin-comments/components/CommentsHeaderButton#CommentsHeaderButton": CommentsHeaderButton_30d38dd40c31eff500900a16a2792204, "@focus-reactive/payload-plugin-comments/providers/CommentsProviderWrapper#CommentsProviderWrapper": CommentsProviderWrapper_bc62ec20ac2037360812e296d7662f4a, "@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 diff --git a/apps/dev/src/payload-types.ts b/apps/dev/src/payload-types.ts index 61bfd06..d48d58c 100644 --- a/apps/dev/src/payload-types.ts +++ b/apps/dev/src/payload-types.ts @@ -72,27 +72,19 @@ export interface Config { pages: Page; presets: Preset; comments: Comment; - releases: Release; - 'release-items': ReleaseItem; 'payload-kv': PayloadKv; 'payload-jobs': PayloadJob; 'payload-locked-documents': PayloadLockedDocument; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; - collectionsJoins: { - releases: { - items: 'release-items'; - }; - }; + collectionsJoins: {}; collectionsSelect: { users: UsersSelect | UsersSelect; media: MediaSelect | MediaSelect; pages: PagesSelect | PagesSelect; presets: PresetsSelect | PresetsSelect; comments: CommentsSelect | CommentsSelect; - releases: ReleasesSelect | ReleasesSelect; - 'release-items': ReleaseItemsSelect | ReleaseItemsSelect; 'payload-kv': PayloadKvSelect | PayloadKvSelect; 'payload-jobs': PayloadJobsSelect | PayloadJobsSelect; 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; @@ -300,76 +292,6 @@ export interface Comment { updatedAt: string; createdAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "releases". - */ -export interface Release { - id: number; - name: string; - description?: string | null; - status: 'draft' | 'scheduled' | 'publishing' | 'published' | 'reverting' | 'reverted' | 'failed' | 'cancelled'; - scheduledAt?: string | null; - publishedAt?: string | null; - items?: { - docs?: (number | ReleaseItem)[]; - hasNextPage?: boolean; - totalDocs?: number; - }; - rollbackSnapshot?: - | { - [k: string]: unknown; - } - | unknown[] - | string - | number - | boolean - | null; - rollbackSkipped?: - | { - [k: string]: unknown; - } - | unknown[] - | string - | number - | boolean - | null; - errorLog?: - | { - [k: string]: unknown; - } - | unknown[] - | string - | number - | boolean - | null; - updatedAt: string; - createdAt: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "release-items". - */ -export interface ReleaseItem { - id: number; - release: number | Release; - targetCollection: 'pages'; - targetDoc: string; - action: 'publish' | 'unpublish'; - status: 'pending' | 'published' | 'failed' | 'skipped'; - snapshot: - | { - [k: string]: unknown; - } - | unknown[] - | string - | number - | boolean - | null; - baseVersion?: string | null; - updatedAt: string; - createdAt: string; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-kv". @@ -505,14 +427,6 @@ export interface PayloadLockedDocument { | ({ relationTo: 'comments'; value: number | Comment; - } | null) - | ({ - relationTo: 'releases'; - value: number | Release; - } | null) - | ({ - relationTo: 'release-items'; - value: number | ReleaseItem; } | null); globalSlug?: string | null; user: { @@ -685,38 +599,6 @@ export interface CommentsSelect { updatedAt?: T; createdAt?: T; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "releases_select". - */ -export interface ReleasesSelect { - name?: T; - description?: T; - status?: T; - scheduledAt?: T; - publishedAt?: T; - items?: T; - rollbackSnapshot?: T; - rollbackSkipped?: T; - errorLog?: T; - updatedAt?: T; - createdAt?: T; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "release-items_select". - */ -export interface ReleaseItemsSelect { - release?: T; - targetCollection?: T; - targetDoc?: T; - action?: T; - status?: T; - snapshot?: T; - baseVersion?: T; - updatedAt?: T; - createdAt?: T; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-kv_select". diff --git a/apps/dev/src/payload.config.ts b/apps/dev/src/payload.config.ts index 30da882..3b1f04f 100644 --- a/apps/dev/src/payload.config.ts +++ b/apps/dev/src/payload.config.ts @@ -14,7 +14,6 @@ import { abTestingPlugin } from '@focus-reactive/payload-plugin-ab' import { presetsPlugin } from '@focus-reactive/payload-plugin-presets' import { schedulePublicationPlugin } from '@focus-reactive/payload-plugin-scheduling' import { commentsPlugin } from '@focus-reactive/payload-plugin-comments' -import { contentReleasesPlugin } from '@focus-reactive/payload-plugin-content-releases' import { abAdapter } from './lib/ab-testing/dbAdapter' const filename = fileURLToPath(import.meta.url) @@ -73,8 +72,5 @@ export default buildConfig({ ], usernameFieldPath: 'name', }), - contentReleasesPlugin({ - enabledCollections: ['pages'], - }), ], }) diff --git a/bun.lock b/bun.lock index 6f71a0f..b1a01e6 100644 --- a/bun.lock +++ b/bun.lock @@ -21,7 +21,6 @@ "dependencies": { "@focus-reactive/payload-plugin-ab": "workspace:*", "@focus-reactive/payload-plugin-comments": "workspace:*", - "@focus-reactive/payload-plugin-content-releases": "workspace:*", "@focus-reactive/payload-plugin-presets": "workspace:*", "@focus-reactive/payload-plugin-scheduling": "workspace:*", "@payloadcms/db-sqlite": "3.79.0", @@ -97,7 +96,7 @@ }, "packages/payload-plugin-comments": { "name": "@focus-reactive/payload-plugin-comments", - "version": "1.6.0", + "version": "1.6.1", "dependencies": { "@radix-ui/react-dropdown-menu": "^2.1.16", "@tanstack/react-query": "5.0.0", @@ -140,31 +139,9 @@ "react-dom", ], }, - "packages/payload-plugin-content-releases": { - "name": "@focus-reactive/payload-plugin-content-releases", - "version": "0.0.0-development", - "devDependencies": { - "@payloadcms/ui": "3.79.0", - "@types/node": "^20.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "next": "15.4.10", - "payload": "3.79.0", - "react": "^19.0.0", - "tsup": "^8.0.0", - "typescript": "^5.0.0", - "vitest": "^3.0.0", - }, - "peerDependencies": { - "@payloadcms/ui": "^3.0.0", - "next": "^14.0.0 || ^15.0.0", - "payload": "^3.0.0", - "react": "^18.0.0 || ^19.0.0", - }, - }, "packages/payload-plugin-presets": { "name": "@focus-reactive/payload-plugin-presets", - "version": "0.9.1", + "version": "0.10.5", "dependencies": { "@radix-ui/react-popover": "1.1.15", }, @@ -382,8 +359,6 @@ "@focus-reactive/payload-plugin-comments": ["@focus-reactive/payload-plugin-comments@workspace:packages/payload-plugin-comments"], - "@focus-reactive/payload-plugin-content-releases": ["@focus-reactive/payload-plugin-content-releases@workspace:packages/payload-plugin-content-releases"], - "@focus-reactive/payload-plugin-presets": ["@focus-reactive/payload-plugin-presets@workspace:packages/payload-plugin-presets"], "@focus-reactive/payload-plugin-scheduling": ["@focus-reactive/payload-plugin-scheduling@workspace:packages/payload-plugin-scheduling"], @@ -912,12 +887,8 @@ "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], - "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], - "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], - "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], - "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -1026,20 +997,6 @@ "@vercel/edge-config-fs": ["@vercel/edge-config-fs@0.1.0", "", {}, "sha512-NRIBwfcS0bUoUbRWlNGetqjvLSwgYH/BqKqDN7vK1g32p7dN96k0712COgaz6VFizAm9b0g6IG6hR6+hc0KCPg=="], - "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], - - "@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="], - - "@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="], - - "@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="], - - "@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="], - - "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="], - - "@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="], - "abbrev": ["abbrev@2.0.0", "", {}, "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ=="], "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], @@ -1096,8 +1053,6 @@ "arrify": ["arrify@1.0.1", "", {}, "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="], - "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], - "ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="], "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], @@ -1168,8 +1123,6 @@ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], - "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], @@ -1184,8 +1137,6 @@ "charenc": ["charenc@0.0.2", "", {}, "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="], - "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], - "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], @@ -1222,12 +1173,8 @@ "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], - "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], - "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], - "console-table-printer": ["console-table-printer@2.12.1", "", { "dependencies": { "simple-wcswidth": "^1.0.1" } }, "sha512-wKGOQRRvdnd89pCeH96e2Fn4wkbenSP6LMHfjfyNLMbGuHEFbMqQNuxXqd0oXG9caIOQ1FTvc5Uijp9/4jujnQ=="], "content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="], @@ -1290,8 +1237,6 @@ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], - "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], @@ -1376,8 +1321,6 @@ "es-iterator-helpers": ["es-iterator-helpers@1.3.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.1", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.5", "math-intrinsics": "^1.1.0", "safe-array-concat": "^1.1.3" } }, "sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ=="], - "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], - "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], @@ -1438,8 +1381,6 @@ "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], - "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], - "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], @@ -1450,8 +1391,6 @@ "executable": ["executable@4.1.1", "", { "dependencies": { "pify": "^2.2.0" } }, "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg=="], - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "ext-list": ["ext-list@2.2.2", "", { "dependencies": { "mime-db": "^1.28.0" } }, "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA=="], "ext-name": ["ext-name@5.0.0", "", { "dependencies": { "ext-list": "^2.0.0", "sort-keys-length": "^1.0.0" } }, "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ=="], @@ -1498,8 +1437,6 @@ "find-versions": ["find-versions@6.0.0", "", { "dependencies": { "semver-regex": "^4.0.5", "super-regex": "^1.0.0" } }, "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA=="], - "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="], - "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], "flatted": ["flatted@3.4.1", "", {}, "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ=="], @@ -1860,8 +1797,6 @@ "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], - "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], - "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], @@ -1970,8 +1905,6 @@ "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], - "mlly": ["mlly@1.8.1", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ=="], - "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="], "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="], @@ -2102,10 +2035,6 @@ "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - - "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], - "payload": ["payload@3.79.0", "", { "dependencies": { "@next/env": "^15.1.5", "@payloadcms/translations": "3.79.0", "@types/busboy": "1.5.4", "ajv": "8.17.1", "bson-objectid": "2.0.4", "busboy": "^1.6.0", "ci-info": "^4.1.0", "console-table-printer": "2.12.1", "croner": "9.1.0", "dataloader": "2.2.3", "deepmerge": "4.3.1", "file-type": "19.3.0", "get-tsconfig": "4.8.1", "http-status": "2.1.0", "image-size": "2.0.2", "ipaddr.js": "2.2.0", "jose": "5.9.6", "json-schema-to-typescript": "15.0.3", "minimist": "1.2.8", "path-to-regexp": "6.3.0", "pino": "9.14.0", "pino-pretty": "13.1.2", "pluralize": "8.0.0", "qs-esm": "7.0.2", "range-parser": "1.2.1", "sanitize-filename": "1.6.3", "ts-essentials": "10.0.3", "tsx": "4.21.0", "undici": "7.18.2", "uuid": "10.0.0", "ws": "^8.16.0" }, "peerDependencies": { "graphql": "^16.8.1" }, "bin": { "payload": "bin.js" } }, "sha512-Pey2gBhFL5QkAmN2KMkzXdiBS4QOi5IiQF4Ji9hCNu7kaDcNYtgk75EeWRGP4hOcb22+dqYnw2TZm5Zs/0KBKw=="], "peberminta": ["peberminta@0.9.0", "", {}, "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="], @@ -2114,7 +2043,7 @@ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="], @@ -2132,8 +2061,6 @@ "pkg-conf": ["pkg-conf@2.1.0", "", { "dependencies": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" } }, "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g=="], - "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], - "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], @@ -2184,7 +2111,7 @@ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], - "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], "react-datepicker": ["react-datepicker@7.6.0", "", { "dependencies": { "@floating-ui/react": "^0.27.0", "clsx": "^2.1.1", "date-fns": "^3.6.0" }, "peerDependencies": { "react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-9cQH6Z/qa4LrGhzdc3XoHbhrxNcMi9MKjZmYgF/1MNNaJwvdSjv3Xd+jjvrEEbKEf71ZgCA3n7fQbdwd70qCRw=="], @@ -2304,8 +2231,6 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], "signale": ["signale@1.4.0", "", { "dependencies": { "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" } }, "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w=="], @@ -2350,12 +2275,8 @@ "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="], - "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - "state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="], - "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], - "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], "stream-buffers": ["stream-buffers@3.0.3", "", {}, "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw=="], @@ -2398,8 +2319,6 @@ "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], - "strip-outer": ["strip-outer@2.0.0", "", {}, "sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg=="], "strtok3": ["strtok3@8.1.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.1.4" } }, "sha512-ExzDvHYPj6F6QkSNe/JxSlBxTh3OrI6wrAIz53ulxo1c4hBJ1bT9C/JrAthEKHWG9riVH3Xzg7B03Oxty6S2Lw=="], @@ -2444,18 +2363,8 @@ "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], - "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], - "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], - "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], - - "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], - - "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], - "to-no-case": ["to-no-case@1.0.2", "", {}, "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -2524,8 +2433,6 @@ "typescript-eslint": ["typescript-eslint@8.0.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.0.0", "@typescript-eslint/parser": "8.0.0", "@typescript-eslint/utils": "8.0.0" } }, "sha512-yQWBJutWL1PmpmDddIOl9/Mi6vZjqNCjqSGBMQ4vsc2Aiodk0SnbQQWPXbSy0HNuKCuGkw1+u4aQ2mO40TdhDQ=="], - "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], - "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="], @@ -2584,12 +2491,6 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], - - "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], - - "vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], - "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "web-worker": ["web-worker@1.5.0", "", {}, "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw=="], @@ -2610,8 +2511,6 @@ "which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="], - "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], @@ -2670,16 +2569,6 @@ "@focus-reactive/payload-plugin-comments/typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], - "@focus-reactive/payload-plugin-content-releases/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="], - - "@focus-reactive/payload-plugin-content-releases/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@focus-reactive/payload-plugin-content-releases/next": ["next@15.4.10", "", { "dependencies": { "@next/env": "15.4.10", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.4.8", "@next/swc-darwin-x64": "15.4.8", "@next/swc-linux-arm64-gnu": "15.4.8", "@next/swc-linux-arm64-musl": "15.4.8", "@next/swc-linux-x64-gnu": "15.4.8", "@next/swc-linux-x64-musl": "15.4.8", "@next/swc-win32-arm64-msvc": "15.4.8", "@next/swc-win32-x64-msvc": "15.4.8", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-itVlc79QjpKMFMRhP+kbGKaSG/gZM6RCvwhEbwmCNF06CdDiNaoHcbeg0PqkEa2GOcn8KJ0nnc7+yL7EjoYLHQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="], - - "@focus-reactive/payload-plugin-presets/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], - "@focus-reactive/payload-plugin-presets/typescript": ["typescript@5.5.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew=="], "@focus-reactive/payload-plugin-scheduling/typescript": ["typescript@5.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw=="], @@ -2706,20 +2595,30 @@ "@next/eslint-plugin-next/fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="], + "@parcel/watcher/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "@payloadcms/db-sqlite/uuid": ["uuid@9.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="], "@payloadcms/drizzle/uuid": ["uuid@9.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="], + "@payloadcms/live-preview-react/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "@payloadcms/live-preview-react/react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "@payloadcms/richtext-lexical/csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + "@payloadcms/richtext-lexical/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "@payloadcms/richtext-lexical/react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], + "@payloadcms/ui/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "@payloadcms/ui/react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], + "@react-email/render/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "@react-email/render/react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "@repo/eslint-config/eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="], @@ -2758,6 +2657,8 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@tanstack/react-query/react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + "@typescript-eslint/parser/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.0.0", "", { "dependencies": { "@typescript-eslint/types": "8.0.0", "@typescript-eslint/visitor-keys": "8.0.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" } }, "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg=="], "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.57.1", "", {}, "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ=="], @@ -2780,8 +2681,6 @@ "anymatch/normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "babel-plugin-macros/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], "bin-check/execa": ["execa@0.7.0", "", { "dependencies": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" } }, "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw=="], @@ -2858,6 +2757,8 @@ "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "fdir/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], "from2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], @@ -2890,8 +2791,6 @@ "meow/type-fest": ["type-fest@0.18.1", "", {}, "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw=="], - "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "minimist-options/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], "monaco-editor/marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="], @@ -3230,8 +3129,6 @@ "readable-web-to-node-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "safe-array-concat/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], @@ -3264,8 +3161,6 @@ "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], - "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], "tempy/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], @@ -3274,16 +3169,14 @@ "through2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "trim-repeated/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "tsx/esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], "tsx/get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="], - "vite/esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], - - "vite/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - "which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "xss/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], @@ -3336,20 +3229,6 @@ "@focus-reactive/payload-plugin-comments/next/sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - "@focus-reactive/payload-plugin-content-releases/next/@next/env": ["@next/env@15.4.10", "", {}, "sha512-knhmoJ0Vv7VRf6pZEPSnciUG1S4bIhWx+qTYBW/AjxEtlzsiNORPk8sFDCEvqLfmKuey56UB9FL1UdHEV3uBrg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], - "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], @@ -3706,52 +3585,6 @@ "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], - "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], - - "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], - - "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.4", "", { "os": "android", "cpu": "arm64" }, "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw=="], - - "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.4", "", { "os": "android", "cpu": "x64" }, "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw=="], - - "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ=="], - - "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw=="], - - "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw=="], - - "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ=="], - - "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.4", "", { "os": "linux", "cpu": "arm" }, "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg=="], - - "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA=="], - - "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA=="], - - "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA=="], - - "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw=="], - - "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA=="], - - "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw=="], - - "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA=="], - - "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.4", "", { "os": "linux", "cpu": "x64" }, "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA=="], - - "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.4", "", { "os": "none", "cpu": "x64" }, "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg=="], - - "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ=="], - - "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g=="], - - "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg=="], - - "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw=="], - - "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], - "@focus-reactive/payload-plugin-comments/next/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], "@focus-reactive/payload-plugin-comments/next/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], @@ -3794,96 +3627,6 @@ "@focus-reactive/payload-plugin-comments/next/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@focus-reactive/payload-plugin-content-releases/next/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.4", "", { "os": "android", "cpu": "arm64" }, "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.4", "", { "os": "android", "cpu": "x64" }, "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.4", "", { "os": "linux", "cpu": "arm" }, "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.4", "", { "os": "linux", "cpu": "x64" }, "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.4", "", { "os": "none", "cpu": "x64" }, "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw=="], - - "@focus-reactive/payload-plugin-content-releases/tsup/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], - "@manypkg/find-root/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], "@repo/eslint-config/typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1" } }, "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg=="], diff --git a/package.json b/package.json index a72c1f2..7a0135b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "lint": "turbo run lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "check-types": "turbo run check-types", - "release": "multi-semantic-release --ignore-private-packages --ignore-packages @focus-reactive/payload-plugin-content-releases" + "release": "multi-semantic-release --ignore-private-packages" }, "devDependencies": { "@semantic-release/changelog": "6.0.3", diff --git a/packages/payload-plugin-content-releases/.gitignore b/packages/payload-plugin-content-releases/.gitignore deleted file mode 100644 index b947077..0000000 --- a/packages/payload-plugin-content-releases/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ diff --git a/packages/payload-plugin-content-releases/README.md b/packages/payload-plugin-content-releases/README.md deleted file mode 100644 index d4f3808..0000000 --- a/packages/payload-plugin-content-releases/README.md +++ /dev/null @@ -1,229 +0,0 @@ -# @focus-reactive/payload-plugin-content-releases - -Batch content publishing plugin for [Payload CMS](https://payloadcms.com/) v3. Group multiple document changes into a single release and publish them together -- manually or on a schedule. - -The plugin creates two collections (`releases` and `release-items`), exposes REST endpoints for publishing and conflict detection, and optionally supports scheduled releases via a cron-triggered endpoint. - ---- - -## Installation - -```bash -bun add @focus-reactive/payload-plugin-content-releases -# or -pnpm add @focus-reactive/payload-plugin-content-releases -# or -npm install @focus-reactive/payload-plugin-content-releases -``` - -**Peer dependencies:** `payload ^3.0.0` - ---- - -## Quick Start - -```ts -// payload.config.ts -import { buildConfig } from "payload"; -import { contentReleasesPlugin } from "@focus-reactive/payload-plugin-content-releases"; - -export default buildConfig({ - plugins: [ - contentReleasesPlugin({ - enabledCollections: ["pages", "posts"], - schedulerSecret: process.env.CRON_SECRET, - }), - ], -}); -``` - ---- - -## Configuration Reference - -| Option | Type | Required | Default | Description | -| -------------------- | -------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------ | -| `enabledCollections` | `string[]` | **Yes** | -- | Collection slugs that can be added as release items | -| `conflictStrategy` | `"fail" \| "force"` | No | `"fail"` | How to handle documents modified after they were staged (see [Conflict Strategies](#conflict-strategies)) | -| `publishBatchSize` | `number` | No | `20` | Number of items processed per batch during publish | -| `useTransactions` | `boolean` | No | `true` | Whether to use database transactions during publish | -| `schedulerSecret` | `string` | No | -- | Bearer token for the `run-scheduled` endpoint. Omit to disable scheduled releases | -| `access` | `{ releases?, releaseItems? }` | No | -- | Payload access control overrides for the generated collections (each accepts `create`, `read`, `update`, `delete`) | -| `hooks` | `{ afterPublish?, onPublishError? }` | No | -- | Lifecycle hooks called after a release is published or when errors occur | - -### Hooks - -```ts -hooks: { - afterPublish: async ({ releaseId, req }) => { - // Called after a successful publish - }, - onPublishError: async ({ releaseId, errors, req }) => { - // Called when one or more items fail to publish - // errors: Array<{ collection, docId, error }> - }, -} -``` - ---- - -## How It Works - -The plugin adds two collections to your Payload config: - -- **`releases`** -- groups of content changes with a name, description, status, and optional scheduled date. -- **`release-items`** -- individual document operations (publish or unpublish) linked to a release. Each item stores a snapshot of the document data and a `baseVersion` timestamp for conflict detection. - -When a release is published, the plugin iterates through its items in batches, applies each snapshot to the target document, and tracks results. A rollback snapshot of previous document states is stored on the release for reference. - ---- - -## Release Lifecycle - -``` -draft --> scheduled --> publishing --> published - \ \--> failed - \--> cancelled -``` - -| Status | Description | -| ------------ | ------------------------------------------------------------ | -| `draft` | Default state. Items can be added or removed. | -| `scheduled` | A `scheduledAt` date has been set. Awaiting cron trigger. | -| `publishing` | Publish is in progress. | -| `published` | All items were published successfully. | -| `failed` | One or more items failed. Check `errorLog` for details. | -| `cancelled` | Release was manually cancelled. | - -Only `draft` releases can be published via the publish endpoint. Scheduled releases transition automatically when the cron fires. - ---- - -## REST API Endpoints - -### Publish a release - -``` -POST /api/content-releases/:id/publish -``` - -Publishes all items in a `draft` release. Returns the result summary. - -**Success response:** - -```json -{ - "ok": true, - "status": "published", - "published": 5, - "failed": 0 -} -``` - -**Failure response (partial):** - -```json -{ - "ok": true, - "status": "failed", - "published": 3, - "failed": 2, - "errors": [ - { "itemId": "...", "collection": "pages", "docId": "...", "error": "Conflict: document modified since staging" } - ] -} -``` - -### Check for conflicts - -``` -GET /api/content-releases/:id/conflicts -``` - -Returns a list of items whose target documents have been modified since they were staged. - -```json -{ - "conflicts": [ - { - "itemId": "...", - "collection": "pages", - "docId": "...", - "reason": "Document was modified since staging. Expected version: ..., current: ..." - } - ], - "total": 5 -} -``` - -### Run scheduled releases - -``` -GET /api/content-releases/run-scheduled -``` - -Only registered when `schedulerSecret` is provided. Finds all releases with status `scheduled` and a `scheduledAt` date in the past, then publishes them. - -**Authentication:** `Authorization: Bearer ` - -**Response:** - -```json -{ - "ok": true, - "processed": 2, - "results": [ - { "releaseId": "...", "status": "published", "published": 3, "failed": 0 }, - { "releaseId": "...", "status": "failed", "published": 1, "failed": 1 } - ] -} -``` - ---- - -## Scheduled Publishing - -To enable scheduled releases, provide `schedulerSecret` in the plugin config and set up a cron to call the `run-scheduled` endpoint. - -### Vercel - -```json -{ - "crons": [ - { - "path": "/api/content-releases/run-scheduled", - "schedule": "* * * * *" - } - ] -} -``` - -Set `CRON_SECRET` in your Vercel project settings. Vercel automatically sends it as `Authorization: Bearer $CRON_SECRET`. - -### External cron / curl - -```bash -curl -X GET https://your-cms.com/api/content-releases/run-scheduled \ - -H "Authorization: Bearer YOUR_SECRET" -``` - ---- - -## Conflict Strategies - -When a release item is staged, the current `updatedAt` timestamp of the target document is stored as `baseVersion`. At publish time, the plugin compares this against the document's current `updatedAt`. - -| Strategy | Behaviour | -| -------- | ------------------------------------------------------------------------- | -| `fail` | If the document was modified since staging, the item is skipped and marked as failed. This is the default. | -| `force` | Conflicts are ignored. The staged snapshot overwrites the document regardless of intermediate changes. | - -Use the `/conflicts` endpoint to check for conflicts before publishing. - ---- - -## Exports Reference - -| Import path | Exports | -| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -| `@focus-reactive/payload-plugin-content-releases` | `contentReleasesPlugin`, `ContentReleasesPluginConfig`, `ReleaseStatus`, `ReleaseItemAction`, `ReleaseItemStatus`, `ConflictStrategy` | diff --git a/packages/payload-plugin-content-releases/package.json b/packages/payload-plugin-content-releases/package.json deleted file mode 100644 index 9432c73..0000000 --- a/packages/payload-plugin-content-releases/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@focus-reactive/payload-plugin-content-releases", - "version": "0.0.0-development", - "description": "Payload CMS plugin for grouping and atomically publishing batches of content changes", - "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "import": "./dist/index.js", - "types": "./dist/index.d.ts" - }, - "./client": { - "import": "./dist/client.js", - "types": "./dist/client.d.ts" - } - }, - "files": [ - "dist" - ], - "repository": { - "type": "git", - "url": "https://github.com/focusreactive/payload-plugins", - "directory": "packages/payload-plugin-content-releases" - }, - "publishConfig": { - "access": "public" - }, - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "test": "vitest run", - "test:watch": "vitest", - "lint": "eslint src/", - "lint:fix": "eslint src/ --fix", - "format": "prettier --write src/" - }, - "peerDependencies": { - "payload": "^3.0.0", - "@payloadcms/ui": "^3.0.0", - "next": "^14.0.0 || ^15.0.0", - "react": "^18.0.0 || ^19.0.0" - }, - "devDependencies": { - "@payloadcms/ui": "3.79.0", - "@types/node": "^20.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "payload": "3.79.0", - "react": "^19.0.0", - "tsup": "^8.0.0", - "typescript": "^5.0.0", - "vitest": "^3.0.0", - "next": "15.4.10" - }, - "license": "MIT" -} diff --git a/packages/payload-plugin-content-releases/src/__tests__/collections/releaseItems.test.ts b/packages/payload-plugin-content-releases/src/__tests__/collections/releaseItems.test.ts deleted file mode 100644 index a1d3755..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/collections/releaseItems.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { buildReleaseItemsCollection } from "../../collections/releaseItems"; -import { - RELEASE_ITEMS_SLUG, - RELEASES_SLUG, - RELEASE_ITEM_ACTIONS, - RELEASE_ITEM_STATUSES, -} from "../../constants"; - -describe("release-items collection", () => { - const enabledCollections = ["pages", "posts", "products"]; - const collection = buildReleaseItemsCollection(enabledCollections); - - it("should have the correct slug", () => { - expect(collection.slug).toBe(RELEASE_ITEMS_SLUG); - }); - - it("should have release relationship to releases collection", () => { - const field = collection.fields.find((f: any) => f.name === "release") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("relationship"); - expect(field.relationTo).toBe(RELEASES_SLUG); - expect(field.required).toBe(true); - }); - - it("should have targetCollection select with enabled collections", () => { - const field = collection.fields.find((f: any) => f.name === "targetCollection") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("select"); - const values = field.options.map((o: any) => o.value ?? o); - expect(values).toEqual(enabledCollections); - }); - - it("should have targetDoc text field", () => { - const field = collection.fields.find((f: any) => f.name === "targetDoc") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("text"); - expect(field.required).toBe(true); - expect(field.admin?.components?.Cell).toBe( - "@focus-reactive/payload-plugin-content-releases/client#TargetDocCell", - ); - }); - - it("should have action select field", () => { - const field = collection.fields.find((f: any) => f.name === "action") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("select"); - const values = field.options.map((o: any) => o.value ?? o); - for (const action of RELEASE_ITEM_ACTIONS) { - expect(values).toContain(action); - } - }); - - it("should have status select field", () => { - const field = collection.fields.find((f: any) => f.name === "status") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("select"); - const values = field.options.map((o: any) => o.value ?? o); - for (const status of RELEASE_ITEM_STATUSES) { - expect(values).toContain(status); - } - }); - - it("should have snapshot json field", () => { - const field = collection.fields.find((f: any) => f.name === "snapshot") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("json"); - }); - - it("should have baseVersion text field", () => { - const field = collection.fields.find((f: any) => f.name === "baseVersion") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("text"); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/collections/releases.test.ts b/packages/payload-plugin-content-releases/src/__tests__/collections/releases.test.ts deleted file mode 100644 index cc6c5fc..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/collections/releases.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { buildReleasesCollection } from "../../collections/releases"; -import { RELEASES_SLUG, RELEASE_STATUSES } from "../../constants"; - -describe("releases collection", () => { - const collection = buildReleasesCollection(); - - it("should have the correct slug", () => { - expect(collection.slug).toBe(RELEASES_SLUG); - }); - - it("should have required name field", () => { - const nameField = collection.fields.find((f: any) => f.name === "name") as any; - expect(nameField).toBeDefined(); - expect(nameField.type).toBe("text"); - expect(nameField.required).toBe(true); - }); - - it("should have status field with all valid statuses", () => { - const statusField = collection.fields.find((f: any) => f.name === "status") as any; - expect(statusField).toBeDefined(); - expect(statusField.type).toBe("select"); - const optionValues = statusField.options.map((o: any) => o.value ?? o); - for (const status of RELEASE_STATUSES) { - expect(optionValues).toContain(status); - } - }); - - it("should have scheduledAt date field", () => { - const field = collection.fields.find((f: any) => f.name === "scheduledAt") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("date"); - }); - - it("should have publishedAt date field", () => { - const field = collection.fields.find((f: any) => f.name === "publishedAt") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("date"); - }); - - it("should have description textarea field", () => { - const field = collection.fields.find((f: any) => f.name === "description") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("textarea"); - }); - - it("should have rollbackSnapshot json field", () => { - const field = collection.fields.find((f: any) => f.name === "rollbackSnapshot") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("json"); - }); - - it("should have errorLog json field", () => { - const field = collection.fields.find((f: any) => f.name === "errorLog") as any; - expect(field).toBeDefined(); - expect(field.type).toBe("json"); - }); - - it("should apply custom access if provided", () => { - const customAccess = { read: () => true }; - const col = buildReleasesCollection({ access: customAccess }); - expect(col.access?.read).toBe(customAccess.read); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/endpoints/checkConflicts.test.ts b/packages/payload-plugin-content-releases/src/__tests__/endpoints/checkConflicts.test.ts deleted file mode 100644 index fb4c63a..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/endpoints/checkConflicts.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { createCheckConflictsHandler } from "../../endpoints/checkConflicts"; - -describe("checkConflicts handler", () => { - const handler = createCheckConflictsHandler(); - - it("should reject unauthenticated requests", async () => { - const req = { - routeParams: { id: "rel-1" }, - payload: { - find: vi.fn().mockResolvedValue({ docs: [] }), - findByID: vi.fn(), - }, - }; - const response = await handler(req as any); - expect(response.status).toBe(401); - }); - - it("should return empty conflicts for items with matching versions", async () => { - const req = { - routeParams: { id: "rel-1" }, - user: { id: "user-1" }, - payload: { - find: vi.fn().mockResolvedValue({ - docs: [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: "2026-01-01T00:00:00Z", action: "publish" }, - ], - }), - findByID: vi.fn().mockResolvedValue({ id: "doc-1", updatedAt: "2026-01-01T00:00:00Z" }), - }, - }; - const response = await handler(req as any); - const body = await response.json(); - expect(body.conflicts).toHaveLength(0); - }); - - it("should return conflicts for modified documents", async () => { - const req = { - routeParams: { id: "rel-1" }, - user: { id: "user-1" }, - payload: { - find: vi.fn().mockResolvedValue({ - docs: [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: "2026-01-01T00:00:00Z", action: "publish" }, - ], - }), - findByID: vi.fn().mockResolvedValue({ id: "doc-1", updatedAt: "2026-01-02T00:00:00Z" }), - }, - }; - const response = await handler(req as any); - const body = await response.json(); - expect(body.conflicts).toHaveLength(1); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/endpoints/previewRollback.test.ts b/packages/payload-plugin-content-releases/src/__tests__/endpoints/previewRollback.test.ts deleted file mode 100644 index 56cbb18..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/endpoints/previewRollback.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { createPreviewRollbackHandler } from "../../endpoints/previewRollback"; - -function makeReq({ - releaseId = "rel-1", - releaseData = { status: "published" } as any, -} = {}) { - return { - routeParams: { id: releaseId }, - user: { id: "user-1" }, - payload: { - findByID: vi.fn().mockResolvedValue(releaseData), - findVersions: vi.fn().mockResolvedValue({ docs: [] }), - }, - }; -} - -describe("createPreviewRollbackHandler", () => { - it("unauthenticated request → 401", async () => { - const handler = createPreviewRollbackHandler(); - const req = makeReq(); - (req as any).user = undefined; - - const response = await handler(req as any); - - expect(response.status).toBe(401); - }); - - it("non-published release → 400", async () => { - const handler = createPreviewRollbackHandler(); - const req = makeReq({ releaseData: { status: "draft" } }); - - const response = await handler(req as any); - - expect(response.status).toBe(400); - const body = await response.json(); - expect(body.error).toBeTruthy(); - }); - - it("valid published release → 200 with eligible and skipped", async () => { - const handler = createPreviewRollbackHandler(); - const req = makeReq({ - releaseData: { - status: "published", - rollbackSnapshot: [ - { - collection: "pages", - docId: "doc-1", - action: "publish", - previousState: { title: "Old" }, - }, - ], - publishedAt: "2026-01-10T00:00:00.000Z", - }, - }); - - const response = await handler(req as any); - - expect(response.status).toBe(200); - const body = await response.json(); - expect(body).toHaveProperty("eligible"); - expect(body).toHaveProperty("skipped"); - expect(Array.isArray(body.eligible)).toBe(true); - expect(Array.isArray(body.skipped)).toBe(true); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/endpoints/publishRelease.test.ts b/packages/payload-plugin-content-releases/src/__tests__/endpoints/publishRelease.test.ts deleted file mode 100644 index 5e9c471..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/endpoints/publishRelease.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { createPublishReleaseHandler } from "../../endpoints/publishRelease"; - -function makeReq({ - releaseId = "rel-1", - releaseData = { status: "draft", name: "Test" } as any, - releaseItems = [] as any[], - updateResult = {} as any, -} = {}) { - return { - routeParams: { id: releaseId }, - user: { id: "user-1" }, - payload: { - findByID: vi.fn().mockResolvedValue(releaseData), - find: vi.fn().mockResolvedValue({ docs: releaseItems }), - update: vi.fn().mockResolvedValue(updateResult), - }, - }; -} - -describe("publishRelease handler", () => { - const handler = createPublishReleaseHandler({ - conflictStrategy: "fail", - publishBatchSize: 20, - }); - - it("should reject unauthenticated requests", async () => { - const req = makeReq(); - (req as any).user = undefined; - const response = await handler(req as any); - expect(response.status).toBe(401); - }); - - it.each(["publishing", "published", "failed"])("should reject publishing a release with status %s", async (status) => { - const req = makeReq({ releaseData: { status, name: "Test" } }); - const response = await handler(req as any); - expect(response.status).toBe(400); - const body = await response.json(); - expect(body.error).toContain(status); - }); - - it.each(["scheduled", "cancelled"])("should allow publishing a release with status %s", async (status) => { - const req = makeReq({ releaseData: { status, name: "Test" } }); - const response = await handler(req as any); - // 200 with failed status (empty items) is acceptable — the guard passed - expect(response.status).toBe(200); - }); - - it("should handle publishing an empty release as failed", async () => { - const req = makeReq({ releaseItems: [] }); - const response = await handler(req as any); - expect(response.status).toBe(200); - const body = await response.json(); - expect(body.status).toBe("failed"); - }); - - it("should return 200 on successful publish", async () => { - const items = [ - { - id: "item-1", - targetCollection: "pages", - targetDoc: "doc-1", - action: "publish", - status: "pending", - baseVersion: null, - snapshot: { title: "Hello", _status: "published" }, - }, - ]; - const req = makeReq({ releaseItems: items }); - req.payload.findByID - .mockResolvedValueOnce({ status: "draft", name: "Test" }) - .mockResolvedValue({ id: "doc-1", updatedAt: "2026-01-01" }); - - const response = await handler(req as any); - expect(response.status).toBe(200); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/endpoints/rollbackRelease.test.ts b/packages/payload-plugin-content-releases/src/__tests__/endpoints/rollbackRelease.test.ts deleted file mode 100644 index 0dbc525..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/endpoints/rollbackRelease.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { createRollbackReleaseHandler } from "../../endpoints/rollbackRelease"; - -const PUBLISHED_RELEASE_WITH_SNAPSHOT = { - status: "published", - rollbackSnapshot: [ - { - collection: "pages", - docId: "doc-1", - action: "publish", - previousState: { title: "Old", _status: "published" }, - }, - ], - publishedAt: "2026-01-01T00:00:00.000Z", -}; - -function makeReq({ - releaseId = "rel-1", - releaseData = PUBLISHED_RELEASE_WITH_SNAPSHOT as any, -} = {}) { - return { - routeParams: { id: releaseId }, - user: { id: "user-1" }, - payload: { - findByID: vi.fn().mockResolvedValue(releaseData), - findVersions: vi.fn().mockResolvedValue({ docs: [] }), - update: vi.fn().mockResolvedValue({}), - }, - }; -} - -describe("createRollbackReleaseHandler", () => { - it("unauthenticated request → 401", async () => { - const handler = createRollbackReleaseHandler({}); - const req = makeReq(); - (req as any).user = undefined; - - const response = await handler(req as any); - - expect(response.status).toBe(401); - }); - - it("non-published release → 400 with error mentioning the current status", async () => { - const handler = createRollbackReleaseHandler({}); - const req = makeReq({ releaseData: { status: "draft" } }); - - const response = await handler(req as any); - - expect(response.status).toBe(400); - const body = await response.json(); - expect(body.error).toMatch(/draft/i); - }); - - it("all eligible, all succeed → 200, status reverted", async () => { - const handler = createRollbackReleaseHandler({}); - const req = makeReq(); - - const response = await handler(req as any); - - expect(response.status).toBe(200); - const body = await response.json(); - expect(body.status).toBe("reverted"); - }); - - it("all eligible, all fail → status failed", async () => { - const handler = createRollbackReleaseHandler({}); - const req = makeReq(); - - // orchestrateRollback calls: - // 1st findByID → release (in orchestrateRollback) - // 2nd findByID → release (in previewRollback) - // 1st update → set to "reverting" - // 2nd update → restore doc (this should fail) - // 3rd update → set final status - req.payload.update - .mockResolvedValueOnce({}) // set to "reverting" - .mockRejectedValueOnce(new Error("DB error")) // restore doc fails - .mockResolvedValue({}); // set final status - - const response = await handler(req as any); - - expect(response.status).toBe(200); - const body = await response.json(); - expect(body.status).toBe("failed"); - }); - - it("afterRollback hook fires on success", async () => { - const afterRollback = vi.fn().mockResolvedValue(undefined); - const handler = createRollbackReleaseHandler({ hooks: { afterRollback } }); - const req = makeReq(); - - const response = await handler(req as any); - const body = await response.json(); - - expect(body.status).toBe("reverted"); - expect(afterRollback).toHaveBeenCalledOnce(); - expect(afterRollback).toHaveBeenCalledWith( - expect.objectContaining({ releaseId: "rel-1" }), - ); - }); - - it("onRollbackError hook fires on failure", async () => { - const onRollbackError = vi.fn().mockResolvedValue(undefined); - const handler = createRollbackReleaseHandler({ hooks: { onRollbackError } }); - const req = makeReq(); - - req.payload.update - .mockResolvedValueOnce({}) // set to "reverting" - .mockRejectedValueOnce(new Error("DB error")) // restore doc fails - .mockResolvedValue({}); // set final status - - const response = await handler(req as any); - const body = await response.json(); - - expect(body.status).toBe("failed"); - expect(onRollbackError).toHaveBeenCalledOnce(); - expect(onRollbackError).toHaveBeenCalledWith( - expect.objectContaining({ - releaseId: "rel-1", - errors: expect.arrayContaining([ - expect.objectContaining({ docId: "doc-1", error: "DB error" }), - ]), - }), - ); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/endpoints/runScheduled.test.ts b/packages/payload-plugin-content-releases/src/__tests__/endpoints/runScheduled.test.ts deleted file mode 100644 index 3f17079..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/endpoints/runScheduled.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { createRunScheduledHandler } from "../../endpoints/runScheduled"; - -describe("runScheduled handler", () => { - const handler = createRunScheduledHandler({ - secret: "test-secret", - conflictStrategy: "fail", - publishBatchSize: 20, - }); - - it("should reject unauthorized requests", async () => { - const req = { headers: { get: () => null }, payload: {} }; - const response = await handler(req as any); - expect(response.status).toBe(401); - }); - - it("should reject wrong bearer token", async () => { - const req = { headers: { get: () => "Bearer wrong-token" }, payload: {} }; - const response = await handler(req as any); - expect(response.status).toBe(401); - }); - - it("should process due scheduled releases", async () => { - const dueRelease = { - id: "rel-1", - name: "Test Release", - status: "scheduled", - scheduledAt: new Date(Date.now() - 60000).toISOString(), - }; - const req = { - headers: { get: () => "Bearer test-secret" }, - payload: { - find: vi.fn() - .mockResolvedValueOnce({ docs: [dueRelease] }) // find due releases - .mockResolvedValueOnce({ docs: [] }), // find items (empty -> failed) - findByID: vi.fn().mockResolvedValue(dueRelease), - update: vi.fn().mockResolvedValue({}), - }, - }; - - const response = await handler(req as any); - expect(response.status).toBe(200); - const body = await response.json(); - expect(body.ok).toBe(true); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/hooks/releaseItemsBeforeChange.test.ts b/packages/payload-plugin-content-releases/src/__tests__/hooks/releaseItemsBeforeChange.test.ts deleted file mode 100644 index 6d9925e..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/hooks/releaseItemsBeforeChange.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { buildReleaseItemsBeforeChange } from "../../hooks/releaseItemsBeforeChange"; - -function makePayload(releaseStatus: string, existingItems: any[] = []) { - return { - findByID: vi.fn().mockResolvedValue({ status: releaseStatus }), - find: vi.fn().mockResolvedValue({ docs: existingItems }), - }; -} - -function makeArgs( - data: Record, - payload: any, - operation: "create" | "update" = "create", - originalDoc?: Record, -) { - return { - data, - originalDoc, - operation, - req: { payload }, - collection: {} as any, - context: {} as any, - }; -} - -describe("releaseItemsBeforeChange", () => { - const hook = buildReleaseItemsBeforeChange(); - - it("should allow adding items to a draft release", async () => { - const payload = makePayload("draft"); - const data = { - release: "rel-1", - targetCollection: "pages", - targetDoc: "doc-1", - snapshot: { title: "Hello" }, - }; - const result = await hook(makeArgs(data, payload) as any); - expect(result).toEqual(data); - }); - - it("should allow adding items to a scheduled release", async () => { - const payload = makePayload("scheduled"); - const data = { - release: "rel-1", - targetCollection: "pages", - targetDoc: "doc-1", - snapshot: { title: "Hello" }, - }; - const result = await hook(makeArgs(data, payload) as any); - expect(result).toEqual(data); - }); - - it("should reject adding items to a published release", async () => { - const payload = makePayload("published"); - const data = { release: "rel-1", targetCollection: "pages", targetDoc: "doc-1" }; - await expect( - hook(makeArgs(data, payload) as any), - ).rejects.toThrow(/can only be modified/i); - }); - - it("should reject duplicate doc in same release on create", async () => { - const existing = [{ id: "item-99", targetCollection: "pages", targetDoc: "doc-1" }]; - const payload = makePayload("draft", existing); - const data = { - release: "rel-1", - targetCollection: "pages", - targetDoc: "doc-1", - }; - await expect( - hook(makeArgs(data, payload) as any), - ).rejects.toThrow(/already exists in this release/i); - }); - - it("should allow status-only updates when release is publishing", async () => { - const payload = makePayload("publishing", []); - const data = { - release: "rel-1", - status: "published", - }; - const result = await hook( - makeArgs(data, payload, "update", { id: "item-1", status: "pending" }) as any, - ); - expect(result.status).toBe("published"); - }); - - it("should reject content updates when release is publishing", async () => { - const payload = makePayload("publishing", []); - const data = { - release: "rel-1", - targetCollection: "pages", - targetDoc: "doc-1", - snapshot: { title: "Sneaky edit" }, - }; - await expect( - hook(makeArgs(data, payload, "update", { id: "item-1" }) as any), - ).rejects.toThrow(/can only be modified/i); - }); - - it("should allow updates to existing items in draft releases", async () => { - const payload = makePayload("draft", []); - const data = { - release: "rel-1", - targetCollection: "pages", - targetDoc: "doc-1", - snapshot: { title: "Updated" }, - }; - const result = await hook( - makeArgs(data, payload, "update", { id: "item-1" }) as any, - ); - expect(result.snapshot.title).toBe("Updated"); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/hooks/releasesBeforeChange.test.ts b/packages/payload-plugin-content-releases/src/__tests__/hooks/releasesBeforeChange.test.ts deleted file mode 100644 index 6a508e0..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/hooks/releasesBeforeChange.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { releasesBeforeChange } from "../../hooks/releasesBeforeChange"; - -function makeArgs(data: Record, originalDoc?: Record) { - return { - data, - originalDoc: originalDoc ?? {}, - req: {} as any, - operation: "update" as const, - collection: {} as any, - context: {} as any, - }; -} - -describe("releasesBeforeChange", () => { - it("should allow creating a release with draft status", () => { - const args = { - data: { name: "My Release", status: "draft" }, - req: {} as any, - operation: "create" as const, - collection: {} as any, - context: {} as any, - }; - const result = releasesBeforeChange(args as any); - expect(result.status).toBe("draft"); - }); - - it("should force draft status on create regardless of input", () => { - const args = { - data: { name: "My Release", status: "published" }, - req: {} as any, - operation: "create" as const, - collection: {} as any, - context: {} as any, - }; - const result = releasesBeforeChange(args as any); - expect(result.status).toBe("draft"); - }); - - it("should allow valid transition from draft to scheduled", () => { - const result = releasesBeforeChange( - makeArgs({ status: "scheduled" }, { status: "draft" }) as any, - ); - expect(result.status).toBe("scheduled"); - }); - - it("should throw on invalid transition from published to draft", () => { - expect(() => - releasesBeforeChange( - makeArgs({ status: "draft" }, { status: "published" }) as any, - ), - ).toThrow(/Invalid status transition/); - }); - - it("should throw on invalid transition from cancelled to draft", () => { - expect(() => - releasesBeforeChange( - makeArgs({ status: "draft" }, { status: "cancelled" }) as any, - ), - ).toThrow(/Invalid status transition/); - }); - - it("should pass through unchanged status", () => { - const result = releasesBeforeChange( - makeArgs({ status: "draft", name: "Updated" }, { status: "draft" }) as any, - ); - expect(result.name).toBe("Updated"); - }); - - it("should allow valid transition to published without setting publishedAt", () => { - const result = releasesBeforeChange( - makeArgs({ status: "published" }, { status: "publishing" }) as any, - ); - expect(result.publishedAt).toBeUndefined(); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/plugin-endpoints.test.ts b/packages/payload-plugin-content-releases/src/__tests__/plugin-endpoints.test.ts deleted file mode 100644 index 14e3d5e..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/plugin-endpoints.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { contentReleasesPlugin } from "../plugin"; -import type { Config } from "payload"; - -function makeBaseConfig(): Config { - return { - collections: [{ slug: "pages", fields: [] }], - globals: [], - } as unknown as Config; -} - -describe("plugin endpoints", () => { - it("should register publish endpoint", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const endpoint = config.endpoints?.find((e: any) => e.path === "/content-releases/:id/publish"); - expect(endpoint).toBeDefined(); - expect(endpoint?.method).toBe("post"); - }); - - it("should register conflicts endpoint", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const endpoint = config.endpoints?.find((e: any) => e.path === "/content-releases/:id/conflicts"); - expect(endpoint).toBeDefined(); - expect(endpoint?.method).toBe("get"); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/plugin-integration.test.ts b/packages/payload-plugin-content-releases/src/__tests__/plugin-integration.test.ts deleted file mode 100644 index ca90c50..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/plugin-integration.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { contentReleasesPlugin } from "../plugin"; -import { RELEASES_SLUG, RELEASE_ITEMS_SLUG } from "../constants"; -import type { Config } from "payload"; - -function makeBaseConfig(overrides?: Partial): Config { - return { - collections: [ - { slug: "pages", fields: [] }, - { slug: "posts", fields: [] }, - ], - globals: [], - ...overrides, - } as unknown as Config; -} - -describe("contentReleasesPlugin", () => { - it("should return a function", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - expect(typeof plugin).toBe("function"); - }); - - it("should inject releases collection", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const releases = config.collections?.find((c: any) => c.slug === RELEASES_SLUG); - expect(releases).toBeDefined(); - }); - - it("should inject release-items collection", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const items = config.collections?.find((c: any) => c.slug === RELEASE_ITEMS_SLUG); - expect(items).toBeDefined(); - }); - - it("should preserve existing collections", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const pages = config.collections?.find((c: any) => c.slug === "pages"); - const posts = config.collections?.find((c: any) => c.slug === "posts"); - expect(pages).toBeDefined(); - expect(posts).toBeDefined(); - }); - - it("should warn about unknown collection slugs", () => { - const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - const plugin = contentReleasesPlugin({ enabledCollections: ["nonexistent"] }); - plugin(makeBaseConfig()); - expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("nonexistent")); - warnSpy.mockRestore(); - }); - - it("should pass access config to releases collection", () => { - const readFn = () => true; - const plugin = contentReleasesPlugin({ - enabledCollections: ["pages"], - access: { releases: { read: readFn } }, - }); - const config = plugin(makeBaseConfig()) as Config; - const releases = config.collections?.find((c: any) => c.slug === RELEASES_SLUG); - expect((releases as any)?.access?.read).toBe(readFn); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/plugin-sidebar.test.ts b/packages/payload-plugin-content-releases/src/__tests__/plugin-sidebar.test.ts deleted file mode 100644 index a04524a..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/plugin-sidebar.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { contentReleasesPlugin } from "../plugin"; -import type { Config } from "payload"; - -function makeBaseConfig(): Config { - return { - collections: [ - { slug: "pages", fields: [{ name: "title", type: "text" }] }, - { slug: "posts", fields: [{ name: "title", type: "text" }] }, - ], - globals: [], - } as unknown as Config; -} - -describe("plugin sidebar injection", () => { - it("should inject _releases UI field into enabled collections", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const pages = config.collections?.find((c: any) => c.slug === "pages"); - const releasesField = pages?.fields.find((f: any) => f.name === "_releases"); - expect(releasesField).toBeDefined(); - expect((releasesField as any).type).toBe("ui"); - expect((releasesField as any).admin?.position).toBe("sidebar"); - }); - - it("should NOT inject _releases field into non-enabled collections", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const posts = config.collections?.find((c: any) => c.slug === "posts"); - const releasesField = posts?.fields.find((f: any) => f.name === "_releases"); - expect(releasesField).toBeUndefined(); - }); - - it("should pass enabledCollections via admin.custom", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - expect((config.admin as any)?.custom?.contentReleases?.enabledCollections).toEqual(["pages"]); - }); - - it("should preserve existing fields on enabled collections", () => { - const plugin = contentReleasesPlugin({ enabledCollections: ["pages"] }); - const config = plugin(makeBaseConfig()) as Config; - const pages = config.collections?.find((c: any) => c.slug === "pages"); - const titleField = pages?.fields.find((f: any) => f.name === "title"); - expect(titleField).toBeDefined(); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/plugin.test.ts b/packages/payload-plugin-content-releases/src/__tests__/plugin.test.ts deleted file mode 100644 index 630019d..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/plugin.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { describe, it, expect } from "vitest"; - -describe("payload-plugin-content-releases", () => { - it("should be importable", async () => { - const mod = await import("../index"); - expect(mod).toBeDefined(); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/publish/detectConflicts.test.ts b/packages/payload-plugin-content-releases/src/__tests__/publish/detectConflicts.test.ts deleted file mode 100644 index ee3556f..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/publish/detectConflicts.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { detectConflicts } from "../../publish/detectConflicts"; - -function makePayload(docs: Record) { - return { - findByID: vi.fn().mockImplementation(({ collection, id }) => { - const key = `${collection}:${id}`; - if (docs[key]) return Promise.resolve(docs[key]); - return Promise.reject(new Error("Not found")); - }), - }; -} - -describe("detectConflicts", () => { - it("should return no conflicts when baseVersion matches", async () => { - const payload = makePayload({ - "pages:doc-1": { id: "doc-1", updatedAt: "2026-01-01T00:00:00Z" }, - }); - const items = [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: "2026-01-01T00:00:00Z", action: "publish" }, - ]; - const result = await detectConflicts(items as any, payload as any); - expect(result).toHaveLength(0); - }); - - it("should detect conflict when baseVersion differs", async () => { - const payload = makePayload({ - "pages:doc-1": { id: "doc-1", updatedAt: "2026-01-02T00:00:00Z" }, - }); - const items = [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: "2026-01-01T00:00:00Z", action: "publish" }, - ]; - const result = await detectConflicts(items as any, payload as any); - expect(result).toHaveLength(1); - expect(result[0]!.itemId).toBe("item-1"); - }); - - it("should detect conflict when document is missing", async () => { - const payload = makePayload({}); - const items = [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: "2026-01-01T00:00:00Z", action: "publish" }, - ]; - const result = await detectConflicts(items as any, payload as any); - expect(result).toHaveLength(1); - expect(result[0]!.reason).toContain("not found"); - }); - - it("should skip conflict check for items without baseVersion", async () => { - const payload = makePayload({ - "pages:doc-1": { id: "doc-1", updatedAt: "2026-01-02T00:00:00Z" }, - }); - const items = [ - { id: "item-1", targetCollection: "pages", targetDoc: "doc-1", baseVersion: null, action: "publish" }, - ]; - const result = await detectConflicts(items as any, payload as any); - expect(result).toHaveLength(0); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/publish/executePublish.test.ts b/packages/payload-plugin-content-releases/src/__tests__/publish/executePublish.test.ts deleted file mode 100644 index e808b34..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/publish/executePublish.test.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { executePublish } from "../../publish/executePublish"; - -function makePayload({ - findByIdResult = {} as any, - updateResult = {} as any, -} = {}) { - return { - findByID: vi.fn().mockResolvedValue(findByIdResult), - update: vi.fn().mockResolvedValue(updateResult), - }; -} - -function makeItems(overrides: any[] = []) { - return overrides.map((o, i) => ({ - id: `item-${i}`, - targetCollection: "pages", - targetDoc: `doc-${i}`, - action: "publish", - status: "pending", - baseVersion: null, - snapshot: { title: `Page ${i}`, _status: "published" }, - ...o, - })); -} - -describe("executePublish", () => { - it("should publish all items by calling payload.update", async () => { - const payload = makePayload({ findByIdResult: { id: "doc-0", updatedAt: "2026-01-01" } }); - const items = makeItems([{ targetDoc: "doc-0" }]); - - const result = await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - collection: "pages", - id: "doc-0", - data: expect.objectContaining({ title: "Page 0" }), - }), - ); - expect(result.published).toHaveLength(1); - expect(result.failed).toHaveLength(0); - }); - - it("should capture rollback snapshot before publishing", async () => { - const originalDoc = { id: "doc-0", title: "Original", updatedAt: "2026-01-01" }; - const payload = makePayload({ findByIdResult: originalDoc }); - const items = makeItems([{ targetDoc: "doc-0" }]); - - const result = await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(result.rollbackSnapshot).toHaveLength(1); - expect(result.rollbackSnapshot[0]!.previousState).toEqual(originalDoc); - }); - - it("should handle unpublish action by setting _status to draft", async () => { - const payload = makePayload({ - findByIdResult: { id: "doc-0", _status: "published", updatedAt: "2026-01-01" }, - }); - const items = makeItems([{ targetDoc: "doc-0", action: "unpublish" }]); - - await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - data: expect.objectContaining({ _status: "draft" }), - }), - ); - }); - - it("should skip items with conflicts when strategy is fail", async () => { - const payload = makePayload({ - findByIdResult: { id: "doc-0", updatedAt: "2026-01-02T00:00:00Z" }, - }); - const items = makeItems([{ targetDoc: "doc-0", baseVersion: "2026-01-01T00:00:00Z" }]); - - const result = await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(result.failed).toHaveLength(1); - expect(result.published).toHaveLength(0); - }); - - it("should force-publish items with conflicts when strategy is force", async () => { - const payload = makePayload({ - findByIdResult: { id: "doc-0", updatedAt: "2026-01-02T00:00:00Z" }, - }); - const items = makeItems([{ targetDoc: "doc-0", baseVersion: "2026-01-01T00:00:00Z" }]); - - const result = await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "force", - batchSize: 20, - }); - - expect(result.published).toHaveLength(1); - }); - - it("should record errors for failed updates", async () => { - const payload = makePayload({ - findByIdResult: { id: "doc-0", updatedAt: "2026-01-01" }, - }); - payload.update.mockRejectedValue(new Error("DB write failed")); - const items = makeItems([{ targetDoc: "doc-0" }]); - - const result = await executePublish({ - items: items as any, - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(result.failed).toHaveLength(1); - expect(result.failed[0]!.error).toContain("DB write failed"); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/rollback/executeRollback.test.ts b/packages/payload-plugin-content-releases/src/__tests__/rollback/executeRollback.test.ts deleted file mode 100644 index a3000bb..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/rollback/executeRollback.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { executeRollback } from "../../rollback/executeRollback"; -import type { RollbackEntry } from "../../rollback/previewRollback"; - -function makePayload({ updateResult = {} as any } = {}) { - return { update: vi.fn().mockResolvedValue(updateResult) }; -} - -function makeEntry(overrides: Partial = {}): RollbackEntry { - return { - collection: "pages", - docId: "doc-1", - action: "publish", - previousState: { - id: "doc-1", - title: "Old Title", - createdAt: "2026-01-01", - updatedAt: "2026-01-05", - _status: "published", - }, - ...overrides, - }; -} - -describe("executeRollback", () => { - it("all succeed → restored list populated, failed empty", async () => { - const payload = makePayload(); - const entry = makeEntry(); - - const result = await executeRollback({ eligible: [entry], payload: payload as any }); - - expect(result.restored).toHaveLength(1); - expect(result.restored[0]).toEqual({ collection: "pages", docId: "doc-1" }); - expect(result.failed).toHaveLength(0); - }); - - it("previousState === null → entry in failed with correct error, loop continues for other entries", async () => { - const payload = makePayload(); - const nullEntry = makeEntry({ docId: "doc-null", previousState: null }); - const goodEntry = makeEntry({ docId: "doc-good" }); - - const result = await executeRollback({ - eligible: [nullEntry, goodEntry], - payload: payload as any, - }); - - expect(result.failed).toHaveLength(1); - expect(result.failed[0]!.docId).toBe("doc-null"); - expect(result.failed[0]!.error).toBe("No previous state to restore"); - - // Loop continued: good entry was still processed - expect(result.restored).toHaveLength(1); - expect(result.restored[0]!.docId).toBe("doc-good"); - }); - - it("payload.update throws → entry in failed, loop continues for other entries", async () => { - const payload = makePayload(); - payload.update - .mockRejectedValueOnce(new Error("DB error")) - .mockResolvedValue({}); - - const failEntry = makeEntry({ docId: "doc-fail" }); - const goodEntry = makeEntry({ docId: "doc-good" }); - - const result = await executeRollback({ - eligible: [failEntry, goodEntry], - payload: payload as any, - }); - - expect(result.failed).toHaveLength(1); - expect(result.failed[0]!.docId).toBe("doc-fail"); - expect(result.failed[0]!.error).toBe("DB error"); - - // Loop continued: second entry still processed - expect(result.restored).toHaveLength(1); - expect(result.restored[0]!.docId).toBe("doc-good"); - }); - - it("strips id, createdAt, updatedAt before calling payload.update", async () => { - const payload = makePayload(); - const entry = makeEntry(); - - await executeRollback({ eligible: [entry], payload: payload as any }); - - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - data: expect.not.objectContaining({ id: expect.anything() }), - }), - ); - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - data: expect.not.objectContaining({ createdAt: expect.anything() }), - }), - ); - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - data: expect.not.objectContaining({ updatedAt: expect.anything() }), - }), - ); - // Verify remaining fields are still passed - expect(payload.update).toHaveBeenCalledWith( - expect.objectContaining({ - collection: "pages", - id: "doc-1", - data: expect.objectContaining({ title: "Old Title", _status: "published" }), - }), - ); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/rollback/previewRollback.test.ts b/packages/payload-plugin-content-releases/src/__tests__/rollback/previewRollback.test.ts deleted file mode 100644 index 65aa4b3..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/rollback/previewRollback.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { previewRollback } from "../../rollback/previewRollback"; - -function makePayload({ - findByIDResult = {} as any, - findVersionsResult = { docs: [] } as any, -} = {}) { - return { - findByID: vi.fn().mockResolvedValue(findByIDResult), - findVersions: vi.fn().mockResolvedValue(findVersionsResult), - }; -} - -const BASE_RELEASE = { - rollbackSnapshot: [ - { - collection: "pages", - docId: "doc-1", - action: "publish", - previousState: { title: "Old" }, - }, - ], - publishedAt: "2026-01-10T00:00:00.000Z", -}; - -describe("previewRollback", () => { - it("no newer published version → entry is eligible", async () => { - const payload = makePayload({ - findByIDResult: BASE_RELEASE, - findVersionsResult: { - docs: [{ updatedAt: "2026-01-05T00:00:00.000Z" }], - }, - }); - - const result = await previewRollback({ releaseId: "rel-1", payload: payload as any }); - - expect(result.eligible).toHaveLength(1); - expect(result.skipped).toHaveLength(0); - expect(result.eligible[0]!.docId).toBe("doc-1"); - }); - - it("published version with updatedAt after release.publishedAt → entry is skipped", async () => { - const payload = makePayload({ - findByIDResult: BASE_RELEASE, - findVersionsResult: { - docs: [{ updatedAt: "2026-01-15T00:00:00.000Z" }], - }, - }); - - const result = await previewRollback({ releaseId: "rel-1", payload: payload as any }); - - expect(result.eligible).toHaveLength(0); - expect(result.skipped).toHaveLength(1); - expect(result.skipped[0]!.docId).toBe("doc-1"); - }); - - it("no versions at all → entry is eligible", async () => { - const payload = makePayload({ - findByIDResult: BASE_RELEASE, - findVersionsResult: { docs: [] }, - }); - - const result = await previewRollback({ releaseId: "rel-1", payload: payload as any }); - - expect(result.eligible).toHaveLength(1); - expect(result.skipped).toHaveLength(0); - }); - - it("mixed entries → correct split between eligible and skipped", async () => { - const release = { - rollbackSnapshot: [ - { - collection: "pages", - docId: "doc-1", - action: "publish", - previousState: { title: "Old Page" }, - }, - { - collection: "pages", - docId: "doc-2", - action: "publish", - previousState: { title: "Old Page 2" }, - }, - ], - publishedAt: "2026-01-10T00:00:00.000Z", - }; - - const payload = makePayload({ findByIDResult: release }); - // First call: version before publishedAt → eligible - // Second call: version after publishedAt → skipped - payload.findVersions - .mockResolvedValueOnce({ docs: [{ updatedAt: "2026-01-05T00:00:00.000Z" }] }) - .mockResolvedValueOnce({ docs: [{ updatedAt: "2026-01-15T00:00:00.000Z" }] }); - - const result = await previewRollback({ releaseId: "rel-1", payload: payload as any }); - - expect(result.eligible).toHaveLength(1); - expect(result.skipped).toHaveLength(1); - expect(result.eligible[0]!.docId).toBe("doc-1"); - expect(result.skipped[0]!.docId).toBe("doc-2"); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/scheduler/checkScheduledReleases.test.ts b/packages/payload-plugin-content-releases/src/__tests__/scheduler/checkScheduledReleases.test.ts deleted file mode 100644 index 0c6ccfc..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/scheduler/checkScheduledReleases.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { describe, it, expect, vi } from "vitest"; -import { checkScheduledReleases } from "../../scheduler/checkScheduledReleases"; - -function makePayload(dueReleases: any[] = [], items: any[] = []) { - return { - find: vi.fn() - .mockResolvedValueOnce({ docs: dueReleases }) // scheduled releases query - .mockResolvedValue({ docs: items }), // release items query - findByID: vi.fn().mockResolvedValue({ id: "doc-1", updatedAt: "2026-01-01" }), - update: vi.fn().mockResolvedValue({}), - logger: { - info: vi.fn(), - error: vi.fn(), - }, - }; -} - -describe("checkScheduledReleases", () => { - it("should do nothing when no releases are due", async () => { - const payload = makePayload([]); - - await checkScheduledReleases({ - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - // Only one find call (for scheduled releases), no updates - expect(payload.find).toHaveBeenCalledTimes(1); - expect(payload.update).not.toHaveBeenCalled(); - }); - - it("should process due releases", async () => { - const dueRelease = { - id: "rel-1", - name: "Spring Campaign", - status: "scheduled", - scheduledAt: new Date(Date.now() - 60000).toISOString(), - }; - const items = [ - { - id: "item-1", - targetCollection: "pages", - targetDoc: "doc-1", - action: "publish", - status: "pending", - baseVersion: null, - snapshot: { title: "Published", _status: "published" }, - }, - ]; - - const payload = makePayload([dueRelease], items); - - await checkScheduledReleases({ - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - // Should have called update multiple times (status transitions + item updates) - expect(payload.update).toHaveBeenCalled(); - expect(payload.logger.info).toHaveBeenCalledWith( - expect.stringContaining("Spring Campaign"), - ); - }); - - it("should log errors for failed releases", async () => { - const dueRelease = { - id: "rel-1", - name: "Bad Release", - status: "scheduled", - scheduledAt: new Date(Date.now() - 60000).toISOString(), - }; - - const payload = makePayload([dueRelease]); - // Make find fail on second call (items query) - payload.find - .mockReset() - .mockResolvedValueOnce({ docs: [dueRelease] }) - .mockRejectedValueOnce(new Error("DB connection lost")); - // orchestratePublish will throw - payload.update.mockRejectedValue(new Error("DB connection lost")); - - await checkScheduledReleases({ - payload: payload as any, - conflictStrategy: "fail", - batchSize: 20, - }); - - expect(payload.logger.error).toHaveBeenCalledWith( - expect.stringContaining("Bad Release"), - ); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/setup.ts b/packages/payload-plugin-content-releases/src/__tests__/setup.ts deleted file mode 100644 index 94b0528..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/setup.ts +++ /dev/null @@ -1 +0,0 @@ -// Global test setup — add shared mocks here as needed diff --git a/packages/payload-plugin-content-releases/src/__tests__/types.test.ts b/packages/payload-plugin-content-releases/src/__tests__/types.test.ts deleted file mode 100644 index 8517e7f..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/types.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { describe, it, expect } from "vitest"; -import type { - ContentReleasesPluginConfig, - ReleaseStatus, - ReleaseItemAction, - ReleaseItemStatus, - ConflictStrategy, -} from "../types"; - -describe("types", () => { - it("should accept a valid minimal config", () => { - const config: ContentReleasesPluginConfig = { - enabledCollections: ["pages", "posts"], - }; - expect(config.enabledCollections).toHaveLength(2); - }); - - it("should accept a full config", () => { - const config: ContentReleasesPluginConfig = { - enabledCollections: ["pages"], - conflictStrategy: "fail", - publishBatchSize: 50, - useTransactions: true, - access: {}, - hooks: {}, - }; - expect(config.conflictStrategy).toBe("fail"); - }); - - it("should define all release statuses", () => { - const statuses: ReleaseStatus[] = [ - "draft", "scheduled", "publishing", "published", "failed", "cancelled", - ]; - expect(statuses).toHaveLength(6); - }); - - it("should define release item actions", () => { - const actions: ReleaseItemAction[] = ["publish", "unpublish"]; - expect(actions).toHaveLength(2); - }); - - it("should define release item statuses", () => { - const statuses: ReleaseItemStatus[] = ["pending", "published", "failed", "skipped"]; - expect(statuses).toHaveLength(4); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/__tests__/validation/statusTransitions.test.ts b/packages/payload-plugin-content-releases/src/__tests__/validation/statusTransitions.test.ts deleted file mode 100644 index d53f3ae..0000000 --- a/packages/payload-plugin-content-releases/src/__tests__/validation/statusTransitions.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { isValidTransition } from "../../validation/statusTransitions"; -import type { ReleaseStatus } from "../../types"; - -describe("isValidTransition", () => { - const validCases: Array<[ReleaseStatus, ReleaseStatus]> = [ - ["draft", "scheduled"], - ["draft", "publishing"], - ["draft", "cancelled"], - ["scheduled", "draft"], - ["scheduled", "publishing"], - ["publishing", "published"], - ["publishing", "failed"], - ["failed", "draft"], - ["cancelled", "publishing"], - ]; - - const invalidCases: Array<[ReleaseStatus, ReleaseStatus]> = [ - ["published", "draft"], - ["published", "cancelled"], - ["cancelled", "draft"], - ["publishing", "cancelled"], - ["draft", "published"], - ["draft", "failed"], - ["scheduled", "published"], - ]; - - it.each(validCases)("should allow transition from %s to %s", (from, to) => { - expect(isValidTransition(from, to)).toBe(true); - }); - - it.each(invalidCases)("should reject transition from %s to %s", (from, to) => { - expect(isValidTransition(from, to)).toBe(false); - }); - - it("should reject same-state transitions", () => { - expect(isValidTransition("draft", "draft")).toBe(false); - }); -}); diff --git a/packages/payload-plugin-content-releases/src/admin/components/ReleaseActionsField.tsx b/packages/payload-plugin-content-releases/src/admin/components/ReleaseActionsField.tsx deleted file mode 100644 index f7ed0b4..0000000 --- a/packages/payload-plugin-content-releases/src/admin/components/ReleaseActionsField.tsx +++ /dev/null @@ -1,83 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { Button, toast, useDocumentInfo } from "@payloadcms/ui"; -import { useRouter } from "next/navigation"; -import { ReleaseStatus } from "../../types"; -import { RollbackButton } from "./RollbackButton"; - -function getButtonProps(status?: ReleaseStatus): { - disabled: boolean; - tooltip?: string; -} { - switch (status) { - case "publishing": - return { - disabled: true, - tooltip: "Release is currently being published", - }; - case "published": - return { - disabled: true, - tooltip: "This release has already been published", - }; - case "failed": - return { - disabled: true, - tooltip: "Release failed to publish", - }; - default: - return { - disabled: false, - }; - } -} - -export function ReleaseActionsField() { - const { id, data } = useDocumentInfo(); - const router = useRouter(); - const [loading, setLoading] = useState(false); - - if (!id) return null; - - const status = data?.status as ReleaseStatus; - const { disabled, tooltip } = getButtonProps(status); - - const handlePublish = async () => { - setLoading(true); - - try { - const res = await fetch(`/api/content-releases/${id}/publish`, { - method: "POST", - }); - - const data = await res.json(); - if (!res.ok) { - toast.error(data?.error ?? "Publish failed"); - return; - } - - toast.success("Release published"); - router.refresh(); - } catch (err) { - toast.error(err instanceof Error ? err.message : "Publish failed"); - } finally { - setLoading(false); - } - }; - - return ( -
- - {status === "published" && } -
- ); -} diff --git a/packages/payload-plugin-content-releases/src/admin/components/ReleaseDrawer.tsx b/packages/payload-plugin-content-releases/src/admin/components/ReleaseDrawer.tsx deleted file mode 100644 index 5091562..0000000 --- a/packages/payload-plugin-content-releases/src/admin/components/ReleaseDrawer.tsx +++ /dev/null @@ -1,303 +0,0 @@ -"use client"; - -import React, { useCallback, useEffect, useState } from "react"; -import { createPortal } from "react-dom"; -import { Button, Drawer, Pill, toast, useModal, DatePicker } from "@payloadcms/ui"; - -interface Release { - id: string; - name: string; - status: string; - createdAt: string; - scheduledAt?: string; -} - -interface ReleaseDrawerProps { - slug: string; - snapshot: Record | null; - collectionSlug: string; - docId: string; - baseVersion?: string; - onSuccess: () => void; - onBack?: () => void; -} - -export function ReleaseDrawer({ - slug, - snapshot, - collectionSlug, - docId, - baseVersion, - onSuccess, - onBack, -}: ReleaseDrawerProps) { - const { closeModal, modalState, containerRef } = useModal(); - const isOpen = !!modalState[slug]?.isOpen; - const [releases, setReleases] = useState([]); - const [loading, setLoading] = useState(true); - const [creating, setCreating] = useState(false); - const [showCreateForm, setShowCreateForm] = useState(false); - const [newName, setNewName] = useState(""); - const [newDescription, setNewDescription] = useState(""); - const [newScheduledAt, setNewScheduledAt] = useState(""); - - const fetchDraftReleases = useCallback(async () => { - if (!isOpen) return; - setLoading(true); - try { - const res = await fetch( - "/api/releases?where[status][in]=draft,scheduled&sort=-createdAt&limit=100" - ); - if (!res.ok) return; - const data = await res.json(); - setReleases(data.docs ?? []); - } catch { - // non-fatal - } finally { - setLoading(false); - } - }, [isOpen]); - - useEffect(() => { - if (isOpen) { - fetchDraftReleases(); - setShowCreateForm(false); - setNewName(""); - setNewDescription(""); - setNewScheduledAt(""); - } - }, [isOpen, fetchDraftReleases]); - - const addToRelease = useCallback( - async (releaseId: string, releaseName: string) => { - if (!snapshot) return; - try { - const res = await fetch("/api/release-items", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - release: releaseId, - targetCollection: collectionSlug, - targetDoc: docId, - action: "publish", - snapshot, - baseVersion: baseVersion ?? null, - }), - }); - - if (!res.ok) { - const err = await res.json(); - const errMsg = err.errors?.[0]?.message ?? err.message ?? "Failed"; - - if (errMsg.toLowerCase().includes("already exists")) { - const confirmed = window.confirm( - "This document is already in this release. Replace snapshot?" - ); - if (confirmed) { - const existing = await fetch( - `/api/release-items?where[release][equals]=${releaseId}&where[targetDoc][equals]=${docId}&where[targetCollection][equals]=${collectionSlug}&limit=1` - ); - const existingData = await existing.json(); - const existingItem = existingData.docs?.[0]; - if (existingItem) { - await fetch(`/api/release-items/${existingItem.id}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ snapshot, baseVersion: baseVersion ?? null }), - }); - toast.success(`Updated snapshot in "${releaseName}"`); - closeModal(slug); - onSuccess(); - return; - } - } - return; - } - toast.error(errMsg); - return; - } - - toast.success(`Added to "${releaseName}"`); - closeModal(slug); - onSuccess(); - } catch { - toast.error("Failed to add to release"); - } - }, - [collectionSlug, docId, snapshot, baseVersion, slug, closeModal, onSuccess] - ); - - const createAndAdd = useCallback(async () => { - if (!newName.trim()) return; - setCreating(true); - try { - const releaseData: Record = { - name: newName.trim(), - description: newDescription.trim() || undefined, - }; - if (newScheduledAt) { - releaseData.scheduledAt = new Date(newScheduledAt).toISOString(); - } - - const res = await fetch("/api/releases", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(releaseData), - }); - if (!res.ok) { - toast.error("Failed to create release"); - return; - } - const data = await res.json(); - await addToRelease(data.doc.id, data.doc.name); - - if (newScheduledAt) { - await fetch(`/api/releases/${data.doc.id}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ status: "scheduled" }), - }); - } - } catch { - toast.error("Failed to create release"); - } finally { - setCreating(false); - } - }, [newName, newDescription, newScheduledAt, addToRelease]); - - const header = ( -
- {onBack && ( - - )} -

Add to Release

-
- ); - - return ( - <> - {isOpen && containerRef.current && createPortal( -
closeModal(slug)} - />, - containerRef.current, - )} - -
- {/* Create New Release */} - {!showCreateForm ? ( - - ) : ( -
-
- - setNewName(e.target.value)} - placeholder="Release name" - autoFocus - /> -
-
- -