canopycms 0.0.68-int.98 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/CHANGELOG.md +2131 -0
  2. package/README.md +47 -63
  3. package/dist/ai/generate.d.ts +5 -0
  4. package/dist/ai/generate.js +244 -115
  5. package/dist/ai/index.d.ts +1 -1
  6. package/dist/ai/json-to-markdown.d.ts +21 -1
  7. package/dist/ai/json-to-markdown.js +120 -57
  8. package/dist/ai/references.d.ts +72 -0
  9. package/dist/ai/references.js +223 -0
  10. package/dist/ai/resolve-branch.js +9 -2
  11. package/dist/ai/to-plain-text.d.ts +17 -8
  12. package/dist/ai/to-plain-text.js +18 -15
  13. package/dist/ai/types.d.ts +84 -3
  14. package/dist/api/admin-branch-health.d.ts +24 -1
  15. package/dist/api/admin-branch-health.js +52 -20
  16. package/dist/api/admin.d.ts +23 -5
  17. package/dist/api/admin.js +36 -1
  18. package/dist/api/assets.js +88 -78
  19. package/dist/api/branch-create-window.d.ts +12 -0
  20. package/dist/api/branch-create-window.js +13 -0
  21. package/dist/api/branch-merge.d.ts +1 -1
  22. package/dist/api/branch-merge.js +1 -1
  23. package/dist/api/branch-review.d.ts +3 -3
  24. package/dist/api/branch-review.js +16 -7
  25. package/dist/api/branch-status.d.ts +16 -6
  26. package/dist/api/branch-status.js +57 -12
  27. package/dist/api/branch-withdraw.d.ts +2 -2
  28. package/dist/api/branch-withdraw.js +8 -3
  29. package/dist/api/branch.d.ts +25 -12
  30. package/dist/api/branch.js +164 -103
  31. package/dist/api/client.d.ts +78 -58
  32. package/dist/api/client.js +150 -117
  33. package/dist/api/comments.d.ts +12 -3
  34. package/dist/api/comments.js +118 -9
  35. package/dist/api/content.d.ts +9 -9
  36. package/dist/api/content.js +131 -22
  37. package/dist/api/entries-constants.d.ts +14 -3
  38. package/dist/api/entries-constants.js +14 -3
  39. package/dist/api/entries.d.ts +40 -2
  40. package/dist/api/entries.js +102 -6
  41. package/dist/api/github-sync.d.ts +19 -0
  42. package/dist/api/github-sync.js +50 -3
  43. package/dist/api/groups.d.ts +4 -4
  44. package/dist/api/groups.js +2 -1
  45. package/dist/api/guards.js +23 -3
  46. package/dist/api/index.d.ts +3 -1
  47. package/dist/api/index.js +1 -0
  48. package/dist/api/permissions.d.ts +21 -2
  49. package/dist/api/permissions.js +50 -3
  50. package/dist/api/request-deadline.d.ts +59 -0
  51. package/dist/api/request-deadline.js +73 -0
  52. package/dist/api/resolve-references.js +8 -7
  53. package/dist/api/route-builder.d.ts +14 -0
  54. package/dist/api/route-builder.js +14 -1
  55. package/dist/api/schema.d.ts +11 -9
  56. package/dist/api/schema.js +2 -0
  57. package/dist/api/settings-helpers.d.ts +5 -1
  58. package/dist/api/settings-helpers.js +10 -2
  59. package/dist/api/types.d.ts +18 -0
  60. package/dist/api/users-constants.d.ts +6 -0
  61. package/dist/api/users-constants.js +6 -0
  62. package/dist/assets/asset-url.d.ts +28 -16
  63. package/dist/assets/asset-url.js +51 -25
  64. package/dist/assets/finalize.js +3 -0
  65. package/dist/assets/index.d.ts +1 -1
  66. package/dist/assets/materialize.d.ts +153 -0
  67. package/dist/assets/materialize.js +402 -0
  68. package/dist/assets/store-local.d.ts +19 -5
  69. package/dist/assets/store-local.js +69 -10
  70. package/dist/assets/store-s3.d.ts +38 -7
  71. package/dist/assets/store-s3.js +128 -22
  72. package/dist/assets/transform-directives.d.ts +52 -13
  73. package/dist/assets/transform-directives.js +87 -27
  74. package/dist/assets/transform.d.ts +3 -3
  75. package/dist/assets/transform.js +13 -8
  76. package/dist/assets/types.d.ts +31 -4
  77. package/dist/auth/cache.d.ts +1 -1
  78. package/dist/auth/cache.js +1 -1
  79. package/dist/auth/caching-auth-plugin.d.ts +2 -0
  80. package/dist/auth/caching-auth-plugin.js +12 -2
  81. package/dist/auth/file-based-auth-cache.d.ts +8 -0
  82. package/dist/auth/file-based-auth-cache.js +18 -8
  83. package/dist/auth/person-name.d.ts +5 -0
  84. package/dist/auth/person-name.js +8 -0
  85. package/dist/auth/plugin.d.ts +10 -1
  86. package/dist/auth/types.d.ts +2 -0
  87. package/dist/auth/user-metadata-lookup.d.ts +21 -0
  88. package/dist/auth/user-metadata-lookup.js +116 -0
  89. package/dist/authorization/branch.d.ts +1 -1
  90. package/dist/authorization/branch.js +12 -13
  91. package/dist/authorization/groups/schema.d.ts +4 -4
  92. package/dist/authorization/helpers.d.ts +8 -0
  93. package/dist/authorization/helpers.js +8 -0
  94. package/dist/authorization/index.d.ts +1 -1
  95. package/dist/authorization/index.js +1 -1
  96. package/dist/authorization/protected-branch.d.ts +5 -4
  97. package/dist/authorization/protected-branch.js +7 -5
  98. package/dist/branch-health.d.ts +35 -8
  99. package/dist/branch-health.js +54 -18
  100. package/dist/branch-metadata-error.d.ts +27 -0
  101. package/dist/branch-metadata-error.js +23 -0
  102. package/dist/branch-metadata-file.d.ts +205 -24
  103. package/dist/branch-metadata-file.js +126 -25
  104. package/dist/branch-metadata.d.ts +45 -6
  105. package/dist/branch-metadata.js +142 -50
  106. package/dist/branch-provisioning.d.ts +167 -0
  107. package/dist/branch-provisioning.js +501 -0
  108. package/dist/branch-registry.d.ts +8 -0
  109. package/dist/branch-registry.js +61 -9
  110. package/dist/branch-schema-cache.d.ts +29 -12
  111. package/dist/branch-schema-cache.js +64 -21
  112. package/dist/branch-sparse.d.ts +23 -0
  113. package/dist/branch-sparse.js +118 -0
  114. package/dist/branch-workspace.d.ts +42 -3
  115. package/dist/branch-workspace.js +239 -100
  116. package/dist/build/asset-refs.d.ts +94 -0
  117. package/dist/build/asset-refs.js +267 -0
  118. package/dist/build/generate-ai-content.js +5 -0
  119. package/dist/build/inline-flight.d.ts +37 -0
  120. package/dist/build/inline-flight.js +142 -0
  121. package/dist/cli/asset-refs.d.ts +52 -0
  122. package/dist/cli/asset-refs.js +194 -0
  123. package/dist/cli/cli.d.ts +15 -1
  124. package/dist/cli/cli.js +8543 -3193
  125. package/dist/cli/configured-asset-store.d.ts +12 -0
  126. package/dist/cli/configured-asset-store.js +46 -0
  127. package/dist/cli/generate-ai-content.js +4244 -1072
  128. package/dist/cli/init.js +217 -126
  129. package/dist/cli/project-detect.d.ts +2 -0
  130. package/dist/cli/project-detect.js +2 -0
  131. package/dist/cli/template-files/Dockerfile.cms.template +13 -5
  132. package/dist/cli/template-files/cms-stack.ts.template +16 -13
  133. package/dist/client.d.ts +1 -2
  134. package/dist/client.js +1 -2
  135. package/dist/comment-store.d.ts +25 -0
  136. package/dist/comment-store.js +43 -8
  137. package/dist/config/flatten.js +2 -0
  138. package/dist/config/helpers.js +2 -2
  139. package/dist/config/index.d.ts +1 -1
  140. package/dist/config/schemas/config.d.ts +12 -29
  141. package/dist/config/schemas/config.js +9 -12
  142. package/dist/config/schemas/field.d.ts +3 -0
  143. package/dist/config/schemas/field.js +58 -4
  144. package/dist/config/schemas/media.d.ts +4 -13
  145. package/dist/config/schemas/media.js +5 -8
  146. package/dist/config/schemas/url.d.ts +2 -20
  147. package/dist/config/schemas/url.js +2 -25
  148. package/dist/config/types.d.ts +116 -22
  149. package/dist/config/types.js +3 -9
  150. package/dist/config/validation.d.ts +25 -4
  151. package/dist/config/validation.js +116 -3
  152. package/dist/content-id-index.js +2 -2
  153. package/dist/content-index-generation.d.ts +1 -1
  154. package/dist/content-index-generation.js +1 -1
  155. package/dist/content-listing.d.ts +10 -1
  156. package/dist/content-listing.js +22 -5
  157. package/dist/content-reader.d.ts +9 -0
  158. package/dist/content-reader.js +16 -11
  159. package/dist/content-store.d.ts +75 -12
  160. package/dist/content-store.js +249 -86
  161. package/dist/content-tree.js +2 -2
  162. package/dist/context.js +5 -2
  163. package/dist/dangling-reference-log.d.ts +17 -0
  164. package/dist/dangling-reference-log.js +29 -0
  165. package/dist/dev-content-watcher.d.ts +1 -1
  166. package/dist/dev-content-watcher.js +1 -1
  167. package/dist/editor/BranchManager.d.ts +23 -7
  168. package/dist/editor/BranchManager.js +119 -54
  169. package/dist/editor/CanopyEditor.d.ts +1 -1
  170. package/dist/editor/CanopyEditor.js +1 -2
  171. package/dist/editor/CommentsPanel.d.ts +14 -0
  172. package/dist/editor/CommentsPanel.js +68 -43
  173. package/dist/editor/Editor.d.ts +11 -5
  174. package/dist/editor/Editor.js +891 -218
  175. package/dist/editor/EditorAuthGate.d.ts +7 -1
  176. package/dist/editor/EditorAuthGate.js +41 -9
  177. package/dist/editor/EntryNavigator.d.ts +22 -0
  178. package/dist/editor/EntryNavigator.js +353 -105
  179. package/dist/editor/FormHeader.d.ts +25 -0
  180. package/dist/editor/FormHeader.js +82 -0
  181. package/dist/editor/FormRenderer.d.ts +27 -3
  182. package/dist/editor/FormRenderer.js +171 -76
  183. package/dist/editor/PreviewFrame.d.ts +40 -0
  184. package/dist/editor/PreviewFrame.js +215 -0
  185. package/dist/editor/PreviewPane.d.ts +47 -0
  186. package/dist/editor/PreviewPane.js +147 -0
  187. package/dist/editor/PreviewToolbarTools.d.ts +22 -0
  188. package/dist/editor/PreviewToolbarTools.js +73 -0
  189. package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
  190. package/dist/editor/admin/SystemHealthPanel.js +163 -33
  191. package/dist/editor/admin/useSystemHealth.d.ts +18 -0
  192. package/dist/editor/admin/useSystemHealth.js +70 -1
  193. package/dist/editor/branch-status.d.ts +17 -0
  194. package/dist/editor/branch-status.js +29 -0
  195. package/dist/editor/canopy-path.d.ts +9 -6
  196. package/dist/editor/canopy-path.js +8 -11
  197. package/dist/editor/client-reference-resolver.d.ts +43 -16
  198. package/dist/editor/client-reference-resolver.js +155 -64
  199. package/dist/editor/comments/BranchComments.d.ts +1 -1
  200. package/dist/editor/comments/BranchComments.js +2 -2
  201. package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
  202. package/dist/editor/comments/CloseRefusedNotice.js +7 -0
  203. package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
  204. package/dist/editor/comments/CommentThreadsPopover.js +274 -0
  205. package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
  206. package/dist/editor/comments/CommentWriteAlert.js +13 -0
  207. package/dist/editor/comments/EntryComments.d.ts +10 -4
  208. package/dist/editor/comments/EntryComments.js +14 -17
  209. package/dist/editor/comments/FieldWrapper.d.ts +18 -4
  210. package/dist/editor/comments/FieldWrapper.js +62 -28
  211. package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
  212. package/dist/editor/comments/InlineCommentThread.js +11 -47
  213. package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
  214. package/dist/editor/comments/ThreadCarousel.js +18 -21
  215. package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
  216. package/dist/editor/comments/ThreadReplyControls.js +92 -0
  217. package/dist/editor/comments/field-comment-context.d.ts +14 -0
  218. package/dist/editor/comments/field-comment-context.js +14 -0
  219. package/dist/editor/comments/form-comments.d.ts +48 -0
  220. package/dist/editor/comments/form-comments.js +178 -0
  221. package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
  222. package/dist/editor/comments/item-anchor-copy.js +6 -0
  223. package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
  224. package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
  225. package/dist/editor/comments/popover-placement.d.ts +18 -0
  226. package/dist/editor/comments/popover-placement.js +58 -0
  227. package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
  228. package/dist/editor/comments/use-tracked-writes.js +53 -0
  229. package/dist/editor/components/BranchAccessList.d.ts +15 -0
  230. package/dist/editor/components/BranchAccessList.js +52 -0
  231. package/dist/editor/components/BranchLockBanner.d.ts +22 -0
  232. package/dist/editor/components/BranchLockBanner.js +39 -0
  233. package/dist/editor/components/BranchPill.d.ts +32 -0
  234. package/dist/editor/components/BranchPill.js +33 -0
  235. package/dist/editor/components/BranchesDrawer.d.ts +11 -0
  236. package/dist/editor/components/BranchesDrawer.js +5 -0
  237. package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
  238. package/dist/editor/components/ConfirmDeleteModal.js +3 -2
  239. package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
  240. package/dist/editor/components/DestructiveMenuItem.js +8 -0
  241. package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
  242. package/dist/editor/components/EditorCrashScreen.js +22 -0
  243. package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
  244. package/dist/editor/components/EditorErrorBoundary.js +40 -0
  245. package/dist/editor/components/EditorHeader.d.ts +56 -106
  246. package/dist/editor/components/EditorHeader.js +130 -131
  247. package/dist/editor/components/EditorRail.d.ts +49 -0
  248. package/dist/editor/components/EditorRail.js +65 -0
  249. package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
  250. package/dist/editor/components/EntryBreadcrumb.js +56 -0
  251. package/dist/editor/components/EntryCreateModal.d.ts +12 -7
  252. package/dist/editor/components/EntryCreateModal.js +51 -57
  253. package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
  254. package/dist/editor/components/NoEditPermissionNotice.js +5 -4
  255. package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
  256. package/dist/editor/components/QuickOpenPalette.js +66 -0
  257. package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
  258. package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
  259. package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
  260. package/dist/editor/components/ReasonedMenuItem.js +15 -0
  261. package/dist/editor/components/ReferencedByList.d.ts +11 -0
  262. package/dist/editor/components/ReferencedByList.js +28 -0
  263. package/dist/editor/components/RelativeTime.d.ts +10 -0
  264. package/dist/editor/components/RelativeTime.js +10 -0
  265. package/dist/editor/components/RenameEntryModal.d.ts +9 -1
  266. package/dist/editor/components/RenameEntryModal.js +19 -31
  267. package/dist/editor/components/RetryToastMessage.d.ts +9 -0
  268. package/dist/editor/components/RetryToastMessage.js +6 -0
  269. package/dist/editor/components/SaveAllResult.d.ts +25 -0
  270. package/dist/editor/components/SaveAllResult.js +86 -0
  271. package/dist/editor/components/SaveSplitButton.d.ts +30 -0
  272. package/dist/editor/components/SaveSplitButton.js +108 -0
  273. package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
  274. package/dist/editor/components/StagedChangesDrawer.js +92 -0
  275. package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
  276. package/dist/editor/components/UnavailableEntryNotice.js +9 -0
  277. package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
  278. package/dist/editor/components/UnavailableTypeMessage.js +9 -0
  279. package/dist/editor/components/UndoToastMessage.d.ts +18 -0
  280. package/dist/editor/components/UndoToastMessage.js +10 -0
  281. package/dist/editor/components/UserBadge.d.ts +2 -5
  282. package/dist/editor/components/UserBadge.js +62 -33
  283. package/dist/editor/components/ValidationSummary.d.ts +14 -0
  284. package/dist/editor/components/ValidationSummary.js +24 -0
  285. package/dist/editor/components/index.d.ts +2 -2
  286. package/dist/editor/components/index.js +2 -2
  287. package/dist/editor/context/ApiClientContext.d.ts +8 -2
  288. package/dist/editor/context/ApiClientContext.js +19 -8
  289. package/dist/editor/context/AssetContext.d.ts +13 -35
  290. package/dist/editor/context/AssetContext.js +12 -31
  291. package/dist/editor/context/EditorStateContext.d.ts +4 -4
  292. package/dist/editor/context/EditorStateContext.js +4 -4
  293. package/dist/editor/context/SWRProvider.d.ts +3 -3
  294. package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
  295. package/dist/editor/context/SiteMdxAllowContext.js +7 -0
  296. package/dist/editor/context/index.d.ts +2 -1
  297. package/dist/editor/context/index.js +2 -1
  298. package/dist/editor/contrast.d.ts +19 -0
  299. package/dist/editor/contrast.js +41 -0
  300. package/dist/editor/copy.d.ts +18 -0
  301. package/dist/editor/copy.js +18 -0
  302. package/dist/editor/editor-config.js +16 -0
  303. package/dist/editor/editor-utils.d.ts +34 -8
  304. package/dist/editor/editor-utils.js +42 -20
  305. package/dist/editor/entry-search.d.ts +20 -0
  306. package/dist/editor/entry-search.js +34 -0
  307. package/dist/editor/field-breadcrumb.d.ts +12 -0
  308. package/dist/editor/field-breadcrumb.js +85 -0
  309. package/dist/editor/field-props.d.ts +86 -0
  310. package/dist/editor/field-props.js +27 -0
  311. package/dist/editor/field-target.d.ts +30 -0
  312. package/dist/editor/field-target.js +77 -0
  313. package/dist/editor/fields/BlockField.d.ts +12 -0
  314. package/dist/editor/fields/BlockField.js +89 -73
  315. package/dist/editor/fields/CodeField.d.ts +2 -0
  316. package/dist/editor/fields/CodeField.js +6 -2
  317. package/dist/editor/fields/DateTimeField.d.ts +4 -29
  318. package/dist/editor/fields/DateTimeField.js +79 -41
  319. package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
  320. package/dist/editor/fields/ExpandAllButton.js +4 -0
  321. package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
  322. package/dist/editor/fields/FieldCrashFallback.js +30 -0
  323. package/dist/editor/fields/FieldLabel.d.ts +37 -0
  324. package/dist/editor/fields/FieldLabel.js +19 -0
  325. package/dist/editor/fields/ImageField.d.ts +4 -0
  326. package/dist/editor/fields/ImageField.js +29 -14
  327. package/dist/editor/fields/InlineGroupField.js +4 -3
  328. package/dist/editor/fields/ItemList.d.ts +42 -0
  329. package/dist/editor/fields/ItemList.js +130 -0
  330. package/dist/editor/fields/MarkdownField.d.ts +32 -0
  331. package/dist/editor/fields/MarkdownField.js +223 -46
  332. package/dist/editor/fields/MdxImageDialog.js +1 -1
  333. package/dist/editor/fields/NumberField.d.ts +2 -0
  334. package/dist/editor/fields/NumberField.js +8 -5
  335. package/dist/editor/fields/NumberListField.d.ts +2 -0
  336. package/dist/editor/fields/NumberListField.js +19 -16
  337. package/dist/editor/fields/ObjectField.d.ts +2 -7
  338. package/dist/editor/fields/ObjectField.js +15 -5
  339. package/dist/editor/fields/ObjectListField.d.ts +29 -0
  340. package/dist/editor/fields/ObjectListField.js +57 -0
  341. package/dist/editor/fields/ReferenceField.d.ts +2 -0
  342. package/dist/editor/fields/ReferenceField.js +34 -9
  343. package/dist/editor/fields/SelectField.d.ts +2 -0
  344. package/dist/editor/fields/SelectField.js +11 -2
  345. package/dist/editor/fields/StringListField.d.ts +4 -1
  346. package/dist/editor/fields/StringListField.js +22 -8
  347. package/dist/editor/fields/TextField.d.ts +2 -0
  348. package/dist/editor/fields/TextField.js +6 -2
  349. package/dist/editor/fields/ToggleField.d.ts +2 -0
  350. package/dist/editor/fields/ToggleField.js +8 -3
  351. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
  352. package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
  353. package/dist/editor/fields/form-expansion.d.ts +9 -0
  354. package/dist/editor/fields/form-expansion.js +2 -0
  355. package/dist/editor/fields/item-expansion.d.ts +15 -0
  356. package/dist/editor/fields/item-expansion.js +60 -0
  357. package/dist/editor/fields/list-item-keys.d.ts +8 -0
  358. package/dist/editor/fields/list-item-keys.js +50 -0
  359. package/dist/editor/fields/list-item-title.d.ts +20 -0
  360. package/dist/editor/fields/list-item-title.js +85 -0
  361. package/dist/editor/fields/markdown-export-options.d.ts +2 -0
  362. package/dist/editor/fields/markdown-export-options.js +8 -0
  363. package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
  364. package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
  365. package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
  366. package/dist/editor/fields/mdx-jsx-support.js +157 -69
  367. package/dist/editor/fields/rich-text-failures.d.ts +5 -0
  368. package/dist/editor/fields/rich-text-failures.js +26 -0
  369. package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
  370. package/dist/editor/fields/toolbar-wrap.js +35 -0
  371. package/dist/editor/form-outline.d.ts +13 -0
  372. package/dist/editor/form-outline.js +70 -0
  373. package/dist/editor/group-manager/GroupCard.d.ts +4 -1
  374. package/dist/editor/group-manager/GroupCard.js +12 -3
  375. package/dist/editor/group-manager/GroupForm.js +1 -1
  376. package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
  377. package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
  378. package/dist/editor/group-manager/MemberList.d.ts +2 -1
  379. package/dist/editor/group-manager/MemberList.js +15 -4
  380. package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
  381. package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
  382. package/dist/editor/group-manager/index.js +34 -5
  383. package/dist/editor/group-manager/types.d.ts +5 -2
  384. package/dist/editor/hooks/create-branch-request.d.ts +20 -0
  385. package/dist/editor/hooks/create-branch-request.js +54 -0
  386. package/dist/editor/hooks/save-all.d.ts +68 -0
  387. package/dist/editor/hooks/save-all.js +61 -0
  388. package/dist/editor/hooks/useBranchActions.d.ts +11 -1
  389. package/dist/editor/hooks/useBranchActions.js +42 -19
  390. package/dist/editor/hooks/useBranchManager.d.ts +21 -0
  391. package/dist/editor/hooks/useBranchManager.js +321 -125
  392. package/dist/editor/hooks/useBranchesData.d.ts +8 -4
  393. package/dist/editor/hooks/useBranchesData.js +9 -5
  394. package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
  395. package/dist/editor/hooks/useCommentSystem.js +79 -55
  396. package/dist/editor/hooks/useCommentsData.d.ts +11 -7
  397. package/dist/editor/hooks/useCommentsData.js +20 -19
  398. package/dist/editor/hooks/useDraftManager.d.ts +77 -3
  399. package/dist/editor/hooks/useDraftManager.js +887 -94
  400. package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
  401. package/dist/editor/hooks/useEditorLayout.js +98 -20
  402. package/dist/editor/hooks/useEntriesData.d.ts +2 -1
  403. package/dist/editor/hooks/useEntriesData.js +18 -4
  404. package/dist/editor/hooks/useEntryManager.d.ts +41 -2
  405. package/dist/editor/hooks/useEntryManager.js +227 -41
  406. package/dist/editor/hooks/useGroupManager.js +13 -16
  407. package/dist/editor/hooks/usePermissionManager.js +14 -6
  408. package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
  409. package/dist/editor/hooks/usePreviewMarks.js +33 -0
  410. package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
  411. package/dist/editor/hooks/useReferenceResolution.js +34 -177
  412. package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
  413. package/dist/editor/hooks/useSchemaManager.js +97 -39
  414. package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
  415. package/dist/editor/hooks/useUserMetadata.js +76 -47
  416. package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
  417. package/dist/editor/hooks/user-metadata-batcher.js +33 -0
  418. package/dist/editor/media/AssetCard.d.ts +6 -7
  419. package/dist/editor/media/AssetCard.js +24 -31
  420. package/dist/editor/media/AssetListRow.d.ts +16 -0
  421. package/dist/editor/media/AssetListRow.js +41 -0
  422. package/dist/editor/media/CropStep.js +6 -1
  423. package/dist/editor/media/MediaLibrary.d.ts +4 -3
  424. package/dist/editor/media/MediaLibrary.js +11 -4
  425. package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
  426. package/dist/editor/media/MediaLibraryBody.js +195 -80
  427. package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
  428. package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
  429. package/dist/editor/media/crop-math.d.ts +3 -4
  430. package/dist/editor/media/crop-math.js +11 -22
  431. package/dist/editor/media/editor-image-src.d.ts +8 -0
  432. package/dist/editor/media/editor-image-src.js +10 -0
  433. package/dist/editor/media/format-bytes.d.ts +2 -0
  434. package/dist/editor/media/format-bytes.js +23 -0
  435. package/dist/editor/media/media-library-prefs.d.ts +23 -0
  436. package/dist/editor/media/media-library-prefs.js +49 -0
  437. package/dist/editor/media/media-library-view.d.ts +34 -0
  438. package/dist/editor/media/media-library-view.js +40 -0
  439. package/dist/editor/media/useAssetLibrary.d.ts +30 -0
  440. package/dist/editor/media/useAssetLibrary.js +126 -0
  441. package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
  442. package/dist/editor/media/useStableAssetOrder.js +37 -0
  443. package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
  444. package/dist/editor/media/useThumbnailFailure.js +16 -0
  445. package/dist/editor/permission-manager/GroupSelector.js +2 -2
  446. package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
  447. package/dist/editor/permission-manager/PermissionEditor.js +15 -4
  448. package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
  449. package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
  450. package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
  451. package/dist/editor/permission-manager/UserSelector.js +3 -3
  452. package/dist/editor/permission-manager/index.js +12 -3
  453. package/dist/editor/permission-manager/types.d.ts +5 -2
  454. package/dist/editor/platform.d.ts +3 -0
  455. package/dist/editor/platform.js +9 -0
  456. package/dist/editor/preview-asset-base.d.ts +9 -0
  457. package/dist/editor/preview-asset-base.js +17 -0
  458. package/dist/editor/preview-bridge.d.ts +51 -27
  459. package/dist/editor/preview-bridge.js +103 -144
  460. package/dist/editor/preview-marks.d.ts +15 -0
  461. package/dist/editor/preview-marks.js +74 -0
  462. package/dist/editor/preview-path.d.ts +12 -0
  463. package/dist/editor/preview-path.js +45 -1
  464. package/dist/editor/preview-scale.d.ts +27 -0
  465. package/dist/editor/preview-scale.js +34 -0
  466. package/dist/editor/raw-asset-base.d.ts +5 -0
  467. package/dist/editor/raw-asset-base.js +14 -0
  468. package/dist/editor/relative-time.d.ts +4 -4
  469. package/dist/editor/relative-time.js +16 -8
  470. package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
  471. package/dist/editor/schema-editor/CollectionEditor.js +361 -62
  472. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
  473. package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
  474. package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
  475. package/dist/editor/schema-editor/collection-draft.js +40 -0
  476. package/dist/editor/schema-editor/index.d.ts +1 -1
  477. package/dist/editor/schema-label.d.ts +10 -0
  478. package/dist/editor/schema-label.js +17 -0
  479. package/dist/editor/settings-conflict.d.ts +5 -0
  480. package/dist/editor/settings-conflict.js +8 -0
  481. package/dist/editor/shell/ActivityRail.d.ts +37 -0
  482. package/dist/editor/shell/ActivityRail.js +91 -0
  483. package/dist/editor/shell/EditorShell.d.ts +17 -0
  484. package/dist/editor/shell/EditorShell.js +31 -0
  485. package/dist/editor/shell/PaneLayout.d.ts +28 -0
  486. package/dist/editor/shell/PaneLayout.js +116 -0
  487. package/dist/editor/shell/SidePanelHost.d.ts +35 -0
  488. package/dist/editor/shell/SidePanelHost.js +184 -0
  489. package/dist/editor/shell/TopBar.d.ts +12 -0
  490. package/dist/editor/shell/TopBar.js +14 -0
  491. package/dist/editor/shell/host-chrome.d.ts +16 -0
  492. package/dist/editor/shell/host-chrome.js +69 -0
  493. package/dist/editor/slug.d.ts +16 -0
  494. package/dist/editor/slug.js +43 -0
  495. package/dist/editor/theme.d.ts +2 -1
  496. package/dist/editor/theme.js +314 -13
  497. package/dist/editor/unanswered.d.ts +17 -0
  498. package/dist/editor/unanswered.js +26 -0
  499. package/dist/editor/unavailable-entry-type.d.ts +20 -0
  500. package/dist/editor/unavailable-entry-type.js +28 -0
  501. package/dist/editor/undo-removal.d.ts +57 -0
  502. package/dist/editor/undo-removal.js +163 -0
  503. package/dist/editor/user-display.d.ts +4 -0
  504. package/dist/editor/user-display.js +5 -0
  505. package/dist/editor/utils/confirm-modal.d.ts +8 -0
  506. package/dist/editor/utils/confirm-modal.js +12 -0
  507. package/dist/editor/utils/editor-errors.d.ts +19 -0
  508. package/dist/editor/utils/editor-errors.js +32 -0
  509. package/dist/editor/utils/focus-return.d.ts +56 -0
  510. package/dist/editor/utils/focus-return.js +106 -0
  511. package/dist/entry-link-resolver.d.ts +11 -1
  512. package/dist/entry-link-resolver.js +65 -5
  513. package/dist/entry-schema-registry.d.ts +3 -3
  514. package/dist/entry-schema-registry.js +7 -4
  515. package/dist/entry-schema.d.ts +49 -3
  516. package/dist/entry-schema.js +18 -0
  517. package/dist/git-manager.d.ts +172 -10
  518. package/dist/git-manager.js +449 -107
  519. package/dist/github-service.d.ts +39 -2
  520. package/dist/github-service.js +101 -7
  521. package/dist/http/handler.js +74 -9
  522. package/dist/http/types.d.ts +2 -0
  523. package/dist/http/worker-not-ready.d.ts +9 -4
  524. package/dist/http/worker-not-ready.js +59 -6
  525. package/dist/index.d.ts +2 -0
  526. package/dist/index.js +3 -0
  527. package/dist/item-keys.d.ts +46 -0
  528. package/dist/item-keys.js +235 -0
  529. package/dist/operating-mode/editor-mode-check.d.ts +15 -0
  530. package/dist/operating-mode/editor-mode-check.js +24 -0
  531. package/dist/operating-mode/mode-env.d.ts +13 -14
  532. package/dist/operating-mode/mode-env.js +13 -14
  533. package/dist/operating-mode/types.d.ts +2 -2
  534. package/dist/paths/branch.d.ts +0 -1
  535. package/dist/paths/branch.js +1 -8
  536. package/dist/paths/index.d.ts +1 -1
  537. package/dist/paths/index.js +1 -1
  538. package/dist/paths/validation.js +0 -2
  539. package/dist/preview.d.ts +8 -0
  540. package/dist/preview.js +7 -0
  541. package/dist/reference-resolver.js +1 -0
  542. package/dist/resolve-canopy-user.d.ts +1 -1
  543. package/dist/resolve-canopy-user.js +1 -1
  544. package/dist/schema/meta-loader.d.ts +18 -8
  545. package/dist/schema/meta-loader.js +42 -9
  546. package/dist/schema/registry-fingerprint.d.ts +14 -0
  547. package/dist/schema/registry-fingerprint.js +63 -0
  548. package/dist/schema/resolver.d.ts +7 -4
  549. package/dist/schema/resolver.js +7 -6
  550. package/dist/schema/schema-store.d.ts +7 -10
  551. package/dist/schema/schema-store.js +13 -11
  552. package/dist/schema/schema-unavailable-error.d.ts +11 -0
  553. package/dist/schema/schema-unavailable-error.js +15 -0
  554. package/dist/schema/types.d.ts +22 -0
  555. package/dist/schema-registry-record.d.ts +35 -0
  556. package/dist/schema-registry-record.js +134 -0
  557. package/dist/server.d.ts +79 -9
  558. package/dist/server.js +62 -8
  559. package/dist/services.d.ts +33 -5
  560. package/dist/services.js +155 -37
  561. package/dist/settings-workspace.d.ts +23 -3
  562. package/dist/settings-workspace.js +159 -45
  563. package/dist/stamp-on-publish.d.ts +36 -0
  564. package/dist/stamp-on-publish.js +71 -0
  565. package/dist/static/index.d.ts +58 -5
  566. package/dist/static/index.js +133 -3
  567. package/dist/static/seo.d.ts +5 -5
  568. package/dist/static/seo.js +5 -5
  569. package/dist/submission-attribution.d.ts +8 -0
  570. package/dist/submission-attribution.js +22 -0
  571. package/dist/system-users.d.ts +12 -0
  572. package/dist/system-users.js +12 -0
  573. package/dist/task-queue/cms-task-queue.d.ts +1 -1
  574. package/dist/task-queue/cms-task-queue.js +1 -1
  575. package/dist/task-queue/index.d.ts +1 -1
  576. package/dist/task-queue/index.js +1 -1
  577. package/dist/task-queue/task-queue.d.ts +6 -0
  578. package/dist/task-queue/task-queue.js +29 -0
  579. package/dist/task-queue/worker-status.d.ts +35 -9
  580. package/dist/task-queue/worker-status.js +84 -17
  581. package/dist/types.d.ts +90 -9
  582. package/dist/url-collision.js +3 -3
  583. package/dist/url-exclusivity-fixtures.d.ts +8 -1
  584. package/dist/url-exclusivity-fixtures.js +11 -1
  585. package/dist/user.js +2 -1
  586. package/dist/utils/atomic-write.js +2 -1
  587. package/dist/utils/base-branch.d.ts +13 -0
  588. package/dist/utils/base-branch.js +23 -0
  589. package/dist/utils/content-serialize.d.ts +15 -7
  590. package/dist/utils/content-serialize.js +353 -51
  591. package/dist/utils/content-write-lock.d.ts +6 -1
  592. package/dist/utils/content-write-lock.js +21 -6
  593. package/dist/utils/debug.d.ts +1 -1
  594. package/dist/utils/debug.js +5 -3
  595. package/dist/utils/error.js +13 -2
  596. package/dist/utils/escape-text.d.ts +7 -0
  597. package/dist/utils/escape-text.js +27 -0
  598. package/dist/utils/fs.d.ts +12 -4
  599. package/dist/utils/fs.js +18 -5
  600. package/dist/utils/git.d.ts +21 -1
  601. package/dist/utils/git.js +63 -8
  602. package/dist/utils/json-source-splice.d.ts +14 -0
  603. package/dist/utils/json-source-splice.js +120 -0
  604. package/dist/utils/markdown-body-splice.d.ts +39 -0
  605. package/dist/utils/markdown-body-splice.js +421 -0
  606. package/dist/utils/occ-json-write.js +18 -12
  607. package/dist/utils/provision-log.d.ts +25 -0
  608. package/dist/utils/provision-log.js +49 -0
  609. package/dist/utils/provisioning-lock.d.ts +32 -1
  610. package/dist/utils/provisioning-lock.js +78 -32
  611. package/dist/utils/sanitize-href.d.ts +9 -23
  612. package/dist/utils/sanitize-href.js +14 -28
  613. package/dist/utils/title-field.d.ts +10 -0
  614. package/dist/utils/title-field.js +47 -0
  615. package/dist/utils/yaml-source-splice.d.ts +58 -0
  616. package/dist/utils/yaml-source-splice.js +515 -0
  617. package/dist/validation/block-structural-keys.d.ts +1 -1
  618. package/dist/validation/block-structural-keys.js +1 -1
  619. package/dist/validation/deletion-checker.d.ts +21 -29
  620. package/dist/validation/deletion-checker.js +41 -117
  621. package/dist/validation/entry-validator.d.ts +6 -10
  622. package/dist/validation/entry-validator.js +19 -26
  623. package/dist/validation/field-traversal.d.ts +22 -0
  624. package/dist/validation/field-traversal.js +39 -8
  625. package/dist/validation/markdown-safety.d.ts +68 -0
  626. package/dist/validation/markdown-safety.js +596 -0
  627. package/dist/validation/mdx-allowlist.d.ts +55 -0
  628. package/dist/validation/mdx-allowlist.js +183 -0
  629. package/dist/validation/reference-validator.d.ts +2 -0
  630. package/dist/validation/reference-validator.js +3 -0
  631. package/dist/version.d.ts +1 -1
  632. package/dist/version.js +1 -1
  633. package/dist/worker/branch-policy.d.ts +124 -0
  634. package/dist/worker/branch-policy.js +243 -0
  635. package/dist/worker/bundle-header.d.ts +117 -0
  636. package/dist/worker/bundle-header.js +253 -0
  637. package/dist/worker/cms-worker.d.ts +236 -142
  638. package/dist/worker/cms-worker.js +772 -285
  639. package/dist/worker/gateway-egress.d.ts +43 -0
  640. package/dist/worker/gateway-egress.js +209 -0
  641. package/dist/worker/gateway-instance.d.ts +42 -0
  642. package/dist/worker/gateway-instance.js +129 -0
  643. package/dist/worker/git-process.d.ts +81 -0
  644. package/dist/worker/git-process.js +234 -0
  645. package/dist/worker/git-sync.d.ts +34 -17
  646. package/dist/worker/git-sync.js +394 -131
  647. package/dist/worker/github-auth.d.ts +9 -9
  648. package/dist/worker/github-auth.js +13 -15
  649. package/dist/worker/github-gateway-http.d.ts +62 -0
  650. package/dist/worker/github-gateway-http.js +977 -0
  651. package/dist/worker/github-gateway-wire.d.ts +590 -0
  652. package/dist/worker/github-gateway-wire.js +488 -0
  653. package/dist/worker/github-gateway.d.ts +238 -0
  654. package/dist/worker/github-gateway.js +726 -0
  655. package/dist/worker/github-mirror-upkeep.d.ts +75 -0
  656. package/dist/worker/github-mirror-upkeep.js +266 -0
  657. package/dist/worker/github-mirror.d.ts +364 -0
  658. package/dist/worker/github-mirror.js +1030 -0
  659. package/dist/worker/github-transfer.d.ts +56 -0
  660. package/dist/worker/github-transfer.js +444 -0
  661. package/dist/worker/history-rewrite.d.ts +4 -5
  662. package/dist/worker/history-rewrite.js +12 -17
  663. package/dist/worker/provisioned-workspace.d.ts +5 -5
  664. package/dist/worker/provisioned-workspace.js +5 -5
  665. package/dist/worker/rebase.d.ts +1 -1
  666. package/dist/worker/rebase.js +58 -54
  667. package/dist/worker/remote-git-maintenance.d.ts +3 -0
  668. package/dist/worker/remote-git-maintenance.js +12 -0
  669. package/dist/worker/schema-gate.d.ts +49 -0
  670. package/dist/worker/schema-gate.js +226 -0
  671. package/dist/worker/self-checks.d.ts +107 -0
  672. package/dist/worker/self-checks.js +358 -0
  673. package/dist/worker/shared-repo-git.d.ts +96 -0
  674. package/dist/worker/shared-repo-git.js +459 -0
  675. package/dist/worker/sparse-cone.d.ts +20 -0
  676. package/dist/worker/sparse-cone.js +136 -0
  677. package/dist/worker/stale-mirror.d.ts +82 -0
  678. package/dist/worker/stale-mirror.js +130 -0
  679. package/dist/worker/task-runner.d.ts +5 -3
  680. package/dist/worker/task-runner.js +287 -186
  681. package/dist/worker/worker-context.d.ts +36 -37
  682. package/package.json +35 -7
  683. package/dist/editor/EditorPanes.d.ts +0 -10
  684. package/dist/editor/EditorPanes.js +0 -98
  685. package/dist/editor/components/EditorFooter.d.ts +0 -11
  686. package/dist/editor/components/EditorFooter.js +0 -9
  687. package/dist/editor/components/EditorSidebar.d.ts +0 -67
  688. package/dist/editor/components/EditorSidebar.js +0 -22
@@ -2,6 +2,8 @@ import { z } from 'zod';
2
2
  import { loadPermissionsFile, mutatePermissionsFile, loadGroupsFile, deriveInternalGroups, SettingsVersionConflictError, SettingsFileConflictError, } from '../authorization/index.js';
3
3
  import { permissionPathSchema } from './validators.js';
4
4
  import { MAX_ENTRIES_PER_PAGE } from './entries-constants.js';
5
+ import { MAX_USER_METADATA_BATCH } from './users-constants.js';
6
+ import { lookupUsersMetadata } from '../auth/user-metadata-lookup.js';
5
7
  import { defineEndpoint } from './route-builder.js';
6
8
  import { getSettingsBranchContext, commitSettings } from './settings-helpers.js';
7
9
  import { getErrorMessage, sanitizeErrorMessage } from '../utils/error.js';
@@ -29,6 +31,10 @@ const searchUsersParamsSchema = z.object({
29
31
  const getUserMetadataParamsSchema = z.object({
30
32
  userId: z.string(),
31
33
  });
34
+ const userIdSchema = z.string().min(1).max(256);
35
+ const batchGetUserMetadataBodySchema = z.object({
36
+ userIds: z.array(userIdSchema).min(1).max(MAX_USER_METADATA_BATCH),
37
+ });
32
38
  const getPermissionsHandler = async (_gc, ctx, _req) => {
33
39
  try {
34
40
  const result = await getSettingsBranchContext(ctx);
@@ -82,6 +88,7 @@ const updatePermissionsHandler = async (_gc, ctx, req, body) => {
82
88
  branchRoot: context.branchRoot,
83
89
  fileName: 'permissions.json',
84
90
  message: 'Update permissions',
91
+ actor: req.user,
85
92
  mode,
86
93
  });
87
94
  if (!commitResult.pushed) {
@@ -95,7 +102,7 @@ const updatePermissionsHandler = async (_gc, ctx, req, body) => {
95
102
  }
96
103
  catch (error) {
97
104
  if (error instanceof SettingsVersionConflictError) {
98
- return { ok: false, status: 409, error: error.message };
105
+ return { ok: false, status: 409, error: error.message, code: 'SETTINGS_CHANGED' };
99
106
  }
100
107
  if (error instanceof SettingsFileConflictError) {
101
108
  return { ok: false, status: 409, error: 'Settings are busy, please try again.' };
@@ -198,8 +205,29 @@ const getUserMetadataHandler = async (_gc, ctx, req, params) => {
198
205
  return { ok: false, status: 501, error: 'Auth plugin not configured' };
199
206
  }
200
207
  try {
201
- const user = await authPlugin.getUserMetadata(params.userId);
202
- return { ok: true, status: 200, data: { user } };
208
+ const users = await lookupUsersMetadata(authPlugin, [params.userId]);
209
+ return { ok: true, status: 200, data: { user: users.get(params.userId) ?? null } };
210
+ }
211
+ catch (error) {
212
+ return {
213
+ ok: false,
214
+ status: 500,
215
+ error: sanitizeErrorMessage(getErrorMessage(error)),
216
+ };
217
+ }
218
+ };
219
+ /**
220
+ * Get metadata for many users at once (for UI display)
221
+ */
222
+ const batchGetUserMetadataHandler = async (_gc, ctx, _req, body) => {
223
+ const authPlugin = ctx.authPlugin;
224
+ if (!authPlugin) {
225
+ return { ok: false, status: 501, error: 'Auth plugin not configured' };
226
+ }
227
+ try {
228
+ const found = await lookupUsersMetadata(authPlugin, body.userIds);
229
+ const users = [...found.values()].filter((user) => user !== null);
230
+ return { ok: true, status: 200, data: { users } };
203
231
  }
204
232
  catch (error) {
205
233
  return {
@@ -288,6 +316,24 @@ const getUserMetadata = defineEndpoint({
288
316
  guards: ['privileged'],
289
317
  handler: getUserMetadataHandler,
290
318
  });
319
+ /**
320
+ * Get metadata for up to MAX_USER_METADATA_BATCH users (admin/reviewer only)
321
+ * POST /users/batch
322
+ */
323
+ const batchGetUserMetadata = defineEndpoint({
324
+ namespace: 'permissions',
325
+ name: 'batchGetUserMetadata',
326
+ method: 'POST',
327
+ readOnly: true,
328
+ path: '/users/batch',
329
+ body: batchGetUserMetadataBodySchema,
330
+ bodyType: 'BatchGetUserMetadataBody',
331
+ responseType: 'BatchGetUserMetadataResponse',
332
+ response: {},
333
+ defaultMockData: { users: [] },
334
+ guards: ['privileged'],
335
+ handler: batchGetUserMetadataHandler,
336
+ });
291
337
  /**
292
338
  * Exported routes for router registration
293
339
  */
@@ -297,4 +343,5 @@ export const PERMISSION_ROUTES = {
297
343
  searchUsers: searchUsers,
298
344
  listGroups: listGroups,
299
345
  getUserMetadata: getUserMetadata,
346
+ batchGetUserMetadata: batchGetUserMetadata,
300
347
  };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Deadlines for the editor's API requests. A request that never answers (network drop, laptop
3
+ * sleep) must not hold a busy state open forever, so every client call runs under a deadline and,
4
+ * past it, rejects with {@link ApiTimeoutError}: a thrown error, as a network failure is, but
5
+ * distinguishable from one. HTTP error statuses stay `ok: false` responses.
6
+ */
7
+ /**
8
+ * @internal Exported for tests.
9
+ *
10
+ * How long each class of request may take. `standard` is past the 60 s an API behind CloudFront
11
+ * gets (canopycms-cdk's `assertOriginReadTimeout`), so a server still working answers, or its
12
+ * proxy's 504 does, before the editor gives up; reads get it too, since any request may first
13
+ * provision the base branch's workspace (`http/handler.ts`). `long` is
14
+ * for the operations that legitimately run longer: branch create, submit, admin scans and
15
+ * repairs, and an upload without progress.
16
+ */
17
+ export declare const REQUEST_TIMEOUT_MS: {
18
+ readonly standard: 75000;
19
+ readonly long: 180000;
20
+ };
21
+ /** An endpoint's timeout class; `none` waits as long as the browser does. */
22
+ export type RequestTimeoutClass = keyof typeof REQUEST_TIMEOUT_MS | 'none';
23
+ /** Per-call options every API client method accepts as its last argument. */
24
+ export interface RequestOptions {
25
+ /** Aborts the request; the call then rejects with the signal's `reason`. */
26
+ signal?: AbortSignal;
27
+ /** Replaces the endpoint's timeout, in ms; `null` waits as long as the browser does. */
28
+ timeoutMs?: number | null;
29
+ }
30
+ /** @internal Exported for tests. A timed-out read's message: retrying it is safe. */
31
+ export declare const REQUEST_TIMED_OUT_MESSAGE = "The server didn't answer in time. Check your connection and try again.";
32
+ /** @internal Exported for tests. A timed-out write's message: the server may have acted on it. */
33
+ export declare const WRITE_TIMED_OUT_MESSAGE = "The server didn't answer, so this may have gone through anyway. Check before trying again.";
34
+ /**
35
+ * A request ran past its deadline and was abandoned; the server may still have acted on it.
36
+ * `readOnly` defaults to GET; a body-taking lookup passes it (`EndpointConfigBase['readOnly']`).
37
+ */
38
+ export declare class ApiTimeoutError extends Error {
39
+ readonly method: string;
40
+ readonly path: string;
41
+ readonly timeoutMs: number;
42
+ readonly name = "ApiTimeoutError";
43
+ constructor(method: string, path: string, timeoutMs: number, readOnly?: boolean);
44
+ }
45
+ export declare function isApiTimeoutError(err: unknown): err is ApiTimeoutError;
46
+ /** The timeout, in ms or `null` for none, that a call with `options` to a `timeout`-class endpoint gets. */
47
+ export declare function resolveTimeoutMs(timeout: RequestTimeoutClass, options: RequestOptions | undefined): number | null;
48
+ /**
49
+ * Run `run` with a signal that aborts at the deadline or when `options.signal` does, and settle
50
+ * then even if `run` ignores its signal (a custom `fetch` may). Past the deadline the call
51
+ * rejects with an {@link ApiTimeoutError}; on the caller's abort, with the caller's reason.
52
+ */
53
+ export declare function runWithDeadline<T>(run: (signal: AbortSignal) => Promise<T>, request: {
54
+ method: string;
55
+ path: string;
56
+ timeoutMs: number | null;
57
+ signal?: AbortSignal;
58
+ readOnly?: boolean;
59
+ }): Promise<T>;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Deadlines for the editor's API requests. A request that never answers (network drop, laptop
3
+ * sleep) must not hold a busy state open forever, so every client call runs under a deadline and,
4
+ * past it, rejects with {@link ApiTimeoutError}: a thrown error, as a network failure is, but
5
+ * distinguishable from one. HTTP error statuses stay `ok: false` responses.
6
+ */
7
+ /**
8
+ * @internal Exported for tests.
9
+ *
10
+ * How long each class of request may take. `standard` is past the 60 s an API behind CloudFront
11
+ * gets (canopycms-cdk's `assertOriginReadTimeout`), so a server still working answers, or its
12
+ * proxy's 504 does, before the editor gives up; reads get it too, since any request may first
13
+ * provision the base branch's workspace (`http/handler.ts`). `long` is
14
+ * for the operations that legitimately run longer: branch create, submit, admin scans and
15
+ * repairs, and an upload without progress.
16
+ */
17
+ export const REQUEST_TIMEOUT_MS = {
18
+ standard: 75_000,
19
+ long: 180_000,
20
+ };
21
+ /** @internal Exported for tests. A timed-out read's message: retrying it is safe. */
22
+ export const REQUEST_TIMED_OUT_MESSAGE = "The server didn't answer in time. Check your connection and try again.";
23
+ /** @internal Exported for tests. A timed-out write's message: the server may have acted on it. */
24
+ export const WRITE_TIMED_OUT_MESSAGE = "The server didn't answer, so this may have gone through anyway. Check before trying again.";
25
+ /**
26
+ * A request ran past its deadline and was abandoned; the server may still have acted on it.
27
+ * `readOnly` defaults to GET; a body-taking lookup passes it (`EndpointConfigBase['readOnly']`).
28
+ */
29
+ export class ApiTimeoutError extends Error {
30
+ constructor(method, path, timeoutMs, readOnly = method === 'GET') {
31
+ super(readOnly ? REQUEST_TIMED_OUT_MESSAGE : WRITE_TIMED_OUT_MESSAGE);
32
+ this.method = method;
33
+ this.path = path;
34
+ this.timeoutMs = timeoutMs;
35
+ this.name = 'ApiTimeoutError';
36
+ }
37
+ }
38
+ export function isApiTimeoutError(err) {
39
+ return err instanceof ApiTimeoutError;
40
+ }
41
+ /** The timeout, in ms or `null` for none, that a call with `options` to a `timeout`-class endpoint gets. */
42
+ export function resolveTimeoutMs(timeout, options) {
43
+ if (options?.timeoutMs !== undefined)
44
+ return options.timeoutMs;
45
+ return timeout === 'none' ? null : REQUEST_TIMEOUT_MS[timeout];
46
+ }
47
+ /**
48
+ * Run `run` with a signal that aborts at the deadline or when `options.signal` does, and settle
49
+ * then even if `run` ignores its signal (a custom `fetch` may). Past the deadline the call
50
+ * rejects with an {@link ApiTimeoutError}; on the caller's abort, with the caller's reason.
51
+ */
52
+ export async function runWithDeadline(run, request) {
53
+ const { signal: callerSignal, timeoutMs } = request;
54
+ callerSignal?.throwIfAborted();
55
+ const controller = new AbortController();
56
+ const onCallerAbort = () => controller.abort(callerSignal?.reason);
57
+ callerSignal?.addEventListener('abort', onCallerAbort, { once: true });
58
+ const timer = timeoutMs === null
59
+ ? undefined
60
+ : setTimeout(() => controller.abort(new ApiTimeoutError(request.method, request.path, timeoutMs, request.readOnly)), timeoutMs);
61
+ const aborted = new Promise((_, reject) => {
62
+ controller.signal.addEventListener('abort', () => reject(controller.signal.reason), {
63
+ once: true,
64
+ });
65
+ });
66
+ try {
67
+ return await Promise.race([run(controller.signal), aborted]);
68
+ }
69
+ finally {
70
+ clearTimeout(timer);
71
+ callerSignal?.removeEventListener('abort', onCallerAbort);
72
+ }
73
+ }
@@ -25,17 +25,16 @@ const resolveReferencesHandler = async (gc, ctx, req, params, body) => {
25
25
  const checkAccess = await ctx.services.createContentAccessChecker(branchContext, branchContext.branchRoot, req.user);
26
26
  const access = (logicalPath) => checkAccess(logicalPath, 'read').allowed;
27
27
  // The resolution `read()` applies to a reference field, so live preview shows this user what
28
- // `read()` would: the target's data, or a `RestrictedReference` for a target they may not
29
- // read. The target's own references stay ids, as in `read()`.
28
+ // `read()` would: the target's data, a `RestrictedReference` for a target they may not read,
29
+ // or a `MissingReference` for an id naming no entry. The target's own references stay ids, as
30
+ // in `read()`.
30
31
  const resolved = {};
31
32
  for (const id of ids) {
32
33
  try {
33
- const value = await store.resolveReferenceTarget(id, access);
34
- if (value)
35
- resolved[id] = value;
34
+ resolved[id] = await store.resolveReferenceTarget(id, access);
36
35
  }
37
36
  catch (error) {
38
- // An id that fails to resolve is omitted rather than failing the whole request.
37
+ // An id whose lookup throws is omitted rather than failing the whole request.
39
38
  console.error(`Failed to resolve reference ID ${id}:`, error);
40
39
  }
41
40
  }
@@ -47,7 +46,8 @@ const resolveReferencesHandler = async (gc, ctx, req, params, body) => {
47
46
  };
48
47
  /**
49
48
  * Resolve reference IDs as a reference field would: full target data, or title + URL tagged
50
- * `unavailable` for a target the user may not read. An id naming no entry is omitted.
49
+ * `unavailable` for a target the user may not read, or `{ id, unavailable: true, reason: 'missing' }`
50
+ * for an id naming no entry.
51
51
  * POST /:branch/resolve-references
52
52
  * Body: { ids: string[] }
53
53
  */
@@ -55,6 +55,7 @@ const resolveReferences = defineEndpoint({
55
55
  namespace: 'content',
56
56
  name: 'resolveReferences',
57
57
  method: 'POST',
58
+ readOnly: true,
58
59
  path: '/:branch/resolve-references',
59
60
  params: resolveReferencesParamsSchema,
60
61
  body: resolveReferencesBodySchema,
@@ -34,6 +34,10 @@ export interface RouteMetadata {
34
34
  defaultMockData?: unknown;
35
35
  /** Casts to apply to mock data fields for branded types */
36
36
  mockDataCasts?: MockDataCasts;
37
+ /** See `EndpointConfigBase['clientTimeout']`. */
38
+ clientTimeout?: 'long' | 'none';
39
+ /** See `EndpointConfigBase['readOnly']`. */
40
+ readOnly?: true;
37
41
  }
38
42
  /**
39
43
  * Route definition created by defineEndpoint.
@@ -100,6 +104,16 @@ interface EndpointConfigBase<TParams extends z.ZodType | undefined, TBody extend
100
104
  mockDataCasts?: MockDataCasts;
101
105
  /** See `RouteDefinition['bodyFormat']` above. */
102
106
  bodyFormat?: 'multipart';
107
+ /**
108
+ * The generated client's timeout for this endpoint, when not `standard`; see
109
+ * `REQUEST_TIMEOUT_MS` in request-deadline.ts.
110
+ */
111
+ clientTimeout?: 'long' | 'none';
112
+ /**
113
+ * A non-GET endpoint that changes nothing, such as a lookup taking its input in a body. Its
114
+ * timeout then says to try again rather than that it may have gone through (`ApiTimeoutError`).
115
+ */
116
+ readOnly?: true;
103
117
  }
104
118
  /** Config for an endpoint without guards */
105
119
  interface UnguardedEndpointConfig<TParams extends z.ZodType | undefined, TBody extends z.ZodType | undefined, TResponse> extends EndpointConfigBase<TParams, TBody> {
@@ -9,6 +9,9 @@
9
9
  * - Self-documents the API surface
10
10
  */
11
11
  import { executeGuards } from './guards.js';
12
+ function isOkResponse(response) {
13
+ return (typeof response === 'object' && response !== null && 'ok' in response && response.ok === true);
14
+ }
12
15
  /**
13
16
  * Global registry - generator reads this
14
17
  */
@@ -28,6 +31,8 @@ export function defineEndpoint(config) {
28
31
  responseTypeName: config.responseType,
29
32
  defaultMockData: config.defaultMockData,
30
33
  mockDataCasts: config.mockDataCasts,
34
+ clientTimeout: config.clientTimeout,
35
+ readOnly: config.readOnly,
31
36
  });
32
37
  // Convert path template to pattern array for router
33
38
  const pattern = config.path.split('/').filter(Boolean);
@@ -71,6 +76,7 @@ export function defineEndpoint(config) {
71
76
  if (config.guards && config.guards.length > 0) {
72
77
  const guards = config.guards;
73
78
  const guardedHandler = config.handler;
79
+ const recordsEditor = guards.includes('writableBranch');
74
80
  handler = async (ctx, req, ...args) => {
75
81
  // Extract params from args (first arg after ctx/req if present)
76
82
  const params = args[0] ?? {};
@@ -79,7 +85,14 @@ export function defineEndpoint(config) {
79
85
  return guardResult.response;
80
86
  }
81
87
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
82
- return guardedHandler(guardResult.guardContext, ctx, req, ...args);
88
+ const response = await guardedHandler(guardResult.guardContext, ctx, req, ...args);
89
+ // Every 'writableBranch' endpoint changes the branch's working tree, so one that succeeds
90
+ // makes its user an editor of the branch.
91
+ if (recordsEditor && isOkResponse(response)) {
92
+ const { branchContext } = guardResult.guardContext;
93
+ await ctx.services.recordBranchEditor(branchContext, req.user);
94
+ }
95
+ return response;
83
96
  };
84
97
  }
85
98
  else {
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { z } from 'zod';
8
8
  import type { ApiResponse } from './types.js';
9
- import type { ContentFormat, EntrySchema } from '../config/index.js';
9
+ import type { EntryTypeUnavailable, ContentFormat, EntrySchema } from '../config/index.js';
10
10
  import { type LogicalPath, type ContentId } from '../paths/index.js';
11
11
  /** Entry type in wire format: schemaRef instead of resolved schema */
12
12
  interface WireEntryType {
@@ -16,6 +16,7 @@ interface WireEntryType {
16
16
  readonly label?: string;
17
17
  readonly default?: boolean;
18
18
  readonly maxItems?: number;
19
+ readonly unavailable?: EntryTypeUnavailable;
19
20
  }
20
21
  /** Collection in wire format (entry types carry schemaRef, not resolved schema) */
21
22
  interface WireCollectionConfig {
@@ -52,6 +53,7 @@ type WireFlatSchemaItem = {
52
53
  schemaRef: string;
53
54
  default?: boolean;
54
55
  maxItems?: number;
56
+ unavailable?: EntryTypeUnavailable;
55
57
  };
56
58
  interface SchemaResponse {
57
59
  flatSchema: WireFlatSchemaItem[];
@@ -339,18 +341,18 @@ export declare const updateEntryType: import("./route-builder.js").RouteDefiniti
339
341
  branch: string & {
340
342
  readonly __brand: "BranchName";
341
343
  };
342
- entryTypeName: string;
343
344
  collectionPath: string & {
344
345
  readonly __brand: "LogicalPath";
345
346
  };
347
+ entryTypeName: string;
346
348
  }, {
347
349
  branch: string & {
348
350
  readonly __brand: "BranchName";
349
351
  };
350
- entryTypeName: string;
351
352
  collectionPath: string & {
352
353
  readonly __brand: "LogicalPath";
353
354
  };
355
+ entryTypeName: string;
354
356
  }>, z.ZodObject<{
355
357
  label: z.ZodOptional<z.ZodString>;
356
358
  format: z.ZodOptional<z.ZodEnum<["md", "mdx", "json", "yaml"]>>;
@@ -383,18 +385,18 @@ export declare const removeEntryType: import("./route-builder.js").RouteDefiniti
383
385
  branch: string & {
384
386
  readonly __brand: "BranchName";
385
387
  };
386
- entryTypeName: string;
387
388
  collectionPath: string & {
388
389
  readonly __brand: "LogicalPath";
389
390
  };
391
+ entryTypeName: string;
390
392
  }, {
391
393
  branch: string & {
392
394
  readonly __brand: "BranchName";
393
395
  };
394
- entryTypeName: string;
395
396
  collectionPath: string & {
396
397
  readonly __brand: "LogicalPath";
397
398
  };
399
+ entryTypeName: string;
398
400
  }>, undefined, RemoveEntryTypeApiResponse>;
399
401
  /**
400
402
  * PATCH /:branch/schema/order/...collectionPath - Update item order
@@ -616,18 +618,18 @@ export declare const SCHEMA_ROUTES: {
616
618
  branch: string & {
617
619
  readonly __brand: "BranchName";
618
620
  };
619
- entryTypeName: string;
620
621
  collectionPath: string & {
621
622
  readonly __brand: "LogicalPath";
622
623
  };
624
+ entryTypeName: string;
623
625
  }, {
624
626
  branch: string & {
625
627
  readonly __brand: "BranchName";
626
628
  };
627
- entryTypeName: string;
628
629
  collectionPath: string & {
629
630
  readonly __brand: "LogicalPath";
630
631
  };
632
+ entryTypeName: string;
631
633
  }>, z.ZodObject<{
632
634
  label: z.ZodOptional<z.ZodString>;
633
635
  format: z.ZodOptional<z.ZodEnum<["md", "mdx", "json", "yaml"]>>;
@@ -655,18 +657,18 @@ export declare const SCHEMA_ROUTES: {
655
657
  branch: string & {
656
658
  readonly __brand: "BranchName";
657
659
  };
658
- entryTypeName: string;
659
660
  collectionPath: string & {
660
661
  readonly __brand: "LogicalPath";
661
662
  };
663
+ entryTypeName: string;
662
664
  }, {
663
665
  branch: string & {
664
666
  readonly __brand: "BranchName";
665
667
  };
666
- entryTypeName: string;
667
668
  collectionPath: string & {
668
669
  readonly __brand: "LogicalPath";
669
670
  };
671
+ entryTypeName: string;
670
672
  }>, undefined, RemoveEntryTypeApiResponse>;
671
673
  readonly updateOrder: import("./route-builder.js").RouteDefinition<z.ZodObject<{
672
674
  branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
@@ -57,6 +57,7 @@ function toWireEntryType(et, registry) {
57
57
  ...(et.label !== undefined && { label: et.label }),
58
58
  ...(et.default !== undefined && { default: et.default }),
59
59
  ...(et.maxItems !== undefined && { maxItems: et.maxItems }),
60
+ ...(et.unavailable && { unavailable: et.unavailable }),
60
61
  };
61
62
  }
62
63
  function toWireCollection(col, registry) {
@@ -99,6 +100,7 @@ function toWireFlatSchema(items, registry) {
99
100
  schemaRef: resolveSchemaRef(item, registry),
100
101
  ...(item.default !== undefined && { default: item.default }),
101
102
  ...(item.maxItems !== undefined && { maxItems: item.maxItems }),
103
+ ...(item.unavailable && { unavailable: item.unavailable }),
102
104
  };
103
105
  });
104
106
  }
@@ -1,5 +1,6 @@
1
1
  import type { ApiContext } from './types.js';
2
2
  import type { OperatingMode } from '../operating-mode/index.js';
3
+ import type { CanopyUser } from '../user.js';
3
4
  /**
4
5
  * Get the appropriate root path for settings (permissions/groups).
5
6
  * Returns the settings root managed by the settings workspace.
@@ -30,7 +31,8 @@ export interface CommitSettingsResult {
30
31
  /**
31
32
  * Commit and push settings changes based on the mode.
32
33
  * Both prod and dev use commitToSettingsBranch.
33
- * Settings changes are never reviewed through a PR (see commitToSettingsBranch).
34
+ * Settings changes are never reviewed through a PR (see commitToSettingsBranch), and the bot
35
+ * authors the commit, so its trailers, not its author line, name who made the change.
34
36
  */
35
37
  export declare function commitSettings(ctx: ApiContext, options: {
36
38
  context: {
@@ -39,5 +41,7 @@ export declare function commitSettings(ctx: ApiContext, options: {
39
41
  branchRoot: string;
40
42
  fileName: string;
41
43
  message: string;
44
+ /** The user making the change, named in the commit's trailers as a submit names its editors. */
45
+ actor: CanopyUser;
42
46
  mode: OperatingMode;
43
47
  }): Promise<CommitSettingsResult>;
@@ -1,5 +1,6 @@
1
1
  import { operatingStrategy } from '../operating-mode/index.js';
2
2
  import { sanitizeErrorMessage } from '../utils/error.js';
3
+ import { appendTrailers, buildEditorTrailers, submissionEditorFromUser, } from '../submission-attribution.js';
3
4
  /**
4
5
  * Get the appropriate root path for settings (permissions/groups).
5
6
  * Returns the settings root managed by the settings workspace.
@@ -23,7 +24,8 @@ export async function getSettingsBranchContext(ctx) {
23
24
  /**
24
25
  * Commit and push settings changes based on the mode.
25
26
  * Both prod and dev use commitToSettingsBranch.
26
- * Settings changes are never reviewed through a PR (see commitToSettingsBranch).
27
+ * Settings changes are never reviewed through a PR (see commitToSettingsBranch), and the bot
28
+ * authors the commit, so its trailers, not its author line, name who made the change.
27
29
  */
28
30
  export async function commitSettings(ctx, options) {
29
31
  const strategy = operatingStrategy(options.mode);
@@ -34,10 +36,16 @@ export async function commitSettings(ctx, options) {
34
36
  }
35
37
  // For modes that use separate settings branch, commit to settings branch
36
38
  if (strategy.usesSeparateSettingsBranch()) {
39
+ const actor = submissionEditorFromUser(options.actor);
40
+ const { config } = ctx.services;
41
+ const trailers = buildEditorTrailers(actor ? [actor] : [], {
42
+ editedBy: config.gitEditedByTrailers ?? true,
43
+ coAuthoredBy: config.gitCoAuthoredByTrailers ?? false,
44
+ });
37
45
  const result = await ctx.services.commitToSettingsBranch({
38
46
  branchRoot: options.branchRoot,
39
47
  files: options.fileName,
40
- message: options.message,
48
+ message: appendTrailers(options.message, trailers),
41
49
  });
42
50
  if (!result.pushed) {
43
51
  console.warn(`${options.message} committed but not pushed:`, result.error);
@@ -48,4 +48,22 @@ export interface ApiResponse<TData = unknown> {
48
48
  fieldPath: string;
49
49
  message: string;
50
50
  }>;
51
+ /** A machine-readable reason for some failures; see {@link ApiErrorCode}. */
52
+ code?: ApiErrorCode;
51
53
  }
54
+ /**
55
+ * `SCHEMA_UNAVAILABLE`: the entry's type names an entry schema the running code lacks (a 503,
56
+ * see `SchemaUnavailableError`). `WORKER_FAILED`: the CMS worker recorded that its latest start
57
+ * failed, so a retry will not help until an admin fixes it (a 503 with no `Retry-After`).
58
+ * `WRITE_OUTCOME_UNKNOWN`: an entry save ran but lost its branch lock mid-write, so it may have
59
+ * landed (a 409); the version the caller holds may be stale, so it must re-read before retrying.
60
+ * `ENTRY_GONE`: an entry update found no file, because the entry was deleted or moved since the
61
+ * caller read it (a 409); it was not saved, and only a create can bring the entry back.
62
+ * `EDITOR_MODE_MISMATCH`: the editor bundle was built for the other operating mode than the
63
+ * server runs (a 412, see operating-mode/editor-mode-check.ts); only a rebuild fixes it.
64
+ * `SETTINGS_CHANGED`: a groups or permissions save named a version the file has moved on from (a
65
+ * 409, see `SettingsVersionConflictError`); nothing was saved, and a reload shows the other edit.
66
+ * The other settings 409, a busy file lock, carries no code. `BRANCH_SYNCING`: an entry save was
67
+ * refused because the branch is mid-rebase (a 409); nothing was saved, and a retry soon can pass.
68
+ */
69
+ export type ApiErrorCode = 'SCHEMA_UNAVAILABLE' | 'WORKER_FAILED' | 'WRITE_OUTCOME_UNKNOWN' | 'ENTRY_GONE' | 'EDITOR_MODE_MISMATCH' | 'SETTINGS_CHANGED' | 'BRANCH_SYNCING';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Constants the user endpoints share with the editor, kept dependency-free so the editor's
3
+ * browser bundle can import them without pulling in `permissions.ts` and its server-only deps.
4
+ */
5
+ /** Most user ids one `POST /users/batch` request may carry; the editor splits larger sets. */
6
+ export declare const MAX_USER_METADATA_BATCH = 100;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Constants the user endpoints share with the editor, kept dependency-free so the editor's
3
+ * browser bundle can import them without pulling in `permissions.ts` and its server-only deps.
4
+ */
5
+ /** Most user ids one `POST /users/batch` request may carry; the editor splits larger sets. */
6
+ export const MAX_USER_METADATA_BATCH = 100;
@@ -1,14 +1,17 @@
1
1
  /**
2
2
  * Build/adjust transform URLs for `<img>`/srcset without pulling in the
3
- * server-only transform engine. Isomorphic - depends only on
4
- * transform-directives.ts, the plain `ASSET_PREFIXES` constant, and
5
- * utils/url-prefix.ts, none of which import node builtins, so this is safe to
6
- * import from client (editor) code as well as during static builds.
3
+ * server-only transform engine. Isomorphic - none of its imports reach a node
4
+ * builtin, so this is safe to import from client (editor) code as well as during
5
+ * static builds.
7
6
  */
8
7
  import { type CropRect, type OutputFormat } from './transform-directives.js';
9
- /** The minimal shape `assetUrl`/`assetSrcSet` need from a stored asset reference. */
8
+ /**
9
+ * The minimal shape `assetUrl`/`assetSrcSet` need from a stored asset reference. An
10
+ * `ImageFieldValue` is one, so passing a field value renders the crop the editor stored.
11
+ */
10
12
  export interface AssetRef {
11
13
  src: string;
14
+ crop?: CropRect;
12
15
  }
13
16
  export interface AssetUrlOptions {
14
17
  width?: number;
@@ -23,16 +26,14 @@ export interface AssetUrlOptions {
23
26
  * option beside it. Two shapes are legitimate, and they are alternatives, never composed:
24
27
  *
25
28
  * - An absolute origin (`https://assets.example.com`) — assets served from another origin.
26
- * `media.publicBaseUrl` is one source of this, and is the source the editor uses; it is
27
- * validated as an absolute URL, so it structurally cannot carry the second shape.
28
29
  * - A same-origin path prefix (`/preview-123`) — the site is deployed under a Next `basePath`
29
30
  * AND its assets are served by Next (`withCanopy`'s `/assets/:path*` rewrite, which Next
30
31
  * auto-prefixes). NOT the right value on a CloudFront/CDK deployment, where the asset
31
32
  * behaviors are anchored at the distribution root and a `basePath` does not move them —
32
33
  * there the correct value is none at all. See the README's asset-mount table.
33
34
  *
34
- * It is a per-render option rather than a config field precisely because the editor and the
35
- * public site can legitimately have different answers.
35
+ * It is a per-render option rather than a config field because different renderers see the
36
+ * `/assets` space at different places.
36
37
  *
37
38
  * **Render-time only — never stored.** A stored `src` is always root-relative (see
38
39
  * `assets/asset-src.ts`), because content moves between branches and environments. Nothing
@@ -41,16 +42,27 @@ export interface AssetUrlOptions {
41
42
  baseUrl?: string;
42
43
  }
43
44
  /**
44
- * Build a transform URL, merging `opts` over the directives already present
45
- * in `ref.src` (opts win). For static srcs (svg/pdf under `/assets/{hash}/...`,
46
- * or any src that isn't one of our own transform URLs) the src is returned
47
- * unchanged and `opts` are ignored - there is nothing to transform.
45
+ * Whether `src` is in canopycms's own `/assets` URL space - a transform or static asset src the
46
+ * asset store serves. Every other src (a site's own static file, an off-site URL, a `data:` URI)
47
+ * is the host's, and the asset store never serves it.
48
+ */
49
+ export declare function isAssetStoreSrc(src: string): boolean;
50
+ /**
51
+ * Build a transform URL, merging `opts` and `ref.crop` over the directives already present
52
+ * in `ref.src` (see `mergeDirectives` for precedence). For static srcs (svg/pdf under
53
+ * `/assets/{hash}/...`, or any src that isn't one of our own transform URLs) the src is
54
+ * returned unchanged and every directive is ignored - there is nothing to transform.
55
+ *
56
+ * In a live preview, a transform URL goes behind the editor's authenticated route
57
+ * (`editor/preview-asset-base.ts`) instead of `opts.baseUrl`: a draft's crop or width may exist
58
+ * nowhere a build put it. Static srcs keep `opts.baseUrl`, since finalize wrote them.
48
59
  */
49
60
  export declare function assetUrl(ref: AssetRef, opts?: AssetUrlOptions): string;
50
61
  /**
51
62
  * Build a comma-joined `url w` srcset descriptor list. `widths` must all be
52
- * on the transform width allowlist (multiples of 160 in [160, 4096]) - this
53
- * is developer-facing (a host app's own responsive-image markup), so an
54
- * invalid width throws rather than silently dropping it.
63
+ * integers in [1, 8192] (the `any` width policy) - this is developer-facing (a
64
+ * host app's own responsive-image markup), so an invalid width throws rather
65
+ * than silently dropping it. A site serving the opt-in lazy public path, which
66
+ * transforms only allowlisted widths, must pick widths from that allowlist.
55
67
  */
56
68
  export declare function assetSrcSet(ref: AssetRef, widths: readonly number[], opts?: Omit<AssetUrlOptions, 'width'>): string;