canopycms 0.0.67-int.90 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (539) hide show
  1. package/README.md +30 -3
  2. package/dist/ai/generate.js +1 -27
  3. package/dist/ai/handler.d.ts +0 -4
  4. package/dist/ai/handler.js +0 -11
  5. package/dist/ai/index.d.ts +1 -8
  6. package/dist/ai/index.js +1 -8
  7. package/dist/ai/json-to-markdown.js +15 -58
  8. package/dist/ai/resolve-branch.d.ts +2 -7
  9. package/dist/ai/resolve-branch.js +2 -8
  10. package/dist/ai/strip-mdx.d.ts +5 -13
  11. package/dist/ai/strip-mdx.js +5 -17
  12. package/dist/ai/to-plain-text.d.ts +10 -28
  13. package/dist/ai/to-plain-text.js +10 -28
  14. package/dist/ai/transform-components.d.ts +2 -4
  15. package/dist/ai/transform-components.js +8 -19
  16. package/dist/ai/types.d.ts +5 -10
  17. package/dist/api/admin-branch-health.d.ts +4 -12
  18. package/dist/api/admin-branch-health.js +26 -66
  19. package/dist/api/admin.d.ts +4 -12
  20. package/dist/api/admin.js +10 -26
  21. package/dist/api/assets.d.ts +0 -25
  22. package/dist/api/assets.js +50 -91
  23. package/dist/api/branch-merge.d.ts +1 -1
  24. package/dist/api/branch-merge.js +0 -2
  25. package/dist/api/branch-review.d.ts +0 -8
  26. package/dist/api/branch-review.js +0 -13
  27. package/dist/api/branch-status.d.ts +0 -3
  28. package/dist/api/branch-status.js +8 -33
  29. package/dist/api/branch-withdraw.d.ts +0 -1
  30. package/dist/api/branch-withdraw.js +6 -9
  31. package/dist/api/branch.d.ts +7 -12
  32. package/dist/api/branch.js +7 -44
  33. package/dist/api/client.d.ts +71 -224
  34. package/dist/api/client.js +82 -233
  35. package/dist/api/comments.d.ts +2 -4
  36. package/dist/api/comments.js +0 -17
  37. package/dist/api/content.d.ts +0 -6
  38. package/dist/api/content.js +66 -142
  39. package/dist/api/entries-constants.d.ts +5 -9
  40. package/dist/api/entries-constants.js +5 -9
  41. package/dist/api/entries.d.ts +8 -13
  42. package/dist/api/entries.js +20 -51
  43. package/dist/api/github-sync.d.ts +2 -4
  44. package/dist/api/github-sync.js +4 -8
  45. package/dist/api/groups.d.ts +3 -0
  46. package/dist/api/groups.js +8 -21
  47. package/dist/api/guards.d.ts +4 -16
  48. package/dist/api/guards.js +3 -22
  49. package/dist/api/index.d.ts +4 -4
  50. package/dist/api/permissions.d.ts +2 -0
  51. package/dist/api/permissions.js +18 -40
  52. package/dist/api/reference-options.d.ts +0 -1
  53. package/dist/api/reference-options.js +3 -11
  54. package/dist/api/request-body-hash.d.ts +12 -23
  55. package/dist/api/request-body-hash.js +12 -23
  56. package/dist/api/resolve-references.d.ts +0 -1
  57. package/dist/api/resolve-references.js +13 -28
  58. package/dist/api/route-builder.d.ts +3 -7
  59. package/dist/api/route-builder.js +1 -1
  60. package/dist/api/routes.d.ts +12 -0
  61. package/dist/api/routes.js +47 -0
  62. package/dist/api/schema.d.ts +23 -33
  63. package/dist/api/schema.js +20 -74
  64. package/dist/api/settings-helpers.js +4 -5
  65. package/dist/api/types.d.ts +0 -5
  66. package/dist/api/user.js +0 -5
  67. package/dist/api/validators.d.ts +14 -52
  68. package/dist/api/validators.js +14 -52
  69. package/dist/assets/asset-prefixes.d.ts +4 -8
  70. package/dist/assets/asset-prefixes.js +4 -8
  71. package/dist/assets/asset-src.d.ts +5 -22
  72. package/dist/assets/asset-src.js +5 -21
  73. package/dist/assets/factory.d.ts +1 -2
  74. package/dist/assets/factory.js +1 -2
  75. package/dist/assets/finalize.d.ts +3 -1
  76. package/dist/assets/finalize.js +3 -1
  77. package/dist/assets/index.d.ts +3 -3
  78. package/dist/assets/index.js +1 -1
  79. package/dist/assets/keys.d.ts +5 -3
  80. package/dist/assets/keys.js +6 -3
  81. package/dist/assets/pipeline.d.ts +3 -2
  82. package/dist/assets/pipeline.js +22 -56
  83. package/dist/assets/sharp-loader.d.ts +2 -10
  84. package/dist/assets/sharp-loader.js +2 -10
  85. package/dist/assets/store-local.d.ts +1 -2
  86. package/dist/assets/store-local.js +1 -2
  87. package/dist/assets/store-s3.d.ts +3 -4
  88. package/dist/assets/svg-sanitizer.d.ts +6 -14
  89. package/dist/assets/svg-sanitizer.js +6 -14
  90. package/dist/assets/transform-directives.d.ts +3 -4
  91. package/dist/assets/transform-directives.js +1 -1
  92. package/dist/assets/transform.d.ts +19 -30
  93. package/dist/assets/transform.js +18 -31
  94. package/dist/auth/cache.d.ts +2 -3
  95. package/dist/auth/cache.js +2 -3
  96. package/dist/auth/caching-auth-plugin.d.ts +11 -22
  97. package/dist/auth/caching-auth-plugin.js +12 -14
  98. package/dist/auth/context-helpers.d.ts +6 -20
  99. package/dist/auth/context-helpers.js +5 -17
  100. package/dist/auth/file-based-auth-cache.d.ts +10 -21
  101. package/dist/auth/file-based-auth-cache.js +23 -51
  102. package/dist/auth/plugin.d.ts +29 -61
  103. package/dist/auth/plugin.js +9 -13
  104. package/dist/auth/types.d.ts +11 -20
  105. package/dist/authorization/branch.d.ts +30 -49
  106. package/dist/authorization/branch.js +16 -42
  107. package/dist/authorization/content.d.ts +11 -40
  108. package/dist/authorization/content.js +13 -45
  109. package/dist/authorization/groups/index.d.ts +0 -3
  110. package/dist/authorization/groups/index.js +0 -3
  111. package/dist/authorization/groups/loader.d.ts +14 -28
  112. package/dist/authorization/groups/loader.js +14 -38
  113. package/dist/authorization/groups/schema.d.ts +0 -6
  114. package/dist/authorization/groups/schema.js +4 -7
  115. package/dist/authorization/helpers.d.ts +9 -28
  116. package/dist/authorization/helpers.js +9 -28
  117. package/dist/authorization/index.d.ts +3 -25
  118. package/dist/authorization/index.js +3 -35
  119. package/dist/authorization/path.d.ts +6 -13
  120. package/dist/authorization/path.js +8 -25
  121. package/dist/authorization/permissions/index.d.ts +0 -3
  122. package/dist/authorization/permissions/index.js +0 -3
  123. package/dist/authorization/permissions/loader.d.ts +14 -27
  124. package/dist/authorization/permissions/loader.js +14 -32
  125. package/dist/authorization/permissions/schema.d.ts +1 -6
  126. package/dist/authorization/permissions/schema.js +6 -13
  127. package/dist/authorization/protected-branch.d.ts +36 -65
  128. package/dist/authorization/protected-branch.js +29 -41
  129. package/dist/authorization/settings-file-store.d.ts +38 -81
  130. package/dist/authorization/settings-file-store.js +38 -79
  131. package/dist/authorization/types.d.ts +4 -26
  132. package/dist/authorization/types.js +0 -6
  133. package/dist/authorization/validation.d.ts +1 -23
  134. package/dist/authorization/validation.js +1 -24
  135. package/dist/branch-health.d.ts +39 -67
  136. package/dist/branch-health.js +27 -43
  137. package/dist/branch-metadata-file.d.ts +16 -32
  138. package/dist/branch-metadata-file.js +13 -26
  139. package/dist/branch-metadata.d.ts +49 -80
  140. package/dist/branch-metadata.js +57 -87
  141. package/dist/branch-registry.d.ts +26 -64
  142. package/dist/branch-registry.js +44 -93
  143. package/dist/branch-schema-cache.d.ts +34 -124
  144. package/dist/branch-schema-cache.js +49 -155
  145. package/dist/branch-workspace.d.ts +4 -4
  146. package/dist/branch-workspace.js +15 -19
  147. package/dist/build/generate-ai-content.d.ts +1 -0
  148. package/dist/build/generate-ai-content.js +12 -25
  149. package/dist/build-canopy.d.ts +17 -27
  150. package/dist/build-canopy.js +16 -23
  151. package/dist/build-mode.d.ts +25 -27
  152. package/dist/build-mode.js +25 -29
  153. package/dist/cli/cli.d.ts +15 -26
  154. package/dist/cli/cli.js +601 -978
  155. package/dist/cli/generate-ai-content.js +351 -628
  156. package/dist/cli/github-app-manifest.d.ts +84 -0
  157. package/dist/cli/github-app-manifest.js +161 -0
  158. package/dist/cli/init-github-app.d.ts +110 -444
  159. package/dist/cli/init-github-app.js +236 -773
  160. package/dist/cli/init.js +39 -80
  161. package/dist/cli/migrate.d.ts +13 -10
  162. package/dist/cli/migrate.js +22 -30
  163. package/dist/cli/project-detect.d.ts +17 -31
  164. package/dist/cli/project-detect.js +31 -42
  165. package/dist/cli/project-root.d.ts +4 -11
  166. package/dist/cli/project-root.js +4 -11
  167. package/dist/cli/prompt.d.ts +10 -0
  168. package/dist/cli/prompt.js +67 -0
  169. package/dist/cli/sync.d.ts +0 -8
  170. package/dist/cli/sync.js +8 -28
  171. package/dist/cli/template-files/middleware.ts.template +15 -29
  172. package/dist/cli/templates.d.ts +2 -12
  173. package/dist/cli/templates.js +4 -4
  174. package/dist/client.d.ts +1 -1
  175. package/dist/comment-store.d.ts +32 -53
  176. package/dist/comment-store.js +32 -52
  177. package/dist/config/flatten.d.ts +0 -3
  178. package/dist/config/flatten.js +2 -12
  179. package/dist/config/helpers.js +2 -2
  180. package/dist/config/index.d.ts +2 -2
  181. package/dist/config/index.js +1 -4
  182. package/dist/config/schemas/collection.d.ts +0 -8
  183. package/dist/config/schemas/collection.js +0 -10
  184. package/dist/config/schemas/config.d.ts +6 -78
  185. package/dist/config/schemas/config.js +38 -54
  186. package/dist/config/schemas/field.d.ts +2 -242
  187. package/dist/config/schemas/field.js +9 -20
  188. package/dist/config/schemas/media.js +1 -1
  189. package/dist/config/schemas/permissions.js +0 -2
  190. package/dist/config/schemas/url.d.ts +5 -6
  191. package/dist/config/schemas/url.js +5 -6
  192. package/dist/config/types.d.ts +45 -33
  193. package/dist/config/types.js +0 -1
  194. package/dist/config.d.ts +1 -8
  195. package/dist/config.js +1 -9
  196. package/dist/content-id-index.d.ts +76 -188
  197. package/dist/content-id-index.js +79 -230
  198. package/dist/content-index-generation.d.ts +27 -48
  199. package/dist/content-index-generation.js +35 -84
  200. package/dist/content-index-registry.d.ts +15 -24
  201. package/dist/content-index-registry.js +5 -9
  202. package/dist/content-listing.d.ts +64 -107
  203. package/dist/content-listing.js +68 -118
  204. package/dist/content-reader.d.ts +20 -29
  205. package/dist/content-reader.js +10 -18
  206. package/dist/content-store.d.ts +210 -336
  207. package/dist/content-store.js +413 -657
  208. package/dist/content-tree.d.ts +44 -86
  209. package/dist/content-tree.js +26 -54
  210. package/dist/context.d.ts +67 -94
  211. package/dist/context.js +53 -72
  212. package/dist/dev-content-watcher.d.ts +18 -18
  213. package/dist/dev-content-watcher.js +41 -44
  214. package/dist/editor/BranchManager.d.ts +3 -6
  215. package/dist/editor/BranchManager.js +24 -44
  216. package/dist/editor/CanopyEditor.js +5 -2
  217. package/dist/editor/CommentsPanel.js +0 -2
  218. package/dist/editor/Editor.js +19 -76
  219. package/dist/editor/EditorAuthGate.d.ts +27 -0
  220. package/dist/editor/EditorAuthGate.js +140 -0
  221. package/dist/editor/EntryNavigator.js +0 -20
  222. package/dist/editor/FormRenderer.d.ts +1 -2
  223. package/dist/editor/FormRenderer.js +8 -23
  224. package/dist/editor/admin/SystemHealthPanel.js +20 -37
  225. package/dist/editor/admin/useSystemHealth.d.ts +2 -3
  226. package/dist/editor/admin/useSystemHealth.js +10 -12
  227. package/dist/editor/client-reference-resolver.d.ts +2 -5
  228. package/dist/editor/client-reference-resolver.js +2 -19
  229. package/dist/editor/comments/BranchComments.js +0 -4
  230. package/dist/editor/comments/EntryComments.js +0 -4
  231. package/dist/editor/comments/FieldWrapper.js +0 -4
  232. package/dist/editor/comments/InlineCommentThread.js +0 -2
  233. package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
  234. package/dist/editor/comments/ThreadCarousel.js +0 -12
  235. package/dist/editor/components/EditorFooter.d.ts +0 -8
  236. package/dist/editor/components/EditorFooter.js +0 -5
  237. package/dist/editor/components/EditorHeader.d.ts +0 -31
  238. package/dist/editor/components/EditorHeader.js +21 -71
  239. package/dist/editor/components/EditorSidebar.d.ts +0 -19
  240. package/dist/editor/components/EditorSidebar.js +0 -16
  241. package/dist/editor/components/EntryCreateModal.d.ts +4 -4
  242. package/dist/editor/components/EntryCreateModal.js +7 -22
  243. package/dist/editor/components/RenameEntryModal.js +0 -4
  244. package/dist/editor/components/UserBadge.js +0 -10
  245. package/dist/editor/components/index.js +0 -2
  246. package/dist/editor/context/ApiClientContext.d.ts +8 -7
  247. package/dist/editor/context/ApiClientContext.js +39 -11
  248. package/dist/editor/context/AssetContext.d.ts +7 -17
  249. package/dist/editor/context/AssetContext.js +7 -17
  250. package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
  251. package/dist/editor/context/EditorIdentityContext.js +7 -0
  252. package/dist/editor/context/EditorStateContext.d.ts +10 -41
  253. package/dist/editor/context/EditorStateContext.js +7 -23
  254. package/dist/editor/context/SWRProvider.d.ts +3 -6
  255. package/dist/editor/context/index.d.ts +1 -20
  256. package/dist/editor/context/index.js +1 -20
  257. package/dist/editor/editor-utils.d.ts +8 -47
  258. package/dist/editor/editor-utils.js +19 -72
  259. package/dist/editor/fields/BlockField.d.ts +2 -2
  260. package/dist/editor/fields/BlockField.js +1 -2
  261. package/dist/editor/fields/CodeField.d.ts +0 -1
  262. package/dist/editor/fields/CodeField.js +0 -1
  263. package/dist/editor/fields/DateTimeField.d.ts +15 -22
  264. package/dist/editor/fields/DateTimeField.js +17 -26
  265. package/dist/editor/fields/ImageField.d.ts +2 -2
  266. package/dist/editor/fields/ImageField.js +8 -14
  267. package/dist/editor/fields/InlineGroupField.d.ts +0 -1
  268. package/dist/editor/fields/InlineGroupField.js +0 -1
  269. package/dist/editor/fields/MarkdownField.d.ts +0 -1
  270. package/dist/editor/fields/MarkdownField.js +6 -11
  271. package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
  272. package/dist/editor/fields/MdxImageDialog.js +0 -1
  273. package/dist/editor/fields/NumberField.d.ts +9 -19
  274. package/dist/editor/fields/NumberField.js +11 -22
  275. package/dist/editor/fields/NumberListField.d.ts +7 -10
  276. package/dist/editor/fields/NumberListField.js +7 -10
  277. package/dist/editor/fields/ObjectField.d.ts +5 -8
  278. package/dist/editor/fields/ObjectField.js +0 -1
  279. package/dist/editor/fields/ReferenceField.d.ts +1 -1
  280. package/dist/editor/fields/ReferenceField.js +11 -16
  281. package/dist/editor/fields/SelectField.d.ts +2 -2
  282. package/dist/editor/fields/SelectField.js +0 -1
  283. package/dist/editor/fields/StringListField.d.ts +0 -4
  284. package/dist/editor/fields/StringListField.js +4 -9
  285. package/dist/editor/fields/TextField.d.ts +0 -1
  286. package/dist/editor/fields/TextField.js +0 -1
  287. package/dist/editor/fields/ToggleField.d.ts +0 -1
  288. package/dist/editor/fields/ToggleField.js +0 -1
  289. package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
  290. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
  291. package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
  292. package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
  293. package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
  294. package/dist/editor/group-manager/GroupCard.d.ts +0 -3
  295. package/dist/editor/group-manager/GroupForm.d.ts +0 -3
  296. package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
  297. package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
  298. package/dist/editor/group-manager/MemberList.d.ts +0 -3
  299. package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
  300. package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
  301. package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
  302. package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
  303. package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
  304. package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
  305. package/dist/editor/group-manager/index.d.ts +0 -6
  306. package/dist/editor/group-manager/index.js +0 -10
  307. package/dist/editor/group-manager/types.d.ts +2 -5
  308. package/dist/editor/group-manager/types.js +0 -3
  309. package/dist/editor/hooks/index.d.ts +6 -11
  310. package/dist/editor/hooks/index.js +6 -12
  311. package/dist/editor/hooks/useBranchActions.d.ts +0 -14
  312. package/dist/editor/hooks/useBranchActions.js +0 -22
  313. package/dist/editor/hooks/useBranchManager.d.ts +2 -48
  314. package/dist/editor/hooks/useBranchManager.js +4 -64
  315. package/dist/editor/hooks/useBranchesData.d.ts +7 -6
  316. package/dist/editor/hooks/useBranchesData.js +7 -6
  317. package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
  318. package/dist/editor/hooks/useCommentSystem.js +1 -36
  319. package/dist/editor/hooks/useDraftManager.d.ts +2 -35
  320. package/dist/editor/hooks/useDraftManager.js +23 -64
  321. package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
  322. package/dist/editor/hooks/useEditorLayout.js +0 -23
  323. package/dist/editor/hooks/useEntriesData.d.ts +1 -0
  324. package/dist/editor/hooks/useEntriesData.js +2 -3
  325. package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
  326. package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
  327. package/dist/editor/hooks/useEntryManager.d.ts +2 -27
  328. package/dist/editor/hooks/useEntryManager.js +29 -78
  329. package/dist/editor/hooks/useGroupManager.d.ts +0 -21
  330. package/dist/editor/hooks/useGroupManager.js +0 -21
  331. package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
  332. package/dist/editor/hooks/usePermissionManager.js +0 -20
  333. package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
  334. package/dist/editor/hooks/useReferenceResolution.js +1 -48
  335. package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
  336. package/dist/editor/hooks/useSchemaManager.js +0 -19
  337. package/dist/editor/hooks/useUserContext.d.ts +2 -9
  338. package/dist/editor/hooks/useUserContext.js +10 -10
  339. package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
  340. package/dist/editor/hooks/useUserMetadata.js +0 -3
  341. package/dist/editor/media/AssetCard.d.ts +0 -1
  342. package/dist/editor/media/AssetCard.js +1 -2
  343. package/dist/editor/media/CropStep.d.ts +0 -1
  344. package/dist/editor/media/CropStep.js +0 -1
  345. package/dist/editor/media/MediaLibrary.d.ts +1 -2
  346. package/dist/editor/media/MediaLibrary.js +1 -2
  347. package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
  348. package/dist/editor/media/MediaLibraryBody.js +0 -1
  349. package/dist/editor/media/crop-math.d.ts +1 -1
  350. package/dist/editor/media/crop-math.js +1 -1
  351. package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
  352. package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
  353. package/dist/editor/permission-manager/PermissionEditor.js +0 -1
  354. package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
  355. package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
  356. package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
  357. package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
  358. package/dist/editor/permission-manager/constants.d.ts +0 -3
  359. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
  360. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
  361. package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
  362. package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
  363. package/dist/editor/permission-manager/index.d.ts +0 -7
  364. package/dist/editor/permission-manager/index.js +0 -16
  365. package/dist/editor/permission-manager/types.d.ts +2 -12
  366. package/dist/editor/permission-manager/types.js +0 -3
  367. package/dist/editor/permission-manager/utils.d.ts +0 -28
  368. package/dist/editor/permission-manager/utils.js +9 -23
  369. package/dist/editor/preview-bridge.d.ts +5 -1
  370. package/dist/editor/preview-bridge.js +4 -4
  371. package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
  372. package/dist/editor/schema-editor/CollectionEditor.js +9 -31
  373. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
  374. package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
  375. package/dist/editor/schema-editor/index.d.ts +0 -7
  376. package/dist/editor/schema-editor/index.js +0 -7
  377. package/dist/editor/utils/env.d.ts +3 -18
  378. package/dist/editor/utils/env.js +6 -25
  379. package/dist/entry-link-resolver.d.ts +13 -35
  380. package/dist/entry-link-resolver.js +20 -53
  381. package/dist/entry-schema-registry.d.ts +20 -60
  382. package/dist/entry-schema-registry.js +20 -69
  383. package/dist/entry-schema.d.ts +118 -223
  384. package/dist/entry-schema.js +46 -91
  385. package/dist/git-manager.d.ts +101 -200
  386. package/dist/git-manager.js +211 -384
  387. package/dist/github-service.d.ts +34 -75
  388. package/dist/github-service.js +37 -91
  389. package/dist/http/handler.d.ts +6 -37
  390. package/dist/http/handler.js +65 -120
  391. package/dist/http/router.d.ts +15 -32
  392. package/dist/http/router.js +34 -99
  393. package/dist/http/types.d.ts +15 -40
  394. package/dist/http/types.js +3 -7
  395. package/dist/id.d.ts +4 -10
  396. package/dist/id.js +4 -10
  397. package/dist/index.js +6 -9
  398. package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
  399. package/dist/operating-mode/client-safe-strategy.js +8 -28
  400. package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
  401. package/dist/operating-mode/client-unsafe-strategy.js +9 -34
  402. package/dist/operating-mode/client.d.ts +3 -10
  403. package/dist/operating-mode/client.js +3 -8
  404. package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
  405. package/dist/operating-mode/deployment-name-fixtures.js +14 -18
  406. package/dist/operating-mode/deployment-name.d.ts +19 -29
  407. package/dist/operating-mode/deployment-name.js +29 -47
  408. package/dist/operating-mode/index.d.ts +4 -25
  409. package/dist/operating-mode/index.js +9 -31
  410. package/dist/operating-mode/mode-env.d.ts +32 -54
  411. package/dist/operating-mode/mode-env.js +36 -58
  412. package/dist/operating-mode/types.d.ts +24 -72
  413. package/dist/operating-mode/types.js +1 -7
  414. package/dist/paths/branch-name.d.ts +30 -40
  415. package/dist/paths/branch-name.js +30 -40
  416. package/dist/paths/branch.d.ts +4 -18
  417. package/dist/paths/branch.js +6 -22
  418. package/dist/paths/index.d.ts +2 -13
  419. package/dist/paths/index.js +3 -23
  420. package/dist/paths/normalize-server.d.ts +3 -15
  421. package/dist/paths/normalize-server.js +3 -15
  422. package/dist/paths/normalize.d.ts +13 -33
  423. package/dist/paths/normalize.js +13 -33
  424. package/dist/paths/resolve.d.ts +4 -17
  425. package/dist/paths/resolve.js +4 -22
  426. package/dist/paths/types.d.ts +12 -34
  427. package/dist/paths/types.js +5 -7
  428. package/dist/paths/validation.d.ts +22 -119
  429. package/dist/paths/validation.js +30 -148
  430. package/dist/reference-resolver.d.ts +0 -13
  431. package/dist/reference-resolver.js +0 -18
  432. package/dist/resolve-canopy-user.d.ts +16 -18
  433. package/dist/resolve-canopy-user.js +17 -26
  434. package/dist/resource-generation.d.ts +16 -25
  435. package/dist/resource-generation.js +34 -97
  436. package/dist/schema/meta-loader.d.ts +2 -14
  437. package/dist/schema/meta-loader.js +15 -64
  438. package/dist/schema/resolver.d.ts +1 -4
  439. package/dist/schema/resolver.js +1 -6
  440. package/dist/schema/schema-store-types.d.ts +0 -12
  441. package/dist/schema/schema-store.d.ts +61 -138
  442. package/dist/schema/schema-store.js +85 -282
  443. package/dist/schema/types.d.ts +0 -4
  444. package/dist/server.d.ts +62 -93
  445. package/dist/server.js +63 -94
  446. package/dist/services.d.ts +23 -47
  447. package/dist/services.js +55 -98
  448. package/dist/settings-workspace.d.ts +17 -30
  449. package/dist/settings-workspace.js +51 -81
  450. package/dist/static/index.d.ts +26 -52
  451. package/dist/static/index.js +33 -67
  452. package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
  453. package/dist/task-queue/cms-task-queue.js +13 -0
  454. package/dist/task-queue/task-queue-config.d.ts +3 -0
  455. package/dist/{worker → task-queue}/task-queue-config.js +1 -6
  456. package/dist/task-queue/task-queue.d.ts +16 -22
  457. package/dist/task-queue/task-queue.js +20 -44
  458. package/dist/task-queue/types.d.ts +0 -1
  459. package/dist/task-queue/worker-status.d.ts +35 -0
  460. package/dist/task-queue/worker-status.js +40 -0
  461. package/dist/types.d.ts +40 -51
  462. package/dist/url-collision.d.ts +26 -40
  463. package/dist/url-collision.js +47 -63
  464. package/dist/url-exclusivity-fixtures.d.ts +15 -20
  465. package/dist/url-exclusivity-fixtures.js +14 -19
  466. package/dist/url-path-resolver.d.ts +8 -16
  467. package/dist/url-path-resolver.js +19 -29
  468. package/dist/user.d.ts +8 -21
  469. package/dist/user.js +10 -19
  470. package/dist/utils/async-mutex.js +4 -6
  471. package/dist/utils/atomic-write.d.ts +2 -11
  472. package/dist/utils/atomic-write.js +2 -11
  473. package/dist/utils/body-field.d.ts +8 -15
  474. package/dist/utils/body-field.js +8 -15
  475. package/dist/utils/content-serialize.d.ts +18 -24
  476. package/dist/utils/content-serialize.js +109 -160
  477. package/dist/utils/content-write-lock.d.ts +51 -106
  478. package/dist/utils/content-write-lock.js +66 -111
  479. package/dist/utils/debug.d.ts +7 -23
  480. package/dist/utils/debug.js +7 -23
  481. package/dist/utils/entry-url.d.ts +11 -23
  482. package/dist/utils/entry-url.js +11 -26
  483. package/dist/utils/error.d.ts +25 -90
  484. package/dist/utils/error.js +60 -147
  485. package/dist/utils/flatten-group-fields.d.ts +5 -7
  486. package/dist/utils/flatten-group-fields.js +5 -7
  487. package/dist/utils/format.d.ts +1 -5
  488. package/dist/utils/format.js +1 -5
  489. package/dist/utils/fs.d.ts +3 -4
  490. package/dist/utils/fs.js +3 -4
  491. package/dist/utils/git.d.ts +52 -83
  492. package/dist/utils/git.js +79 -125
  493. package/dist/utils/logger.d.ts +35 -50
  494. package/dist/utils/logger.js +35 -52
  495. package/dist/utils/provisioning-lock.d.ts +23 -35
  496. package/dist/utils/provisioning-lock.js +49 -69
  497. package/dist/utils/sanitize-href.d.ts +5 -10
  498. package/dist/utils/sanitize-href.js +8 -18
  499. package/dist/utils/title-field.d.ts +17 -20
  500. package/dist/utils/title-field.js +18 -27
  501. package/dist/utils/typed-filename.d.ts +20 -48
  502. package/dist/utils/typed-filename.js +25 -61
  503. package/dist/utils/url-prefix.d.ts +3 -3
  504. package/dist/utils/url-prefix.js +3 -3
  505. package/dist/validation/block-structural-keys.d.ts +16 -31
  506. package/dist/validation/block-structural-keys.js +19 -29
  507. package/dist/validation/deletion-checker.d.ts +0 -34
  508. package/dist/validation/deletion-checker.js +1 -43
  509. package/dist/validation/entry-link-validator.d.ts +6 -13
  510. package/dist/validation/entry-link-validator.js +4 -13
  511. package/dist/validation/entry-type-reference-validator.d.ts +13 -18
  512. package/dist/validation/entry-type-reference-validator.js +13 -18
  513. package/dist/validation/entry-validator.d.ts +13 -25
  514. package/dist/validation/entry-validator.js +15 -32
  515. package/dist/validation/field-traversal.d.ts +3 -30
  516. package/dist/validation/field-traversal.js +1 -32
  517. package/dist/validation/reference-validator.d.ts +5 -24
  518. package/dist/validation/reference-validator.js +5 -30
  519. package/dist/worker/cms-worker.d.ts +172 -232
  520. package/dist/worker/cms-worker.js +241 -333
  521. package/dist/worker/git-sync.d.ts +32 -133
  522. package/dist/worker/git-sync.js +129 -191
  523. package/dist/worker/github-auth.d.ts +13 -19
  524. package/dist/worker/github-auth.js +13 -19
  525. package/dist/worker/history-rewrite.d.ts +53 -66
  526. package/dist/worker/history-rewrite.js +54 -60
  527. package/dist/worker/log.d.ts +24 -41
  528. package/dist/worker/log.js +25 -42
  529. package/dist/worker/rebase.d.ts +20 -110
  530. package/dist/worker/rebase.js +279 -354
  531. package/dist/worker/task-runner.d.ts +32 -66
  532. package/dist/worker/task-runner.js +126 -162
  533. package/dist/worker/worker-context.d.ts +41 -81
  534. package/package.json +4 -4
  535. package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
  536. package/dist/worker/task-queue-config.d.ts +0 -8
  537. package/dist/worker/task-queue.js +0 -19
  538. package/dist/worker/worker-status.d.ts +0 -47
  539. package/dist/worker/worker-status.js +0 -52
@@ -1,82 +1,46 @@
1
1
  import { isValidId } from '../id.js';
2
- // Lives here rather than in content-listing.ts, where it was born, purely so dependency-light
3
- // modules can use it: content-listing imports ContentStore, so anything content-store itself
4
- // imports (url-collision.ts) cannot reach back into it without a cycle. content-listing
5
- // re-exports this and `canopycms/server` re-exports it from there, so the public surface is
6
- // unchanged.
2
+ // Lives here rather than in content-listing.ts so dependency-light modules can use it:
3
+ // content-listing imports ContentStore, so url-collision.ts (which content-store imports) cannot
4
+ // reach back into it without a cycle. content-listing and `canopycms/server` re-export it.
7
5
  /**
8
6
  * Parse a Canopy content filename into its `{type}.{slug}.{id}.{ext}` parts.
9
7
  *
10
- * ## Filename grammar
8
+ * The slug may itself contain dots (`getting.started.guide`), so type and ID anchor the split:
9
+ * the ID is the second-to-last dot-separated segment, the slug is everything between the type and
10
+ * it (lowercased), and the extension is stripped. The ID is a 12-character Base58 content ID, and
11
+ * a would-be ID segment that fails `isValidId` rejects the whole parse.
11
12
  *
12
- * Every entry file on disk is named `{type}.{slug}.{id}.{ext}`:
13
- * - `type` — the entry type name (a key in the collection's `entries` config).
14
- * - `slug` — the entry's URL slug. May itself contain dots (e.g. a slug of
15
- * `getting.started.guide`), so the type and ID anchor the split: the ID is
16
- * always the second-to-last dot-separated segment, and the slug is
17
- * everything between the type and the ID. The returned `slug` is
18
- * lowercased.
19
- * - `id` — a 12-character Base58 content ID (`generateId()`/`isValidId()`).
20
- * Base58 excludes the ambiguous characters `0`, `O`, `I`, `l` so IDs are
21
- * unambiguous when read aloud or hand-transcribed. A filename whose
22
- * would-be ID segment doesn't pass `isValidId` is rejected — the whole
23
- * parse returns `null`, even if the rest of the shape looks right.
24
- * - `ext` — the format extension (`.md`, `.mdx`, `.json`, `.yaml`), stripped
25
- * before parsing and not part of the returned result.
13
+ * `filename` must be a bare filename, and **that precondition is not enforced**: the parser splits
14
+ * purely on `.`, so a `/` or `\` is neither rejected nor treated as special and becomes part of
15
+ * whichever segment it falls in (`'foo/bar.slug.<validId>.md'` gives `type: 'foo/bar'`). Strip the
16
+ * directory component yourself (`path.basename`) — every internal caller does. A leading-dot
17
+ * filename is always rejected, matching `extractEntryTypeFromFilename` in `content-id-index.ts`.
26
18
  *
27
- * @param filename - The bare filename (no directory component). **This precondition is
28
- * not enforced.** The parser splits purely on `.`, so a `/` or `\` you pass in is not
29
- * rejected and is not treated as special — it becomes part of whichever segment it
30
- * falls in, most often the `type` segment (e.g. `'foo/bar.slug.<validId>.md'` parses
31
- * to `type: 'foo/bar'`). Strip any directory component yourself (e.g.
32
- * `path.basename(filePath)`) before calling this — every internal caller already does.
33
- * @param entryTypes - When provided, the parsed `type` segment must match one
34
- * of these entry types by name, or the parse is rejected (this is how
35
- * `listCollectionEntries` filters out files that don't belong to the
36
- * collection's configured entry types). Omit this argument to parse
37
- * structurally without validating the type against a known list — useful
38
- * for adopter code that needs to recover `{type, slug, id}` from a
39
- * filename without having a schema/entry-types list on hand (e.g. a
40
- * filesystem walk over content for tooling or diagnostics). Even without
41
- * `entryTypes`, a leading-dot filename (dotfile, editor swap/backup file)
42
- * is always rejected — an empty string is never a legal type, matching the
43
- * `filename.startsWith('.')` guard `extractEntryTypeFromFilename` in
44
- * `content-id-index.ts` already applies.
45
- * @returns `{ type, slug, id }`, or `null` if `filename` doesn't match the
46
- * `{type}.{slug}.{id}.{ext}` shape (too few segments, no extension, a
47
- * leading dot, an invalid ID, or — when `entryTypes` is given — an
48
- * unrecognized type). `id` is validated (`isValidId`) and safe to trust. **`slug` is
49
- * not** — it is the raw dot-joined middle segment(s), lowercased, cast to the branded
50
- * `Slug` type without running `parseSlug`'s validation. A filename with an
51
- * unconventional slug segment (e.g. containing a space, or a dot) still parses and still
52
- * receives the `Slug` brand. Callers that need a validated slug must run the result
53
- * through `parseSlug` themselves; this function's contract is "split the filename
54
- * grammar apart," not "validate every part." `listCollectionEntries` (content-listing.ts)
55
- * is exactly such a caller that does NOT re-validate — it lists the file and computes a
56
- * `urlPath` for it regardless — so a dotted slug listed this way builds and gets
57
- * advertised (sitemap, `generateStaticParams`) but can never be read back through
58
- * `readByUrlPath`, which does run every URL-resolution candidate through `parseSlug`.
59
- * `static/index.ts`'s `assertRoutableSlugs` is the build-time guard that catches this.
19
+ * `entryTypes`, when given, restricts the `type` segment to those entry types — how
20
+ * `listCollectionEntries` filters out files that do not belong to the collection. Omit it to
21
+ * parse structurally, for adopter code recovering `{type, slug, id}` with no schema on hand.
22
+ *
23
+ * `id` is validated and safe to trust. **`slug` is not** — it is the raw dot-joined middle,
24
+ * lowercased and cast to the branded `Slug` without `parseSlug`'s validation, so a slug holding a
25
+ * space or a dot still parses and still carries the brand. Callers needing a validated slug run
26
+ * `parseSlug` themselves. `listCollectionEntries` does NOT, so a dotted slug is listed and
27
+ * advertised (sitemap, `generateStaticParams`) yet can never be read back through `readByUrlPath`,
28
+ * which runs every candidate through `parseSlug`; `static/index.ts`'s `assertRoutableSlugs` is the
29
+ * build-time guard for that.
60
30
  */
61
31
  export const parseTypedFilename = (filename, entryTypes) => {
62
- // Reject dotfiles outright (matching extractEntryTypeFromFilename's guard in
63
- // content-id-index.ts): a leading dot can never be a legal entry type, and this
64
- // is exactly the shape of the files a structural (no-entryTypes) parse would
65
- // otherwise misparse -- e.g. '.hidden.file.aB3cD4eF5gH6.md' -> potentialType ''.
32
+ // A leading dot can never be a legal entry type, and a dotfile is exactly what a structural
33
+ // (no-entryTypes) parse would otherwise misparse: '.hidden.file.aB3cD4eF5gH6.md' -> type ''.
66
34
  if (filename.startsWith('.'))
67
35
  return null;
68
- // Remove extension
69
36
  const lastDot = filename.lastIndexOf('.');
70
37
  if (lastDot === -1)
71
38
  return null;
72
39
  const nameWithoutExt = filename.slice(0, lastDot);
73
- // Parse: {type}.{slug}.{id}
74
40
  const parts = nameWithoutExt.split('.');
75
41
  if (parts.length < 3)
76
42
  return null;
77
43
  const potentialType = parts[0];
78
- // When a known-types list is supplied, the first segment must match one of
79
- // them. Without it, any non-empty first segment is accepted as the type.
80
44
  if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
81
45
  return null;
82
46
  }
@@ -21,9 +21,9 @@
21
21
  * Whether `url` is a DECLARED off-site pointer - a scheme-qualified absolute URL
22
22
  * (`https://example.com/x`) or a literal protocol-relative one (`//cdn.example.com/x`).
23
23
  *
24
- * Deliberately narrower than "resolves off-origin": a WHATWG-backslash-equivalent spelling
25
- * (`/\evil.com`, `\\evil.com`, `\/evil.com` — see `utils/sanitize-href.ts`'s
26
- * `isImplicitlyOffOrigin`) also resolves off-origin in a browser, but is NOT recognized here as
24
+ * Deliberately narrower than "resolves off-origin": a backslash-equivalent spelling (see
25
+ * `utils/sanitize-href.ts`'s `declaresScheme` and `isImplicitlyOffOrigin`)
26
+ * also resolves off-origin in a browser, but is NOT recognized here as
27
27
  * an intentional off-site pointer the way a literal `//cdn…` is. Callers handle that case
28
28
  * separately, by neutralizing (`neutralizeImplicitOffOrigin`) rather than passing through: a
29
29
  * `false` result here isn't a guarantee the value is a safe site-relative path on its own, only
@@ -22,9 +22,9 @@ import { declaresScheme, neutralizeImplicitOffOrigin } from './sanitize-href.js'
22
22
  * Whether `url` is a DECLARED off-site pointer - a scheme-qualified absolute URL
23
23
  * (`https://example.com/x`) or a literal protocol-relative one (`//cdn.example.com/x`).
24
24
  *
25
- * Deliberately narrower than "resolves off-origin": a WHATWG-backslash-equivalent spelling
26
- * (`/\evil.com`, `\\evil.com`, `\/evil.com` — see `utils/sanitize-href.ts`'s
27
- * `isImplicitlyOffOrigin`) also resolves off-origin in a browser, but is NOT recognized here as
25
+ * Deliberately narrower than "resolves off-origin": a backslash-equivalent spelling (see
26
+ * `utils/sanitize-href.ts`'s `declaresScheme` and `isImplicitlyOffOrigin`)
27
+ * also resolves off-origin in a browser, but is NOT recognized here as
28
28
  * an intentional off-site pointer the way a literal `//cdn…` is. Callers handle that case
29
29
  * separately, by neutralizing (`neutralizeImplicitOffOrigin`) rather than passing through: a
30
30
  * `false` result here isn't a guarantee the value is a safe site-relative path on its own, only
@@ -1,41 +1,26 @@
1
1
  /**
2
- * The keys a block item carries that are STRUCTURE rather than content.
2
+ * The keys a block item carries that are STRUCTURE rather than content: the
3
+ * discriminator naming the block's TEMPLATE — a category label shared by every
4
+ * block of that kind, not an identifier for this one — present in either on-disk
5
+ * shape: canonical `{ template: 'hero', value: {...} }` or the defensive inline
6
+ * `{ _type: 'hero', ...fields }` (see `resolveBlockItem` in `./field-traversal`).
3
7
  *
4
- * A block on disk is `{ template: 'hero', value: { ...fields } }` — the canonical shape the
5
- * editor writes and `ContentStore` persists — or, defensively, the inline `{ _type: 'hero',
6
- * ...fields }` shape (see `resolveBlockItem` in `./field-traversal`). Either way the
7
- * discriminator names the block's TEMPLATE, which is a category label shared by every block of
8
- * that kind, not an identifier for this particular block.
8
+ * The list lives here, not in either caller, so the two below can't drift apart:
9
+ * - `findUnknownKeys` (./entry-validator) must not report the discriminator as a
10
+ * stale key — it isn't a schema field, but is supposed to be there.
11
+ * - `looksLikeSameItem` (../utils/content-serialize) must not accept it as evidence
12
+ * two list items are the same item — every `hero` shares `template: hero`, so
13
+ * counting it would migrate an editorial comment off a deleted block onto an
14
+ * unrelated survivor.
9
15
  *
10
- * That distinction matters to two callers for opposite-looking reasons, which is why the list
11
- * lives here rather than in either of them:
12
- *
13
- * - `findUnknownKeys` (./entry-validator) must not report the discriminator as a stale key: it
14
- * is not a schema field, but it is supposed to be there.
15
- * - `looksLikeSameItem` (../utils/content-serialize) must not accept the discriminator as
16
- * evidence that two list items are the same item: two `hero` blocks share `template: hero`,
17
- * so counting it migrated an editorial comment off a deleted block onto an unrelated
18
- * survivor.
19
- *
20
- * A single list keeps those two from drifting apart — a third discriminator added for one of
21
- * them but not the other would resurrect exactly one of those bugs.
22
- *
23
- * Note that two other readers deliberately still spell the keys out themselves, because they
24
- * READ the discriminator's value positionally rather than testing membership, and they do not
25
- * agree on precedence: `resolveBlockItem` prefers `template`, while `ai/json-to-markdown.ts`
26
- * prefers `_type`. Reconciling that is a behaviour question, not a refactor — see
16
+ * Two other readers still spell the keys out themselves — they read the value
17
+ * positionally and disagree on precedence (`resolveBlockItem` prefers `template`,
18
+ * `ai/json-to-markdown.ts` prefers `_type`) — see
27
19
  * `.claude/future-tasks/block-discriminator-precedence-disagreement.md`.
28
20
  *
29
- * Dependency-free on purpose: both importers are reachable from contexts that must not pull in
21
+ * Dependency-free on purpose: both importers reach contexts that must not pull in
30
22
  * schema types or node built-ins.
31
23
  */
32
- /**
33
- * The discriminator keys, in the precedence `resolveBlockItem` reads them.
34
- *
35
- * Ordered (rather than a bare Set) so a caller that needs the VALUE can iterate it, and so the
36
- * canonical shape's key stays visibly first.
37
- */
38
- export declare const BLOCK_DISCRIMINATOR_KEYS: readonly ["template", "_type"];
39
24
  /** Membership form of {@link BLOCK_DISCRIMINATOR_KEYS}, for the two set-test callers. */
40
25
  export declare const BLOCK_STRUCTURAL_KEYS: ReadonlySet<string>;
41
26
  /** True for a key that names a block's template rather than holding any of its content. */
@@ -1,41 +1,31 @@
1
1
  /**
2
- * The keys a block item carries that are STRUCTURE rather than content.
2
+ * The keys a block item carries that are STRUCTURE rather than content: the
3
+ * discriminator naming the block's TEMPLATE — a category label shared by every
4
+ * block of that kind, not an identifier for this one — present in either on-disk
5
+ * shape: canonical `{ template: 'hero', value: {...} }` or the defensive inline
6
+ * `{ _type: 'hero', ...fields }` (see `resolveBlockItem` in `./field-traversal`).
3
7
  *
4
- * A block on disk is `{ template: 'hero', value: { ...fields } }` — the canonical shape the
5
- * editor writes and `ContentStore` persists — or, defensively, the inline `{ _type: 'hero',
6
- * ...fields }` shape (see `resolveBlockItem` in `./field-traversal`). Either way the
7
- * discriminator names the block's TEMPLATE, which is a category label shared by every block of
8
- * that kind, not an identifier for this particular block.
8
+ * The list lives here, not in either caller, so the two below can't drift apart:
9
+ * - `findUnknownKeys` (./entry-validator) must not report the discriminator as a
10
+ * stale key — it isn't a schema field, but is supposed to be there.
11
+ * - `looksLikeSameItem` (../utils/content-serialize) must not accept it as evidence
12
+ * two list items are the same item — every `hero` shares `template: hero`, so
13
+ * counting it would migrate an editorial comment off a deleted block onto an
14
+ * unrelated survivor.
9
15
  *
10
- * That distinction matters to two callers for opposite-looking reasons, which is why the list
11
- * lives here rather than in either of them:
12
- *
13
- * - `findUnknownKeys` (./entry-validator) must not report the discriminator as a stale key: it
14
- * is not a schema field, but it is supposed to be there.
15
- * - `looksLikeSameItem` (../utils/content-serialize) must not accept the discriminator as
16
- * evidence that two list items are the same item: two `hero` blocks share `template: hero`,
17
- * so counting it migrated an editorial comment off a deleted block onto an unrelated
18
- * survivor.
19
- *
20
- * A single list keeps those two from drifting apart — a third discriminator added for one of
21
- * them but not the other would resurrect exactly one of those bugs.
22
- *
23
- * Note that two other readers deliberately still spell the keys out themselves, because they
24
- * READ the discriminator's value positionally rather than testing membership, and they do not
25
- * agree on precedence: `resolveBlockItem` prefers `template`, while `ai/json-to-markdown.ts`
26
- * prefers `_type`. Reconciling that is a behaviour question, not a refactor — see
16
+ * Two other readers still spell the keys out themselves — they read the value
17
+ * positionally and disagree on precedence (`resolveBlockItem` prefers `template`,
18
+ * `ai/json-to-markdown.ts` prefers `_type`) — see
27
19
  * `.claude/future-tasks/block-discriminator-precedence-disagreement.md`.
28
20
  *
29
- * Dependency-free on purpose: both importers are reachable from contexts that must not pull in
21
+ * Dependency-free on purpose: both importers reach contexts that must not pull in
30
22
  * schema types or node built-ins.
31
23
  */
32
24
  /**
33
- * The discriminator keys, in the precedence `resolveBlockItem` reads them.
34
- *
35
- * Ordered (rather than a bare Set) so a caller that needs the VALUE can iterate it, and so the
36
- * canonical shape's key stays visibly first.
25
+ * The discriminator keys, in the precedence `resolveBlockItem` reads them. Ordered (not a
26
+ * bare Set) so a caller needing the VALUE can iterate, and the canonical key stays first.
37
27
  */
38
- export const BLOCK_DISCRIMINATOR_KEYS = ['template', '_type'];
28
+ const BLOCK_DISCRIMINATOR_KEYS = ['template', '_type'];
39
29
  /** Membership form of {@link BLOCK_DISCRIMINATOR_KEYS}, for the two set-test callers. */
40
30
  export const BLOCK_STRUCTURAL_KEYS = new Set(BLOCK_DISCRIMINATOR_KEYS);
41
31
  /** True for a key that names a block's template rather than holding any of its content. */
@@ -15,18 +15,6 @@ export interface DeletionCheckResult {
15
15
  }
16
16
  /**
17
17
  * DeletionChecker finds all references to an entry before deletion.
18
- *
19
- * This class provides referential integrity checking by:
20
- * - Scanning all entries for references to a target ID
21
- * - Identifying which entries and fields reference the target
22
- * - Preventing deletion of entries that are still referenced
23
- *
24
- * Usage:
25
- * const checker = new DeletionChecker(store, idIndex, schema)
26
- * const result = await checker.canDelete(targetId)
27
- * if (!result.canDelete) {
28
- * console.log('Cannot delete:', result.referencedBy)
29
- * }
30
18
  */
31
19
  export declare class DeletionChecker {
32
20
  private store;
@@ -35,31 +23,9 @@ export declare class DeletionChecker {
35
23
  constructor(store: ContentStore, idIndex: ContentIdIndex, collections: Map<LogicalPath, {
36
24
  fields: FieldConfig[];
37
25
  }>);
38
- /**
39
- * Check if an entry can be safely deleted.
40
- *
41
- * @param id - The content ID to check
42
- * @returns Result indicating if deletion is safe and what references exist
43
- */
44
26
  canDelete(id: string): Promise<DeletionCheckResult>;
45
- /**
46
- * Find all entries that reference the target ID.
47
- *
48
- * @param targetId - The content ID to search for
49
- * @returns Array of reference info for each referencing entry
50
- */
51
27
  findReferences(targetId: string): Promise<ReferenceInfo[]>;
52
- /**
53
- * Scan a single collection for references to the target ID.
54
- */
55
28
  private scanCollection;
56
- /**
57
- * Find all occurrences of target ID in entry data.
58
- * Returns field paths where the ID was found.
59
- */
60
29
  private findIdInData;
61
- /**
62
- * Helper to list all entries in a collection from the ID index.
63
- */
64
30
  private listEntriesInCollection;
65
31
  }
@@ -1,18 +1,6 @@
1
1
  import { resolveBlockItem } from './field-traversal.js';
2
2
  /**
3
3
  * DeletionChecker finds all references to an entry before deletion.
4
- *
5
- * This class provides referential integrity checking by:
6
- * - Scanning all entries for references to a target ID
7
- * - Identifying which entries and fields reference the target
8
- * - Preventing deletion of entries that are still referenced
9
- *
10
- * Usage:
11
- * const checker = new DeletionChecker(store, idIndex, schema)
12
- * const result = await checker.canDelete(targetId)
13
- * if (!result.canDelete) {
14
- * console.log('Cannot delete:', result.referencedBy)
15
- * }
16
4
  */
17
5
  export class DeletionChecker {
18
6
  constructor(store, idIndex, collections) {
@@ -20,12 +8,6 @@ export class DeletionChecker {
20
8
  this.idIndex = idIndex;
21
9
  this.collections = collections;
22
10
  }
23
- /**
24
- * Check if an entry can be safely deleted.
25
- *
26
- * @param id - The content ID to check
27
- * @returns Result indicating if deletion is safe and what references exist
28
- */
29
11
  async canDelete(id) {
30
12
  const referencedBy = await this.findReferences(id);
31
13
  return {
@@ -33,27 +15,16 @@ export class DeletionChecker {
33
15
  referencedBy,
34
16
  };
35
17
  }
36
- /**
37
- * Find all entries that reference the target ID.
38
- *
39
- * @param targetId - The content ID to search for
40
- * @returns Array of reference info for each referencing entry
41
- */
42
18
  async findReferences(targetId) {
43
19
  const references = [];
44
- // Scan all collections for references
45
20
  for (const [collectionPath, collectionDef] of this.collections.entries()) {
46
21
  const refs = await this.scanCollection(collectionPath, collectionDef.fields, targetId);
47
22
  references.push(...refs);
48
23
  }
49
24
  return references;
50
25
  }
51
- /**
52
- * Scan a single collection for references to the target ID.
53
- */
54
26
  async scanCollection(collectionPath, fields, targetId) {
55
27
  const references = [];
56
- // Get all entries in this collection from the ID index
57
28
  const entries = this.listEntriesInCollection(collectionPath);
58
29
  for (const entry of entries) {
59
30
  try {
@@ -71,20 +42,15 @@ export class DeletionChecker {
71
42
  }
72
43
  }
73
44
  catch {
74
- // Skip entries that can't be read
75
45
  continue;
76
46
  }
77
47
  }
78
48
  return references;
79
49
  }
80
- /**
81
- * Find all occurrences of target ID in entry data.
82
- * Returns field paths where the ID was found.
83
- */
84
50
  findIdInData(data, targetId, schema, pathPrefix = '') {
85
51
  const found = [];
86
52
  for (const field of schema) {
87
- // Inline groups are transparent — recurse into their children at the same data level
53
+ // Inline groups are transparent (walkFields, ./field-traversal) — recurse at the same level.
88
54
  if (field.type === 'group') {
89
55
  found.push(...this.findIdInData(data, targetId, field.fields, pathPrefix));
90
56
  continue;
@@ -94,7 +60,6 @@ export class DeletionChecker {
94
60
  if (value === undefined || value === null)
95
61
  continue;
96
62
  if (field.type === 'reference') {
97
- // Check if this reference field contains the target ID
98
63
  if (Array.isArray(value)) {
99
64
  if (value.includes(targetId)) {
100
65
  found.push(fieldPath);
@@ -122,8 +87,6 @@ export class DeletionChecker {
122
87
  }
123
88
  }
124
89
  else if (field.type === 'block') {
125
- // Handle block fields — real block items are { template, value }, with
126
- // nested field values under `value` (resolved by resolveBlockItem)
127
90
  const blockField = field;
128
91
  if (Array.isArray(value)) {
129
92
  value.forEach((item, index) => {
@@ -139,16 +102,11 @@ export class DeletionChecker {
139
102
  }
140
103
  return found;
141
104
  }
142
- /**
143
- * Helper to list all entries in a collection from the ID index.
144
- */
145
105
  listEntriesInCollection(collectionPath) {
146
106
  const entries = [];
147
- // Get all locations from the index
148
107
  const allLocations = this.idIndex.getAllLocations();
149
108
  for (const location of allLocations) {
150
109
  if (location.type === 'entry') {
151
- // Check if this entry is in the target collection
152
110
  if (location.collection === collectionPath ||
153
111
  location.collection?.startsWith(collectionPath + '/')) {
154
112
  entries.push({
@@ -1,14 +1,12 @@
1
1
  /**
2
- * EntryLinkValidator validates that entry:ID patterns in body/markdown fields
3
- * reference existing entries.
4
- *
5
- * Returns warnings (not errors) — saves are never blocked by broken entry links.
6
- * This parallels ReferenceValidator but operates on inline links in text content
7
- * rather than structured reference fields.
2
+ * Scans body/markdown/mdx fields for `entry:ID` links and checks that each ID
3
+ * resolves to an existing entry. Warns rather than blocks — a save is never
4
+ * rejected over a broken entry link. Parallels `ReferenceValidator`, but for
5
+ * inline links in text rather than structured reference fields.
8
6
  */
9
7
  import type { ContentIdIndex } from '../content-id-index.js';
10
8
  import type { FieldConfig } from '../config/index.js';
11
- export interface EntryLinkWarning {
9
+ interface EntryLinkWarning {
12
10
  field: string;
13
11
  fieldPath: string;
14
12
  id: string;
@@ -17,10 +15,5 @@ export interface EntryLinkWarning {
17
15
  export interface EntryLinkValidationResult {
18
16
  warnings: EntryLinkWarning[];
19
17
  }
20
- /**
21
- * Validate entry links in body/markdown/mdx fields of the provided data.
22
- *
23
- * Scans all markdown and mdx fields for entry:ID patterns
24
- * and checks that each referenced ID exists in the content index.
25
- */
26
18
  export declare function validateEntryLinks(data: Record<string, unknown>, schema: readonly FieldConfig[], idIndex: ContentIdIndex, bodyContent?: string): EntryLinkValidationResult;
19
+ export {};
@@ -1,26 +1,17 @@
1
1
  /**
2
- * EntryLinkValidator validates that entry:ID patterns in body/markdown fields
3
- * reference existing entries.
4
- *
5
- * Returns warnings (not errors) — saves are never blocked by broken entry links.
6
- * This parallels ReferenceValidator but operates on inline links in text content
7
- * rather than structured reference fields.
2
+ * Scans body/markdown/mdx fields for `entry:ID` links and checks that each ID
3
+ * resolves to an existing entry. Warns rather than blocks — a save is never
4
+ * rejected over a broken entry link. Parallels `ReferenceValidator`, but for
5
+ * inline links in text rather than structured reference fields.
8
6
  */
9
7
  import { extractEntryLinkIds } from '../entry-link-resolver.js';
10
8
  import { findFieldsByType } from './field-traversal.js';
11
- /**
12
- * Validate entry links in body/markdown/mdx fields of the provided data.
13
- *
14
- * Scans all markdown and mdx fields for entry:ID patterns
15
- * and checks that each referenced ID exists in the content index.
16
- */
17
9
  export function validateEntryLinks(data, schema, idIndex, bodyContent) {
18
10
  const warnings = [];
19
11
  // Check body content (for md/mdx entries, body is separate from data)
20
12
  if (bodyContent) {
21
13
  checkText(bodyContent, 'body', 'body', idIndex, warnings);
22
14
  }
23
- // Check markdown/mdx fields in structured data
24
15
  const markdownTypes = ['markdown', 'mdx'];
25
16
  for (const fieldType of markdownTypes) {
26
17
  const contexts = findFieldsByType(schema, data, fieldType);
@@ -1,27 +1,22 @@
1
1
  /**
2
2
  * Validates that every reference field's `entryTypes` names an entry type that
3
- * actually exists in the resolved schema.
3
+ * actually exists in the resolved schema — without this, a typo like
4
+ * `entryTypes: ['parter']` is accepted silently and surfaces later as a
5
+ * reference picker returning zero results, with nothing pointing at the cause.
4
6
  *
5
- * Without this, a typo (`entryTypes: ['parter']` for `'partner'`) is accepted
6
- * silently and surfaces much later as a reference picker that returns zero
7
- * results, with nothing pointing at the cause.
8
- *
9
- * This runs after schema resolution rather than at config-validation time on
10
- * purpose: entry types are declared per-collection in `.collection.json` files
11
- * on disk, so the set of valid names only exists once a branch's schema has
12
- * been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
13
- * at entry-schema *registration* (entry-schema-registry.ts), before any branch
14
- * schema exists, and so cannot perform this check.
7
+ * Runs after schema resolution, not at config-validation time: entry types are
8
+ * declared per-collection in `.collection.json` files on disk, so the valid-name
9
+ * set only exists once a branch's schema is resolved. `config/validation.ts`'s
10
+ * `ensureReferenceFieldsHaveScope` runs at entry-schema registration
11
+ * (entry-schema-registry.ts), before any branch schema exists, so it can't.
15
12
  */
16
13
  import type { RootCollectionConfig } from '../config/index.js';
17
14
  /**
18
- * Collect every entry type name defined anywhere in the schema.
19
- *
20
- * Entry types are scoped per collection, and the same name may legitimately
21
- * appear in several collections, so this is a flat set of names: a reference
22
- * field's `entryTypes` is matched against entries across all collections
23
- * (see reference-resolver.ts, which filters resolved entries by entry type name
24
- * without regard to which collection defined it).
15
+ * Collect every entry type name defined anywhere in the schema, as a flat set:
16
+ * a reference field's `entryTypes` matches entries across ALL collections, since
17
+ * the same type name may legitimately appear in more than one (see
18
+ * reference-resolver.ts, which filters by type name regardless of collection).
19
+ * @internal Exported for tests.
25
20
  */
26
21
  export declare const collectEntryTypeNames: (schema: RootCollectionConfig) => Set<string>;
27
22
  /**
@@ -1,17 +1,14 @@
1
1
  /**
2
2
  * Validates that every reference field's `entryTypes` names an entry type that
3
- * actually exists in the resolved schema.
3
+ * actually exists in the resolved schema — without this, a typo like
4
+ * `entryTypes: ['parter']` is accepted silently and surfaces later as a
5
+ * reference picker returning zero results, with nothing pointing at the cause.
4
6
  *
5
- * Without this, a typo (`entryTypes: ['parter']` for `'partner'`) is accepted
6
- * silently and surfaces much later as a reference picker that returns zero
7
- * results, with nothing pointing at the cause.
8
- *
9
- * This runs after schema resolution rather than at config-validation time on
10
- * purpose: entry types are declared per-collection in `.collection.json` files
11
- * on disk, so the set of valid names only exists once a branch's schema has
12
- * been resolved. `config/validation.ts`'s `ensureReferenceFieldsHaveScope` runs
13
- * at entry-schema *registration* (entry-schema-registry.ts), before any branch
14
- * schema exists, and so cannot perform this check.
7
+ * Runs after schema resolution, not at config-validation time: entry types are
8
+ * declared per-collection in `.collection.json` files on disk, so the valid-name
9
+ * set only exists once a branch's schema is resolved. `config/validation.ts`'s
10
+ * `ensureReferenceFieldsHaveScope` runs at entry-schema registration
11
+ * (entry-schema-registry.ts), before any branch schema exists, so it can't.
15
12
  */
16
13
  import { forEachReferenceField } from '../config/validation.js';
17
14
  /**
@@ -59,13 +56,11 @@ const forEachEntryType = (schema, visit) => {
59
56
  walk(schema, '');
60
57
  };
61
58
  /**
62
- * Collect every entry type name defined anywhere in the schema.
63
- *
64
- * Entry types are scoped per collection, and the same name may legitimately
65
- * appear in several collections, so this is a flat set of names: a reference
66
- * field's `entryTypes` is matched against entries across all collections
67
- * (see reference-resolver.ts, which filters resolved entries by entry type name
68
- * without regard to which collection defined it).
59
+ * Collect every entry type name defined anywhere in the schema, as a flat set:
60
+ * a reference field's `entryTypes` matches entries across ALL collections, since
61
+ * the same type name may legitimately appear in more than one (see
62
+ * reference-resolver.ts, which filters by type name regardless of collection).
63
+ * @internal Exported for tests.
69
64
  */
70
65
  export const collectEntryTypeNames = (schema) => {
71
66
  const names = new Set();