canopycms 0.0.67-int.90 → 0.0.67

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 (539) hide show
  1. package/README.md +30 -3
  2. package/dist/ai/generate.js +1 -27
  3. package/dist/ai/handler.d.ts +0 -4
  4. package/dist/ai/handler.js +0 -11
  5. package/dist/ai/index.d.ts +1 -8
  6. package/dist/ai/index.js +1 -8
  7. package/dist/ai/json-to-markdown.js +15 -58
  8. package/dist/ai/resolve-branch.d.ts +2 -7
  9. package/dist/ai/resolve-branch.js +2 -8
  10. package/dist/ai/strip-mdx.d.ts +5 -13
  11. package/dist/ai/strip-mdx.js +5 -17
  12. package/dist/ai/to-plain-text.d.ts +10 -28
  13. package/dist/ai/to-plain-text.js +10 -28
  14. package/dist/ai/transform-components.d.ts +2 -4
  15. package/dist/ai/transform-components.js +8 -19
  16. package/dist/ai/types.d.ts +5 -10
  17. package/dist/api/admin-branch-health.d.ts +4 -12
  18. package/dist/api/admin-branch-health.js +26 -66
  19. package/dist/api/admin.d.ts +4 -12
  20. package/dist/api/admin.js +10 -26
  21. package/dist/api/assets.d.ts +0 -25
  22. package/dist/api/assets.js +50 -91
  23. package/dist/api/branch-merge.d.ts +1 -1
  24. package/dist/api/branch-merge.js +0 -2
  25. package/dist/api/branch-review.d.ts +0 -8
  26. package/dist/api/branch-review.js +0 -13
  27. package/dist/api/branch-status.d.ts +0 -3
  28. package/dist/api/branch-status.js +8 -33
  29. package/dist/api/branch-withdraw.d.ts +0 -1
  30. package/dist/api/branch-withdraw.js +6 -9
  31. package/dist/api/branch.d.ts +7 -12
  32. package/dist/api/branch.js +7 -44
  33. package/dist/api/client.d.ts +71 -224
  34. package/dist/api/client.js +82 -233
  35. package/dist/api/comments.d.ts +2 -4
  36. package/dist/api/comments.js +0 -17
  37. package/dist/api/content.d.ts +0 -6
  38. package/dist/api/content.js +66 -142
  39. package/dist/api/entries-constants.d.ts +5 -9
  40. package/dist/api/entries-constants.js +5 -9
  41. package/dist/api/entries.d.ts +8 -13
  42. package/dist/api/entries.js +20 -51
  43. package/dist/api/github-sync.d.ts +2 -4
  44. package/dist/api/github-sync.js +4 -8
  45. package/dist/api/groups.d.ts +3 -0
  46. package/dist/api/groups.js +8 -21
  47. package/dist/api/guards.d.ts +4 -16
  48. package/dist/api/guards.js +3 -22
  49. package/dist/api/index.d.ts +4 -4
  50. package/dist/api/permissions.d.ts +2 -0
  51. package/dist/api/permissions.js +18 -40
  52. package/dist/api/reference-options.d.ts +0 -1
  53. package/dist/api/reference-options.js +3 -11
  54. package/dist/api/request-body-hash.d.ts +12 -23
  55. package/dist/api/request-body-hash.js +12 -23
  56. package/dist/api/resolve-references.d.ts +0 -1
  57. package/dist/api/resolve-references.js +13 -28
  58. package/dist/api/route-builder.d.ts +3 -7
  59. package/dist/api/route-builder.js +1 -1
  60. package/dist/api/routes.d.ts +12 -0
  61. package/dist/api/routes.js +47 -0
  62. package/dist/api/schema.d.ts +23 -33
  63. package/dist/api/schema.js +20 -74
  64. package/dist/api/settings-helpers.js +4 -5
  65. package/dist/api/types.d.ts +0 -5
  66. package/dist/api/user.js +0 -5
  67. package/dist/api/validators.d.ts +14 -52
  68. package/dist/api/validators.js +14 -52
  69. package/dist/assets/asset-prefixes.d.ts +4 -8
  70. package/dist/assets/asset-prefixes.js +4 -8
  71. package/dist/assets/asset-src.d.ts +5 -22
  72. package/dist/assets/asset-src.js +5 -21
  73. package/dist/assets/factory.d.ts +1 -2
  74. package/dist/assets/factory.js +1 -2
  75. package/dist/assets/finalize.d.ts +3 -1
  76. package/dist/assets/finalize.js +3 -1
  77. package/dist/assets/index.d.ts +3 -3
  78. package/dist/assets/index.js +1 -1
  79. package/dist/assets/keys.d.ts +5 -3
  80. package/dist/assets/keys.js +6 -3
  81. package/dist/assets/pipeline.d.ts +3 -2
  82. package/dist/assets/pipeline.js +22 -56
  83. package/dist/assets/sharp-loader.d.ts +2 -10
  84. package/dist/assets/sharp-loader.js +2 -10
  85. package/dist/assets/store-local.d.ts +1 -2
  86. package/dist/assets/store-local.js +1 -2
  87. package/dist/assets/store-s3.d.ts +3 -4
  88. package/dist/assets/svg-sanitizer.d.ts +6 -14
  89. package/dist/assets/svg-sanitizer.js +6 -14
  90. package/dist/assets/transform-directives.d.ts +3 -4
  91. package/dist/assets/transform-directives.js +1 -1
  92. package/dist/assets/transform.d.ts +19 -30
  93. package/dist/assets/transform.js +18 -31
  94. package/dist/auth/cache.d.ts +2 -3
  95. package/dist/auth/cache.js +2 -3
  96. package/dist/auth/caching-auth-plugin.d.ts +11 -22
  97. package/dist/auth/caching-auth-plugin.js +12 -14
  98. package/dist/auth/context-helpers.d.ts +6 -20
  99. package/dist/auth/context-helpers.js +5 -17
  100. package/dist/auth/file-based-auth-cache.d.ts +10 -21
  101. package/dist/auth/file-based-auth-cache.js +23 -51
  102. package/dist/auth/plugin.d.ts +29 -61
  103. package/dist/auth/plugin.js +9 -13
  104. package/dist/auth/types.d.ts +11 -20
  105. package/dist/authorization/branch.d.ts +30 -49
  106. package/dist/authorization/branch.js +16 -42
  107. package/dist/authorization/content.d.ts +11 -40
  108. package/dist/authorization/content.js +13 -45
  109. package/dist/authorization/groups/index.d.ts +0 -3
  110. package/dist/authorization/groups/index.js +0 -3
  111. package/dist/authorization/groups/loader.d.ts +14 -28
  112. package/dist/authorization/groups/loader.js +14 -38
  113. package/dist/authorization/groups/schema.d.ts +0 -6
  114. package/dist/authorization/groups/schema.js +4 -7
  115. package/dist/authorization/helpers.d.ts +9 -28
  116. package/dist/authorization/helpers.js +9 -28
  117. package/dist/authorization/index.d.ts +3 -25
  118. package/dist/authorization/index.js +3 -35
  119. package/dist/authorization/path.d.ts +6 -13
  120. package/dist/authorization/path.js +8 -25
  121. package/dist/authorization/permissions/index.d.ts +0 -3
  122. package/dist/authorization/permissions/index.js +0 -3
  123. package/dist/authorization/permissions/loader.d.ts +14 -27
  124. package/dist/authorization/permissions/loader.js +14 -32
  125. package/dist/authorization/permissions/schema.d.ts +1 -6
  126. package/dist/authorization/permissions/schema.js +6 -13
  127. package/dist/authorization/protected-branch.d.ts +36 -65
  128. package/dist/authorization/protected-branch.js +29 -41
  129. package/dist/authorization/settings-file-store.d.ts +38 -81
  130. package/dist/authorization/settings-file-store.js +38 -79
  131. package/dist/authorization/types.d.ts +4 -26
  132. package/dist/authorization/types.js +0 -6
  133. package/dist/authorization/validation.d.ts +1 -23
  134. package/dist/authorization/validation.js +1 -24
  135. package/dist/branch-health.d.ts +39 -67
  136. package/dist/branch-health.js +27 -43
  137. package/dist/branch-metadata-file.d.ts +16 -32
  138. package/dist/branch-metadata-file.js +13 -26
  139. package/dist/branch-metadata.d.ts +49 -80
  140. package/dist/branch-metadata.js +57 -87
  141. package/dist/branch-registry.d.ts +26 -64
  142. package/dist/branch-registry.js +44 -93
  143. package/dist/branch-schema-cache.d.ts +34 -124
  144. package/dist/branch-schema-cache.js +49 -155
  145. package/dist/branch-workspace.d.ts +4 -4
  146. package/dist/branch-workspace.js +15 -19
  147. package/dist/build/generate-ai-content.d.ts +1 -0
  148. package/dist/build/generate-ai-content.js +12 -25
  149. package/dist/build-canopy.d.ts +17 -27
  150. package/dist/build-canopy.js +16 -23
  151. package/dist/build-mode.d.ts +25 -27
  152. package/dist/build-mode.js +25 -29
  153. package/dist/cli/cli.d.ts +15 -26
  154. package/dist/cli/cli.js +601 -978
  155. package/dist/cli/generate-ai-content.js +351 -628
  156. package/dist/cli/github-app-manifest.d.ts +84 -0
  157. package/dist/cli/github-app-manifest.js +161 -0
  158. package/dist/cli/init-github-app.d.ts +110 -444
  159. package/dist/cli/init-github-app.js +236 -773
  160. package/dist/cli/init.js +39 -80
  161. package/dist/cli/migrate.d.ts +13 -10
  162. package/dist/cli/migrate.js +22 -30
  163. package/dist/cli/project-detect.d.ts +17 -31
  164. package/dist/cli/project-detect.js +31 -42
  165. package/dist/cli/project-root.d.ts +4 -11
  166. package/dist/cli/project-root.js +4 -11
  167. package/dist/cli/prompt.d.ts +10 -0
  168. package/dist/cli/prompt.js +67 -0
  169. package/dist/cli/sync.d.ts +0 -8
  170. package/dist/cli/sync.js +8 -28
  171. package/dist/cli/template-files/middleware.ts.template +15 -29
  172. package/dist/cli/templates.d.ts +2 -12
  173. package/dist/cli/templates.js +4 -4
  174. package/dist/client.d.ts +1 -1
  175. package/dist/comment-store.d.ts +32 -53
  176. package/dist/comment-store.js +32 -52
  177. package/dist/config/flatten.d.ts +0 -3
  178. package/dist/config/flatten.js +2 -12
  179. package/dist/config/helpers.js +2 -2
  180. package/dist/config/index.d.ts +2 -2
  181. package/dist/config/index.js +1 -4
  182. package/dist/config/schemas/collection.d.ts +0 -8
  183. package/dist/config/schemas/collection.js +0 -10
  184. package/dist/config/schemas/config.d.ts +6 -78
  185. package/dist/config/schemas/config.js +38 -54
  186. package/dist/config/schemas/field.d.ts +2 -242
  187. package/dist/config/schemas/field.js +9 -20
  188. package/dist/config/schemas/media.js +1 -1
  189. package/dist/config/schemas/permissions.js +0 -2
  190. package/dist/config/schemas/url.d.ts +5 -6
  191. package/dist/config/schemas/url.js +5 -6
  192. package/dist/config/types.d.ts +45 -33
  193. package/dist/config/types.js +0 -1
  194. package/dist/config.d.ts +1 -8
  195. package/dist/config.js +1 -9
  196. package/dist/content-id-index.d.ts +76 -188
  197. package/dist/content-id-index.js +79 -230
  198. package/dist/content-index-generation.d.ts +27 -48
  199. package/dist/content-index-generation.js +35 -84
  200. package/dist/content-index-registry.d.ts +15 -24
  201. package/dist/content-index-registry.js +5 -9
  202. package/dist/content-listing.d.ts +64 -107
  203. package/dist/content-listing.js +68 -118
  204. package/dist/content-reader.d.ts +20 -29
  205. package/dist/content-reader.js +10 -18
  206. package/dist/content-store.d.ts +210 -336
  207. package/dist/content-store.js +413 -657
  208. package/dist/content-tree.d.ts +44 -86
  209. package/dist/content-tree.js +26 -54
  210. package/dist/context.d.ts +67 -94
  211. package/dist/context.js +53 -72
  212. package/dist/dev-content-watcher.d.ts +18 -18
  213. package/dist/dev-content-watcher.js +41 -44
  214. package/dist/editor/BranchManager.d.ts +3 -6
  215. package/dist/editor/BranchManager.js +24 -44
  216. package/dist/editor/CanopyEditor.js +5 -2
  217. package/dist/editor/CommentsPanel.js +0 -2
  218. package/dist/editor/Editor.js +19 -76
  219. package/dist/editor/EditorAuthGate.d.ts +27 -0
  220. package/dist/editor/EditorAuthGate.js +140 -0
  221. package/dist/editor/EntryNavigator.js +0 -20
  222. package/dist/editor/FormRenderer.d.ts +1 -2
  223. package/dist/editor/FormRenderer.js +8 -23
  224. package/dist/editor/admin/SystemHealthPanel.js +20 -37
  225. package/dist/editor/admin/useSystemHealth.d.ts +2 -3
  226. package/dist/editor/admin/useSystemHealth.js +10 -12
  227. package/dist/editor/client-reference-resolver.d.ts +2 -5
  228. package/dist/editor/client-reference-resolver.js +2 -19
  229. package/dist/editor/comments/BranchComments.js +0 -4
  230. package/dist/editor/comments/EntryComments.js +0 -4
  231. package/dist/editor/comments/FieldWrapper.js +0 -4
  232. package/dist/editor/comments/InlineCommentThread.js +0 -2
  233. package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
  234. package/dist/editor/comments/ThreadCarousel.js +0 -12
  235. package/dist/editor/components/EditorFooter.d.ts +0 -8
  236. package/dist/editor/components/EditorFooter.js +0 -5
  237. package/dist/editor/components/EditorHeader.d.ts +0 -31
  238. package/dist/editor/components/EditorHeader.js +21 -71
  239. package/dist/editor/components/EditorSidebar.d.ts +0 -19
  240. package/dist/editor/components/EditorSidebar.js +0 -16
  241. package/dist/editor/components/EntryCreateModal.d.ts +4 -4
  242. package/dist/editor/components/EntryCreateModal.js +7 -22
  243. package/dist/editor/components/RenameEntryModal.js +0 -4
  244. package/dist/editor/components/UserBadge.js +0 -10
  245. package/dist/editor/components/index.js +0 -2
  246. package/dist/editor/context/ApiClientContext.d.ts +8 -7
  247. package/dist/editor/context/ApiClientContext.js +39 -11
  248. package/dist/editor/context/AssetContext.d.ts +7 -17
  249. package/dist/editor/context/AssetContext.js +7 -17
  250. package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
  251. package/dist/editor/context/EditorIdentityContext.js +7 -0
  252. package/dist/editor/context/EditorStateContext.d.ts +10 -41
  253. package/dist/editor/context/EditorStateContext.js +7 -23
  254. package/dist/editor/context/SWRProvider.d.ts +3 -6
  255. package/dist/editor/context/index.d.ts +1 -20
  256. package/dist/editor/context/index.js +1 -20
  257. package/dist/editor/editor-utils.d.ts +8 -47
  258. package/dist/editor/editor-utils.js +19 -72
  259. package/dist/editor/fields/BlockField.d.ts +2 -2
  260. package/dist/editor/fields/BlockField.js +1 -2
  261. package/dist/editor/fields/CodeField.d.ts +0 -1
  262. package/dist/editor/fields/CodeField.js +0 -1
  263. package/dist/editor/fields/DateTimeField.d.ts +15 -22
  264. package/dist/editor/fields/DateTimeField.js +17 -26
  265. package/dist/editor/fields/ImageField.d.ts +2 -2
  266. package/dist/editor/fields/ImageField.js +8 -14
  267. package/dist/editor/fields/InlineGroupField.d.ts +0 -1
  268. package/dist/editor/fields/InlineGroupField.js +0 -1
  269. package/dist/editor/fields/MarkdownField.d.ts +0 -1
  270. package/dist/editor/fields/MarkdownField.js +6 -11
  271. package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
  272. package/dist/editor/fields/MdxImageDialog.js +0 -1
  273. package/dist/editor/fields/NumberField.d.ts +9 -19
  274. package/dist/editor/fields/NumberField.js +11 -22
  275. package/dist/editor/fields/NumberListField.d.ts +7 -10
  276. package/dist/editor/fields/NumberListField.js +7 -10
  277. package/dist/editor/fields/ObjectField.d.ts +5 -8
  278. package/dist/editor/fields/ObjectField.js +0 -1
  279. package/dist/editor/fields/ReferenceField.d.ts +1 -1
  280. package/dist/editor/fields/ReferenceField.js +11 -16
  281. package/dist/editor/fields/SelectField.d.ts +2 -2
  282. package/dist/editor/fields/SelectField.js +0 -1
  283. package/dist/editor/fields/StringListField.d.ts +0 -4
  284. package/dist/editor/fields/StringListField.js +4 -9
  285. package/dist/editor/fields/TextField.d.ts +0 -1
  286. package/dist/editor/fields/TextField.js +0 -1
  287. package/dist/editor/fields/ToggleField.d.ts +0 -1
  288. package/dist/editor/fields/ToggleField.js +0 -1
  289. package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
  290. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
  291. package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
  292. package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
  293. package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
  294. package/dist/editor/group-manager/GroupCard.d.ts +0 -3
  295. package/dist/editor/group-manager/GroupForm.d.ts +0 -3
  296. package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
  297. package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
  298. package/dist/editor/group-manager/MemberList.d.ts +0 -3
  299. package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
  300. package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
  301. package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
  302. package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
  303. package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
  304. package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
  305. package/dist/editor/group-manager/index.d.ts +0 -6
  306. package/dist/editor/group-manager/index.js +0 -10
  307. package/dist/editor/group-manager/types.d.ts +2 -5
  308. package/dist/editor/group-manager/types.js +0 -3
  309. package/dist/editor/hooks/index.d.ts +6 -11
  310. package/dist/editor/hooks/index.js +6 -12
  311. package/dist/editor/hooks/useBranchActions.d.ts +0 -14
  312. package/dist/editor/hooks/useBranchActions.js +0 -22
  313. package/dist/editor/hooks/useBranchManager.d.ts +2 -48
  314. package/dist/editor/hooks/useBranchManager.js +4 -64
  315. package/dist/editor/hooks/useBranchesData.d.ts +7 -6
  316. package/dist/editor/hooks/useBranchesData.js +7 -6
  317. package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
  318. package/dist/editor/hooks/useCommentSystem.js +1 -36
  319. package/dist/editor/hooks/useDraftManager.d.ts +2 -35
  320. package/dist/editor/hooks/useDraftManager.js +23 -64
  321. package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
  322. package/dist/editor/hooks/useEditorLayout.js +0 -23
  323. package/dist/editor/hooks/useEntriesData.d.ts +1 -0
  324. package/dist/editor/hooks/useEntriesData.js +2 -3
  325. package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
  326. package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
  327. package/dist/editor/hooks/useEntryManager.d.ts +2 -27
  328. package/dist/editor/hooks/useEntryManager.js +29 -78
  329. package/dist/editor/hooks/useGroupManager.d.ts +0 -21
  330. package/dist/editor/hooks/useGroupManager.js +0 -21
  331. package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
  332. package/dist/editor/hooks/usePermissionManager.js +0 -20
  333. package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
  334. package/dist/editor/hooks/useReferenceResolution.js +1 -48
  335. package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
  336. package/dist/editor/hooks/useSchemaManager.js +0 -19
  337. package/dist/editor/hooks/useUserContext.d.ts +2 -9
  338. package/dist/editor/hooks/useUserContext.js +10 -10
  339. package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
  340. package/dist/editor/hooks/useUserMetadata.js +0 -3
  341. package/dist/editor/media/AssetCard.d.ts +0 -1
  342. package/dist/editor/media/AssetCard.js +1 -2
  343. package/dist/editor/media/CropStep.d.ts +0 -1
  344. package/dist/editor/media/CropStep.js +0 -1
  345. package/dist/editor/media/MediaLibrary.d.ts +1 -2
  346. package/dist/editor/media/MediaLibrary.js +1 -2
  347. package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
  348. package/dist/editor/media/MediaLibraryBody.js +0 -1
  349. package/dist/editor/media/crop-math.d.ts +1 -1
  350. package/dist/editor/media/crop-math.js +1 -1
  351. package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
  352. package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
  353. package/dist/editor/permission-manager/PermissionEditor.js +0 -1
  354. package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
  355. package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
  356. package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
  357. package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
  358. package/dist/editor/permission-manager/constants.d.ts +0 -3
  359. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
  360. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
  361. package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
  362. package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
  363. package/dist/editor/permission-manager/index.d.ts +0 -7
  364. package/dist/editor/permission-manager/index.js +0 -16
  365. package/dist/editor/permission-manager/types.d.ts +2 -12
  366. package/dist/editor/permission-manager/types.js +0 -3
  367. package/dist/editor/permission-manager/utils.d.ts +0 -28
  368. package/dist/editor/permission-manager/utils.js +9 -23
  369. package/dist/editor/preview-bridge.d.ts +5 -1
  370. package/dist/editor/preview-bridge.js +4 -4
  371. package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
  372. package/dist/editor/schema-editor/CollectionEditor.js +9 -31
  373. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
  374. package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
  375. package/dist/editor/schema-editor/index.d.ts +0 -7
  376. package/dist/editor/schema-editor/index.js +0 -7
  377. package/dist/editor/utils/env.d.ts +3 -18
  378. package/dist/editor/utils/env.js +6 -25
  379. package/dist/entry-link-resolver.d.ts +13 -35
  380. package/dist/entry-link-resolver.js +20 -53
  381. package/dist/entry-schema-registry.d.ts +20 -60
  382. package/dist/entry-schema-registry.js +20 -69
  383. package/dist/entry-schema.d.ts +118 -223
  384. package/dist/entry-schema.js +46 -91
  385. package/dist/git-manager.d.ts +101 -200
  386. package/dist/git-manager.js +211 -384
  387. package/dist/github-service.d.ts +34 -75
  388. package/dist/github-service.js +37 -91
  389. package/dist/http/handler.d.ts +6 -37
  390. package/dist/http/handler.js +65 -120
  391. package/dist/http/router.d.ts +15 -32
  392. package/dist/http/router.js +34 -99
  393. package/dist/http/types.d.ts +15 -40
  394. package/dist/http/types.js +3 -7
  395. package/dist/id.d.ts +4 -10
  396. package/dist/id.js +4 -10
  397. package/dist/index.js +6 -9
  398. package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
  399. package/dist/operating-mode/client-safe-strategy.js +8 -28
  400. package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
  401. package/dist/operating-mode/client-unsafe-strategy.js +9 -34
  402. package/dist/operating-mode/client.d.ts +3 -10
  403. package/dist/operating-mode/client.js +3 -8
  404. package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
  405. package/dist/operating-mode/deployment-name-fixtures.js +14 -18
  406. package/dist/operating-mode/deployment-name.d.ts +19 -29
  407. package/dist/operating-mode/deployment-name.js +29 -47
  408. package/dist/operating-mode/index.d.ts +4 -25
  409. package/dist/operating-mode/index.js +9 -31
  410. package/dist/operating-mode/mode-env.d.ts +32 -54
  411. package/dist/operating-mode/mode-env.js +36 -58
  412. package/dist/operating-mode/types.d.ts +24 -72
  413. package/dist/operating-mode/types.js +1 -7
  414. package/dist/paths/branch-name.d.ts +30 -40
  415. package/dist/paths/branch-name.js +30 -40
  416. package/dist/paths/branch.d.ts +4 -18
  417. package/dist/paths/branch.js +6 -22
  418. package/dist/paths/index.d.ts +2 -13
  419. package/dist/paths/index.js +3 -23
  420. package/dist/paths/normalize-server.d.ts +3 -15
  421. package/dist/paths/normalize-server.js +3 -15
  422. package/dist/paths/normalize.d.ts +13 -33
  423. package/dist/paths/normalize.js +13 -33
  424. package/dist/paths/resolve.d.ts +4 -17
  425. package/dist/paths/resolve.js +4 -22
  426. package/dist/paths/types.d.ts +12 -34
  427. package/dist/paths/types.js +5 -7
  428. package/dist/paths/validation.d.ts +22 -119
  429. package/dist/paths/validation.js +30 -148
  430. package/dist/reference-resolver.d.ts +0 -13
  431. package/dist/reference-resolver.js +0 -18
  432. package/dist/resolve-canopy-user.d.ts +16 -18
  433. package/dist/resolve-canopy-user.js +17 -26
  434. package/dist/resource-generation.d.ts +16 -25
  435. package/dist/resource-generation.js +34 -97
  436. package/dist/schema/meta-loader.d.ts +2 -14
  437. package/dist/schema/meta-loader.js +15 -64
  438. package/dist/schema/resolver.d.ts +1 -4
  439. package/dist/schema/resolver.js +1 -6
  440. package/dist/schema/schema-store-types.d.ts +0 -12
  441. package/dist/schema/schema-store.d.ts +61 -138
  442. package/dist/schema/schema-store.js +85 -282
  443. package/dist/schema/types.d.ts +0 -4
  444. package/dist/server.d.ts +62 -93
  445. package/dist/server.js +63 -94
  446. package/dist/services.d.ts +23 -47
  447. package/dist/services.js +55 -98
  448. package/dist/settings-workspace.d.ts +17 -30
  449. package/dist/settings-workspace.js +51 -81
  450. package/dist/static/index.d.ts +26 -52
  451. package/dist/static/index.js +33 -67
  452. package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
  453. package/dist/task-queue/cms-task-queue.js +13 -0
  454. package/dist/task-queue/task-queue-config.d.ts +3 -0
  455. package/dist/{worker → task-queue}/task-queue-config.js +1 -6
  456. package/dist/task-queue/task-queue.d.ts +16 -22
  457. package/dist/task-queue/task-queue.js +20 -44
  458. package/dist/task-queue/types.d.ts +0 -1
  459. package/dist/task-queue/worker-status.d.ts +35 -0
  460. package/dist/task-queue/worker-status.js +40 -0
  461. package/dist/types.d.ts +40 -51
  462. package/dist/url-collision.d.ts +26 -40
  463. package/dist/url-collision.js +47 -63
  464. package/dist/url-exclusivity-fixtures.d.ts +15 -20
  465. package/dist/url-exclusivity-fixtures.js +14 -19
  466. package/dist/url-path-resolver.d.ts +8 -16
  467. package/dist/url-path-resolver.js +19 -29
  468. package/dist/user.d.ts +8 -21
  469. package/dist/user.js +10 -19
  470. package/dist/utils/async-mutex.js +4 -6
  471. package/dist/utils/atomic-write.d.ts +2 -11
  472. package/dist/utils/atomic-write.js +2 -11
  473. package/dist/utils/body-field.d.ts +8 -15
  474. package/dist/utils/body-field.js +8 -15
  475. package/dist/utils/content-serialize.d.ts +18 -24
  476. package/dist/utils/content-serialize.js +109 -160
  477. package/dist/utils/content-write-lock.d.ts +51 -106
  478. package/dist/utils/content-write-lock.js +66 -111
  479. package/dist/utils/debug.d.ts +7 -23
  480. package/dist/utils/debug.js +7 -23
  481. package/dist/utils/entry-url.d.ts +11 -23
  482. package/dist/utils/entry-url.js +11 -26
  483. package/dist/utils/error.d.ts +25 -90
  484. package/dist/utils/error.js +60 -147
  485. package/dist/utils/flatten-group-fields.d.ts +5 -7
  486. package/dist/utils/flatten-group-fields.js +5 -7
  487. package/dist/utils/format.d.ts +1 -5
  488. package/dist/utils/format.js +1 -5
  489. package/dist/utils/fs.d.ts +3 -4
  490. package/dist/utils/fs.js +3 -4
  491. package/dist/utils/git.d.ts +52 -83
  492. package/dist/utils/git.js +79 -125
  493. package/dist/utils/logger.d.ts +35 -50
  494. package/dist/utils/logger.js +35 -52
  495. package/dist/utils/provisioning-lock.d.ts +23 -35
  496. package/dist/utils/provisioning-lock.js +49 -69
  497. package/dist/utils/sanitize-href.d.ts +5 -10
  498. package/dist/utils/sanitize-href.js +8 -18
  499. package/dist/utils/title-field.d.ts +17 -20
  500. package/dist/utils/title-field.js +18 -27
  501. package/dist/utils/typed-filename.d.ts +20 -48
  502. package/dist/utils/typed-filename.js +25 -61
  503. package/dist/utils/url-prefix.d.ts +3 -3
  504. package/dist/utils/url-prefix.js +3 -3
  505. package/dist/validation/block-structural-keys.d.ts +16 -31
  506. package/dist/validation/block-structural-keys.js +19 -29
  507. package/dist/validation/deletion-checker.d.ts +0 -34
  508. package/dist/validation/deletion-checker.js +1 -43
  509. package/dist/validation/entry-link-validator.d.ts +6 -13
  510. package/dist/validation/entry-link-validator.js +4 -13
  511. package/dist/validation/entry-type-reference-validator.d.ts +13 -18
  512. package/dist/validation/entry-type-reference-validator.js +13 -18
  513. package/dist/validation/entry-validator.d.ts +13 -25
  514. package/dist/validation/entry-validator.js +15 -32
  515. package/dist/validation/field-traversal.d.ts +3 -30
  516. package/dist/validation/field-traversal.js +1 -32
  517. package/dist/validation/reference-validator.d.ts +5 -24
  518. package/dist/validation/reference-validator.js +5 -30
  519. package/dist/worker/cms-worker.d.ts +172 -232
  520. package/dist/worker/cms-worker.js +241 -333
  521. package/dist/worker/git-sync.d.ts +32 -133
  522. package/dist/worker/git-sync.js +129 -191
  523. package/dist/worker/github-auth.d.ts +13 -19
  524. package/dist/worker/github-auth.js +13 -19
  525. package/dist/worker/history-rewrite.d.ts +53 -66
  526. package/dist/worker/history-rewrite.js +54 -60
  527. package/dist/worker/log.d.ts +24 -41
  528. package/dist/worker/log.js +25 -42
  529. package/dist/worker/rebase.d.ts +20 -110
  530. package/dist/worker/rebase.js +279 -354
  531. package/dist/worker/task-runner.d.ts +32 -66
  532. package/dist/worker/task-runner.js +126 -162
  533. package/dist/worker/worker-context.d.ts +41 -81
  534. package/package.json +4 -4
  535. package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
  536. package/dist/worker/task-queue-config.d.ts +0 -8
  537. package/dist/worker/task-queue.js +0 -19
  538. package/dist/worker/worker-status.d.ts +0 -47
  539. package/dist/worker/worker-status.js +0 -52
@@ -1,14 +1,7 @@
1
1
  /**
2
- * Authorization helper functions
3
- *
4
- * Simple utilities for checking user roles and permissions.
5
- */
6
- /**
7
- * Reserved groups for CanopyCMS permission system.
8
- *
9
- * These groups have special meaning and cannot be deleted or renamed.
10
- * - Admins: Full access to all CMS operations
11
- * - Reviewers: Can review branches, request changes, approve PRs
2
+ * Reserved groups for the CanopyCMS permission system; they cannot be deleted
3
+ * or renamed. Admins have full access to every CMS operation; Reviewers can
4
+ * review branches, request changes and approve PRs.
12
5
  *
13
6
  * SECURITY: membership in a reserved group grants privilege, so these IDs must
14
7
  * only ever come from Canopy-managed sources (internal groups in
@@ -21,30 +14,18 @@ export declare const RESERVED_GROUPS: {
21
14
  readonly REVIEWERS: "Reviewers";
22
15
  };
23
16
  export type ReservedGroupId = (typeof RESERVED_GROUPS)[keyof typeof RESERVED_GROUPS];
24
- /**
25
- * Check if a group ID is a reserved group
26
- */
27
17
  export declare function isReservedGroup(groupId: string): groupId is ReservedGroupId;
28
18
  /**
29
19
  * Remove reserved privileged group IDs (Admins, Reviewers) from a group list.
30
20
  *
31
- * SECURITY (SEC-H1): apply this to externally-supplied group lists (identity
32
- * provider groups) before merging them into a user's effective groups, so a
33
- * provider-controlled group name can never grant CanopyCMS privilege.
34
- * Non-reserved groups pass through unchanged and remain usable for ordinary
35
- * path/branch ACL membership.
21
+ * SECURITY: apply this to identity-provider group lists before merging them
22
+ * into a user's effective groups, so a provider-controlled group name can never
23
+ * grant CanopyCMS privilege. Non-reserved groups pass through unchanged and
24
+ * remain usable for ordinary path/branch ACL membership.
36
25
  */
37
26
  export declare function stripReservedGroups<T extends string>(groups: readonly T[]): T[];
38
- /**
39
- * Check if user is in the Admins group
40
- */
41
27
  export declare function isAdmin(groups: readonly string[] | undefined): boolean;
42
- /**
43
- * Check if user is in the Reviewers group (or is an Admin, since Admins can do everything)
44
- */
28
+ /** True for the Reviewers group and for Admins, who can do everything. */
45
29
  export declare function isReviewer(groups: readonly string[] | undefined): boolean;
46
- /**
47
- * Check if user has privileged access (Admin or Reviewer)
48
- * Used for operations that require elevated permissions but not full admin
49
- */
30
+ /** For operations that need elevated rights but not full admin. */
50
31
  export declare function isPrivileged(groups: readonly string[] | undefined): boolean;
@@ -1,14 +1,7 @@
1
1
  /**
2
- * Authorization helper functions
3
- *
4
- * Simple utilities for checking user roles and permissions.
5
- */
6
- /**
7
- * Reserved groups for CanopyCMS permission system.
8
- *
9
- * These groups have special meaning and cannot be deleted or renamed.
10
- * - Admins: Full access to all CMS operations
11
- * - Reviewers: Can review branches, request changes, approve PRs
2
+ * Reserved groups for the CanopyCMS permission system; they cannot be deleted
3
+ * or renamed. Admins have full access to every CMS operation; Reviewers can
4
+ * review branches, request changes and approve PRs.
12
5
  *
13
6
  * SECURITY: membership in a reserved group grants privilege, so these IDs must
14
7
  * only ever come from Canopy-managed sources (internal groups in
@@ -20,40 +13,28 @@ export const RESERVED_GROUPS = {
20
13
  ADMINS: 'Admins',
21
14
  REVIEWERS: 'Reviewers',
22
15
  };
23
- /**
24
- * Check if a group ID is a reserved group
25
- */
26
16
  export function isReservedGroup(groupId) {
27
17
  return Object.values(RESERVED_GROUPS).includes(groupId);
28
18
  }
29
19
  /**
30
20
  * Remove reserved privileged group IDs (Admins, Reviewers) from a group list.
31
21
  *
32
- * SECURITY (SEC-H1): apply this to externally-supplied group lists (identity
33
- * provider groups) before merging them into a user's effective groups, so a
34
- * provider-controlled group name can never grant CanopyCMS privilege.
35
- * Non-reserved groups pass through unchanged and remain usable for ordinary
36
- * path/branch ACL membership.
22
+ * SECURITY: apply this to identity-provider group lists before merging them
23
+ * into a user's effective groups, so a provider-controlled group name can never
24
+ * grant CanopyCMS privilege. Non-reserved groups pass through unchanged and
25
+ * remain usable for ordinary path/branch ACL membership.
37
26
  */
38
27
  export function stripReservedGroups(groups) {
39
28
  return groups.filter((group) => !isReservedGroup(group));
40
29
  }
41
- /**
42
- * Check if user is in the Admins group
43
- */
44
30
  export function isAdmin(groups) {
45
31
  return groups?.includes(RESERVED_GROUPS.ADMINS) ?? false;
46
32
  }
47
- /**
48
- * Check if user is in the Reviewers group (or is an Admin, since Admins can do everything)
49
- */
33
+ /** True for the Reviewers group and for Admins, who can do everything. */
50
34
  export function isReviewer(groups) {
51
35
  return isAdmin(groups) || (groups?.includes(RESERVED_GROUPS.REVIEWERS) ?? false);
52
36
  }
53
- /**
54
- * Check if user has privileged access (Admin or Reviewer)
55
- * Used for operations that require elevated permissions but not full admin
56
- */
37
+ /** For operations that need elevated rights but not full admin. */
57
38
  export function isPrivileged(groups) {
58
39
  return isReviewer(groups);
59
40
  }
@@ -1,29 +1,7 @@
1
1
  /**
2
- * Authorization module for CanopyCMS
3
- *
4
- * This module provides a unified API for checking user access to branches and content.
5
- *
6
- * ## Quick Start
7
- *
8
- * For most use cases, use `checkContentAccess` which handles both branch and path permissions:
9
- *
10
- * ```ts
11
- * import { checkContentAccess } from './authorization.js'
12
- *
13
- * const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/post.mdx', user, 'edit')
14
- * if (result.allowed) {
15
- * // User can edit the file
16
- * }
17
- * ```
18
- *
19
- * ## Module Structure
20
- *
21
- * - `content.ts` - Combined branch + path access (main entry point)
22
- * - `branch.ts` - Branch-level access control
23
- * - `path.ts` - Path-level permissions
24
- * - `helpers.ts` - Utility functions (isAdmin, isReviewer, etc.)
25
- * - `permissions/` - Permissions file schema and loader
26
- * - `groups/` - Groups file schema and loader
2
+ * Authorization for CanopyCMS: checking user access to branches and content.
3
+ * Most callers want `checkContentAccess(deps, context, branchRoot, path, user,
4
+ * level)`, which covers both the branch and the path layer.
27
5
  */
28
6
  export type { BranchAccessResult, PathPermissionResult, ContentAccessResult, ContentAccessDeps, PermissionPath, } from './types.js';
29
7
  export { parsePermissionPath } from './validation.js';
@@ -1,46 +1,14 @@
1
1
  /**
2
- * Authorization module for CanopyCMS
3
- *
4
- * This module provides a unified API for checking user access to branches and content.
5
- *
6
- * ## Quick Start
7
- *
8
- * For most use cases, use `checkContentAccess` which handles both branch and path permissions:
9
- *
10
- * ```ts
11
- * import { checkContentAccess } from './authorization.js'
12
- *
13
- * const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/post.mdx', user, 'edit')
14
- * if (result.allowed) {
15
- * // User can edit the file
16
- * }
17
- * ```
18
- *
19
- * ## Module Structure
20
- *
21
- * - `content.ts` - Combined branch + path access (main entry point)
22
- * - `branch.ts` - Branch-level access control
23
- * - `path.ts` - Path-level permissions
24
- * - `helpers.ts` - Utility functions (isAdmin, isReviewer, etc.)
25
- * - `permissions/` - Permissions file schema and loader
26
- * - `groups/` - Groups file schema and loader
2
+ * Authorization for CanopyCMS: checking user access to branches and content.
3
+ * Most callers want `checkContentAccess(deps, context, branchRoot, path, user,
4
+ * level)`, which covers both the branch and the path layer.
27
5
  */
28
- // Validation
29
6
  export { parsePermissionPath } from './validation.js';
30
- // Main content access (recommended for most cases)
31
7
  export { checkContentAccess, createCheckContentAccess, createContentAccessChecker, } from './content.js';
32
- // Branch-level access
33
8
  export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch.js';
34
- // Protected base branch (submit-block + read-only predicate)
35
9
  export { getBranchProtection, getBranchWriteProtection, } from './protected-branch.js';
36
- // Path-level access
37
10
  export { checkPathAccess, createCheckPathAccess, resolveDefaultPathAccess } from './path.js';
38
- // Helper functions
39
11
  export { RESERVED_GROUPS, isReservedGroup, stripReservedGroups, isAdmin, isReviewer, isPrivileged, } from './helpers.js';
40
- // Permissions file handling
41
12
  export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './permissions/index.js';
42
- // Groups file handling
43
13
  export { GroupsFileSchema, createDefaultGroupsFile, loadGroupsFile, loadInternalGroups, deriveInternalGroups, mutateGroupsFile, } from './groups/index.js';
44
- // Settings file store — cross-host layered locking shared by
45
- // permissions.json and groups.json (see authorization/settings-file-store.ts)
46
14
  export { mutateSettingsJsonFile, SettingsFileConflictError, SettingsVersionConflictError, } from './settings-file-store.js';
@@ -1,23 +1,19 @@
1
- /**
2
- * Path-level authorization
3
- *
4
- * Handles checking if a user can access a specific path based on permission rules.
5
- */
6
1
  import type { PathPermission, DefaultPathAccess, PermissionLevel } from '../config/index.js';
7
2
  import type { CanopyUser } from '../user.js';
8
3
  import type { PathPermissionResult } from './types.js';
9
4
  import type { PhysicalPath } from '../paths/types.js';
10
5
  /**
11
- * Resolve a `defaultPathAccess` config value to an 'allow'/'deny' verdict for one
12
- * permission level. String form applies the same value to every level (unchanged
13
- * behavior). Object form looks up the level; an absent level resolves to 'deny'
14
- * (fail-closed), so scoping e.g. `{ read: 'allow' }` doesn't accidentally open
15
- * edit/review.
6
+ * Resolve `defaultPathAccess` to an 'allow'/'deny' verdict for one permission
7
+ * level. String form applies to every level; object form looks up the level,
8
+ * and an absent level resolves to 'deny' (fail-closed) so `{ read: 'allow' }`
9
+ * cannot accidentally open edit/review.
10
+ * @internal Exported for tests.
16
11
  */
17
12
  export declare function resolveDefaultPathAccess(defaultAccess: DefaultPathAccess, level: PermissionLevel): 'allow' | 'deny';
18
13
  /**
19
14
  * Evaluate access for a relative path against config-defined rules.
20
15
  * Uses defaultAccess when no rule matches. First matching rule wins.
16
+ * @internal Exported for tests.
21
17
  */
22
18
  export declare function checkPathAccess({ rules, relativePath, user, defaultAccess, level, }: {
23
19
  rules: PathPermission[];
@@ -26,9 +22,6 @@ export declare function checkPathAccess({ rules, relativePath, user, defaultAcce
26
22
  defaultAccess: DefaultPathAccess;
27
23
  level: PermissionLevel;
28
24
  }): PathPermissionResult;
29
- /**
30
- * Factory to bind rules and defaultAccess once.
31
- */
32
25
  export declare function createCheckPathAccess(rules: PathPermission[], defaultAccess: DefaultPathAccess): (input: {
33
26
  relativePath: PhysicalPath;
34
27
  user: CanopyUser;
@@ -1,31 +1,17 @@
1
- /**
2
- * Path-level authorization
3
- *
4
- * Handles checking if a user can access a specific path based on permission rules.
5
- */
6
1
  import path from 'node:path';
7
2
  import { minimatch } from 'minimatch';
8
3
  import { isAdmin } from './helpers.js';
9
- /**
10
- * Normalize a path for consistent matching
11
- */
12
4
  function normalize(p) {
13
5
  const normalized = p.split(path.sep).join('/');
14
6
  return normalized.replace(/^\.?\/*/, '');
15
7
  }
16
- /**
17
- * Check if a path matches a permission rule
18
- */
19
8
  function matchesRule(rule, relativePath) {
20
9
  return minimatch(relativePath, rule.path, { dot: true });
21
10
  }
22
- /**
23
- * Check if user matches a permission target
24
- */
25
11
  function isAllowedByTarget(target, user) {
26
12
  const hasUserConstraint = !!target.allowedUsers?.length;
27
13
  const hasGroupConstraint = !!target.allowedGroups?.length;
28
- // No constraints means allowed (rule applies to everyone)
14
+ // A target with no constraints applies to everyone.
29
15
  if (!hasUserConstraint && !hasGroupConstraint) {
30
16
  return true;
31
17
  }
@@ -34,11 +20,11 @@ function isAllowedByTarget(target, user) {
34
20
  return Boolean(matchesUser || matchesGroup);
35
21
  }
36
22
  /**
37
- * Resolve a `defaultPathAccess` config value to an 'allow'/'deny' verdict for one
38
- * permission level. String form applies the same value to every level (unchanged
39
- * behavior). Object form looks up the level; an absent level resolves to 'deny'
40
- * (fail-closed), so scoping e.g. `{ read: 'allow' }` doesn't accidentally open
41
- * edit/review.
23
+ * Resolve `defaultPathAccess` to an 'allow'/'deny' verdict for one permission
24
+ * level. String form applies to every level; object form looks up the level,
25
+ * and an absent level resolves to 'deny' (fail-closed) so `{ read: 'allow' }`
26
+ * cannot accidentally open edit/review.
27
+ * @internal Exported for tests.
42
28
  */
43
29
  export function resolveDefaultPathAccess(defaultAccess, level) {
44
30
  if (typeof defaultAccess === 'string')
@@ -48,6 +34,7 @@ export function resolveDefaultPathAccess(defaultAccess, level) {
48
34
  /**
49
35
  * Evaluate access for a relative path against config-defined rules.
50
36
  * Uses defaultAccess when no rule matches. First matching rule wins.
37
+ * @internal Exported for tests.
51
38
  */
52
39
  export function checkPathAccess({ rules, relativePath, user, defaultAccess, level, }) {
53
40
  const normalizedPath = normalize(relativePath);
@@ -59,10 +46,9 @@ export function checkPathAccess({ rules, relativePath, user, defaultAccess, leve
59
46
  if (!matchesRule(rule, normalizedPath)) {
60
47
  continue;
61
48
  }
62
- // Get the permission target for this level
63
49
  const target = rule[level];
64
50
  if (!target) {
65
- // No permissions defined for this level on this rule, continue to next rule
51
+ // A rule that defines nothing for this level does not decide it.
66
52
  continue;
67
53
  }
68
54
  const allowed = isAllowedByTarget(target, user);
@@ -77,9 +63,6 @@ export function checkPathAccess({ rules, relativePath, user, defaultAccess, leve
77
63
  reason: 'no_rule_match',
78
64
  };
79
65
  }
80
- /**
81
- * Factory to bind rules and defaultAccess once.
82
- */
83
66
  export function createCheckPathAccess(rules, defaultAccess) {
84
67
  return (input) => checkPathAccess({ ...input, rules, defaultAccess });
85
68
  }
@@ -1,5 +1,2 @@
1
- /**
2
- * Permissions module exports
3
- */
4
1
  export { PermissionsFileSchema, createDefaultPermissionsFile, type PermissionsFile } from './schema.js';
5
2
  export { loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './loader.js';
@@ -1,5 +1,2 @@
1
- /**
2
- * Permissions module exports
3
- */
4
1
  export { PermissionsFileSchema, createDefaultPermissionsFile } from './schema.js';
5
2
  export { loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './loader.js';
@@ -1,46 +1,33 @@
1
1
  /**
2
- * Permissions file loader
3
- *
4
- * Handles loading path permissions from the filesystem and mutating
5
- * permissions.json under the cross-host layered lock in
6
- * authorization/settings-file-store.ts.
2
+ * Loads path permissions, and mutates permissions.json under the cross-host
3
+ * layered lock in authorization/settings-file-store.ts.
7
4
  */
8
5
  import type { PathPermission } from '../../config/index.js';
9
6
  import type { PermissionsFile } from './schema.js';
10
7
  import type { OperatingMode } from '../../operating-mode/index.js';
11
8
  import type { OccWriteResult } from '../../utils/occ-json-write.js';
12
- /**
13
- * Load full permissions file (for version checking)
14
- * Returns null if file doesn't exist.
15
- *
16
- * @param repoRoot - Repository root directory
17
- * @param mode - Operating mode (determines file path)
18
- */
9
+ /** Returns null when the file doesn't exist. */
19
10
  export declare function loadPermissionsFile(repoRoot: string, mode: OperatingMode): Promise<PermissionsFile | null>;
20
11
  /**
21
- * Load path permissions from .canopycms/permissions.json (or .local.json in dev mode)
22
- * Returns empty array if file doesn't exist (no restrictions).
23
- *
24
- * @param repoRoot - Repository root directory
25
- * @param mode - Operating mode (determines file path)
12
+ * Loads .canopycms/permissions.json (permissions.local.json in dev mode).
13
+ * Returns an empty array when the file doesn't exist: no restrictions.
26
14
  */
27
15
  export declare function loadPathPermissions(repoRoot: string, mode: OperatingMode): Promise<PathPermission[]>;
28
16
  /**
29
- * Mutate permissions.json (or .local.json in dev mode) under the full
30
- * cross-host lock + OCC-retry stack (see
31
- * authorization/settings-file-store.ts). `mutate` is called with the
32
- * current parsed file (`null` if it doesn't exist yet) and the version to
33
- * write under; it returns the next raw payload, or `null` for a deliberate
34
- * no-op. The returned payload is validated against
35
- * {@link PermissionsFileSchema} before being written, preserving the
36
- * previous validate-before-write behavior of the old `savePathPermissions`.
17
+ * Mutate permissions.json (permissions.local.json in dev mode) under the full
18
+ * cross-host lock + OCC-retry stack (see authorization/settings-file-store.ts).
19
+ * `mutate` receives the current parsed file (`null` if absent) and the version
20
+ * to write under, and returns the next raw payload or `null` for a deliberate
21
+ * no-op. The payload is validated against {@link PermissionsFileSchema} before
22
+ * writing.
37
23
  */
38
24
  export declare function mutatePermissionsFile(repoRoot: string, mode: OperatingMode, mutate: (current: PermissionsFile | null, version: number) => Record<string, unknown> | null, options?: {
39
25
  settleMs?: number;
40
26
  maxAttempts?: number;
41
27
  }): Promise<OccWriteResult | null>;
42
28
  /**
43
- * Initialize permissions file if it doesn't exist. A no-op when the file is
44
- * already present (the mutator returns `null`, so no write happens).
29
+ * Create the permissions file if it doesn't exist; a no-op when it is already
30
+ * present (the mutator returns `null`, so no write happens).
31
+ * @internal Exported for tests.
45
32
  */
46
33
  export declare function ensurePermissionsFile(repoRoot: string, userId: string, mode: OperatingMode): Promise<void>;
@@ -1,27 +1,15 @@
1
1
  /**
2
- * Permissions file loader
3
- *
4
- * Handles loading path permissions from the filesystem and mutating
5
- * permissions.json under the cross-host layered lock in
6
- * authorization/settings-file-store.ts.
2
+ * Loads path permissions, and mutates permissions.json under the cross-host
3
+ * layered lock in authorization/settings-file-store.ts.
7
4
  */
8
5
  import fs from 'node:fs/promises';
9
6
  import { PermissionsFileSchema } from './schema.js';
10
7
  import { operatingStrategy } from '../../operating-mode/index.js';
11
8
  import { mutateSettingsJsonFile } from '../settings-file-store.js';
12
- /**
13
- * Get the appropriate permissions file path based on mode
14
- */
15
9
  function getPermissionsFilePath(repoRoot, mode) {
16
10
  return operatingStrategy(mode).getPermissionsFilePath(repoRoot);
17
11
  }
18
- /**
19
- * Load full permissions file (for version checking)
20
- * Returns null if file doesn't exist.
21
- *
22
- * @param repoRoot - Repository root directory
23
- * @param mode - Operating mode (determines file path)
24
- */
12
+ /** Returns null when the file doesn't exist. */
25
13
  export async function loadPermissionsFile(repoRoot, mode) {
26
14
  const permissionsPath = getPermissionsFilePath(repoRoot, mode);
27
15
  try {
@@ -31,35 +19,28 @@ export async function loadPermissionsFile(repoRoot, mode) {
31
19
  return validated;
32
20
  }
33
21
  catch (error) {
34
- // File doesn't exist
35
22
  if (error.code === 'ENOENT') {
36
23
  return null;
37
24
  }
38
- // Parse/validation error - this is more serious
39
25
  console.error('CanopyCMS: Failed to parse permissions file', error);
40
26
  throw new Error(`Invalid permissions file: ${error instanceof Error ? error.message : 'unknown error'}`);
41
27
  }
42
28
  }
43
29
  /**
44
- * Load path permissions from .canopycms/permissions.json (or .local.json in dev mode)
45
- * Returns empty array if file doesn't exist (no restrictions).
46
- *
47
- * @param repoRoot - Repository root directory
48
- * @param mode - Operating mode (determines file path)
30
+ * Loads .canopycms/permissions.json (permissions.local.json in dev mode).
31
+ * Returns an empty array when the file doesn't exist: no restrictions.
49
32
  */
50
33
  export async function loadPathPermissions(repoRoot, mode) {
51
34
  const file = await loadPermissionsFile(repoRoot, mode);
52
35
  return file?.pathPermissions ?? [];
53
36
  }
54
37
  /**
55
- * Mutate permissions.json (or .local.json in dev mode) under the full
56
- * cross-host lock + OCC-retry stack (see
57
- * authorization/settings-file-store.ts). `mutate` is called with the
58
- * current parsed file (`null` if it doesn't exist yet) and the version to
59
- * write under; it returns the next raw payload, or `null` for a deliberate
60
- * no-op. The returned payload is validated against
61
- * {@link PermissionsFileSchema} before being written, preserving the
62
- * previous validate-before-write behavior of the old `savePathPermissions`.
38
+ * Mutate permissions.json (permissions.local.json in dev mode) under the full
39
+ * cross-host lock + OCC-retry stack (see authorization/settings-file-store.ts).
40
+ * `mutate` receives the current parsed file (`null` if absent) and the version
41
+ * to write under, and returns the next raw payload or `null` for a deliberate
42
+ * no-op. The payload is validated against {@link PermissionsFileSchema} before
43
+ * writing.
63
44
  */
64
45
  export async function mutatePermissionsFile(repoRoot, mode, mutate, options) {
65
46
  const permissionsPath = getPermissionsFilePath(repoRoot, mode);
@@ -75,8 +56,9 @@ export async function mutatePermissionsFile(repoRoot, mode, mutate, options) {
75
56
  });
76
57
  }
77
58
  /**
78
- * Initialize permissions file if it doesn't exist. A no-op when the file is
79
- * already present (the mutator returns `null`, so no write happens).
59
+ * Create the permissions file if it doesn't exist; a no-op when it is already
60
+ * present (the mutator returns `null`, so no write happens).
61
+ * @internal Exported for tests.
80
62
  */
81
63
  export async function ensurePermissionsFile(repoRoot, userId, mode) {
82
64
  await mutatePermissionsFile(repoRoot, mode, (current) => {
@@ -1,14 +1,8 @@
1
- /**
2
- * Schema for permissions.json file
3
- */
4
1
  import { z } from 'zod';
5
2
  import type { CanopyUserId } from '../../types.js';
6
3
  import type { PermissionPath } from '../types.js';
7
4
  /**
8
5
  * Schema for .canopycms/permissions.json
9
- *
10
- * SECURITY: Permission paths are validated to prevent path traversal attacks.
11
- * Any path containing '..' or other traversal sequences will be rejected.
12
6
  */
13
7
  export declare const PermissionsFileSchema: z.ZodObject<{
14
8
  version: z.ZodOptional<z.ZodNumber>;
@@ -129,5 +123,6 @@ export type PermissionsFile = z.infer<typeof PermissionsFileSchema>;
129
123
  /**
130
124
  * Default permissions file. Omits `version`/`writeId` — the writer
131
125
  * (mutateSettingsJsonFile via writeOccJsonFile) manages those.
126
+ * @internal Exported for tests.
132
127
  */
133
128
  export declare function createDefaultPermissionsFile(userId: CanopyUserId): PermissionsFile;
@@ -1,15 +1,10 @@
1
- /**
2
- * Schema for permissions.json file
3
- */
4
1
  import { z } from 'zod';
5
2
  import { parsePermissionPath } from '../validation.js';
6
3
  const permissionTargetSchema = z.object({
7
4
  allowedUsers: z.array(z.string()).optional(),
8
5
  allowedGroups: z.array(z.string()).optional(),
9
6
  });
10
- /**
11
- * Zod schema for PermissionPath - validates and prevents path traversal attacks.
12
- */
7
+ /** PermissionPath field: rejects path traversal via parsePermissionPath. */
13
8
  const permissionPathSchema = z
14
9
  .string()
15
10
  .min(1)
@@ -26,15 +21,12 @@ const permissionPathSchema = z
26
21
  });
27
22
  /**
28
23
  * Schema for .canopycms/permissions.json
29
- *
30
- * SECURITY: Permission paths are validated to prevent path traversal attacks.
31
- * Any path containing '..' or other traversal sequences will be rejected.
32
24
  */
33
25
  export const PermissionsFileSchema = z.object({
34
- // Managed by writeOccJsonFile (see authorization/settings-file-store.ts) —
35
- // the single OCC counter for this file. Optional so a hand-written file
36
- // with no version field parses as version 0. A legacy `contentVersion`
37
- // field (if present) is silently stripped by this non-strict zod parse.
26
+ // Managed by writeOccJsonFile (see authorization/settings-file-store.ts):
27
+ // the single OCC counter for this file. Optional so a hand-written file with
28
+ // no version field parses as version 0; a stray `contentVersion` key is
29
+ // silently stripped by this non-strict zod parse.
38
30
  version: z.number().int().nonnegative().optional(),
39
31
  writeId: z.string().optional(),
40
32
  updatedAt: z.string().datetime(),
@@ -49,6 +41,7 @@ export const PermissionsFileSchema = z.object({
49
41
  /**
50
42
  * Default permissions file. Omits `version`/`writeId` — the writer
51
43
  * (mutateSettingsJsonFile via writeOccJsonFile) manages those.
44
+ * @internal Exported for tests.
52
45
  */
53
46
  export function createDefaultPermissionsFile(userId) {
54
47
  return {