@valkyrianlabs/payload-markdown-docs 0.1.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -0
- package/dist/admin/DocsSetManager.d.ts +2 -0
- package/dist/admin/DocsSetManager.js +298 -0
- package/dist/admin/DocsSetManager.js.map +1 -0
- package/dist/admin/docsSetManagerData.d.ts +25 -0
- package/dist/admin/docsSetManagerData.js +266 -0
- package/dist/admin/docsSetManagerData.js.map +1 -0
- package/dist/admin/docsSetManagerTypes.d.ts +103 -0
- package/dist/admin/docsSetManagerTypes.js +3 -0
- package/dist/admin/docsSetManagerTypes.js.map +1 -0
- package/dist/admin/index.d.ts +3 -0
- package/dist/admin/index.js +4 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/cli/commands/install.d.ts +2 -0
- package/dist/cli/commands/install.js +211 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keygen.d.ts +2 -0
- package/dist/cli/commands/keygen.js +89 -0
- package/dist/cli/commands/keygen.js.map +1 -0
- package/dist/cli/commands/manifest.d.ts +2 -0
- package/dist/cli/commands/manifest.js +50 -0
- package/dist/cli/commands/manifest.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.js +110 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/push.d.ts +3 -0
- package/dist/cli/commands/push.js +308 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.js +109 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/filesystem.d.ts +20 -0
- package/dist/cli/filesystem.js +96 -0
- package/dist/cli/filesystem.js.map +1 -0
- package/dist/cli/format.d.ts +35 -0
- package/dist/cli/format.js +76 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/http.d.ts +19 -0
- package/dist/cli/http.js +39 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +214 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +5 -0
- package/dist/cli/parseArgs.js +219 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/cli/types.d.ts +51 -0
- package/dist/cli/types.js +3 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/collections/docs.d.ts +9 -0
- package/dist/collections/docs.js +168 -0
- package/dist/collections/docs.js.map +1 -0
- package/dist/collections/docsGroups.d.ts +5 -0
- package/dist/collections/docsGroups.js +57 -0
- package/dist/collections/docsGroups.js.map +1 -0
- package/dist/collections/docsSets.d.ts +8 -0
- package/dist/collections/docsSets.js +158 -0
- package/dist/collections/docsSets.js.map +1 -0
- package/dist/collections/index.d.ts +10 -0
- package/dist/collections/index.js +7 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/nonces.d.ts +6 -0
- package/dist/collections/nonces.js +57 -0
- package/dist/collections/nonces.js.map +1 -0
- package/dist/collections/syncRuns.d.ts +5 -0
- package/dist/collections/syncRuns.js +139 -0
- package/dist/collections/syncRuns.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +23 -0
- package/dist/constants.js.map +1 -0
- package/dist/endpoints/index.d.ts +2 -0
- package/dist/endpoints/index.js +3 -0
- package/dist/endpoints/index.js.map +1 -0
- package/dist/endpoints/sync.d.ts +47 -0
- package/dist/endpoints/sync.js +616 -0
- package/dist/endpoints/sync.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/next/PayloadMarkdownDocsPage.d.ts +7 -0
- package/dist/next/PayloadMarkdownDocsPage.js +142 -0
- package/dist/next/PayloadMarkdownDocsPage.js.map +1 -0
- package/dist/next/index.d.ts +9 -0
- package/dist/next/index.js +7 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/markdown.d.ts +14 -0
- package/dist/next/markdown.js +232 -0
- package/dist/next/markdown.js.map +1 -0
- package/dist/next/metadata.d.ts +3 -0
- package/dist/next/metadata.js +33 -0
- package/dist/next/metadata.js.map +1 -0
- package/dist/next/records.d.ts +14 -0
- package/dist/next/records.js +146 -0
- package/dist/next/records.js.map +1 -0
- package/dist/next/route.d.ts +6 -0
- package/dist/next/route.js +271 -0
- package/dist/next/route.js.map +1 -0
- package/dist/next/sidebar.d.ts +15 -0
- package/dist/next/sidebar.js +137 -0
- package/dist/next/sidebar.js.map +1 -0
- package/dist/next/types.d.ts +117 -0
- package/dist/next/types.js +3 -0
- package/dist/next/types.js.map +1 -0
- package/dist/payload/applyDocsSync.d.ts +54 -0
- package/dist/payload/applyDocsSync.js +176 -0
- package/dist/payload/applyDocsSync.js.map +1 -0
- package/dist/payload/docsConflicts.d.ts +12 -0
- package/dist/payload/docsConflicts.js +34 -0
- package/dist/payload/docsConflicts.js.map +1 -0
- package/dist/payload/docsData.d.ts +23 -0
- package/dist/payload/docsData.js +59 -0
- package/dist/payload/docsData.js.map +1 -0
- package/dist/payload/docsSets.d.ts +38 -0
- package/dist/payload/docsSets.js +57 -0
- package/dist/payload/docsSets.js.map +1 -0
- package/dist/payload/existingDocs.d.ts +43 -0
- package/dist/payload/existingDocs.js +97 -0
- package/dist/payload/existingDocs.js.map +1 -0
- package/dist/payload/index.d.ts +15 -0
- package/dist/payload/index.js +10 -0
- package/dist/payload/index.js.map +1 -0
- package/dist/payload/routeCollisions.d.ts +31 -0
- package/dist/payload/routeCollisions.js +104 -0
- package/dist/payload/routeCollisions.js.map +1 -0
- package/dist/payload/syncRuns.d.ts +60 -0
- package/dist/payload/syncRuns.js +53 -0
- package/dist/payload/syncRuns.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +165 -0
- package/dist/plugin.js.map +1 -0
- package/dist/routing/index.d.ts +3 -0
- package/dist/routing/index.js +4 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/paths.d.ts +7 -0
- package/dist/routing/paths.js +23 -0
- package/dist/routing/paths.js.map +1 -0
- package/dist/routing/reservations.d.ts +37 -0
- package/dist/routing/reservations.js +79 -0
- package/dist/routing/reservations.js.map +1 -0
- package/dist/security/canonical.d.ts +12 -0
- package/dist/security/canonical.js +24 -0
- package/dist/security/canonical.js.map +1 -0
- package/dist/security/githubOidc.d.ts +45 -0
- package/dist/security/githubOidc.js +177 -0
- package/dist/security/githubOidc.js.map +1 -0
- package/dist/security/headers.d.ts +22 -0
- package/dist/security/headers.js +44 -0
- package/dist/security/headers.js.map +1 -0
- package/dist/security/index.d.ts +15 -0
- package/dist/security/index.js +9 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/jwks.d.ts +20 -0
- package/dist/security/jwks.js +40 -0
- package/dist/security/jwks.js.map +1 -0
- package/dist/security/jwt.d.ts +10 -0
- package/dist/security/jwt.js +42 -0
- package/dist/security/jwt.js.map +1 -0
- package/dist/security/nonce.d.ts +34 -0
- package/dist/security/nonce.js +43 -0
- package/dist/security/nonce.js.map +1 -0
- package/dist/security/sign.d.ts +13 -0
- package/dist/security/sign.js +39 -0
- package/dist/security/sign.js.map +1 -0
- package/dist/security/verify.d.ts +28 -0
- package/dist/security/verify.js +54 -0
- package/dist/security/verify.js.map +1 -0
- package/dist/skills/codex/SKILL.md +173 -0
- package/dist/skills/codex/examples/docs-page.md +42 -0
- package/dist/skills/codex/examples/github-actions.md +64 -0
- package/dist/skills/codex/reference/admin.md +28 -0
- package/dist/skills/codex/reference/frontmatter.md +39 -0
- package/dist/skills/codex/reference/payload-markdown-directives.md +77 -0
- package/dist/skills/codex/reference/routing.md +35 -0
- package/dist/skills/codex/reference/sync.md +35 -0
- package/dist/skills/codex/reference/troubleshooting.md +53 -0
- package/dist/skills/codex/reference/workflow.md +39 -0
- package/dist/sync/aiExportManifest.d.ts +58 -0
- package/dist/sync/aiExportManifest.js +430 -0
- package/dist/sync/aiExportManifest.js.map +1 -0
- package/dist/sync/frontmatter.d.ts +28 -0
- package/dist/sync/frontmatter.js +210 -0
- package/dist/sync/frontmatter.js.map +1 -0
- package/dist/sync/hash.d.ts +1 -0
- package/dist/sync/hash.js +8 -0
- package/dist/sync/hash.js.map +1 -0
- package/dist/sync/index.d.ts +12 -0
- package/dist/sync/index.js +9 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/manifest.d.ts +58 -0
- package/dist/sync/manifest.js +21 -0
- package/dist/sync/manifest.js.map +1 -0
- package/dist/sync/paths.d.ts +16 -0
- package/dist/sync/paths.js +116 -0
- package/dist/sync/paths.js.map +1 -0
- package/dist/sync/plan.d.ts +29 -0
- package/dist/sync/plan.js +72 -0
- package/dist/sync/plan.js.map +1 -0
- package/dist/sync/validate.d.ts +26 -0
- package/dist/sync/validate.js +308 -0
- package/dist/sync/validate.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +143 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/payload/syncRuns.ts"],"sourcesContent":["import type {\n DocsDeleteBehavior,\n DocsSyncMode,\n DocsValidationIssue,\n} from '../sync/index.js'\n\nexport type SyncRunStatus = 'failed' | 'pending' | 'success'\n\nexport type SyncRunSummary = {\n archive: number\n create: number\n delete: number\n draft: number\n unchanged: number\n update: number\n warnings: number\n}\n\nexport type PayloadRecordId = number | string\n\nexport type SyncRunsPayloadOperations = {\n create: (args: {\n collection: string\n data: Record<string, unknown>\n overrideAccess?: boolean\n }) => Promise<Record<string, unknown>>\n update?: (args: {\n collection: string\n data: Record<string, unknown>\n id: PayloadRecordId\n overrideAccess?: boolean\n }) => Promise<Record<string, unknown>>\n}\n\nexport type CreateSyncRunAuditInput = {\n actor?: string\n bodyHash: string\n branch?: string\n collectionSlug: string\n commit?: string\n completedAt: Date\n deleteBehavior: DocsDeleteBehavior\n effectivePublishMode?: 'draft' | 'preserve' | 'published'\n errors: DocsValidationIssue[]\n fileCount: number\n keyId: string\n mode: DocsSyncMode\n payload: SyncRunsPayloadOperations\n publishRequested: boolean\n repository?: string\n sourceId: string\n startedAt: Date\n status: SyncRunStatus\n summary: SyncRunSummary\n totalBytes: number\n warnings: DocsValidationIssue[]\n}\n\nconst issueToArrayRow = (issue: DocsValidationIssue): { message: string } => ({\n message: issue.path ? `${issue.path}: ${issue.message}` : issue.message,\n})\n\nexport const createSyncRunAudit = async ({\n actor,\n bodyHash,\n branch,\n collectionSlug,\n commit,\n completedAt,\n deleteBehavior,\n effectivePublishMode,\n errors,\n fileCount,\n keyId,\n mode,\n payload,\n publishRequested,\n repository,\n sourceId,\n startedAt,\n status,\n summary,\n totalBytes,\n warnings,\n}: CreateSyncRunAuditInput): Promise<Record<string, unknown>> =>\n payload.create({\n collection: collectionSlug,\n data: {\n actor,\n bodyHash,\n branch,\n commit,\n completedAt: completedAt.toISOString(),\n deleteBehavior,\n effectivePublishMode,\n errors: errors.map(issueToArrayRow),\n fileCount,\n keyId,\n mode,\n publishRequested,\n repository,\n sourceId,\n startedAt: startedAt.toISOString(),\n status,\n summary,\n totalBytes,\n warnings: warnings.map(issueToArrayRow),\n },\n overrideAccess: true,\n })\n\nexport const getRecordId = (\n record: Record<string, unknown>,\n): PayloadRecordId | undefined => {\n if (typeof record.id === 'string' || typeof record.id === 'number') {\n return record.id\n }\n\n return undefined\n}\n\nexport const updateSyncRunAudit = async ({\n collectionSlug,\n completedAt,\n errors,\n payload,\n status,\n summary,\n syncRunId,\n warnings,\n}: {\n collectionSlug: string\n completedAt: Date\n errors?: DocsValidationIssue[]\n payload: SyncRunsPayloadOperations\n status: SyncRunStatus\n summary?: SyncRunSummary\n syncRunId: PayloadRecordId\n warnings?: DocsValidationIssue[]\n}): Promise<Record<string, unknown> | undefined> => {\n if (!payload.update) {\n return undefined\n }\n\n return payload.update({\n id: syncRunId,\n collection: collectionSlug,\n data: {\n completedAt: completedAt.toISOString(),\n errors: errors?.map(issueToArrayRow),\n status,\n summary,\n warnings: warnings?.map(issueToArrayRow),\n },\n overrideAccess: true,\n })\n}\n"],"names":["issueToArrayRow","issue","message","path","createSyncRunAudit","actor","bodyHash","branch","collectionSlug","commit","completedAt","deleteBehavior","effectivePublishMode","errors","fileCount","keyId","mode","payload","publishRequested","repository","sourceId","startedAt","status","summary","totalBytes","warnings","create","collection","data","toISOString","map","overrideAccess","getRecordId","record","id","undefined","updateSyncRunAudit","syncRunId","update"],"mappings":"AA0DA,MAAMA,kBAAkB,CAACC,QAAqD,CAAA;QAC5EC,SAASD,MAAME,IAAI,GAAG,GAAGF,MAAME,IAAI,CAAC,EAAE,EAAEF,MAAMC,OAAO,EAAE,GAAGD,MAAMC,OAAO;IACzE,CAAA;AAEA,OAAO,MAAME,qBAAqB,OAAO,EACvCC,KAAK,EACLC,QAAQ,EACRC,MAAM,EACNC,cAAc,EACdC,MAAM,EACNC,WAAW,EACXC,cAAc,EACdC,oBAAoB,EACpBC,MAAM,EACNC,SAAS,EACTC,KAAK,EACLC,IAAI,EACJC,OAAO,EACPC,gBAAgB,EAChBC,UAAU,EACVC,QAAQ,EACRC,SAAS,EACTC,MAAM,EACNC,OAAO,EACPC,UAAU,EACVC,QAAQ,EACgB,GACxBR,QAAQS,MAAM,CAAC;QACbC,YAAYnB;QACZoB,MAAM;YACJvB;YACAC;YACAC;YACAE;YACAC,aAAaA,YAAYmB,WAAW;YACpClB;YACAC;YACAC,QAAQA,OAAOiB,GAAG,CAAC9B;YACnBc;YACAC;YACAC;YACAE;YACAC;YACAC;YACAC,WAAWA,UAAUQ,WAAW;YAChCP;YACAC;YACAC;YACAC,UAAUA,SAASK,GAAG,CAAC9B;QACzB;QACA+B,gBAAgB;IAClB,GAAE;AAEJ,OAAO,MAAMC,cAAc,CACzBC;IAEA,IAAI,OAAOA,OAAOC,EAAE,KAAK,YAAY,OAAOD,OAAOC,EAAE,KAAK,UAAU;QAClE,OAAOD,OAAOC,EAAE;IAClB;IAEA,OAAOC;AACT,EAAC;AAED,OAAO,MAAMC,qBAAqB,OAAO,EACvC5B,cAAc,EACdE,WAAW,EACXG,MAAM,EACNI,OAAO,EACPK,MAAM,EACNC,OAAO,EACPc,SAAS,EACTZ,QAAQ,EAUT;IACC,IAAI,CAACR,QAAQqB,MAAM,EAAE;QACnB,OAAOH;IACT;IAEA,OAAOlB,QAAQqB,MAAM,CAAC;QACpBJ,IAAIG;QACJV,YAAYnB;QACZoB,MAAM;YACJlB,aAAaA,YAAYmB,WAAW;YACpChB,QAAQA,QAAQiB,IAAI9B;YACpBsB;YACAC;YACAE,UAAUA,UAAUK,IAAI9B;QAC1B;QACA+B,gBAAgB;IAClB;AACF,EAAC"}
|
package/dist/plugin.d.ts
ADDED
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { createDocsCollection, createDocsGroupsCollection, createDocsSetsCollection, createNoncesCollection, createSyncRunsCollection } from './collections/index.js';
|
|
2
|
+
import { DEFAULT_DOCS_COLLECTION_SLUG, DEFAULT_DOCS_GROUPS_COLLECTION_SLUG, DEFAULT_DOCS_ROUTE_BASE, DEFAULT_DOCS_SETS_COLLECTION_SLUG, DEFAULT_DOCS_SYNC_ENDPOINT_PATH, DEFAULT_DOCS_SYNC_NONCES_COLLECTION_SLUG, DEFAULT_DOCS_SYNC_RUNS_COLLECTION_SLUG, DEFAULT_MARKDOWN_FIELD_NAME, DEFAULT_MAX_BODY_BYTES, DEFAULT_PAGES_BRIDGE_FIELD, DEFAULT_PAGES_COLLECTION_SLUG, DEFAULT_PAGES_ROUTE_FIELD } from './constants.js';
|
|
3
|
+
import { createSyncEndpoint } from './endpoints/index.js';
|
|
4
|
+
const normalizeEndpointPath = (path)=>{
|
|
5
|
+
const normalized = `/${path.trim()}`.replace(/\/+/g, '/');
|
|
6
|
+
return normalized.length > 1 ? normalized.replace(/\/+$/g, '') : normalized;
|
|
7
|
+
};
|
|
8
|
+
const resolveCollectionOptions = (pluginOptions)=>{
|
|
9
|
+
if (pluginOptions.target?.type === 'existingCollection') {
|
|
10
|
+
throw new Error('payloadMarkdownDocs: target.type "existingCollection" is not supported yet. Use target.type "docsCollection".');
|
|
11
|
+
}
|
|
12
|
+
const docsSlugFromTarget = pluginOptions.target?.slug;
|
|
13
|
+
const docsSlugFromCollections = pluginOptions.collections?.docs?.slug;
|
|
14
|
+
if (docsSlugFromTarget && docsSlugFromCollections && docsSlugFromTarget !== docsSlugFromCollections) {
|
|
15
|
+
throw new Error('payloadMarkdownDocs: target.slug and collections.docs.slug must match when both are provided.');
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
docsCollectionSlug: docsSlugFromTarget ?? docsSlugFromCollections ?? DEFAULT_DOCS_COLLECTION_SLUG,
|
|
19
|
+
docsEnabled: pluginOptions.collections?.docs?.enabled !== false,
|
|
20
|
+
docsGroupsCollectionSlug: pluginOptions.collections?.docsGroups?.slug ?? DEFAULT_DOCS_GROUPS_COLLECTION_SLUG,
|
|
21
|
+
docsGroupsEnabled: pluginOptions.collections?.docsGroups?.enabled !== false,
|
|
22
|
+
docsSetsCollectionSlug: pluginOptions.collections?.docsSets?.slug ?? DEFAULT_DOCS_SETS_COLLECTION_SLUG,
|
|
23
|
+
docsSetsEnabled: pluginOptions.collections?.docsSets?.enabled !== false,
|
|
24
|
+
enableDrafts: pluginOptions.target?.type === 'docsCollection' ? pluginOptions.target.enableDrafts === true : false,
|
|
25
|
+
markdownFieldName: pluginOptions.target?.type === 'docsCollection' ? pluginOptions.target.markdownField ?? DEFAULT_MARKDOWN_FIELD_NAME : DEFAULT_MARKDOWN_FIELD_NAME,
|
|
26
|
+
noncesCollectionSlug: pluginOptions.collections?.nonces?.slug ?? DEFAULT_DOCS_SYNC_NONCES_COLLECTION_SLUG,
|
|
27
|
+
noncesEnabled: pluginOptions.collections?.nonces?.enabled !== false,
|
|
28
|
+
syncRunsCollectionSlug: pluginOptions.collections?.syncRuns?.slug ?? DEFAULT_DOCS_SYNC_RUNS_COLLECTION_SLUG,
|
|
29
|
+
syncRunsEnabled: pluginOptions.collections?.syncRuns?.enabled !== false
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const assertCollectionOptionCompatibility = ({ docsGroupsEnabled, docsSetsEnabled })=>{
|
|
33
|
+
if (docsSetsEnabled && !docsGroupsEnabled) {
|
|
34
|
+
throw new Error('payloadMarkdownDocs: collections.docsSets requires collections.docsGroups to be enabled.');
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const assertNoCollectionSlugConflicts = (incomingConfig, collectionSlugsToAdd)=>{
|
|
38
|
+
const duplicateRequestedSlug = collectionSlugsToAdd.find((slug, index)=>collectionSlugsToAdd.indexOf(slug) !== index);
|
|
39
|
+
if (duplicateRequestedSlug) {
|
|
40
|
+
throw new Error(`payloadMarkdownDocs: collection slug "${duplicateRequestedSlug}" is configured more than once.`);
|
|
41
|
+
}
|
|
42
|
+
const existingCollectionSlugs = new Set(incomingConfig.collections?.map((collection)=>collection.slug) ?? []);
|
|
43
|
+
const conflictingSlug = collectionSlugsToAdd.find((slug)=>existingCollectionSlugs.has(slug));
|
|
44
|
+
if (conflictingSlug) {
|
|
45
|
+
throw new Error(`payloadMarkdownDocs: collection slug "${conflictingSlug}" already exists in the Payload config.`);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export const payloadMarkdownDocs = (pluginOptions = {})=>(incomingConfig)=>{
|
|
49
|
+
if (pluginOptions.enabled === false) {
|
|
50
|
+
return incomingConfig;
|
|
51
|
+
}
|
|
52
|
+
const { docsCollectionSlug, docsEnabled, docsGroupsCollectionSlug, docsGroupsEnabled, docsSetsCollectionSlug, docsSetsEnabled, enableDrafts, markdownFieldName, noncesCollectionSlug, noncesEnabled, syncRunsCollectionSlug, syncRunsEnabled } = resolveCollectionOptions(pluginOptions);
|
|
53
|
+
assertCollectionOptionCompatibility({
|
|
54
|
+
docsCollectionSlug,
|
|
55
|
+
docsEnabled,
|
|
56
|
+
docsGroupsCollectionSlug,
|
|
57
|
+
docsGroupsEnabled,
|
|
58
|
+
docsSetsCollectionSlug,
|
|
59
|
+
docsSetsEnabled,
|
|
60
|
+
enableDrafts,
|
|
61
|
+
markdownFieldName,
|
|
62
|
+
noncesCollectionSlug,
|
|
63
|
+
noncesEnabled,
|
|
64
|
+
syncRunsCollectionSlug,
|
|
65
|
+
syncRunsEnabled
|
|
66
|
+
});
|
|
67
|
+
const endpointPath = normalizeEndpointPath(pluginOptions.endpoint?.path ?? DEFAULT_DOCS_SYNC_ENDPOINT_PATH);
|
|
68
|
+
const collectionSlugsToAdd = [
|
|
69
|
+
...docsGroupsEnabled ? [
|
|
70
|
+
docsGroupsCollectionSlug
|
|
71
|
+
] : [],
|
|
72
|
+
...docsSetsEnabled ? [
|
|
73
|
+
docsSetsCollectionSlug
|
|
74
|
+
] : [],
|
|
75
|
+
...docsEnabled ? [
|
|
76
|
+
docsCollectionSlug
|
|
77
|
+
] : [],
|
|
78
|
+
...syncRunsEnabled ? [
|
|
79
|
+
syncRunsCollectionSlug
|
|
80
|
+
] : [],
|
|
81
|
+
...noncesEnabled ? [
|
|
82
|
+
noncesCollectionSlug
|
|
83
|
+
] : []
|
|
84
|
+
];
|
|
85
|
+
assertNoCollectionSlugConflicts(incomingConfig, collectionSlugsToAdd);
|
|
86
|
+
const addedCollections = [
|
|
87
|
+
...docsGroupsEnabled ? [
|
|
88
|
+
createDocsGroupsCollection({
|
|
89
|
+
slug: docsGroupsCollectionSlug
|
|
90
|
+
})
|
|
91
|
+
] : [],
|
|
92
|
+
...docsSetsEnabled ? [
|
|
93
|
+
createDocsSetsCollection({
|
|
94
|
+
slug: docsSetsCollectionSlug,
|
|
95
|
+
docsCollectionSlug: docsEnabled ? docsCollectionSlug : undefined,
|
|
96
|
+
docsGroupsCollectionSlug,
|
|
97
|
+
syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined
|
|
98
|
+
})
|
|
99
|
+
] : [],
|
|
100
|
+
...docsEnabled ? [
|
|
101
|
+
createDocsCollection({
|
|
102
|
+
slug: docsCollectionSlug,
|
|
103
|
+
docsSetsCollectionSlug: docsSetsEnabled ? docsSetsCollectionSlug : undefined,
|
|
104
|
+
enableDrafts,
|
|
105
|
+
markdownFieldName,
|
|
106
|
+
syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined
|
|
107
|
+
})
|
|
108
|
+
] : [],
|
|
109
|
+
...syncRunsEnabled ? [
|
|
110
|
+
createSyncRunsCollection({
|
|
111
|
+
slug: syncRunsCollectionSlug
|
|
112
|
+
})
|
|
113
|
+
] : [],
|
|
114
|
+
...noncesEnabled ? [
|
|
115
|
+
createNoncesCollection({
|
|
116
|
+
slug: noncesCollectionSlug,
|
|
117
|
+
syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined
|
|
118
|
+
})
|
|
119
|
+
] : []
|
|
120
|
+
];
|
|
121
|
+
return {
|
|
122
|
+
...incomingConfig,
|
|
123
|
+
collections: [
|
|
124
|
+
...incomingConfig.collections ?? [],
|
|
125
|
+
...addedCollections
|
|
126
|
+
],
|
|
127
|
+
endpoints: [
|
|
128
|
+
...incomingConfig.endpoints ?? [],
|
|
129
|
+
createSyncEndpoint({
|
|
130
|
+
allowHardDelete: pluginOptions.sync?.allowHardDelete,
|
|
131
|
+
allowPublish: pluginOptions.sync?.allowPublish,
|
|
132
|
+
allowWrites: pluginOptions.sync?.allowWrites,
|
|
133
|
+
auth: pluginOptions.auth,
|
|
134
|
+
defaultPublishMode: pluginOptions.sync?.defaultPublishMode,
|
|
135
|
+
deleteBehavior: pluginOptions.sync?.deleteBehavior,
|
|
136
|
+
docsCollectionSlug,
|
|
137
|
+
docsEnabled,
|
|
138
|
+
docsEnableDrafts: enableDrafts,
|
|
139
|
+
docsSetsCollectionSlug,
|
|
140
|
+
docsSetsEnabled,
|
|
141
|
+
endpointPath,
|
|
142
|
+
markdownFieldName,
|
|
143
|
+
maxBodyBytes: pluginOptions.endpoint?.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,
|
|
144
|
+
noncesCollectionSlug,
|
|
145
|
+
noncesEnabled,
|
|
146
|
+
requireDryRunBeforeApply: pluginOptions.sync?.requireDryRunBeforeApply,
|
|
147
|
+
routeBase: DEFAULT_DOCS_ROUTE_BASE,
|
|
148
|
+
routing: {
|
|
149
|
+
pages: {
|
|
150
|
+
allowBridgePages: pluginOptions.routing?.pages?.allowBridgePages ?? true,
|
|
151
|
+
bridgeField: pluginOptions.routing?.pages?.bridgeField ?? DEFAULT_PAGES_BRIDGE_FIELD,
|
|
152
|
+
collection: pluginOptions.routing?.pages?.collection ?? DEFAULT_PAGES_COLLECTION_SLUG,
|
|
153
|
+
enabled: pluginOptions.routing?.pages?.enabled === true,
|
|
154
|
+
routeField: pluginOptions.routing?.pages?.routeField ?? DEFAULT_PAGES_ROUTE_FIELD
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
sources: pluginOptions.sources,
|
|
158
|
+
syncRunsCollectionSlug,
|
|
159
|
+
syncRunsEnabled
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config, Plugin } from 'payload'\n\nimport type { PayloadMarkdownDocsConfig } from './types.js'\n\nimport {\n createDocsCollection,\n createDocsGroupsCollection,\n createDocsSetsCollection,\n createNoncesCollection,\n createSyncRunsCollection,\n} from './collections/index.js'\nimport {\n DEFAULT_DOCS_COLLECTION_SLUG,\n DEFAULT_DOCS_GROUPS_COLLECTION_SLUG,\n DEFAULT_DOCS_ROUTE_BASE,\n DEFAULT_DOCS_SETS_COLLECTION_SLUG,\n DEFAULT_DOCS_SYNC_ENDPOINT_PATH,\n DEFAULT_DOCS_SYNC_NONCES_COLLECTION_SLUG,\n DEFAULT_DOCS_SYNC_RUNS_COLLECTION_SLUG,\n DEFAULT_MARKDOWN_FIELD_NAME,\n DEFAULT_MAX_BODY_BYTES,\n DEFAULT_PAGES_BRIDGE_FIELD,\n DEFAULT_PAGES_COLLECTION_SLUG,\n DEFAULT_PAGES_ROUTE_FIELD,\n} from './constants.js'\nimport { createSyncEndpoint } from './endpoints/index.js'\n\ntype ResolvedCollectionOptions = {\n docsCollectionSlug: string\n docsEnabled: boolean\n docsGroupsCollectionSlug: string\n docsGroupsEnabled: boolean\n docsSetsCollectionSlug: string\n docsSetsEnabled: boolean\n enableDrafts: boolean\n markdownFieldName: string\n noncesCollectionSlug: string\n noncesEnabled: boolean\n syncRunsCollectionSlug: string\n syncRunsEnabled: boolean\n}\n\nconst normalizeEndpointPath = (path: string): string => {\n const normalized = `/${path.trim()}`.replace(/\\/+/g, '/')\n\n return normalized.length > 1 ? normalized.replace(/\\/+$/g, '') : normalized\n}\n\nconst resolveCollectionOptions = (\n pluginOptions: PayloadMarkdownDocsConfig,\n): ResolvedCollectionOptions => {\n if (pluginOptions.target?.type === 'existingCollection') {\n throw new Error(\n 'payloadMarkdownDocs: target.type \"existingCollection\" is not supported yet. Use target.type \"docsCollection\".',\n )\n }\n\n const docsSlugFromTarget = pluginOptions.target?.slug\n const docsSlugFromCollections = pluginOptions.collections?.docs?.slug\n\n if (\n docsSlugFromTarget &&\n docsSlugFromCollections &&\n docsSlugFromTarget !== docsSlugFromCollections\n ) {\n throw new Error(\n 'payloadMarkdownDocs: target.slug and collections.docs.slug must match when both are provided.',\n )\n }\n\n return {\n docsCollectionSlug:\n docsSlugFromTarget ?? docsSlugFromCollections ?? DEFAULT_DOCS_COLLECTION_SLUG,\n docsEnabled: pluginOptions.collections?.docs?.enabled !== false,\n docsGroupsCollectionSlug:\n pluginOptions.collections?.docsGroups?.slug ?? DEFAULT_DOCS_GROUPS_COLLECTION_SLUG,\n docsGroupsEnabled: pluginOptions.collections?.docsGroups?.enabled !== false,\n docsSetsCollectionSlug:\n pluginOptions.collections?.docsSets?.slug ?? DEFAULT_DOCS_SETS_COLLECTION_SLUG,\n docsSetsEnabled: pluginOptions.collections?.docsSets?.enabled !== false,\n enableDrafts:\n pluginOptions.target?.type === 'docsCollection'\n ? pluginOptions.target.enableDrafts === true\n : false,\n markdownFieldName:\n pluginOptions.target?.type === 'docsCollection'\n ? pluginOptions.target.markdownField ?? DEFAULT_MARKDOWN_FIELD_NAME\n : DEFAULT_MARKDOWN_FIELD_NAME,\n noncesCollectionSlug:\n pluginOptions.collections?.nonces?.slug ?? DEFAULT_DOCS_SYNC_NONCES_COLLECTION_SLUG,\n noncesEnabled: pluginOptions.collections?.nonces?.enabled !== false,\n syncRunsCollectionSlug:\n pluginOptions.collections?.syncRuns?.slug ?? DEFAULT_DOCS_SYNC_RUNS_COLLECTION_SLUG,\n syncRunsEnabled: pluginOptions.collections?.syncRuns?.enabled !== false,\n }\n}\n\nconst assertCollectionOptionCompatibility = ({\n docsGroupsEnabled,\n docsSetsEnabled,\n}: ResolvedCollectionOptions) => {\n if (docsSetsEnabled && !docsGroupsEnabled) {\n throw new Error(\n 'payloadMarkdownDocs: collections.docsSets requires collections.docsGroups to be enabled.',\n )\n }\n}\n\nconst assertNoCollectionSlugConflicts = (\n incomingConfig: Config,\n collectionSlugsToAdd: string[],\n) => {\n const duplicateRequestedSlug = collectionSlugsToAdd.find(\n (slug, index) => collectionSlugsToAdd.indexOf(slug) !== index,\n )\n\n if (duplicateRequestedSlug) {\n throw new Error(\n `payloadMarkdownDocs: collection slug \"${duplicateRequestedSlug}\" is configured more than once.`,\n )\n }\n\n const existingCollectionSlugs = new Set(\n incomingConfig.collections?.map((collection) => collection.slug) ?? [],\n )\n\n const conflictingSlug = collectionSlugsToAdd.find((slug) =>\n existingCollectionSlugs.has(slug),\n )\n\n if (conflictingSlug) {\n throw new Error(\n `payloadMarkdownDocs: collection slug \"${conflictingSlug}\" already exists in the Payload config.`,\n )\n }\n}\n\nexport const payloadMarkdownDocs =\n (pluginOptions: PayloadMarkdownDocsConfig = {}): Plugin =>\n (incomingConfig: Config): Config => {\n if (pluginOptions.enabled === false) {\n return incomingConfig\n }\n\n const {\n docsCollectionSlug,\n docsEnabled,\n docsGroupsCollectionSlug,\n docsGroupsEnabled,\n docsSetsCollectionSlug,\n docsSetsEnabled,\n enableDrafts,\n markdownFieldName,\n noncesCollectionSlug,\n noncesEnabled,\n syncRunsCollectionSlug,\n syncRunsEnabled,\n } = resolveCollectionOptions(pluginOptions)\n assertCollectionOptionCompatibility({\n docsCollectionSlug,\n docsEnabled,\n docsGroupsCollectionSlug,\n docsGroupsEnabled,\n docsSetsCollectionSlug,\n docsSetsEnabled,\n enableDrafts,\n markdownFieldName,\n noncesCollectionSlug,\n noncesEnabled,\n syncRunsCollectionSlug,\n syncRunsEnabled,\n })\n const endpointPath = normalizeEndpointPath(\n pluginOptions.endpoint?.path ?? DEFAULT_DOCS_SYNC_ENDPOINT_PATH,\n )\n\n const collectionSlugsToAdd = [\n ...(docsGroupsEnabled ? [docsGroupsCollectionSlug] : []),\n ...(docsSetsEnabled ? [docsSetsCollectionSlug] : []),\n ...(docsEnabled ? [docsCollectionSlug] : []),\n ...(syncRunsEnabled ? [syncRunsCollectionSlug] : []),\n ...(noncesEnabled ? [noncesCollectionSlug] : []),\n ]\n\n assertNoCollectionSlugConflicts(incomingConfig, collectionSlugsToAdd)\n\n const addedCollections = [\n ...(docsGroupsEnabled\n ? [\n createDocsGroupsCollection({\n slug: docsGroupsCollectionSlug,\n }),\n ]\n : []),\n ...(docsSetsEnabled\n ? [\n createDocsSetsCollection({\n slug: docsSetsCollectionSlug,\n docsCollectionSlug: docsEnabled ? docsCollectionSlug : undefined,\n docsGroupsCollectionSlug,\n syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined,\n }),\n ]\n : []),\n ...(docsEnabled\n ? [\n createDocsCollection({\n slug: docsCollectionSlug,\n docsSetsCollectionSlug: docsSetsEnabled\n ? docsSetsCollectionSlug\n : undefined,\n enableDrafts,\n markdownFieldName,\n syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined,\n }),\n ]\n : []),\n ...(syncRunsEnabled\n ? [\n createSyncRunsCollection({\n slug: syncRunsCollectionSlug,\n }),\n ]\n : []),\n ...(noncesEnabled\n ? [\n createNoncesCollection({\n slug: noncesCollectionSlug,\n syncRunsCollectionSlug: syncRunsEnabled ? syncRunsCollectionSlug : undefined,\n }),\n ]\n : []),\n ]\n\n return {\n ...incomingConfig,\n collections: [...(incomingConfig.collections ?? []), ...addedCollections],\n endpoints: [\n ...(incomingConfig.endpoints ?? []),\n createSyncEndpoint({\n allowHardDelete: pluginOptions.sync?.allowHardDelete,\n allowPublish: pluginOptions.sync?.allowPublish,\n allowWrites: pluginOptions.sync?.allowWrites,\n auth: pluginOptions.auth,\n defaultPublishMode: pluginOptions.sync?.defaultPublishMode,\n deleteBehavior: pluginOptions.sync?.deleteBehavior,\n docsCollectionSlug,\n docsEnabled,\n docsEnableDrafts: enableDrafts,\n docsSetsCollectionSlug,\n docsSetsEnabled,\n endpointPath,\n markdownFieldName,\n maxBodyBytes: pluginOptions.endpoint?.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES,\n noncesCollectionSlug,\n noncesEnabled,\n requireDryRunBeforeApply: pluginOptions.sync?.requireDryRunBeforeApply,\n routeBase: DEFAULT_DOCS_ROUTE_BASE,\n routing: {\n pages: {\n allowBridgePages:\n pluginOptions.routing?.pages?.allowBridgePages ?? true,\n bridgeField:\n pluginOptions.routing?.pages?.bridgeField ?? DEFAULT_PAGES_BRIDGE_FIELD,\n collection:\n pluginOptions.routing?.pages?.collection ?? DEFAULT_PAGES_COLLECTION_SLUG,\n enabled: pluginOptions.routing?.pages?.enabled === true,\n routeField:\n pluginOptions.routing?.pages?.routeField ?? DEFAULT_PAGES_ROUTE_FIELD,\n },\n },\n sources: pluginOptions.sources,\n syncRunsCollectionSlug,\n syncRunsEnabled,\n }),\n ],\n }\n }\n"],"names":["createDocsCollection","createDocsGroupsCollection","createDocsSetsCollection","createNoncesCollection","createSyncRunsCollection","DEFAULT_DOCS_COLLECTION_SLUG","DEFAULT_DOCS_GROUPS_COLLECTION_SLUG","DEFAULT_DOCS_ROUTE_BASE","DEFAULT_DOCS_SETS_COLLECTION_SLUG","DEFAULT_DOCS_SYNC_ENDPOINT_PATH","DEFAULT_DOCS_SYNC_NONCES_COLLECTION_SLUG","DEFAULT_DOCS_SYNC_RUNS_COLLECTION_SLUG","DEFAULT_MARKDOWN_FIELD_NAME","DEFAULT_MAX_BODY_BYTES","DEFAULT_PAGES_BRIDGE_FIELD","DEFAULT_PAGES_COLLECTION_SLUG","DEFAULT_PAGES_ROUTE_FIELD","createSyncEndpoint","normalizeEndpointPath","path","normalized","trim","replace","length","resolveCollectionOptions","pluginOptions","target","type","Error","docsSlugFromTarget","slug","docsSlugFromCollections","collections","docs","docsCollectionSlug","docsEnabled","enabled","docsGroupsCollectionSlug","docsGroups","docsGroupsEnabled","docsSetsCollectionSlug","docsSets","docsSetsEnabled","enableDrafts","markdownFieldName","markdownField","noncesCollectionSlug","nonces","noncesEnabled","syncRunsCollectionSlug","syncRuns","syncRunsEnabled","assertCollectionOptionCompatibility","assertNoCollectionSlugConflicts","incomingConfig","collectionSlugsToAdd","duplicateRequestedSlug","find","index","indexOf","existingCollectionSlugs","Set","map","collection","conflictingSlug","has","payloadMarkdownDocs","endpointPath","endpoint","addedCollections","undefined","endpoints","allowHardDelete","sync","allowPublish","allowWrites","auth","defaultPublishMode","deleteBehavior","docsEnableDrafts","maxBodyBytes","requireDryRunBeforeApply","routeBase","routing","pages","allowBridgePages","bridgeField","routeField","sources"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { deriveDocsSetRouteBase, isRouteDescendant, joinRouteSegments, normalizeRoutePath, } from './paths.js';
|
|
2
|
+
export { createDocRouteReservations, createDocsGroupRouteReservation, createDocsSetRouteReservation, findPageRouteCollisions, findRouteReservationCollisions, } from './reservations.js';
|
|
3
|
+
export type { DocsRouteCollision, DocsRouteCollisionReason, DocsRouteReservation, DocsRouteReservationOwnerType, } from './reservations.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { deriveDocsSetRouteBase, isRouteDescendant, joinRouteSegments, normalizeRoutePath } from './paths.js';
|
|
2
|
+
export { createDocRouteReservations, createDocsGroupRouteReservation, createDocsSetRouteReservation, findPageRouteCollisions, findRouteReservationCollisions } from './reservations.js';
|
|
3
|
+
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routing/index.ts"],"sourcesContent":["export {\n deriveDocsSetRouteBase,\n isRouteDescendant,\n joinRouteSegments,\n normalizeRoutePath,\n} from './paths.js'\nexport {\n createDocRouteReservations,\n createDocsGroupRouteReservation,\n createDocsSetRouteReservation,\n findPageRouteCollisions,\n findRouteReservationCollisions,\n} from './reservations.js'\nexport type {\n DocsRouteCollision,\n DocsRouteCollisionReason,\n DocsRouteReservation,\n DocsRouteReservationOwnerType,\n} from './reservations.js'\n"],"names":["deriveDocsSetRouteBase","isRouteDescendant","joinRouteSegments","normalizeRoutePath","createDocRouteReservations","createDocsGroupRouteReservation","createDocsSetRouteReservation","findPageRouteCollisions","findRouteReservationCollisions"],"mappings":"AAAA,SACEA,sBAAsB,EACtBC,iBAAiB,EACjBC,iBAAiB,EACjBC,kBAAkB,QACb,aAAY;AACnB,SACEC,0BAA0B,EAC1BC,+BAA+B,EAC/BC,6BAA6B,EAC7BC,uBAAuB,EACvBC,8BAA8B,QACzB,oBAAmB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const normalizeRoutePath: (input: string) => string;
|
|
2
|
+
export declare const joinRouteSegments: (...segments: (string | undefined)[]) => string;
|
|
3
|
+
export declare const deriveDocsSetRouteBase: ({ docsSetSlug, groupRoutePath, }: {
|
|
4
|
+
docsSetSlug: string;
|
|
5
|
+
groupRoutePath?: string;
|
|
6
|
+
}) => string;
|
|
7
|
+
export declare const isRouteDescendant: (parent: string, child: string) => boolean;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const normalizeRoutePath = (input)=>{
|
|
2
|
+
const trimmed = input.trim();
|
|
3
|
+
if (!trimmed || trimmed === '/') {
|
|
4
|
+
return '/';
|
|
5
|
+
}
|
|
6
|
+
const normalized = `/${trimmed}`.replace(/\\/g, '/').replace(/\/+/g, '/').replace(/\/+$/g, '');
|
|
7
|
+
return normalized || '/';
|
|
8
|
+
};
|
|
9
|
+
export const joinRouteSegments = (...segments)=>{
|
|
10
|
+
const normalizedSegments = segments.flatMap((segment)=>(segment ?? '').split(/[\\/]+/)).map((segment)=>segment.trim()).filter(Boolean);
|
|
11
|
+
return normalizeRoutePath(normalizedSegments.join('/'));
|
|
12
|
+
};
|
|
13
|
+
export const deriveDocsSetRouteBase = ({ docsSetSlug, groupRoutePath })=>joinRouteSegments(groupRoutePath ?? '/', docsSetSlug);
|
|
14
|
+
export const isRouteDescendant = (parent, child)=>{
|
|
15
|
+
const normalizedParent = normalizeRoutePath(parent);
|
|
16
|
+
const normalizedChild = normalizeRoutePath(child);
|
|
17
|
+
if (normalizedParent === '/') {
|
|
18
|
+
return normalizedChild !== '/';
|
|
19
|
+
}
|
|
20
|
+
return normalizedChild.startsWith(`${normalizedParent}/`);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routing/paths.ts"],"sourcesContent":["export const normalizeRoutePath = (input: string): string => {\n const trimmed = input.trim()\n\n if (!trimmed || trimmed === '/') {\n return '/'\n }\n\n const normalized = `/${trimmed}`\n .replace(/\\\\/g, '/')\n .replace(/\\/+/g, '/')\n .replace(/\\/+$/g, '')\n\n return normalized || '/'\n}\n\nexport const joinRouteSegments = (...segments: (string | undefined)[]): string => {\n const normalizedSegments = segments\n .flatMap((segment) => (segment ?? '').split(/[\\\\/]+/))\n .map((segment) => segment.trim())\n .filter(Boolean)\n\n return normalizeRoutePath(normalizedSegments.join('/'))\n}\n\nexport const deriveDocsSetRouteBase = ({\n docsSetSlug,\n groupRoutePath,\n}: {\n docsSetSlug: string\n groupRoutePath?: string\n}): string => joinRouteSegments(groupRoutePath ?? '/', docsSetSlug)\n\nexport const isRouteDescendant = (parent: string, child: string): boolean => {\n const normalizedParent = normalizeRoutePath(parent)\n const normalizedChild = normalizeRoutePath(child)\n\n if (normalizedParent === '/') {\n return normalizedChild !== '/'\n }\n\n return normalizedChild.startsWith(`${normalizedParent}/`)\n}\n"],"names":["normalizeRoutePath","input","trimmed","trim","normalized","replace","joinRouteSegments","segments","normalizedSegments","flatMap","segment","split","map","filter","Boolean","join","deriveDocsSetRouteBase","docsSetSlug","groupRoutePath","isRouteDescendant","parent","child","normalizedParent","normalizedChild","startsWith"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB,CAACC;IACjC,MAAMC,UAAUD,MAAME,IAAI;IAE1B,IAAI,CAACD,WAAWA,YAAY,KAAK;QAC/B,OAAO;IACT;IAEA,MAAME,aAAa,CAAC,CAAC,EAAEF,SAAS,CAC7BG,OAAO,CAAC,OAAO,KACfA,OAAO,CAAC,QAAQ,KAChBA,OAAO,CAAC,SAAS;IAEpB,OAAOD,cAAc;AACvB,EAAC;AAED,OAAO,MAAME,oBAAoB,CAAC,GAAGC;IACnC,MAAMC,qBAAqBD,SACxBE,OAAO,CAAC,CAACC,UAAY,AAACA,CAAAA,WAAW,EAAC,EAAGC,KAAK,CAAC,WAC3CC,GAAG,CAAC,CAACF,UAAYA,QAAQP,IAAI,IAC7BU,MAAM,CAACC;IAEV,OAAOd,mBAAmBQ,mBAAmBO,IAAI,CAAC;AACpD,EAAC;AAED,OAAO,MAAMC,yBAAyB,CAAC,EACrCC,WAAW,EACXC,cAAc,EAIf,GAAaZ,kBAAkBY,kBAAkB,KAAKD,aAAY;AAEnE,OAAO,MAAME,oBAAoB,CAACC,QAAgBC;IAChD,MAAMC,mBAAmBtB,mBAAmBoB;IAC5C,MAAMG,kBAAkBvB,mBAAmBqB;IAE3C,IAAIC,qBAAqB,KAAK;QAC5B,OAAOC,oBAAoB;IAC7B;IAEA,OAAOA,gBAAgBC,UAAU,CAAC,GAAGF,iBAAiB,CAAC,CAAC;AAC1D,EAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type DocsRouteReservationOwnerType = 'doc' | 'docsGroup' | 'docsSet' | 'page';
|
|
2
|
+
export type DocsRouteReservation = {
|
|
3
|
+
allowBridge?: boolean;
|
|
4
|
+
ownerId?: string;
|
|
5
|
+
ownerType: DocsRouteReservationOwnerType;
|
|
6
|
+
reservesDescendants?: boolean;
|
|
7
|
+
route: string;
|
|
8
|
+
};
|
|
9
|
+
export type DocsRouteCollisionReason = 'descendant_route_collision' | 'exact_route_collision';
|
|
10
|
+
export type DocsRouteCollision = {
|
|
11
|
+
first: DocsRouteReservation;
|
|
12
|
+
reason: DocsRouteCollisionReason;
|
|
13
|
+
second: DocsRouteReservation;
|
|
14
|
+
};
|
|
15
|
+
export declare const findRouteReservationCollisions: (reservations: DocsRouteReservation[]) => DocsRouteCollision[];
|
|
16
|
+
export declare const createDocRouteReservations: (docs: {
|
|
17
|
+
ownerId?: string;
|
|
18
|
+
route: string;
|
|
19
|
+
}[]) => DocsRouteReservation[];
|
|
20
|
+
export declare const createDocsSetRouteReservation: ({ ownerId, routeBase, }: {
|
|
21
|
+
ownerId?: string;
|
|
22
|
+
routeBase: string;
|
|
23
|
+
}) => DocsRouteReservation;
|
|
24
|
+
export declare const createDocsGroupRouteReservation: ({ ownerId, routePath, serveIndex, }: {
|
|
25
|
+
ownerId?: string;
|
|
26
|
+
routePath: string;
|
|
27
|
+
serveIndex?: boolean;
|
|
28
|
+
}) => DocsRouteReservation;
|
|
29
|
+
export declare const findPageRouteCollisions: ({ allowBridgePages, docsSetRouteBase, pages, }: {
|
|
30
|
+
allowBridgePages?: boolean;
|
|
31
|
+
docsSetRouteBase: string;
|
|
32
|
+
pages: {
|
|
33
|
+
bridge?: boolean;
|
|
34
|
+
id?: string;
|
|
35
|
+
route: string;
|
|
36
|
+
}[];
|
|
37
|
+
}) => DocsRouteCollision[];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { isRouteDescendant, normalizeRoutePath } from './paths.js';
|
|
2
|
+
const normalizeReservation = (reservation)=>({
|
|
3
|
+
...reservation,
|
|
4
|
+
route: normalizeRoutePath(reservation.route)
|
|
5
|
+
});
|
|
6
|
+
const sameOwner = (first, second)=>first.ownerType === second.ownerType && first.ownerId !== undefined && first.ownerId === second.ownerId;
|
|
7
|
+
const isAllowedBridgeCollision = (first, second)=>{
|
|
8
|
+
if (first.route !== second.route) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return first.ownerType === 'page' && first.allowBridge === true || second.ownerType === 'page' && second.allowBridge === true;
|
|
12
|
+
};
|
|
13
|
+
export const findRouteReservationCollisions = (reservations)=>{
|
|
14
|
+
const normalizedReservations = reservations.map(normalizeReservation);
|
|
15
|
+
const collisions = [];
|
|
16
|
+
for(let index = 0; index < normalizedReservations.length; index += 1){
|
|
17
|
+
for(let comparedIndex = index + 1; comparedIndex < normalizedReservations.length; comparedIndex += 1){
|
|
18
|
+
const first = normalizedReservations[index];
|
|
19
|
+
const second = normalizedReservations[comparedIndex];
|
|
20
|
+
if (!first || !second || sameOwner(first, second)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (first.route === second.route) {
|
|
24
|
+
if (!isAllowedBridgeCollision(first, second)) {
|
|
25
|
+
collisions.push({
|
|
26
|
+
first,
|
|
27
|
+
reason: 'exact_route_collision',
|
|
28
|
+
second
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (first.reservesDescendants && isRouteDescendant(first.route, second.route) || second.reservesDescendants && isRouteDescendant(second.route, first.route)) {
|
|
34
|
+
collisions.push({
|
|
35
|
+
first,
|
|
36
|
+
reason: 'descendant_route_collision',
|
|
37
|
+
second
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return collisions;
|
|
43
|
+
};
|
|
44
|
+
export const createDocRouteReservations = (docs)=>docs.map((doc)=>({
|
|
45
|
+
ownerId: doc.ownerId,
|
|
46
|
+
ownerType: 'doc',
|
|
47
|
+
route: doc.route
|
|
48
|
+
}));
|
|
49
|
+
export const createDocsSetRouteReservation = ({ ownerId, routeBase })=>({
|
|
50
|
+
ownerId,
|
|
51
|
+
ownerType: 'docsSet',
|
|
52
|
+
reservesDescendants: true,
|
|
53
|
+
route: routeBase
|
|
54
|
+
});
|
|
55
|
+
export const createDocsGroupRouteReservation = ({ ownerId, routePath, serveIndex })=>({
|
|
56
|
+
ownerId,
|
|
57
|
+
ownerType: 'docsGroup',
|
|
58
|
+
reservesDescendants: false,
|
|
59
|
+
route: routePath,
|
|
60
|
+
...serveIndex ? {} : {
|
|
61
|
+
allowBridge: true
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
export const findPageRouteCollisions = ({ allowBridgePages = true, docsSetRouteBase, pages })=>{
|
|
65
|
+
const reservations = [
|
|
66
|
+
createDocsSetRouteReservation({
|
|
67
|
+
routeBase: docsSetRouteBase
|
|
68
|
+
}),
|
|
69
|
+
...pages.map((page)=>({
|
|
70
|
+
allowBridge: allowBridgePages && page.bridge === true,
|
|
71
|
+
ownerId: page.id,
|
|
72
|
+
ownerType: 'page',
|
|
73
|
+
route: page.route
|
|
74
|
+
}))
|
|
75
|
+
];
|
|
76
|
+
return findRouteReservationCollisions(reservations).filter((collision)=>collision.first.ownerType === 'page' || collision.second.ownerType === 'page');
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=reservations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/routing/reservations.ts"],"sourcesContent":["import { isRouteDescendant, normalizeRoutePath } from './paths.js'\n\nexport type DocsRouteReservationOwnerType = 'doc' | 'docsGroup' | 'docsSet' | 'page'\n\nexport type DocsRouteReservation = {\n allowBridge?: boolean\n ownerId?: string\n ownerType: DocsRouteReservationOwnerType\n reservesDescendants?: boolean\n route: string\n}\n\nexport type DocsRouteCollisionReason =\n | 'descendant_route_collision'\n | 'exact_route_collision'\n\nexport type DocsRouteCollision = {\n first: DocsRouteReservation\n reason: DocsRouteCollisionReason\n second: DocsRouteReservation\n}\n\nconst normalizeReservation = (\n reservation: DocsRouteReservation,\n): DocsRouteReservation => ({\n ...reservation,\n route: normalizeRoutePath(reservation.route),\n})\n\nconst sameOwner = (\n first: DocsRouteReservation,\n second: DocsRouteReservation,\n): boolean =>\n first.ownerType === second.ownerType &&\n first.ownerId !== undefined &&\n first.ownerId === second.ownerId\n\nconst isAllowedBridgeCollision = (\n first: DocsRouteReservation,\n second: DocsRouteReservation,\n): boolean => {\n if (first.route !== second.route) {\n return false\n }\n\n return (\n (first.ownerType === 'page' && first.allowBridge === true) ||\n (second.ownerType === 'page' && second.allowBridge === true)\n )\n}\n\nexport const findRouteReservationCollisions = (\n reservations: DocsRouteReservation[],\n): DocsRouteCollision[] => {\n const normalizedReservations = reservations.map(normalizeReservation)\n const collisions: DocsRouteCollision[] = []\n\n for (let index = 0; index < normalizedReservations.length; index += 1) {\n for (\n let comparedIndex = index + 1;\n comparedIndex < normalizedReservations.length;\n comparedIndex += 1\n ) {\n const first = normalizedReservations[index]\n const second = normalizedReservations[comparedIndex]\n\n if (!first || !second || sameOwner(first, second)) {\n continue\n }\n\n if (first.route === second.route) {\n if (!isAllowedBridgeCollision(first, second)) {\n collisions.push({\n first,\n reason: 'exact_route_collision',\n second,\n })\n }\n\n continue\n }\n\n if (\n (first.reservesDescendants && isRouteDescendant(first.route, second.route)) ||\n (second.reservesDescendants && isRouteDescendant(second.route, first.route))\n ) {\n collisions.push({\n first,\n reason: 'descendant_route_collision',\n second,\n })\n }\n }\n }\n\n return collisions\n}\n\nexport const createDocRouteReservations = (\n docs: {\n ownerId?: string\n route: string\n }[],\n): DocsRouteReservation[] =>\n docs.map((doc) => ({\n ownerId: doc.ownerId,\n ownerType: 'doc',\n route: doc.route,\n }))\n\nexport const createDocsSetRouteReservation = ({\n ownerId,\n routeBase,\n}: {\n ownerId?: string\n routeBase: string\n}): DocsRouteReservation => ({\n ownerId,\n ownerType: 'docsSet',\n reservesDescendants: true,\n route: routeBase,\n})\n\nexport const createDocsGroupRouteReservation = ({\n ownerId,\n routePath,\n serveIndex,\n}: {\n ownerId?: string\n routePath: string\n serveIndex?: boolean\n}): DocsRouteReservation => ({\n ownerId,\n ownerType: 'docsGroup',\n reservesDescendants: false,\n route: routePath,\n ...(serveIndex ? {} : { allowBridge: true }),\n})\n\nexport const findPageRouteCollisions = ({\n allowBridgePages = true,\n docsSetRouteBase,\n pages,\n}: {\n allowBridgePages?: boolean\n docsSetRouteBase: string\n pages: {\n bridge?: boolean\n id?: string\n route: string\n }[]\n}): DocsRouteCollision[] => {\n const reservations = [\n createDocsSetRouteReservation({\n routeBase: docsSetRouteBase,\n }),\n ...pages.map((page) => ({\n allowBridge: allowBridgePages && page.bridge === true,\n ownerId: page.id,\n ownerType: 'page' as const,\n route: page.route,\n })),\n ]\n\n return findRouteReservationCollisions(reservations).filter(\n (collision) =>\n collision.first.ownerType === 'page' || collision.second.ownerType === 'page',\n )\n}\n"],"names":["isRouteDescendant","normalizeRoutePath","normalizeReservation","reservation","route","sameOwner","first","second","ownerType","ownerId","undefined","isAllowedBridgeCollision","allowBridge","findRouteReservationCollisions","reservations","normalizedReservations","map","collisions","index","length","comparedIndex","push","reason","reservesDescendants","createDocRouteReservations","docs","doc","createDocsSetRouteReservation","routeBase","createDocsGroupRouteReservation","routePath","serveIndex","findPageRouteCollisions","allowBridgePages","docsSetRouteBase","pages","page","bridge","id","filter","collision"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type CanonicalSigningStringInput = {
|
|
2
|
+
bodySha256: string;
|
|
3
|
+
method: string;
|
|
4
|
+
nonce: string;
|
|
5
|
+
path: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const buildCanonicalSigningString: ({ bodySha256, method, nonce, path, timestamp, }: CanonicalSigningStringInput) => string;
|
|
9
|
+
export declare const getCanonicalPathFromRequestUrl: ({ endpointPath, url, }: {
|
|
10
|
+
endpointPath: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
}) => string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const normalizeCanonicalPath = (path)=>{
|
|
2
|
+
const normalized = `/${path.trim()}`.replace(/\/+/g, '/');
|
|
3
|
+
return normalized.length > 1 ? normalized.replace(/\/+$/g, '') : normalized;
|
|
4
|
+
};
|
|
5
|
+
export const buildCanonicalSigningString = ({ bodySha256, method, nonce, path, timestamp })=>[
|
|
6
|
+
'v1',
|
|
7
|
+
method.toUpperCase(),
|
|
8
|
+
normalizeCanonicalPath(path),
|
|
9
|
+
timestamp,
|
|
10
|
+
nonce,
|
|
11
|
+
bodySha256.toLowerCase()
|
|
12
|
+
].join('\n');
|
|
13
|
+
export const getCanonicalPathFromRequestUrl = ({ endpointPath, url })=>{
|
|
14
|
+
if (url) {
|
|
15
|
+
try {
|
|
16
|
+
return new URL(url).pathname;
|
|
17
|
+
} catch {
|
|
18
|
+
// Fall through to the configured Payload API route.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return `/api/${endpointPath}`.replace(/\/+/g, '/');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=canonical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/security/canonical.ts"],"sourcesContent":["export type CanonicalSigningStringInput = {\n bodySha256: string\n method: string\n nonce: string\n path: string\n timestamp: string\n}\n\nconst normalizeCanonicalPath = (path: string): string => {\n const normalized = `/${path.trim()}`.replace(/\\/+/g, '/')\n\n return normalized.length > 1 ? normalized.replace(/\\/+$/g, '') : normalized\n}\n\nexport const buildCanonicalSigningString = ({\n bodySha256,\n method,\n nonce,\n path,\n timestamp,\n}: CanonicalSigningStringInput): string =>\n [\n 'v1',\n method.toUpperCase(),\n normalizeCanonicalPath(path),\n timestamp,\n nonce,\n bodySha256.toLowerCase(),\n ].join('\\n')\n\nexport const getCanonicalPathFromRequestUrl = ({\n endpointPath,\n url,\n}: {\n endpointPath: string\n url?: string\n}): string => {\n if (url) {\n try {\n return new URL(url).pathname\n } catch {\n // Fall through to the configured Payload API route.\n }\n }\n\n return `/api/${endpointPath}`.replace(/\\/+/g, '/')\n}\n\n"],"names":["normalizeCanonicalPath","path","normalized","trim","replace","length","buildCanonicalSigningString","bodySha256","method","nonce","timestamp","toUpperCase","toLowerCase","join","getCanonicalPathFromRequestUrl","endpointPath","url","URL","pathname"],"mappings":"AAQA,MAAMA,yBAAyB,CAACC;IAC9B,MAAMC,aAAa,CAAC,CAAC,EAAED,KAAKE,IAAI,IAAI,CAACC,OAAO,CAAC,QAAQ;IAErD,OAAOF,WAAWG,MAAM,GAAG,IAAIH,WAAWE,OAAO,CAAC,SAAS,MAAMF;AACnE;AAEA,OAAO,MAAMI,8BAA8B,CAAC,EAC1CC,UAAU,EACVC,MAAM,EACNC,KAAK,EACLR,IAAI,EACJS,SAAS,EACmB,GAC5B;QACE;QACAF,OAAOG,WAAW;QAClBX,uBAAuBC;QACvBS;QACAD;QACAF,WAAWK,WAAW;KACvB,CAACC,IAAI,CAAC,MAAK;AAEd,OAAO,MAAMC,iCAAiC,CAAC,EAC7CC,YAAY,EACZC,GAAG,EAIJ;IACC,IAAIA,KAAK;QACP,IAAI;YACF,OAAO,IAAIC,IAAID,KAAKE,QAAQ;QAC9B,EAAE,OAAM;QACN,oDAAoD;QACtD;IACF;IAEA,OAAO,CAAC,KAAK,EAAEH,cAAc,CAACX,OAAO,CAAC,QAAQ;AAChD,EAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PayloadMarkdownDocsAuthConfig } from '../types.js';
|
|
2
|
+
import type { FetchJson } from './jwks.js';
|
|
3
|
+
export type GitHubOidcErrorCode = 'oidc_environment_not_allowed' | 'oidc_expired' | 'oidc_invalid_audience' | 'oidc_invalid_issuer' | 'oidc_invalid_token' | 'oidc_jwks_unavailable' | 'oidc_missing_claim' | 'oidc_missing_jti' | 'oidc_not_yet_valid' | 'oidc_owner_not_allowed' | 'oidc_pull_request_not_allowed' | 'oidc_ref_not_allowed' | 'oidc_repository_not_allowed' | 'oidc_workflow_not_allowed';
|
|
4
|
+
export type GitHubOidcClaims = {
|
|
5
|
+
actor?: string;
|
|
6
|
+
aud: string | string[];
|
|
7
|
+
environment?: string;
|
|
8
|
+
event_name?: string;
|
|
9
|
+
exp: number;
|
|
10
|
+
iat: number;
|
|
11
|
+
iss: string;
|
|
12
|
+
job_workflow_ref?: string;
|
|
13
|
+
jti: string;
|
|
14
|
+
nbf?: number;
|
|
15
|
+
ref: string;
|
|
16
|
+
repository: string;
|
|
17
|
+
repository_owner: string;
|
|
18
|
+
sha?: string;
|
|
19
|
+
sub: string;
|
|
20
|
+
workflow?: string;
|
|
21
|
+
workflow_ref?: string;
|
|
22
|
+
};
|
|
23
|
+
export type VerifiedGitHubOidcToken = {
|
|
24
|
+
claims: GitHubOidcClaims;
|
|
25
|
+
expiresAt: Date;
|
|
26
|
+
keyId: string;
|
|
27
|
+
};
|
|
28
|
+
export type VerifyGitHubOidcTokenResult = {
|
|
29
|
+
code: GitHubOidcErrorCode;
|
|
30
|
+
message: string;
|
|
31
|
+
ok: false;
|
|
32
|
+
} | {
|
|
33
|
+
ok: true;
|
|
34
|
+
token: VerifiedGitHubOidcToken;
|
|
35
|
+
};
|
|
36
|
+
type GitHubOidcAuthConfig = Extract<PayloadMarkdownDocsAuthConfig, {
|
|
37
|
+
mode: 'github-oidc';
|
|
38
|
+
}>;
|
|
39
|
+
export declare const verifyGitHubOidcToken: ({ config, fetchJson, now, token, }: {
|
|
40
|
+
config: GitHubOidcAuthConfig;
|
|
41
|
+
fetchJson?: FetchJson;
|
|
42
|
+
now?: Date;
|
|
43
|
+
token: string;
|
|
44
|
+
}) => Promise<VerifyGitHubOidcTokenResult>;
|
|
45
|
+
export {};
|