@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.
Files changed (204) hide show
  1. package/README.md +195 -0
  2. package/dist/admin/DocsSetManager.d.ts +2 -0
  3. package/dist/admin/DocsSetManager.js +298 -0
  4. package/dist/admin/DocsSetManager.js.map +1 -0
  5. package/dist/admin/docsSetManagerData.d.ts +25 -0
  6. package/dist/admin/docsSetManagerData.js +266 -0
  7. package/dist/admin/docsSetManagerData.js.map +1 -0
  8. package/dist/admin/docsSetManagerTypes.d.ts +103 -0
  9. package/dist/admin/docsSetManagerTypes.js +3 -0
  10. package/dist/admin/docsSetManagerTypes.js.map +1 -0
  11. package/dist/admin/index.d.ts +3 -0
  12. package/dist/admin/index.js +4 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/cli/commands/install.d.ts +2 -0
  15. package/dist/cli/commands/install.js +211 -0
  16. package/dist/cli/commands/install.js.map +1 -0
  17. package/dist/cli/commands/keygen.d.ts +2 -0
  18. package/dist/cli/commands/keygen.js +89 -0
  19. package/dist/cli/commands/keygen.js.map +1 -0
  20. package/dist/cli/commands/manifest.d.ts +2 -0
  21. package/dist/cli/commands/manifest.js +50 -0
  22. package/dist/cli/commands/manifest.js.map +1 -0
  23. package/dist/cli/commands/plan.d.ts +2 -0
  24. package/dist/cli/commands/plan.js +110 -0
  25. package/dist/cli/commands/plan.js.map +1 -0
  26. package/dist/cli/commands/push.d.ts +3 -0
  27. package/dist/cli/commands/push.js +308 -0
  28. package/dist/cli/commands/push.js.map +1 -0
  29. package/dist/cli/commands/validate.d.ts +3 -0
  30. package/dist/cli/commands/validate.js +109 -0
  31. package/dist/cli/commands/validate.js.map +1 -0
  32. package/dist/cli/filesystem.d.ts +20 -0
  33. package/dist/cli/filesystem.js +96 -0
  34. package/dist/cli/filesystem.js.map +1 -0
  35. package/dist/cli/format.d.ts +35 -0
  36. package/dist/cli/format.js +76 -0
  37. package/dist/cli/format.js.map +1 -0
  38. package/dist/cli/http.d.ts +19 -0
  39. package/dist/cli/http.js +39 -0
  40. package/dist/cli/http.js.map +1 -0
  41. package/dist/cli/index.d.ts +3 -0
  42. package/dist/cli/index.js +214 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/cli/parseArgs.d.ts +5 -0
  45. package/dist/cli/parseArgs.js +219 -0
  46. package/dist/cli/parseArgs.js.map +1 -0
  47. package/dist/cli/types.d.ts +51 -0
  48. package/dist/cli/types.js +3 -0
  49. package/dist/cli/types.js.map +1 -0
  50. package/dist/collections/docs.d.ts +9 -0
  51. package/dist/collections/docs.js +168 -0
  52. package/dist/collections/docs.js.map +1 -0
  53. package/dist/collections/docsGroups.d.ts +5 -0
  54. package/dist/collections/docsGroups.js +57 -0
  55. package/dist/collections/docsGroups.js.map +1 -0
  56. package/dist/collections/docsSets.d.ts +8 -0
  57. package/dist/collections/docsSets.js +158 -0
  58. package/dist/collections/docsSets.js.map +1 -0
  59. package/dist/collections/index.d.ts +10 -0
  60. package/dist/collections/index.js +7 -0
  61. package/dist/collections/index.js.map +1 -0
  62. package/dist/collections/nonces.d.ts +6 -0
  63. package/dist/collections/nonces.js +57 -0
  64. package/dist/collections/nonces.js.map +1 -0
  65. package/dist/collections/syncRuns.d.ts +5 -0
  66. package/dist/collections/syncRuns.js +139 -0
  67. package/dist/collections/syncRuns.js.map +1 -0
  68. package/dist/constants.d.ts +21 -0
  69. package/dist/constants.js +23 -0
  70. package/dist/constants.js.map +1 -0
  71. package/dist/endpoints/index.d.ts +2 -0
  72. package/dist/endpoints/index.js +3 -0
  73. package/dist/endpoints/index.js.map +1 -0
  74. package/dist/endpoints/sync.d.ts +47 -0
  75. package/dist/endpoints/sync.js +616 -0
  76. package/dist/endpoints/sync.js.map +1 -0
  77. package/dist/index.d.ts +9 -0
  78. package/dist/index.js +7 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/next/PayloadMarkdownDocsPage.d.ts +7 -0
  81. package/dist/next/PayloadMarkdownDocsPage.js +142 -0
  82. package/dist/next/PayloadMarkdownDocsPage.js.map +1 -0
  83. package/dist/next/index.d.ts +9 -0
  84. package/dist/next/index.js +7 -0
  85. package/dist/next/index.js.map +1 -0
  86. package/dist/next/markdown.d.ts +14 -0
  87. package/dist/next/markdown.js +232 -0
  88. package/dist/next/markdown.js.map +1 -0
  89. package/dist/next/metadata.d.ts +3 -0
  90. package/dist/next/metadata.js +33 -0
  91. package/dist/next/metadata.js.map +1 -0
  92. package/dist/next/records.d.ts +14 -0
  93. package/dist/next/records.js +146 -0
  94. package/dist/next/records.js.map +1 -0
  95. package/dist/next/route.d.ts +6 -0
  96. package/dist/next/route.js +271 -0
  97. package/dist/next/route.js.map +1 -0
  98. package/dist/next/sidebar.d.ts +15 -0
  99. package/dist/next/sidebar.js +137 -0
  100. package/dist/next/sidebar.js.map +1 -0
  101. package/dist/next/types.d.ts +117 -0
  102. package/dist/next/types.js +3 -0
  103. package/dist/next/types.js.map +1 -0
  104. package/dist/payload/applyDocsSync.d.ts +54 -0
  105. package/dist/payload/applyDocsSync.js +176 -0
  106. package/dist/payload/applyDocsSync.js.map +1 -0
  107. package/dist/payload/docsConflicts.d.ts +12 -0
  108. package/dist/payload/docsConflicts.js +34 -0
  109. package/dist/payload/docsConflicts.js.map +1 -0
  110. package/dist/payload/docsData.d.ts +23 -0
  111. package/dist/payload/docsData.js +59 -0
  112. package/dist/payload/docsData.js.map +1 -0
  113. package/dist/payload/docsSets.d.ts +38 -0
  114. package/dist/payload/docsSets.js +57 -0
  115. package/dist/payload/docsSets.js.map +1 -0
  116. package/dist/payload/existingDocs.d.ts +43 -0
  117. package/dist/payload/existingDocs.js +97 -0
  118. package/dist/payload/existingDocs.js.map +1 -0
  119. package/dist/payload/index.d.ts +15 -0
  120. package/dist/payload/index.js +10 -0
  121. package/dist/payload/index.js.map +1 -0
  122. package/dist/payload/routeCollisions.d.ts +31 -0
  123. package/dist/payload/routeCollisions.js +104 -0
  124. package/dist/payload/routeCollisions.js.map +1 -0
  125. package/dist/payload/syncRuns.d.ts +60 -0
  126. package/dist/payload/syncRuns.js +53 -0
  127. package/dist/payload/syncRuns.js.map +1 -0
  128. package/dist/plugin.d.ts +3 -0
  129. package/dist/plugin.js +165 -0
  130. package/dist/plugin.js.map +1 -0
  131. package/dist/routing/index.d.ts +3 -0
  132. package/dist/routing/index.js +4 -0
  133. package/dist/routing/index.js.map +1 -0
  134. package/dist/routing/paths.d.ts +7 -0
  135. package/dist/routing/paths.js +23 -0
  136. package/dist/routing/paths.js.map +1 -0
  137. package/dist/routing/reservations.d.ts +37 -0
  138. package/dist/routing/reservations.js +79 -0
  139. package/dist/routing/reservations.js.map +1 -0
  140. package/dist/security/canonical.d.ts +12 -0
  141. package/dist/security/canonical.js +24 -0
  142. package/dist/security/canonical.js.map +1 -0
  143. package/dist/security/githubOidc.d.ts +45 -0
  144. package/dist/security/githubOidc.js +177 -0
  145. package/dist/security/githubOidc.js.map +1 -0
  146. package/dist/security/headers.d.ts +22 -0
  147. package/dist/security/headers.js +44 -0
  148. package/dist/security/headers.js.map +1 -0
  149. package/dist/security/index.d.ts +15 -0
  150. package/dist/security/index.js +9 -0
  151. package/dist/security/index.js.map +1 -0
  152. package/dist/security/jwks.d.ts +20 -0
  153. package/dist/security/jwks.js +40 -0
  154. package/dist/security/jwks.js.map +1 -0
  155. package/dist/security/jwt.d.ts +10 -0
  156. package/dist/security/jwt.js +42 -0
  157. package/dist/security/jwt.js.map +1 -0
  158. package/dist/security/nonce.d.ts +34 -0
  159. package/dist/security/nonce.js +43 -0
  160. package/dist/security/nonce.js.map +1 -0
  161. package/dist/security/sign.d.ts +13 -0
  162. package/dist/security/sign.js +39 -0
  163. package/dist/security/sign.js.map +1 -0
  164. package/dist/security/verify.d.ts +28 -0
  165. package/dist/security/verify.js +54 -0
  166. package/dist/security/verify.js.map +1 -0
  167. package/dist/skills/codex/SKILL.md +173 -0
  168. package/dist/skills/codex/examples/docs-page.md +42 -0
  169. package/dist/skills/codex/examples/github-actions.md +64 -0
  170. package/dist/skills/codex/reference/admin.md +28 -0
  171. package/dist/skills/codex/reference/frontmatter.md +39 -0
  172. package/dist/skills/codex/reference/payload-markdown-directives.md +77 -0
  173. package/dist/skills/codex/reference/routing.md +35 -0
  174. package/dist/skills/codex/reference/sync.md +35 -0
  175. package/dist/skills/codex/reference/troubleshooting.md +53 -0
  176. package/dist/skills/codex/reference/workflow.md +39 -0
  177. package/dist/sync/aiExportManifest.d.ts +58 -0
  178. package/dist/sync/aiExportManifest.js +430 -0
  179. package/dist/sync/aiExportManifest.js.map +1 -0
  180. package/dist/sync/frontmatter.d.ts +28 -0
  181. package/dist/sync/frontmatter.js +210 -0
  182. package/dist/sync/frontmatter.js.map +1 -0
  183. package/dist/sync/hash.d.ts +1 -0
  184. package/dist/sync/hash.js +8 -0
  185. package/dist/sync/hash.js.map +1 -0
  186. package/dist/sync/index.d.ts +12 -0
  187. package/dist/sync/index.js +9 -0
  188. package/dist/sync/index.js.map +1 -0
  189. package/dist/sync/manifest.d.ts +58 -0
  190. package/dist/sync/manifest.js +21 -0
  191. package/dist/sync/manifest.js.map +1 -0
  192. package/dist/sync/paths.d.ts +16 -0
  193. package/dist/sync/paths.js +116 -0
  194. package/dist/sync/paths.js.map +1 -0
  195. package/dist/sync/plan.d.ts +29 -0
  196. package/dist/sync/plan.js +72 -0
  197. package/dist/sync/plan.js.map +1 -0
  198. package/dist/sync/validate.d.ts +26 -0
  199. package/dist/sync/validate.js +308 -0
  200. package/dist/sync/validate.js.map +1 -0
  201. package/dist/types.d.ts +84 -0
  202. package/dist/types.js +3 -0
  203. package/dist/types.js.map +1 -0
  204. 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"}
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'payload';
2
+ import type { PayloadMarkdownDocsConfig } from './types.js';
3
+ export declare const payloadMarkdownDocs: (pluginOptions?: PayloadMarkdownDocsConfig) => Plugin;
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 {};