canopycms 0.0.59 → 0.0.61-int.74

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 (286) hide show
  1. package/dist/api/__test__/mock-client.d.ts +29 -0
  2. package/dist/api/__test__/mock-client.d.ts.map +1 -1
  3. package/dist/api/__test__/mock-client.js +55 -4
  4. package/dist/api/__test__/mock-client.js.map +1 -1
  5. package/dist/api/admin-branch-health.d.ts +65 -0
  6. package/dist/api/admin-branch-health.d.ts.map +1 -0
  7. package/dist/api/admin-branch-health.js +448 -0
  8. package/dist/api/admin-branch-health.js.map +1 -0
  9. package/dist/api/admin.d.ts +136 -0
  10. package/dist/api/admin.d.ts.map +1 -0
  11. package/dist/api/admin.js +338 -0
  12. package/dist/api/admin.js.map +1 -0
  13. package/dist/api/assets.d.ts.map +1 -1
  14. package/dist/api/assets.js +4 -0
  15. package/dist/api/assets.js.map +1 -1
  16. package/dist/api/branch-merge.d.ts +6 -0
  17. package/dist/api/branch-merge.d.ts.map +1 -1
  18. package/dist/api/branch-merge.js +15 -9
  19. package/dist/api/branch-merge.js.map +1 -1
  20. package/dist/api/branch-status.d.ts.map +1 -1
  21. package/dist/api/branch-status.js +15 -5
  22. package/dist/api/branch-status.js.map +1 -1
  23. package/dist/api/branch-withdraw.d.ts +6 -0
  24. package/dist/api/branch-withdraw.d.ts.map +1 -1
  25. package/dist/api/branch-withdraw.js +34 -7
  26. package/dist/api/branch-withdraw.js.map +1 -1
  27. package/dist/api/branch.d.ts +11 -1
  28. package/dist/api/branch.d.ts.map +1 -1
  29. package/dist/api/branch.js +70 -4
  30. package/dist/api/branch.js.map +1 -1
  31. package/dist/api/client.d.ts +34 -0
  32. package/dist/api/client.d.ts.map +1 -1
  33. package/dist/api/client.js +47 -0
  34. package/dist/api/client.js.map +1 -1
  35. package/dist/api/comments.d.ts.map +1 -1
  36. package/dist/api/comments.js +4 -0
  37. package/dist/api/comments.js.map +1 -1
  38. package/dist/api/content.d.ts.map +1 -1
  39. package/dist/api/content.js +4 -4
  40. package/dist/api/content.js.map +1 -1
  41. package/dist/api/entries.d.ts.map +1 -1
  42. package/dist/api/entries.js +23 -4
  43. package/dist/api/entries.js.map +1 -1
  44. package/dist/api/github-sync.d.ts.map +1 -1
  45. package/dist/api/github-sync.js +14 -3
  46. package/dist/api/github-sync.js.map +1 -1
  47. package/dist/api/groups.d.ts +3 -0
  48. package/dist/api/groups.d.ts.map +1 -1
  49. package/dist/api/groups.js +89 -68
  50. package/dist/api/groups.js.map +1 -1
  51. package/dist/api/guards.d.ts +7 -1
  52. package/dist/api/guards.d.ts.map +1 -1
  53. package/dist/api/guards.js +54 -0
  54. package/dist/api/guards.js.map +1 -1
  55. package/dist/api/index.d.ts +1 -0
  56. package/dist/api/index.d.ts.map +1 -1
  57. package/dist/api/index.js +0 -1
  58. package/dist/api/index.js.map +1 -1
  59. package/dist/api/permissions.d.ts +1 -0
  60. package/dist/api/permissions.d.ts.map +1 -1
  61. package/dist/api/permissions.js +23 -20
  62. package/dist/api/permissions.js.map +1 -1
  63. package/dist/api/schema.d.ts.map +1 -1
  64. package/dist/api/schema.js +36 -22
  65. package/dist/api/schema.js.map +1 -1
  66. package/dist/authorization/branch.d.ts +14 -1
  67. package/dist/authorization/branch.d.ts.map +1 -1
  68. package/dist/authorization/branch.js +5 -3
  69. package/dist/authorization/branch.js.map +1 -1
  70. package/dist/authorization/groups/index.d.ts +1 -1
  71. package/dist/authorization/groups/index.d.ts.map +1 -1
  72. package/dist/authorization/groups/index.js +1 -1
  73. package/dist/authorization/groups/index.js.map +1 -1
  74. package/dist/authorization/groups/loader.d.ts +25 -4
  75. package/dist/authorization/groups/loader.d.ts.map +1 -1
  76. package/dist/authorization/groups/loader.js +39 -20
  77. package/dist/authorization/groups/loader.js.map +1 -1
  78. package/dist/authorization/groups/schema.d.ts +8 -7
  79. package/dist/authorization/groups/schema.d.ts.map +1 -1
  80. package/dist/authorization/groups/schema.js +8 -4
  81. package/dist/authorization/groups/schema.js.map +1 -1
  82. package/dist/authorization/index.d.ts +5 -3
  83. package/dist/authorization/index.d.ts.map +1 -1
  84. package/dist/authorization/index.js +8 -3
  85. package/dist/authorization/index.js.map +1 -1
  86. package/dist/authorization/path.d.ts +8 -0
  87. package/dist/authorization/path.d.ts.map +1 -1
  88. package/dist/authorization/path.js +16 -1
  89. package/dist/authorization/path.js.map +1 -1
  90. package/dist/authorization/permissions/index.d.ts +1 -1
  91. package/dist/authorization/permissions/index.d.ts.map +1 -1
  92. package/dist/authorization/permissions/index.js +1 -1
  93. package/dist/authorization/permissions/index.js.map +1 -1
  94. package/dist/authorization/permissions/loader.d.ts +18 -4
  95. package/dist/authorization/permissions/loader.d.ts.map +1 -1
  96. package/dist/authorization/permissions/loader.js +35 -24
  97. package/dist/authorization/permissions/loader.js.map +1 -1
  98. package/dist/authorization/permissions/schema.d.ts +8 -7
  99. package/dist/authorization/permissions/schema.d.ts.map +1 -1
  100. package/dist/authorization/permissions/schema.js +8 -4
  101. package/dist/authorization/permissions/schema.js.map +1 -1
  102. package/dist/authorization/protected-branch.d.ts +39 -0
  103. package/dist/authorization/protected-branch.d.ts.map +1 -0
  104. package/dist/authorization/protected-branch.js +43 -0
  105. package/dist/authorization/protected-branch.js.map +1 -0
  106. package/dist/authorization/settings-file-store.d.ts +127 -0
  107. package/dist/authorization/settings-file-store.d.ts.map +1 -0
  108. package/dist/authorization/settings-file-store.js +156 -0
  109. package/dist/authorization/settings-file-store.js.map +1 -0
  110. package/dist/branch-health.d.ts +78 -0
  111. package/dist/branch-health.d.ts.map +1 -0
  112. package/dist/branch-health.js +151 -0
  113. package/dist/branch-health.js.map +1 -0
  114. package/dist/branch-metadata.d.ts +31 -0
  115. package/dist/branch-metadata.d.ts.map +1 -1
  116. package/dist/branch-metadata.js +43 -1
  117. package/dist/branch-metadata.js.map +1 -1
  118. package/dist/branch-registry.d.ts.map +1 -1
  119. package/dist/branch-registry.js +13 -1
  120. package/dist/branch-registry.js.map +1 -1
  121. package/dist/cli/cli.js +398 -200
  122. package/dist/cli/generate-ai-content.js +72 -13
  123. package/dist/cli/init.js +84 -2
  124. package/dist/cli/migrate.d.ts.map +1 -1
  125. package/dist/cli/migrate.js +39 -11
  126. package/dist/cli/migrate.js.map +1 -1
  127. package/dist/cli/sync.d.ts.map +1 -1
  128. package/dist/cli/sync.js +4 -1
  129. package/dist/cli/sync.js.map +1 -1
  130. package/dist/config/index.d.ts +1 -1
  131. package/dist/config/index.d.ts.map +1 -1
  132. package/dist/config/index.js.map +1 -1
  133. package/dist/config/schemas/config.d.ts +55 -5
  134. package/dist/config/schemas/config.d.ts.map +1 -1
  135. package/dist/config/schemas/config.js +18 -1
  136. package/dist/config/schemas/config.js.map +1 -1
  137. package/dist/config/types.d.ts +11 -1
  138. package/dist/config/types.d.ts.map +1 -1
  139. package/dist/content-store.d.ts +16 -0
  140. package/dist/content-store.d.ts.map +1 -1
  141. package/dist/content-store.js +22 -6
  142. package/dist/content-store.js.map +1 -1
  143. package/dist/context.d.ts +3 -0
  144. package/dist/context.d.ts.map +1 -1
  145. package/dist/context.js +25 -3
  146. package/dist/context.js.map +1 -1
  147. package/dist/editor/BranchManager.d.ts +11 -0
  148. package/dist/editor/BranchManager.d.ts.map +1 -1
  149. package/dist/editor/BranchManager.js +34 -10
  150. package/dist/editor/BranchManager.js.map +1 -1
  151. package/dist/editor/CommentsPanel.d.ts.map +1 -1
  152. package/dist/editor/CommentsPanel.js +4 -12
  153. package/dist/editor/CommentsPanel.js.map +1 -1
  154. package/dist/editor/Editor.d.ts.map +1 -1
  155. package/dist/editor/Editor.js +46 -10
  156. package/dist/editor/Editor.js.map +1 -1
  157. package/dist/editor/EntryNavigator.d.ts +7 -0
  158. package/dist/editor/EntryNavigator.d.ts.map +1 -1
  159. package/dist/editor/EntryNavigator.js +17 -5
  160. package/dist/editor/EntryNavigator.js.map +1 -1
  161. package/dist/editor/FormRenderer.d.ts.map +1 -1
  162. package/dist/editor/FormRenderer.js +4 -0
  163. package/dist/editor/FormRenderer.js.map +1 -1
  164. package/dist/editor/admin/SystemHealthPanel.d.ts +6 -0
  165. package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -0
  166. package/dist/editor/admin/SystemHealthPanel.js +234 -0
  167. package/dist/editor/admin/SystemHealthPanel.js.map +1 -0
  168. package/dist/editor/admin/useSystemHealth.d.ts +40 -0
  169. package/dist/editor/admin/useSystemHealth.d.ts.map +1 -0
  170. package/dist/editor/admin/useSystemHealth.js +205 -0
  171. package/dist/editor/admin/useSystemHealth.js.map +1 -0
  172. package/dist/editor/comments/FieldWrapper.d.ts.map +1 -1
  173. package/dist/editor/comments/FieldWrapper.js +1 -1
  174. package/dist/editor/comments/FieldWrapper.js.map +1 -1
  175. package/dist/editor/comments/InlineCommentThread.d.ts.map +1 -1
  176. package/dist/editor/comments/InlineCommentThread.js +2 -21
  177. package/dist/editor/comments/InlineCommentThread.js.map +1 -1
  178. package/dist/editor/comments/ThreadCarousel.d.ts +2 -0
  179. package/dist/editor/comments/ThreadCarousel.d.ts.map +1 -1
  180. package/dist/editor/comments/ThreadCarousel.js +5 -2
  181. package/dist/editor/comments/ThreadCarousel.js.map +1 -1
  182. package/dist/editor/components/EditorHeader.d.ts +11 -0
  183. package/dist/editor/components/EditorHeader.d.ts.map +1 -1
  184. package/dist/editor/components/EditorHeader.js +75 -41
  185. package/dist/editor/components/EditorHeader.js.map +1 -1
  186. package/dist/editor/components/EditorSidebar.d.ts +7 -1
  187. package/dist/editor/components/EditorSidebar.d.ts.map +1 -1
  188. package/dist/editor/components/EditorSidebar.js +3 -3
  189. package/dist/editor/components/EditorSidebar.js.map +1 -1
  190. package/dist/editor/fields/ImageField.d.ts.map +1 -1
  191. package/dist/editor/fields/ImageField.js +4 -1
  192. package/dist/editor/fields/ImageField.js.map +1 -1
  193. package/dist/editor/fields/StringListField.d.ts +20 -0
  194. package/dist/editor/fields/StringListField.d.ts.map +1 -0
  195. package/dist/editor/fields/StringListField.js +25 -0
  196. package/dist/editor/fields/StringListField.js.map +1 -0
  197. package/dist/editor/hooks/useBranchActions.d.ts.map +1 -1
  198. package/dist/editor/hooks/useBranchActions.js +8 -2
  199. package/dist/editor/hooks/useBranchActions.js.map +1 -1
  200. package/dist/editor/hooks/useBranchManager.d.ts +14 -3
  201. package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
  202. package/dist/editor/hooks/useBranchManager.js +18 -1
  203. package/dist/editor/hooks/useBranchManager.js.map +1 -1
  204. package/dist/editor/hooks/useDraftManager.d.ts +7 -0
  205. package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
  206. package/dist/editor/hooks/useDraftManager.js +57 -3
  207. package/dist/editor/hooks/useDraftManager.js.map +1 -1
  208. package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
  209. package/dist/editor/hooks/useEntryManager.js +25 -7
  210. package/dist/editor/hooks/useEntryManager.js.map +1 -1
  211. package/dist/editor/hooks/useGroupManager.d.ts.map +1 -1
  212. package/dist/editor/hooks/useGroupManager.js +13 -2
  213. package/dist/editor/hooks/useGroupManager.js.map +1 -1
  214. package/dist/editor/hooks/usePermissionManager.d.ts.map +1 -1
  215. package/dist/editor/hooks/usePermissionManager.js +13 -2
  216. package/dist/editor/hooks/usePermissionManager.js.map +1 -1
  217. package/dist/editor/media/AssetCard.d.ts.map +1 -1
  218. package/dist/editor/media/AssetCard.js +23 -2
  219. package/dist/editor/media/AssetCard.js.map +1 -1
  220. package/dist/editor/relative-time.d.ts +8 -0
  221. package/dist/editor/relative-time.d.ts.map +1 -0
  222. package/dist/editor/relative-time.js +26 -0
  223. package/dist/editor/relative-time.js.map +1 -0
  224. package/dist/git-manager.d.ts.map +1 -1
  225. package/dist/git-manager.js +16 -2
  226. package/dist/git-manager.js.map +1 -1
  227. package/dist/http/handler.d.ts.map +1 -1
  228. package/dist/http/handler.js +20 -9
  229. package/dist/http/handler.js.map +1 -1
  230. package/dist/http/router.d.ts.map +1 -1
  231. package/dist/http/router.js +2 -0
  232. package/dist/http/router.js.map +1 -1
  233. package/dist/paths/branch-name.d.ts +20 -0
  234. package/dist/paths/branch-name.d.ts.map +1 -0
  235. package/dist/paths/branch-name.js +24 -0
  236. package/dist/paths/branch-name.js.map +1 -0
  237. package/dist/paths/branch.d.ts +2 -8
  238. package/dist/paths/branch.d.ts.map +1 -1
  239. package/dist/paths/branch.js +6 -12
  240. package/dist/paths/branch.js.map +1 -1
  241. package/dist/paths/index.d.ts +2 -1
  242. package/dist/paths/index.d.ts.map +1 -1
  243. package/dist/paths/index.js +4 -1
  244. package/dist/paths/index.js.map +1 -1
  245. package/dist/schema/schema-store.d.ts +98 -0
  246. package/dist/schema/schema-store.d.ts.map +1 -1
  247. package/dist/schema/schema-store.js +187 -29
  248. package/dist/schema/schema-store.js.map +1 -1
  249. package/dist/services.js +9 -1
  250. package/dist/services.js.map +1 -1
  251. package/dist/task-queue/index.d.ts +2 -2
  252. package/dist/task-queue/index.d.ts.map +1 -1
  253. package/dist/task-queue/index.js +1 -1
  254. package/dist/task-queue/index.js.map +1 -1
  255. package/dist/task-queue/task-queue.d.ts +37 -1
  256. package/dist/task-queue/task-queue.d.ts.map +1 -1
  257. package/dist/task-queue/task-queue.js +104 -0
  258. package/dist/task-queue/task-queue.js.map +1 -1
  259. package/dist/task-queue/types.d.ts +11 -0
  260. package/dist/task-queue/types.d.ts.map +1 -1
  261. package/dist/types.d.ts +54 -0
  262. package/dist/types.d.ts.map +1 -1
  263. package/dist/utils/occ-json-write.d.ts.map +1 -1
  264. package/dist/utils/occ-json-write.js +7 -0
  265. package/dist/utils/occ-json-write.js.map +1 -1
  266. package/dist/utils/provisioning-lock.d.ts +19 -0
  267. package/dist/utils/provisioning-lock.d.ts.map +1 -1
  268. package/dist/utils/provisioning-lock.js +26 -0
  269. package/dist/utils/provisioning-lock.js.map +1 -1
  270. package/dist/validation/reference-validator.d.ts +17 -1
  271. package/dist/validation/reference-validator.d.ts.map +1 -1
  272. package/dist/validation/reference-validator.js +33 -10
  273. package/dist/validation/reference-validator.js.map +1 -1
  274. package/dist/worker/cms-worker.d.ts +74 -0
  275. package/dist/worker/cms-worker.d.ts.map +1 -1
  276. package/dist/worker/cms-worker.js +542 -29
  277. package/dist/worker/cms-worker.js.map +1 -1
  278. package/dist/worker/task-queue.d.ts +3 -3
  279. package/dist/worker/task-queue.d.ts.map +1 -1
  280. package/dist/worker/task-queue.js +2 -2
  281. package/dist/worker/task-queue.js.map +1 -1
  282. package/dist/worker/worker-status.d.ts +48 -0
  283. package/dist/worker/worker-status.d.ts.map +1 -0
  284. package/dist/worker/worker-status.js +53 -0
  285. package/dist/worker/worker-status.js.map +1 -0
  286. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/authorization/branch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAI/C;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAsB,EACtB,IAAgB,EAChB,gBAAqC,MAAM;IAE3C,+CAA+C;IAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAA;IACpC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAA;IACvD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAA;IACzD,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,IAAI,KAAK,CAAA;IAEnE,IAAI,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,IAAI,qBAAqB,EAAE,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;QACpD,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,KAAK,OAAO,CAAA;QACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;IACtC,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,IAAI,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACnF,MAAM,YAAY,GAChB,kBAAkB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAEnF,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC,CAAA;IACpD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,EAAE,CAAA;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,gBAAqC,MAAM;IACjF,OAAO,CAAC,OAAsB,EAAE,IAAgB,EAAsB,EAAE,CACtE,4BAA4B,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAsB,EACtB,IAAgB,EAChB,gBAAqC,MAAM;IAE3C,4EAA4E;IAC5E,MAAM,YAAY,GAAG,4BAA4B,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;IAE/E,6DAA6D;IAC7D,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,CAAA;IAE9D,2CAA2C;IAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,kBAAkB,CAAA;IAEtE,YAAY;IACZ,6BAA6B;IAC7B,wEAAwE;IACxE,uCAAuC;IACvC,OAAO,CACL,aAAa;QACb,YAAY,CAAC,MAAM,KAAK,YAAY;QACpC,YAAY,CAAC,MAAM,KAAK,gBAAgB;QACxC,CAAC,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,CACzC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/authorization/branch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAI/C;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAsB,EACtB,IAAgB,EAChB,gBAAqC,MAAM;IAE3C,+CAA+C;IAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA;IAChD,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAA;IACpC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAA;IACvD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAA;IACzD,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,IAAI,KAAK,CAAA;IAEnE,IAAI,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,IAAI,qBAAqB,EAAE,CAAC;YAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;QACpD,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,KAAK,OAAO,CAAA;QACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;IACtC,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,IAAI,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACnF,MAAM,YAAY,GAChB,kBAAkB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAEnF,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC,CAAA;IACpD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,EAAE,CAAA;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,gBAAqC,MAAM;IACjF,OAAO,CAAC,OAAsB,EAAE,IAAgB,EAAsB,EAAE,CACtE,4BAA4B,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;AAC9D,CAAC;AAcD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAsB,EACtB,IAAgB,EAChB,gBAAqC,MAAM,EAC3C,OAA+B;IAE/B,4EAA4E;IAC5E,MAAM,YAAY,GAAG,4BAA4B,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;IAE/E,6DAA6D;IAC7D,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,CAAA;IAE9D,kFAAkF;IAClF,MAAM,cAAc,GAClB,CAAC,OAAO,EAAE,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,kBAAkB,CAAA;IAEhF,YAAY;IACZ,6BAA6B;IAC7B,wEAAwE;IACxE,uCAAuC;IACvC,OAAO,CACL,aAAa;QACb,YAAY,CAAC,MAAM,KAAK,YAAY;QACpC,YAAY,CAAC,MAAM,KAAK,gBAAgB;QACxC,CAAC,cAAc,IAAI,YAAY,CAAC,OAAO,CAAC,CACzC,CAAA;AACH,CAAC"}
@@ -2,5 +2,5 @@
2
2
  * Groups module exports
3
3
  */
4
4
  export { GroupsFileSchema, createDefaultGroupsFile, type GroupsFile, type InternalGroup, } from './schema';
5
- export { loadGroupsFile, loadInternalGroups, saveInternalGroups } from './loader';
5
+ export { loadGroupsFile, loadInternalGroups, deriveInternalGroups, mutateGroupsFile, } from './loader';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,UAAU,CAAA"}
@@ -2,5 +2,5 @@
2
2
  * Groups module exports
3
3
  */
4
4
  export { GroupsFileSchema, createDefaultGroupsFile, } from './schema.js';
5
- export { loadGroupsFile, loadInternalGroups, saveInternalGroups } from './loader.js';
5
+ export { loadGroupsFile, loadInternalGroups, deriveInternalGroups, mutateGroupsFile, } from './loader.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authorization/groups/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GAGxB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authorization/groups/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GAGxB,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,UAAU,CAAA"}
@@ -1,16 +1,27 @@
1
1
  /**
2
2
  * Groups file loader
3
3
  *
4
- * Handles loading and saving internal groups from the filesystem.
4
+ * Handles loading internal groups from the filesystem and mutating
5
+ * groups.json under the cross-host layered lock in
6
+ * authorization/settings-file-store.ts.
5
7
  */
6
- import type { CanopyUserId } from '../../types';
7
8
  import { type InternalGroup, type GroupsFile } from './schema';
8
9
  import type { OperatingMode } from '../../operating-mode';
10
+ import type { OccWriteResult } from '../../utils/occ-json-write';
9
11
  /**
10
12
  * Load full groups file (for version checking)
11
13
  * Returns null if file doesn't exist.
12
14
  */
13
15
  export declare function loadGroupsFile(branchRoot: string, mode: OperatingMode): Promise<GroupsFile | null>;
16
+ /**
17
+ * Derive the effective internal groups list from the raw groups array
18
+ * stored on disk: ensures the reserved Admins/Reviewers groups always exist
19
+ * (synthesizing defaults when absent) and merges bootstrap admin IDs into
20
+ * Admins. Pure — no disk I/O — so a caller that already holds a freshly
21
+ * loaded file (e.g. a settings-file mutator, which reloads on every retry
22
+ * attempt) can reconcile against it without a second read.
23
+ */
24
+ export declare function deriveInternalGroups(fileGroups: InternalGroup[], bootstrapAdminIds?: Set<string>): InternalGroup[];
14
25
  /**
15
26
  * Load internal groups from .canopycms/groups.json (or .local.json in dev mode)
16
27
  * Ensures Admins and Reviewers groups always exist, adding them dynamically if not present.
@@ -18,7 +29,17 @@ export declare function loadGroupsFile(branchRoot: string, mode: OperatingMode):
18
29
  */
19
30
  export declare function loadInternalGroups(branchRoot: string, mode: OperatingMode, bootstrapAdminIds?: Set<string>): Promise<InternalGroup[]>;
20
31
  /**
21
- * Save internal groups to .canopycms/groups.json (or .local.json in dev mode)
32
+ * Mutate groups.json (or .local.json in dev mode) under the full cross-host
33
+ * lock + OCC-retry stack (see authorization/settings-file-store.ts).
34
+ * `mutate` is called with the current parsed file (`null` if it doesn't
35
+ * exist yet) and the version to write under; it returns the next raw
36
+ * payload, or `null` for a deliberate no-op. The returned payload is
37
+ * validated against {@link GroupsFileSchema} before being written,
38
+ * preserving the previous validate-before-write behavior of the old
39
+ * `saveInternalGroups`.
22
40
  */
23
- export declare function saveInternalGroups(branchRoot: string, groups: InternalGroup[], updatedBy: CanopyUserId, mode: OperatingMode, contentVersion?: number): Promise<void>;
41
+ export declare function mutateGroupsFile(branchRoot: string, mode: OperatingMode, mutate: (current: GroupsFile | null, version: number) => Record<string, unknown> | null, options?: {
42
+ settleMs?: number;
43
+ maxAttempts?: number;
44
+ }): Promise<OccWriteResult | null>;
24
45
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAoB,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAYzD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAe5B;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,EACnB,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAa,GACzC,OAAO,CAAC,aAAa,EAAE,CAAC,CA0C1B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,aAAa,EAAE,EACvB,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,aAAa,EACnB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAoB,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAIzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAShE;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAe5B;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EAAE,EAC3B,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAa,GACzC,aAAa,EAAE,CAuCjB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,EACnB,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAa,GACzC,OAAO,CAAC,aAAa,EAAE,CAAC,CAG1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACvF,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAahC"}
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * Groups file loader
3
3
  *
4
- * Handles loading and saving internal groups from the filesystem.
4
+ * Handles loading internal groups from the filesystem and mutating
5
+ * groups.json under the cross-host layered lock in
6
+ * authorization/settings-file-store.ts.
5
7
  */
6
8
  import { promises as fs } from 'node:fs';
7
9
  import { GroupsFileSchema } from './schema.js';
8
10
  import { operatingStrategy } from '../../operating-mode/index.js';
9
11
  import { RESERVED_GROUPS } from '../helpers.js';
10
- import { atomicWriteFile } from '../../utils/atomic-write.js';
12
+ import { mutateSettingsJsonFile } from '../settings-file-store.js';
11
13
  /**
12
14
  * Get the appropriate groups file path based on mode
13
15
  */
@@ -35,13 +37,14 @@ export async function loadGroupsFile(branchRoot, mode) {
35
37
  }
36
38
  }
37
39
  /**
38
- * Load internal groups from .canopycms/groups.json (or .local.json in dev mode)
39
- * Ensures Admins and Reviewers groups always exist, adding them dynamically if not present.
40
- * If Admins group exists in file, merges with bootstrap admin IDs.
40
+ * Derive the effective internal groups list from the raw groups array
41
+ * stored on disk: ensures the reserved Admins/Reviewers groups always exist
42
+ * (synthesizing defaults when absent) and merges bootstrap admin IDs into
43
+ * Admins. Pure — no disk I/O — so a caller that already holds a freshly
44
+ * loaded file (e.g. a settings-file mutator, which reloads on every retry
45
+ * attempt) can reconcile against it without a second read.
41
46
  */
42
- export async function loadInternalGroups(branchRoot, mode, bootstrapAdminIds = new Set()) {
43
- const file = await loadGroupsFile(branchRoot, mode);
44
- const fileGroups = file?.groups ?? [];
47
+ export function deriveInternalGroups(fileGroups, bootstrapAdminIds = new Set()) {
45
48
  // Find existing Admins and Reviewers groups
46
49
  let adminsGroup = fileGroups.find((g) => g.id === RESERVED_GROUPS.ADMINS);
47
50
  let reviewersGroup = fileGroups.find((g) => g.id === RESERVED_GROUPS.REVIEWERS);
@@ -77,19 +80,35 @@ export async function loadInternalGroups(branchRoot, mode, bootstrapAdminIds = n
77
80
  return [adminsGroup, reviewersGroup, ...otherGroups];
78
81
  }
79
82
  /**
80
- * Save internal groups to .canopycms/groups.json (or .local.json in dev mode)
83
+ * Load internal groups from .canopycms/groups.json (or .local.json in dev mode)
84
+ * Ensures Admins and Reviewers groups always exist, adding them dynamically if not present.
85
+ * If Admins group exists in file, merges with bootstrap admin IDs.
86
+ */
87
+ export async function loadInternalGroups(branchRoot, mode, bootstrapAdminIds = new Set()) {
88
+ const file = await loadGroupsFile(branchRoot, mode);
89
+ return deriveInternalGroups(file?.groups ?? [], bootstrapAdminIds);
90
+ }
91
+ /**
92
+ * Mutate groups.json (or .local.json in dev mode) under the full cross-host
93
+ * lock + OCC-retry stack (see authorization/settings-file-store.ts).
94
+ * `mutate` is called with the current parsed file (`null` if it doesn't
95
+ * exist yet) and the version to write under; it returns the next raw
96
+ * payload, or `null` for a deliberate no-op. The returned payload is
97
+ * validated against {@link GroupsFileSchema} before being written,
98
+ * preserving the previous validate-before-write behavior of the old
99
+ * `saveInternalGroups`.
81
100
  */
82
- export async function saveInternalGroups(branchRoot, groups, updatedBy, mode, contentVersion) {
101
+ export async function mutateGroupsFile(branchRoot, mode, mutate, options) {
83
102
  const groupsPath = getGroupsFilePath(branchRoot, mode);
84
- const groupsFile = {
85
- version: 1,
86
- contentVersion: contentVersion ?? 1,
87
- updatedAt: new Date().toISOString(),
88
- updatedBy,
89
- groups,
90
- };
91
- // Validate before writing
92
- GroupsFileSchema.parse(groupsFile);
93
- await atomicWriteFile(groupsPath, JSON.stringify(groupsFile, null, 2));
103
+ return mutateSettingsJsonFile({
104
+ filePath: groupsPath,
105
+ parse: (raw) => GroupsFileSchema.parse(JSON.parse(raw)),
106
+ mutate: (current, version) => {
107
+ const payload = mutate(current, version);
108
+ return payload === null ? null : GroupsFileSchema.parse(payload);
109
+ },
110
+ settleMs: options?.settleMs,
111
+ maxAttempts: options?.maxAttempts,
112
+ });
94
113
  }
95
114
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/authorization/groups/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/authorization/groups/loader.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@ import type { CanopyUserId, CanopyGroupId } from '../../types';
7
7
  * Schema for .canopycms/groups.json
8
8
  */
9
9
  export declare const GroupsFileSchema: z.ZodObject<{
10
- version: z.ZodLiteral<1>;
11
- contentVersion: z.ZodOptional<z.ZodNumber>;
10
+ version: z.ZodOptional<z.ZodNumber>;
11
+ writeId: z.ZodOptional<z.ZodString>;
12
12
  updatedAt: z.ZodString;
13
13
  updatedBy: z.ZodType<CanopyUserId>;
14
14
  groups: z.ZodArray<z.ZodObject<{
@@ -28,7 +28,6 @@ export declare const GroupsFileSchema: z.ZodObject<{
28
28
  description?: string | undefined;
29
29
  }>, "many">;
30
30
  }, "strip", z.ZodTypeAny, {
31
- version: 1;
32
31
  updatedAt: string;
33
32
  groups: {
34
33
  name: string;
@@ -37,9 +36,9 @@ export declare const GroupsFileSchema: z.ZodObject<{
37
36
  description?: string | undefined;
38
37
  }[];
39
38
  updatedBy: string;
40
- contentVersion?: number | undefined;
39
+ version?: number | undefined;
40
+ writeId?: string | undefined;
41
41
  }, {
42
- version: 1;
43
42
  updatedAt: string;
44
43
  groups: {
45
44
  name: string;
@@ -48,7 +47,8 @@ export declare const GroupsFileSchema: z.ZodObject<{
48
47
  description?: string | undefined;
49
48
  }[];
50
49
  updatedBy: string;
51
- contentVersion?: number | undefined;
50
+ version?: number | undefined;
51
+ writeId?: string | undefined;
52
52
  }>;
53
53
  export type GroupsFile = z.infer<typeof GroupsFileSchema>;
54
54
  /**
@@ -61,7 +61,8 @@ export interface InternalGroup {
61
61
  members: CanopyUserId[];
62
62
  }
63
63
  /**
64
- * Default groups file
64
+ * Default groups file. Omits `version`/`writeId` — the writer
65
+ * (mutateSettingsJsonFile via writeOccJsonFile) manages those.
65
66
  */
66
67
  export declare function createDefaultGroupsFile(userId: CanopyUserId): GroupsFile;
67
68
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE9D;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;eAIF,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;;YAG1B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM9C,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,aAAa,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAOxE"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/authorization/groups/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE9D;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;eAQF,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;;YAG1B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM9C,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,aAAa,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,YAAY,EAAE,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAMxE"}
@@ -6,8 +6,12 @@ import { z } from 'zod';
6
6
  * Schema for .canopycms/groups.json
7
7
  */
8
8
  export const GroupsFileSchema = z.object({
9
- version: z.literal(1),
10
- contentVersion: z.number().optional(), // For optimistic locking
9
+ // Managed by writeOccJsonFile (see authorization/settings-file-store.ts) —
10
+ // the single OCC counter for this file. Optional so a hand-written file
11
+ // with no version field parses as version 0. A legacy `contentVersion`
12
+ // field (if present) is silently stripped by this non-strict zod parse.
13
+ version: z.number().int().nonnegative().optional(),
14
+ writeId: z.string().optional(),
11
15
  updatedAt: z.string().datetime(),
12
16
  updatedBy: z.string(),
13
17
  groups: z.array(z.object({
@@ -18,11 +22,11 @@ export const GroupsFileSchema = z.object({
18
22
  })),
19
23
  });
20
24
  /**
21
- * Default groups file
25
+ * Default groups file. Omits `version`/`writeId` — the writer
26
+ * (mutateSettingsJsonFile via writeOccJsonFile) manages those.
22
27
  */
23
28
  export function createDefaultGroupsFile(userId) {
24
29
  return {
25
- version: 1,
26
30
  updatedAt: new Date().toISOString(),
27
31
  updatedBy: userId,
28
32
  groups: [],
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/authorization/groups/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,yBAAyB;IAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAA6B;IAChD,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAA8B;QAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAA6B,CAAC;KACxD,CAAC,CACH;CACF,CAAC,CAAA;AAcF;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAoB;IAC1D,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,MAAM;QACjB,MAAM,EAAE,EAAE;KACX,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/authorization/groups/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,2EAA2E;IAC3E,wEAAwE;IACxE,uEAAuE;IACvE,wEAAwE;IACxE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAClD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAA6B;IAChD,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAA8B;QAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAA6B,CAAC;KACxD,CAAC,CACH;CACF,CAAC,CAAA;AAcF;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAoB;IAC1D,OAAO;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,MAAM;QACjB,MAAM,EAAE,EAAE;KACX,CAAA;AACH,CAAC"}
@@ -29,8 +29,10 @@ export type { BranchAccessResult, PathPermissionResult, ContentAccessResult, Con
29
29
  export { parsePermissionPath } from './validation';
30
30
  export { checkContentAccess, createCheckContentAccess, createContentAccessChecker, type ContentAccessChecker, } from './content';
31
31
  export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch';
32
- export { checkPathAccess, createCheckPathAccess } from './path';
32
+ export { getBranchProtection, type BranchProtection } from './protected-branch';
33
+ export { checkPathAccess, createCheckPathAccess, resolveDefaultPathAccess } from './path';
33
34
  export { RESERVED_GROUPS, type ReservedGroupId, isReservedGroup, stripReservedGroups, isAdmin, isReviewer, isPrivileged, } from './helpers';
34
- export { PermissionsFileSchema, createDefaultPermissionsFile, type PermissionsFile, loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './permissions';
35
- export { GroupsFileSchema, createDefaultGroupsFile, type GroupsFile, type InternalGroup, loadGroupsFile, loadInternalGroups, saveInternalGroups, } from './groups';
35
+ export { PermissionsFileSchema, createDefaultPermissionsFile, type PermissionsFile, loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './permissions';
36
+ export { GroupsFileSchema, createDefaultGroupsFile, type GroupsFile, type InternalGroup, loadGroupsFile, loadInternalGroups, deriveInternalGroups, mutateGroupsFile, } from './groups';
37
+ export { mutateSettingsJsonFile, SettingsFileConflictError, SettingsVersionConflictError, type MutateSettingsFileOptions, } from './settings-file-store';
36
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authorization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GACf,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAA;AAG/D,OAAO,EACL,eAAe,EACf,KAAK,eAAe,EACpB,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,KAAK,eAAe,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authorization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GACf,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG/E,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAA;AAGzF,OAAO,EACL,eAAe,EACf,KAAK,eAAe,EACpB,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,KAAK,eAAe,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAIjB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,4BAA4B,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAA"}
@@ -31,12 +31,17 @@ export { parsePermissionPath } from './validation.js';
31
31
  export { checkContentAccess, createCheckContentAccess, createContentAccessChecker, } from './content.js';
32
32
  // Branch-level access
33
33
  export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch.js';
34
+ // Protected base branch (submit-block + read-only predicate)
35
+ export { getBranchProtection } from './protected-branch.js';
34
36
  // Path-level access
35
- export { checkPathAccess, createCheckPathAccess } from './path.js';
37
+ export { checkPathAccess, createCheckPathAccess, resolveDefaultPathAccess } from './path.js';
36
38
  // Helper functions
37
39
  export { RESERVED_GROUPS, isReservedGroup, stripReservedGroups, isAdmin, isReviewer, isPrivileged, } from './helpers.js';
38
40
  // Permissions file handling
39
- export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './permissions/index.js';
41
+ export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './permissions/index.js';
40
42
  // Groups file handling
41
- export { GroupsFileSchema, createDefaultGroupsFile, loadGroupsFile, loadInternalGroups, saveInternalGroups, } from './groups/index.js';
43
+ 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
+ export { mutateSettingsJsonFile, SettingsFileConflictError, SettingsVersionConflictError, } from './settings-file-store.js';
42
47
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authorization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,mDAAmD;AACnD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,GAE3B,MAAM,WAAW,CAAA;AAElB,sBAAsB;AACtB,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,UAAU,CAAA;AAEjB,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAA;AAE/D,mBAAmB;AACnB,OAAO,EACL,eAAe,EAEf,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAElB,4BAA4B;AAC5B,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAE5B,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,eAAe,CAAA;AAEtB,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EAGvB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authorization/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElD,mDAAmD;AACnD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,GAE3B,MAAM,WAAW,CAAA;AAElB,sBAAsB;AACtB,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,UAAU,CAAA;AAEjB,6DAA6D;AAC7D,OAAO,EAAE,mBAAmB,EAAyB,MAAM,oBAAoB,CAAA;AAE/E,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAA;AAEzF,mBAAmB;AACnB,OAAO,EACL,eAAe,EAEf,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAElB,4BAA4B;AAC5B,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAE5B,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAA;AAEtB,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EAGvB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAEjB,6DAA6D;AAC7D,8EAA8E;AAC9E,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,4BAA4B,GAE7B,MAAM,uBAAuB,CAAA"}
@@ -7,6 +7,14 @@ import type { PathPermission, DefaultPathAccess, PermissionLevel } from '../conf
7
7
  import type { CanopyUser } from '../user';
8
8
  import type { PathPermissionResult } from './types';
9
9
  import type { PhysicalPath } from '../paths/types';
10
+ /**
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.
16
+ */
17
+ export declare function resolveDefaultPathAccess(defaultAccess: DefaultPathAccess, level: PermissionLevel): 'allow' | 'deny';
10
18
  /**
11
19
  * Evaluate access for a relative path against config-defined rules.
12
20
  * Uses defaultAccess when no rule matches. First matching rule wins.
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/authorization/path.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAA;AAElB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAoClD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,KAAK,GACN,EAAE;IACD,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,aAAa,EAAE,iBAAiB,CAAA;IAChC,KAAK,EAAE,eAAe,CAAA;CACvB,GAAG,oBAAoB,CA6BvB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,aAAa,EAAE,iBAAiB,IACrF,OAAO;IACb,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,eAAe,CAAA;CACvB,KAAG,oBAAoB,CACzB"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/authorization/path.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAA;AAElB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAoClD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,iBAAiB,EAChC,KAAK,EAAE,eAAe,GACrB,OAAO,GAAG,MAAM,CAGlB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,KAAK,GACN,EAAE;IACD,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,aAAa,EAAE,iBAAiB,CAAA;IAChC,KAAK,EAAE,eAAe,CAAA;CACvB,GAAG,oBAAoB,CAgCvB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,aAAa,EAAE,iBAAiB,IACrF,OAAO;IACb,YAAY,EAAE,YAAY,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,eAAe,CAAA;CACvB,KAAG,oBAAoB,CACzB"}
@@ -33,6 +33,18 @@ function isAllowedByTarget(target, user) {
33
33
  const matchesGroup = hasGroupConstraint && user.groups?.some((gid) => target.allowedGroups?.includes(gid));
34
34
  return Boolean(matchesUser || matchesGroup);
35
35
  }
36
+ /**
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.
42
+ */
43
+ export function resolveDefaultPathAccess(defaultAccess, level) {
44
+ if (typeof defaultAccess === 'string')
45
+ return defaultAccess;
46
+ return defaultAccess[level] ?? 'deny';
47
+ }
36
48
  /**
37
49
  * Evaluate access for a relative path against config-defined rules.
38
50
  * Uses defaultAccess when no rule matches. First matching rule wins.
@@ -60,7 +72,10 @@ export function checkPathAccess({ rules, relativePath, user, defaultAccess, leve
60
72
  reason: allowed ? 'allowed_by_rule' : 'denied_by_rule',
61
73
  };
62
74
  }
63
- return { allowed: defaultAccess === 'allow', reason: 'no_rule_match' };
75
+ return {
76
+ allowed: resolveDefaultPathAccess(defaultAccess, level) === 'allow',
77
+ reason: 'no_rule_match',
78
+ };
64
79
  }
65
80
  /**
66
81
  * Factory to bind rules and defaultAccess once.
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/authorization/path.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAQrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC;;GAEG;AACH,SAAS,SAAS,CAAC,CAAe;IAChC,MAAM,UAAU,GAAI,CAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC1D,OAAO,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAiB,CAAA;AAC1D,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,IAAoB,EAAE,YAA0B;IACnE,OAAO,SAAS,CAAC,YAAsB,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;AACpE,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAwB,EAAE,IAAgB;IACnE,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAA;IACvD,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAA;IAEzD,0DAA0D;IAC1D,IAAI,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,IAAI,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACnF,MAAM,YAAY,GAChB,kBAAkB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAEvF,OAAO,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC,CAAA;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,KAAK,GAON;IACC,MAAM,cAAc,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;IAE9C,0CAA0C;IAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;IAC3C,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,CAAC;YACvC,SAAQ;QACV,CAAC;QAED,2CAA2C;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,4EAA4E;YAC5E,SAAQ;QACV,CAAC;QAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC/C,OAAO;YACL,OAAO;YACP,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,gBAAgB;SACvD,CAAA;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,aAAa,KAAK,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAuB,EAAE,aAAgC;IAC7F,OAAO,CAAC,KAIP,EAAwB,EAAE,CAAC,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAA;AACjF,CAAC"}
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/authorization/path.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@
2
2
  * Permissions module exports
3
3
  */
4
4
  export { PermissionsFileSchema, createDefaultPermissionsFile, type PermissionsFile } from './schema';
5
- export { loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './loader';
5
+ export { loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './loader';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authorization/permissions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACpG,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authorization/permissions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACpG,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAA"}
@@ -2,5 +2,5 @@
2
2
  * Permissions module exports
3
3
  */
4
4
  export { PermissionsFileSchema, createDefaultPermissionsFile } from './schema.js';
5
- export { loadPermissionsFile, loadPathPermissions, savePathPermissions, ensurePermissionsFile, } from './loader.js';
5
+ export { loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './loader.js';
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authorization/permissions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAwB,MAAM,UAAU,CAAA;AACpG,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authorization/permissions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAwB,MAAM,UAAU,CAAA;AACpG,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAA"}
@@ -1,11 +1,14 @@
1
1
  /**
2
2
  * Permissions file loader
3
3
  *
4
- * Handles loading and saving path permissions from the filesystem.
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.
5
7
  */
6
8
  import type { PathPermission } from '../../config';
7
9
  import type { PermissionsFile } from './schema';
8
10
  import type { OperatingMode } from '../../operating-mode';
11
+ import type { OccWriteResult } from '../../utils/occ-json-write';
9
12
  /**
10
13
  * Load full permissions file (for version checking)
11
14
  * Returns null if file doesn't exist.
@@ -23,11 +26,22 @@ export declare function loadPermissionsFile(repoRoot: string, mode: OperatingMod
23
26
  */
24
27
  export declare function loadPathPermissions(repoRoot: string, mode: OperatingMode): Promise<PathPermission[]>;
25
28
  /**
26
- * Save path permissions to .canopycms/permissions.json (or .local.json in dev mode)
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`.
27
37
  */
28
- export declare function savePathPermissions(repoRoot: string, permissions: PathPermission[], updatedBy: string, mode: OperatingMode, contentVersion?: number): Promise<void>;
38
+ export declare function mutatePermissionsFile(repoRoot: string, mode: OperatingMode, mutate: (current: PermissionsFile | null, version: number) => Record<string, unknown> | null, options?: {
39
+ settleMs?: number;
40
+ maxAttempts?: number;
41
+ }): Promise<OccWriteResult | null>;
29
42
  /**
30
- * Initialize permissions file if it doesn't exist
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).
31
45
  */
32
46
  export declare function ensurePermissionsFile(repoRoot: string, userId: string, mode: OperatingMode): Promise<void>;
33
47
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/authorization/permissions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWzD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoBjC;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,cAAc,EAAE,EAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,aAAa,EACnB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAUf"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/authorization/permissions/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAShE;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoBjC;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3B;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAC5F,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAahC;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * Permissions file loader
3
3
  *
4
- * Handles loading and saving path permissions from the filesystem.
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.
5
7
  */
6
8
  import fs from 'node:fs/promises';
7
9
  import { PermissionsFileSchema } from './schema.js';
8
10
  import { operatingStrategy } from '../../operating-mode/index.js';
9
- import { atomicWriteFile } from '../../utils/atomic-write.js';
11
+ import { mutateSettingsJsonFile } from '../settings-file-store.js';
10
12
  /**
11
13
  * Get the appropriate permissions file path based on mode
12
14
  */
@@ -50,33 +52,42 @@ export async function loadPathPermissions(repoRoot, mode) {
50
52
  return file?.pathPermissions ?? [];
51
53
  }
52
54
  /**
53
- * Save path permissions to .canopycms/permissions.json (or .local.json in dev mode)
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`.
54
63
  */
55
- export async function savePathPermissions(repoRoot, permissions, updatedBy, mode, contentVersion) {
64
+ export async function mutatePermissionsFile(repoRoot, mode, mutate, options) {
56
65
  const permissionsPath = getPermissionsFilePath(repoRoot, mode);
57
- const permissionsFile = {
58
- version: 1,
59
- contentVersion: contentVersion ?? 1,
60
- updatedAt: new Date().toISOString(),
61
- updatedBy,
62
- pathPermissions: permissions,
63
- };
64
- // Validate before writing
65
- PermissionsFileSchema.parse(permissionsFile);
66
- await atomicWriteFile(permissionsPath, JSON.stringify(permissionsFile, null, 2));
66
+ return mutateSettingsJsonFile({
67
+ filePath: permissionsPath,
68
+ parse: (raw) => PermissionsFileSchema.parse(JSON.parse(raw)),
69
+ mutate: (current, version) => {
70
+ const payload = mutate(current, version);
71
+ return payload === null ? null : PermissionsFileSchema.parse(payload);
72
+ },
73
+ settleMs: options?.settleMs,
74
+ maxAttempts: options?.maxAttempts,
75
+ });
67
76
  }
68
77
  /**
69
- * Initialize permissions file if it doesn't exist
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).
70
80
  */
71
81
  export async function ensurePermissionsFile(repoRoot, userId, mode) {
72
- const permissionsPath = getPermissionsFilePath(repoRoot, mode);
73
- try {
74
- await fs.access(permissionsPath);
75
- // File exists, nothing to do
76
- }
77
- catch {
78
- // File doesn't exist, create default
79
- await savePathPermissions(repoRoot, [], userId, mode);
80
- }
82
+ await mutatePermissionsFile(repoRoot, mode, (current) => {
83
+ if (current) {
84
+ return null;
85
+ }
86
+ return {
87
+ updatedAt: new Date().toISOString(),
88
+ updatedBy: userId,
89
+ pathPermissions: [],
90
+ };
91
+ });
81
92
  }
82
93
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/authorization/permissions/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAGjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D;;GAEG;AACH,SAAS,sBAAsB,CAAC,QAAgB,EAAE,IAAmB;IACnE,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAA;AACjE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,IAAmB;IAEnB,MAAM,eAAe,GAAG,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAE9D,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACrD,OAAO,SAAS,CAAA;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,qBAAqB;QACrB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,gDAAgD;QAChD,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAA;QACnE,MAAM,IAAI,KAAK,CACb,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACxF,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,IAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACtD,OAAO,IAAI,EAAE,eAAe,IAAI,EAAE,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB,EAChB,WAA6B,EAC7B,SAAiB,EACjB,IAAmB,EACnB,cAAuB;IAEvB,MAAM,eAAe,GAAG,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAE9D,MAAM,eAAe,GAAoB;QACvC,OAAO,EAAE,CAAC;QACV,cAAc,EAAE,cAAc,IAAI,CAAC;QACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS;QACT,eAAe,EAAE,WAAW;KAC7B,CAAA;IAED,0BAA0B;IAC1B,qBAAqB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;IAE5C,MAAM,eAAe,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAClF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAgB,EAChB,MAAc,EACd,IAAmB;IAEnB,MAAM,eAAe,GAAG,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAE9D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;QAChC,6BAA6B;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,MAAM,mBAAmB,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IACvD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/authorization/permissions/loader.ts"],"names":[],"mappings":"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"}