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
@@ -1,122 +1,46 @@
1
- import { resolveBlockItem } from './field-traversal.js';
2
- /**
3
- * DeletionChecker finds all references to an entry before deletion.
4
- */
5
- export class DeletionChecker {
6
- constructor(store, idIndex, collections) {
7
- this.store = store;
8
- this.idIndex = idIndex;
9
- this.collections = collections;
1
+ import { extractEntryLinkIds } from '../entry-link-resolver.js';
2
+ import { collectReferenceIds } from './field-traversal.js';
3
+ /** Entries but the target whose schema's reference fields or `entry:` links hold `targetId`. */
4
+ export function findReferencingEntries(entries, targetId) {
5
+ const found = [];
6
+ for (const entry of entries) {
7
+ if (entry.entryId === targetId)
8
+ continue;
9
+ const fields = entry.schemaUnavailable
10
+ ? findIdPaths(entry.data, '', targetId)
11
+ : entry.schema
12
+ ? collectReferenceIds(entry.schema, entry.data)
13
+ .filter((occurrence) => occurrence.id === targetId)
14
+ .map((occurrence) => occurrence.path)
15
+ : [];
16
+ const links = findLinkingPaths(entry.data, '', targetId);
17
+ if (fields.length > 0 || links.length > 0)
18
+ found.push({ entry, fields, links });
10
19
  }
11
- async canDelete(id) {
12
- const referencedBy = await this.findReferences(id);
13
- return {
14
- canDelete: referencedBy.length === 0,
15
- referencedBy,
16
- };
17
- }
18
- async findReferences(targetId) {
19
- const references = [];
20
- for (const [collectionPath, collectionDef] of this.collections.entries()) {
21
- const refs = await this.scanCollection(collectionPath, collectionDef.fields, targetId);
22
- references.push(...refs);
23
- }
24
- return references;
25
- }
26
- async scanCollection(collectionPath, fields, targetId) {
27
- const references = [];
28
- const entries = this.listEntriesInCollection(collectionPath);
29
- for (const entry of entries) {
30
- try {
31
- const doc = await this.store.read(entry.collection, entry.slug);
32
- const refs = this.findIdInData(doc.data, targetId, fields);
33
- if (refs.length > 0) {
34
- const id = this.idIndex.findByPath(entry.relativePath);
35
- references.push({
36
- entryPath: id || '',
37
- entryTitle: doc.data.title,
38
- collection: entry.collection,
39
- slug: entry.slug,
40
- fields: refs,
41
- });
42
- }
43
- }
44
- catch {
45
- continue;
46
- }
47
- }
48
- return references;
20
+ return found;
21
+ }
22
+ /** Paths of every string in `value` equal to `targetId`; `seen` stops at a YAML alias cycle. */
23
+ function findIdPaths(value, path, targetId, seen = new WeakSet()) {
24
+ if (typeof value === 'string')
25
+ return value === targetId ? [path] : [];
26
+ if (value === null || typeof value !== 'object' || seen.has(value))
27
+ return [];
28
+ seen.add(value);
29
+ if (Array.isArray(value)) {
30
+ return value.flatMap((item, index) => findIdPaths(item, `${path}[${index}]`, targetId, seen));
49
31
  }
50
- findIdInData(data, targetId, schema, pathPrefix = '') {
51
- const found = [];
52
- for (const field of schema) {
53
- // Inline groups are transparent (walkFields, ./field-traversal) — recurse at the same level.
54
- if (field.type === 'group') {
55
- found.push(...this.findIdInData(data, targetId, field.fields, pathPrefix));
56
- continue;
57
- }
58
- const fieldPath = pathPrefix ? `${pathPrefix}.${field.name}` : field.name;
59
- const value = data[field.name];
60
- if (value === undefined || value === null)
61
- continue;
62
- if (field.type === 'reference') {
63
- if (Array.isArray(value)) {
64
- if (value.includes(targetId)) {
65
- found.push(fieldPath);
66
- }
67
- }
68
- else if (value === targetId) {
69
- found.push(fieldPath);
70
- }
71
- }
72
- else if (field.type === 'object') {
73
- // Recurse into object fields — handles both single objects and list:true (array of objects)
74
- const objectField = field;
75
- if (objectField.fields) {
76
- if (Array.isArray(value)) {
77
- // list: true — value is an array of objects
78
- value.forEach((item, index) => {
79
- if (typeof item === 'object' && item !== null) {
80
- found.push(...this.findIdInData(item, targetId, objectField.fields, `${fieldPath}[${index}]`));
81
- }
82
- });
83
- }
84
- else if (typeof value === 'object' && value !== null) {
85
- found.push(...this.findIdInData(value, targetId, objectField.fields, fieldPath));
86
- }
87
- }
88
- }
89
- else if (field.type === 'block') {
90
- const blockField = field;
91
- if (Array.isArray(value)) {
92
- value.forEach((item, index) => {
93
- if (typeof item === 'object' && item !== null) {
94
- const resolved = resolveBlockItem(blockField, item);
95
- if (resolved) {
96
- found.push(...this.findIdInData(resolved.data, targetId, resolved.fields, `${fieldPath}[${index}]`));
97
- }
98
- }
99
- });
100
- }
101
- }
102
- }
103
- return found;
32
+ return Object.entries(value).flatMap(([key, item]) => findIdPaths(item, path ? `${path}.${key}` : key, targetId, seen));
33
+ }
34
+ /** Mirrors `resolveEntryLinksInData` (any string); `seen` stops at a YAML alias cycle. */
35
+ function findLinkingPaths(value, path, targetId, seen = new WeakSet()) {
36
+ if (typeof value === 'string') {
37
+ return extractEntryLinkIds(value).some((link) => link.id === targetId) ? [path] : [];
104
38
  }
105
- listEntriesInCollection(collectionPath) {
106
- const entries = [];
107
- const allLocations = this.idIndex.getAllLocations();
108
- for (const location of allLocations) {
109
- if (location.type === 'entry') {
110
- if (location.collection === collectionPath ||
111
- location.collection?.startsWith(collectionPath + '/')) {
112
- entries.push({
113
- relativePath: location.relativePath,
114
- collection: location.collection,
115
- slug: location.slug,
116
- });
117
- }
118
- }
119
- }
120
- return entries;
39
+ if (value === null || typeof value !== 'object' || seen.has(value))
40
+ return [];
41
+ seen.add(value);
42
+ if (Array.isArray(value)) {
43
+ return value.flatMap((item, index) => findLinkingPaths(item, `${path}[${index}]`, targetId, seen));
121
44
  }
45
+ return Object.entries(value).flatMap(([key, item]) => findLinkingPaths(item, path ? `${path}.${key}` : key, targetId, seen));
122
46
  }
@@ -21,26 +21,22 @@ export interface EntryFieldError {
21
21
  fieldPath: string;
22
22
  message: string;
23
23
  }
24
- /**
25
- * Extract the id from a reference value. The editor holds references either
26
- * as an id string or as a resolved object `{ id, slug, collection, ... }`
27
- * (content reads resolve references by default). Returns undefined for any
28
- * other shape.
29
- * @internal Exported for tests.
30
- */
31
- export declare function referenceValueId(value: unknown): string | undefined;
32
24
  /**
33
25
  * Merge an md/mdx body string into the data record under the schema's body
34
26
  * field name (`isBody: true`, defaulting to `'body'`), so required/type checks
35
27
  * apply to the body like any other field.
36
28
  */
37
29
  export declare function mergeBodyIntoData(fields: EntrySchema, data: Record<string, unknown>, body: string | undefined): Record<string, unknown>;
30
+ export interface ValidateEntryOptions {
31
+ /** False skips the required-field checks and keeps every type and format check. Default true. */
32
+ required?: boolean;
33
+ }
38
34
  /**
39
35
  * Validate entry data against an entry schema. Pure — safe to run in the
40
36
  * browser. Returns one error per offending field path; an empty array means
41
37
  * the data is structurally valid.
42
38
  */
43
- export declare function validateEntryData(fields: EntrySchema, data: Record<string, unknown>, pathPrefix?: string): EntryFieldError[];
39
+ export declare function validateEntryData(fields: EntrySchema, data: Record<string, unknown>, pathPrefix?: string, options?: ValidateEntryOptions): EntryFieldError[];
44
40
  /**
45
41
  * Validate an editor FormValue (client-side entry point). For md/mdx formats
46
42
  * the editor keeps the body under the literal `body` key; remap it to the
@@ -59,7 +55,7 @@ export declare function validateEntryFormValue(fields: EntrySchema, format: Cont
59
55
  * a save, and the write path now preserves it and its comments), so this feeds the
60
56
  * non-blocking `validationWarnings` channel, not the 422 path.
61
57
  *
62
- * Deliberately not reported: a container with no fields at all (`api/content.ts`
58
+ * Deliberately not reported: a list item's `ITEM_KEY`, a container with no fields at all (`api/content.ts`
63
59
  * falls back to `[]` for a collection with no configured entry type — "no schema"
64
60
  * isn't "every key is unknown"), and anything inside a `reference` value (a resolved
65
61
  * reference's value is `{ ...target data, id, slug, collection, urlPath }`; the
@@ -12,9 +12,10 @@
12
12
  * `ReferenceValidator` at the write boundary.
13
13
  */
14
14
  import { fieldTypes } from '../config/index.js';
15
- import { isValidCropRect } from '../assets/transform-directives.js';
15
+ import { isValidCropRect, roundCropRect } from '../assets/transform-directives.js';
16
16
  import { BLOCK_STRUCTURAL_KEYS } from './block-structural-keys.js';
17
- import { resolveBlockItem, traverseFields } from './field-traversal.js';
17
+ import { ITEM_KEY } from '../item-keys.js';
18
+ import { referenceValueId, resolveBlockItem, traverseFields } from './field-traversal.js';
18
19
  import { findBodyFieldName } from '../utils/body-field.js';
19
20
  import { flattenGroupFields } from '../utils/flatten-group-fields.js';
20
21
  import { isDataOnlyFormat } from '../utils/format.js';
@@ -27,7 +28,10 @@ function isPlainRecord(value) {
27
28
  function isPositiveInt(value) {
28
29
  return typeof value === 'number' && Number.isInteger(value) && value > 0;
29
30
  }
30
- /** True when `value` is a well-formed `{ x, y, w, h }` normalized crop rect. */
31
+ /**
32
+ * True when `value` is a well-formed `{ x, y, w, h }` normalized crop rect that is still valid
33
+ * after `roundCropRect`, the rounding its transform URL applies.
34
+ */
31
35
  function isValidImageCropValue(value) {
32
36
  if (!isPlainRecord(value))
33
37
  return false;
@@ -38,7 +42,10 @@ function isValidImageCropValue(value) {
38
42
  typeof h !== 'number') {
39
43
  return false;
40
44
  }
41
- return isValidCropRect(x, y, w, h);
45
+ if (!isValidCropRect(x, y, w, h))
46
+ return false;
47
+ const rounded = roundCropRect({ x, y, w, h });
48
+ return isValidCropRect(rounded.x, rounded.y, rounded.w, rounded.h);
42
49
  }
43
50
  /**
44
51
  * Validate a structured `image` field value: `{ src, alt, width?, height?, crop? }`
@@ -73,20 +80,6 @@ function validateImageValue(field, value, path) {
73
80
  }
74
81
  return errors;
75
82
  }
76
- /**
77
- * Extract the id from a reference value. The editor holds references either
78
- * as an id string or as a resolved object `{ id, slug, collection, ... }`
79
- * (content reads resolve references by default). Returns undefined for any
80
- * other shape.
81
- * @internal Exported for tests.
82
- */
83
- export function referenceValueId(value) {
84
- if (typeof value === 'string')
85
- return value;
86
- if (isPlainRecord(value) && typeof value.id === 'string')
87
- return value.id;
88
- return undefined;
89
- }
90
83
  const selectOptionValues = (field) => (field.options ?? []).map((opt) => (typeof opt === 'string' ? opt : opt.value));
91
84
  /**
92
85
  * Merge an md/mdx body string into the data record under the schema's body
@@ -160,17 +153,17 @@ function isEmptyForRequired(field, value) {
160
153
  * browser. Returns one error per offending field path; an empty array means
161
154
  * the data is structurally valid.
162
155
  */
163
- export function validateEntryData(fields, data, pathPrefix = '') {
156
+ export function validateEntryData(fields, data, pathPrefix = '', options = {}) {
164
157
  const errors = [];
165
158
  for (const field of fields) {
166
159
  // Inline groups are transparent (walkFields, ./field-traversal) — children live at this level.
167
160
  if (field.type === 'group') {
168
- errors.push(...validateEntryData(field.fields, data, pathPrefix));
161
+ errors.push(...validateEntryData(field.fields, data, pathPrefix, options));
169
162
  continue;
170
163
  }
171
164
  const path = pathPrefix ? `${pathPrefix}.${field.name}` : field.name;
172
165
  const value = data[field.name];
173
- const isRequired = 'required' in field && field.required === true;
166
+ const isRequired = options.required !== false && 'required' in field && field.required === true;
174
167
  if (isRequired && isEmptyForRequired(field, value)) {
175
168
  const message = Array.isArray(value)
176
169
  ? 'At least one item is required'
@@ -201,7 +194,7 @@ export function validateEntryData(fields, data, pathPrefix = '') {
201
194
  });
202
195
  return;
203
196
  }
204
- errors.push(...validateEntryData(resolved.fields, resolved.data, itemPath));
197
+ errors.push(...validateEntryData(resolved.fields, resolved.data, itemPath, options));
205
198
  });
206
199
  continue;
207
200
  }
@@ -219,7 +212,7 @@ export function validateEntryData(fields, data, pathPrefix = '') {
219
212
  return;
220
213
  }
221
214
  if (objectField.fields) {
222
- errors.push(...validateEntryData(objectField.fields, item, itemPath));
215
+ errors.push(...validateEntryData(objectField.fields, item, itemPath, options));
223
216
  }
224
217
  });
225
218
  }
@@ -227,7 +220,7 @@ export function validateEntryData(fields, data, pathPrefix = '') {
227
220
  errors.push({ fieldPath: path, message: 'Expected an object' });
228
221
  }
229
222
  else if (objectField.fields) {
230
- errors.push(...validateEntryData(objectField.fields, value, path));
223
+ errors.push(...validateEntryData(objectField.fields, value, path, options));
231
224
  }
232
225
  continue;
233
226
  }
@@ -273,7 +266,7 @@ export function validateEntryFormValue(fields, format, value) {
273
266
  * a save, and the write path now preserves it and its comments), so this feeds the
274
267
  * non-blocking `validationWarnings` channel, not the 422 path.
275
268
  *
276
- * Deliberately not reported: a container with no fields at all (`api/content.ts`
269
+ * Deliberately not reported: a list item's `ITEM_KEY`, a container with no fields at all (`api/content.ts`
277
270
  * falls back to `[]` for a collection with no configured entry type — "no schema"
278
271
  * isn't "every key is unknown"), and anything inside a `reference` value (a resolved
279
272
  * reference's value is `{ ...target data, id, slug, collection, urlPath }`; the
@@ -285,7 +278,7 @@ export function findUnknownKeys(fields, data) {
285
278
  return [];
286
279
  const known = new Set(flattenGroupFields(containerFields).map((field) => field.name));
287
280
  return Object.keys(record)
288
- .filter((key) => !known.has(key) && !BLOCK_STRUCTURAL_KEYS.has(key))
281
+ .filter((key) => !known.has(key) && !BLOCK_STRUCTURAL_KEYS.has(key) && key !== ITEM_KEY)
289
282
  .map((key) => (path ? `${path}.${key}` : key));
290
283
  });
291
284
  }
@@ -36,6 +36,12 @@ interface ContainerContext {
36
36
  data: Record<string, unknown>;
37
37
  /** Path to the record itself ('' at the top level, e.g. `blocks[0]` inside a block). */
38
38
  path: string;
39
+ /**
40
+ * The keys that lead from the traversed root to this record (`[]` at the top level). Unlike
41
+ * `path`, it addresses the data rather than the schema: a block item's fields live under its
42
+ * `value`, so the third block's record is `['blocks', 2, 'value']` where `path` reads `blocks[2]`.
43
+ */
44
+ dataPath: readonly (string | number)[];
39
45
  }
40
46
  /**
41
47
  * Visitor called once per container, before its fields are walked.
@@ -52,6 +58,8 @@ export interface ResolvedBlockItem {
52
58
  /** The record containing the block's nested field values */
53
59
  data: Record<string, unknown>;
54
60
  }
61
+ /** A record of named fields: not null, and not an array, which spreading would index-key. */
62
+ export declare function isPlainRecord(value: unknown): value is Record<string, unknown>;
55
63
  /**
56
64
  * Resolve a block item to its template fields and nested data record.
57
65
  *
@@ -78,4 +86,18 @@ export declare function resolveBlockItem(blockField: BlockFieldConfig, item: Rec
78
86
  */
79
87
  export declare function traverseFields<T>(fields: readonly FieldConfig[], data: Record<string, unknown>, visitor: FieldVisitor<T>, pathPrefix?: string, onContainer?: ContainerVisitor<T>): T[];
80
88
  export declare function findFieldsByType(fields: readonly FieldConfig[], data: Record<string, unknown>, fieldType: string): TraversalContext[];
89
+ /** The id of a reference value held as an id string or a resolved `{ id, ... }` object. */
90
+ export declare function referenceValueId(value: unknown): string | undefined;
91
+ export interface ReferenceIdOccurrence {
92
+ id: string;
93
+ path: string;
94
+ }
95
+ /**
96
+ * Every id held by the schema's `reference` fields, in traversal order, one per stored value
97
+ * (duplicates kept). `path` is traverseFields' (`a.b`, `items[0].x`, `blocks[2].author`), plus
98
+ * `[i]` per element of a `list: true` reference (`reviewers[1]`). Raw ids and resolved or
99
+ * `unavailable` objects both yield their id (`referenceValueId`); `''`, null, and values with
100
+ * no id are skipped.
101
+ */
102
+ export declare function collectReferenceIds(fields: readonly FieldConfig[], data: Record<string, unknown>): ReferenceIdOccurrence[];
81
103
  export {};
@@ -5,7 +5,8 @@
5
5
  * according to a schema, handling objects, blocks, and arrays with their
6
6
  * own schemas.
7
7
  */
8
- function isPlainRecord(value) {
8
+ /** A record of named fields: not null, and not an array, which spreading would index-key. */
9
+ export function isPlainRecord(value) {
9
10
  return typeof value === 'object' && value !== null && !Array.isArray(value);
10
11
  }
11
12
  /**
@@ -49,7 +50,7 @@ export function resolveBlockItem(blockField, item) {
49
50
  * @returns Array of all items returned by the visitors
50
51
  */
51
52
  export function traverseFields(fields, data, visitor, pathPrefix = '', onContainer) {
52
- return walkFields(fields, data, visitor, pathPrefix, onContainer, true);
53
+ return walkFields(fields, data, visitor, pathPrefix, [], onContainer, true);
53
54
  }
54
55
  /**
55
56
  * The traversal itself. `fireContainer` is what keeps an inline group from being mistaken for a
@@ -58,10 +59,10 @@ export function traverseFields(fields, data, visitor, pathPrefix = '', onContain
58
59
  * every sibling of the group reads as an unknown key. The hook still propagates INTO the group,
59
60
  * so a nested object or block below it is reported normally.
60
61
  */
61
- function walkFields(fields, data, visitor, pathPrefix, onContainer, fireContainer) {
62
+ function walkFields(fields, data, visitor, pathPrefix, dataPath, onContainer, fireContainer) {
62
63
  const results = [];
63
64
  if (onContainer && fireContainer) {
64
- results.push(...onContainer({ fields, data, path: pathPrefix }));
65
+ results.push(...onContainer({ fields, data, path: pathPrefix, dataPath }));
65
66
  }
66
67
  for (const field of fields) {
67
68
  const fieldPath = pathPrefix ? `${pathPrefix}.${field.name}` : field.name;
@@ -69,7 +70,7 @@ function walkFields(fields, data, visitor, pathPrefix, onContainer, fireContaine
69
70
  // Inline groups are transparent to the data — their children live at the parent
70
71
  // data level, not under field.name, so skip the null/undefined guard for them.
71
72
  if (field.type === 'group') {
72
- results.push(...walkFields(field.fields, data, visitor, pathPrefix, onContainer, false));
73
+ results.push(...walkFields(field.fields, data, visitor, pathPrefix, dataPath, onContainer, false));
73
74
  continue;
74
75
  }
75
76
  if (value === undefined || value === null)
@@ -82,12 +83,12 @@ function walkFields(fields, data, visitor, pathPrefix, onContainer, fireContaine
82
83
  // list: true — value is an array of objects
83
84
  value.forEach((item, index) => {
84
85
  if (typeof item === 'object' && item !== null) {
85
- results.push(...walkFields(objectField.fields, item, visitor, `${fieldPath}[${index}]`, onContainer, true));
86
+ results.push(...walkFields(objectField.fields, item, visitor, `${fieldPath}[${index}]`, [...dataPath, field.name, index], onContainer, true));
86
87
  }
87
88
  });
88
89
  }
89
90
  else if (typeof value === 'object' && value !== null) {
90
- results.push(...walkFields(objectField.fields, value, visitor, fieldPath, onContainer, true));
91
+ results.push(...walkFields(objectField.fields, value, visitor, fieldPath, [...dataPath, field.name], onContainer, true));
91
92
  }
92
93
  }
93
94
  }
@@ -98,7 +99,9 @@ function walkFields(fields, data, visitor, pathPrefix, onContainer, fireContaine
98
99
  if (typeof item === 'object' && item !== null) {
99
100
  const resolved = resolveBlockItem(blockField, item);
100
101
  if (resolved) {
101
- results.push(...walkFields(resolved.fields, resolved.data, visitor, `${fieldPath}[${index}]`, onContainer, true));
102
+ results.push(...walkFields(resolved.fields, resolved.data, visitor, `${fieldPath}[${index}]`, resolved.data === item
103
+ ? [...dataPath, field.name, index]
104
+ : [...dataPath, field.name, index, 'value'], onContainer, true));
102
105
  }
103
106
  }
104
107
  });
@@ -115,3 +118,31 @@ export function findFieldsByType(fields, data, fieldType) {
115
118
  return [];
116
119
  });
117
120
  }
121
+ /** The id of a reference value held as an id string or a resolved `{ id, ... }` object. */
122
+ export function referenceValueId(value) {
123
+ if (typeof value === 'string')
124
+ return value;
125
+ if (isPlainRecord(value) && typeof value.id === 'string')
126
+ return value.id;
127
+ return undefined;
128
+ }
129
+ /**
130
+ * Every id held by the schema's `reference` fields, in traversal order, one per stored value
131
+ * (duplicates kept). `path` is traverseFields' (`a.b`, `items[0].x`, `blocks[2].author`), plus
132
+ * `[i]` per element of a `list: true` reference (`reviewers[1]`). Raw ids and resolved or
133
+ * `unavailable` objects both yield their id (`referenceValueId`); `''`, null, and values with
134
+ * no id are skipped.
135
+ */
136
+ export function collectReferenceIds(fields, data) {
137
+ return traverseFields(fields, data, ({ field, value, path }) => {
138
+ if (field.type !== 'reference')
139
+ return [];
140
+ const items = Array.isArray(value)
141
+ ? value.map((item, index) => ({ item, path: `${path}[${index}]` }))
142
+ : [{ item: value, path }];
143
+ return items.flatMap(({ item, path: itemPath }) => {
144
+ const id = referenceValueId(item);
145
+ return id ? [{ id, path: itemPath }] : [];
146
+ });
147
+ });
148
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The save-time policy that keeps code out of `markdown` and `mdx` content.
3
+ *
4
+ * MDX compiles `{expressions}`, `import`/`export` and JSX into JavaScript that runs wherever a
5
+ * body renders: a preview with the viewer's session, a server render, a CI build. A body this
6
+ * policy accepts runs only the site's own components. A field or body `markdownPolicyOf` checks as
7
+ * MDX accepts:
8
+ *
9
+ * - no `import`/`export`, and no `{…}` expression except a comment or a static literal
10
+ * (`{300}`, `{["a", "b"]}`), in text or as an attribute value; no spread attributes;
11
+ * - components by plain name (`<Callout>`, the site's own code) and HTML tags from
12
+ * `SAFE_HTML_TAGS` only, since a tag is a real element whose attributes need no expression to
13
+ * run code (`<script>`, `<iframe srcdoc>`);
14
+ * - on an HTML tag, attributes from `SAFE_HTML_ATTRIBUTES` and `aria-*` only; no event handler
15
+ * (`on…` on a tag, `onX` on a component), `dangerouslySetInnerHTML` or `srcdoc` anywhere;
16
+ * - URLs, in links, images, definitions and URL attributes, that are relative, use a scheme in
17
+ * `SAFE_URL_SCHEMES`, or are raster `data:` images; no `javascript:` or `vbscript:` value in any
18
+ * prop. React 18 renders a `javascript:` href as given.
19
+ *
20
+ * An `mdxAllow` allowlist (`mdx-allowlist.ts`) narrows this further. Other markdown renders braces
21
+ * and imports as text and runs no tag without raw HTML, so only its URLs are checked; a field with
22
+ * `executable: true` is not checked. A body is parsed with and without GFM, so `remark-gfm` cannot
23
+ * hide a construct; an MDX body that does not parse cannot be checked, so is refused.
24
+ *
25
+ * A save keeps code the stored entry already holds (from outside the CMS, or from before this
26
+ * policy) only in a field saved unchanged: code reads what surrounds it (the props beside it, its
27
+ * parent, the markup a script reads), so no smaller unit is safe to keep. Other fields stay
28
+ * editable, and removing the code is always accepted.
29
+ */
30
+ import type { ContentFormat, EntrySchema, MdxAllowlist } from '../config/index.js';
31
+ import type { EntryFieldError } from './entry-validator.js';
32
+ import type { ResolvedMdxAllowlist } from './mdx-allowlist.js';
33
+ type MarkdownDialect = 'md' | 'mdx';
34
+ interface MarkdownSafetyIssue {
35
+ message: string;
36
+ /** 1-based line in the checked source, when known. */
37
+ line?: number;
38
+ /** What a stored issue must match to be kept: its dialect, allowlist and whole field. None: never kept. */
39
+ key?: string;
40
+ }
41
+ /** One field's issues. */
42
+ export interface MarkdownSafetyFinding {
43
+ fieldPath: string;
44
+ issues: MarkdownSafetyIssue[];
45
+ }
46
+ /**
47
+ * Every construct in `source` that runs code, or loads a URL that does, when it renders.
48
+ * @internal Exported for tests.
49
+ */
50
+ export declare function findUnsafeMarkdown(source: string, dialect: MarkdownDialect, allow?: ResolvedMdxAllowlist): MarkdownSafetyIssue[];
51
+ /**
52
+ * The policy's issues in one entry's on-disk-shaped data, the body merged in under the schema's
53
+ * body field name. The body is checked as `markdownPolicyOf` says for its field and the entry's
54
+ * format, even when the schema declares no body field; it is exempt only when its field is
55
+ * `executable`. `siteAllow` is the config's `mdxAllow`, under each field's own.
56
+ */
57
+ export declare function findMarkdownSafetyIssues(fields: EntrySchema, format: ContentFormat | undefined, data: Record<string, unknown>, siteAllow?: MdxAllowlist): MarkdownSafetyFinding[];
58
+ /**
59
+ * Splits a save's findings into those it adds, which refuse it, and those of a field saved exactly
60
+ * as the stored entry held it, which it keeps. Fields are matched by site and key, one stored field
61
+ * for one saved field, so a second copy of a stored field is refused, as is one moved to a field of
62
+ * another name or allowlist. A finding with an unkeyed issue is never kept.
63
+ */
64
+ export declare function splitByStored(found: readonly MarkdownSafetyFinding[], stored: readonly MarkdownSafetyFinding[]): {
65
+ refused: EntryFieldError[];
66
+ kept: EntryFieldError[];
67
+ };
68
+ export {};