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
@@ -2,10 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useId } from 'react';
3
3
  import { Input } from '@mantine/core';
4
4
  /**
5
- * Convert a stored value (ISO 8601 UTC, e.g. "2024-03-15T14:30:00.000Z")
6
- * into the "local wall-clock" string a `datetime-local` input expects
7
- * (`YYYY-MM-DDTHH:mm:ss`, no timezone). Returns '' for '' or an unparsable
8
- * value.
5
+ * Converts a stored value (ISO 8601 UTC, e.g. `YYYY-MM-DDTHH:mm:ss.sssZ`)
6
+ * into the local wall-clock string a `datetime-local` input expects
7
+ * (`YYYY-MM-DDTHH:mm:ss`, no timezone). Returns '' for '' or an unparsable value.
8
+ * @internal Exported for tests.
9
9
  */
10
10
  export function isoToDatetimeLocalValue(iso) {
11
11
  if (!iso)
@@ -16,15 +16,14 @@ export function isoToDatetimeLocalValue(iso) {
16
16
  const pad = (n) => String(n).padStart(2, '0');
17
17
  const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
18
18
  `T${pad(date.getHours())}:${pad(date.getMinutes())}`;
19
- // Match the platform's own canonical `datetime-local` serialization: the
20
- // seconds component is included only when non-zero (a real browser's
21
- // input.value getter does the same), so the value we set and what the
22
- // control reports back agree exactly.
19
+ // Seconds are included only when non-zero, matching a real browser's own
20
+ // `datetime-local` serialization, so the value we set agrees with what the control reports back.
23
21
  return date.getSeconds() === 0 ? base : `${base}:${pad(date.getSeconds())}`;
24
22
  }
25
23
  /**
26
24
  * Convert a `datetime-local` input's local wall-clock string back into the
27
25
  * ISO 8601 UTC storage format. Returns '' for '' or an unparsable value.
26
+ * @internal Exported for tests.
28
27
  */
29
28
  export function datetimeLocalValueToIso(local) {
30
29
  if (!local)
@@ -37,29 +36,21 @@ export function datetimeLocalValueToIso(local) {
37
36
  /**
38
37
  * Editor for `type: 'datetime'` fields.
39
38
  *
40
- * Storage format: ISO 8601 UTC string (e.g. "2024-03-15T14:30:00.000Z") —
41
- * what `Date.prototype.toISOString()` produces and what
42
- * `validation/entry-validator.ts`'s datetime check (`Date.parse`) accepts.
43
- * Empty string means "not set" (matches entry-validator's empty-string
44
- * check for required fields).
39
+ * Storage format: ISO 8601 UTC string (e.g. `YYYY-MM-DDTHH:mm:ss.sssZ`) — what
40
+ * `Date.prototype.toISOString()` produces and `validation/entry-validator.ts`'s
41
+ * datetime check (`Date.parse`) accepts. Empty string means "not set".
45
42
  *
46
- * `@mantine/dates` is not a dependency of this package, so per house rules
47
- * we don't add one just for this field: a native `<input
48
- * type="datetime-local">` wrapped in Mantine's `Input`/`Input.Wrapper`
49
- * gives a real date+time picker with zero new dependencies.
43
+ * Uses a native `datetime-local` input in Mantine's `Input.Wrapper` rather than
44
+ * `@mantine/dates` (not a dependency here) — a real picker with zero new deps.
50
45
  *
51
- * `datetime-local` has no timezone concept — it shows/accepts local
52
- * "wall-clock" time. We convert UTC ISO -> local for display and local ->
53
- * UTC ISO on change, so loading a value and saving it unedited round-trips
54
- * to the exact same stored string instead of drifting by the browser's UTC
55
- * offset. `step={1}` keeps seconds in that round trip; sub-second
56
- * precision in the source data is not preserved (`datetime-local` has no
57
- * milliseconds field), so a stored value with non-zero milliseconds will
58
- * have them zeroed out once resaved.
46
+ * `datetime-local` has no timezone: converts UTC ISO -> local for display and
47
+ * back on change, so an unedited load-then-save round-trips exactly instead of
48
+ * drifting by the browser's offset. `step={1}` preserves seconds in that
49
+ * round-trip; sub-second precision is not preserved (no milliseconds field),
50
+ * so a value with non-zero milliseconds is zeroed out once resaved.
59
51
  */
60
52
  export const DateTimeField = ({ id, label, value, onChange, dataCanopyField, }) => {
61
53
  const generatedId = useId();
62
54
  const inputId = id ?? generatedId;
63
55
  return (_jsx(Input.Wrapper, { id: inputId, label: label, size: "sm", children: _jsx(Input, { type: "datetime-local", step: 1, size: "sm", value: isoToDatetimeLocalValue(value), onChange: (e) => onChange(datetimeLocalValueToIso(e.currentTarget.value)), "data-canopy-field": dataCanopyField }) }));
64
56
  };
65
- export default DateTimeField;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { ImageFieldValue } from '../../config/index.js';
3
- export interface ImageFieldErrors {
3
+ interface ImageFieldErrors {
4
4
  src?: string;
5
5
  alt?: string;
6
6
  crop?: string;
@@ -18,4 +18,4 @@ export interface ImageFieldProps {
18
18
  errors?: ImageFieldErrors;
19
19
  }
20
20
  export declare const ImageField: React.FC<ImageFieldProps>;
21
- export default ImageField;
21
+ export {};
@@ -20,8 +20,7 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
20
20
  const [pickerOpen, setPickerOpen] = useState(false);
21
21
  const [cropRequest, setCropRequest] = useState(null);
22
22
  // Dropzone-level rejections (wrong type/too large) never reach useAssetUpload
23
- // (Dropzone filters them out before onDrop fires), so they need their own
24
- // error slot rather than piggybacking on upload.error.
23
+ // (filtered before onDrop fires), so they need their own error slot.
25
24
  const [dropError, setDropError] = useState(null);
26
25
  const altInputRef = useRef(null);
27
26
  const justCommittedRef = useRef(false);
@@ -30,20 +29,17 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
30
29
  const previewSrc = value
31
30
  ? assetUrl({ src: value.src }, { width: PREVIEW_WIDTH, crop: value.crop, baseUrl })
32
31
  : undefined;
33
- // Broken-preview fallback, consistent with AssetCard's thumbnail fallback
34
- // (same icon/copy, same "adjust state during render" reset pattern rather
35
- // than a useEffect - see AssetCard.tsx for the rationale). This covers
36
- // both an asset that was broken at upload time (pre-existing content) and
37
- // a transform that fails for some other reason at render time.
32
+ // Broken-preview fallback, mirroring AssetCard.tsx's thumbnail fallback (same
33
+ // icon/copy, same reset-during-render pattern). Covers both an asset broken
34
+ // at upload time and a transform failing at render time.
38
35
  const [previewFailed, setPreviewFailed] = useState(false);
39
36
  const [prevPreviewSrc, setPrevPreviewSrc] = useState(previewSrc);
40
37
  if (previewSrc !== prevPreviewSrc) {
41
38
  setPrevPreviewSrc(previewSrc);
42
39
  setPreviewFailed(false);
43
40
  }
44
- // Focus the alt input right after a new image commits (pick or upload),
45
- // so the editor's next keystroke goes straight into the field most likely
46
- // to need attention.
41
+ // Focuses the alt input right after a new image commits (pick or upload),
42
+ // so the next keystroke lands in the field most likely to need attention.
47
43
  useEffect(() => {
48
44
  if (justCommittedRef.current) {
49
45
  justCommittedRef.current = false;
@@ -54,9 +50,8 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
54
50
  justCommittedRef.current = true;
55
51
  onChange({
56
52
  src: asset.src,
57
- // Preserve the current alt text on replace - it often still describes
58
- // the new image (e.g. "hero photo"), and the editor can always edit it.
59
- // Selecting into an empty field has no prior alt, so it stays ''.
53
+ // Preserves the current alt text on replace (it often still fits); an
54
+ // empty field has no prior alt, so it stays ''.
60
55
  alt: value?.alt ?? '',
61
56
  ...(asset.width !== undefined ? { width: asset.width } : {}),
62
57
  ...(asset.height !== undefined ? { height: asset.height } : {}),
@@ -123,4 +118,3 @@ export const ImageField = ({ id, label, value, onChange, aspect, altOptional, da
123
118
  display: 'block',
124
119
  }, onError: () => setPreviewFailed(true) })), errors?.src && (_jsx(Text, { size: "xs", c: "red", children: errors.src })), _jsx(TextInput, { id: inputId, ref: altInputRef, label: "Alt text", required: !altOptional, value: value.alt, onChange: (event) => handleAltChange(event.currentTarget.value), error: errors?.alt, size: "sm", "data-testid": `image-field-alt-${dataCanopyField}` }), _jsxs(Group, { gap: "xs", children: [_jsx(Button, { variant: "light", size: "xs", onClick: () => setPickerOpen(true), "data-testid": `image-field-replace-${dataCanopyField}`, children: "Replace" }), aspectRatio !== undefined && (_jsx(Button, { variant: "light", size: "xs", onClick: () => setCropRequest({ kind: 'existing' }), "data-testid": `image-field-crop-${dataCanopyField}`, children: "Crop" })), _jsx(Button, { variant: "subtle", color: "red", size: "xs", onClick: handleRemove, "data-testid": `image-field-remove-${dataCanopyField}`, children: "Remove" })] }), errors?.crop && (_jsx(Text, { size: "xs", c: "red", children: errors.crop }))] })), _jsx(MediaLibrary, { opened: pickerOpen, onClose: () => setPickerOpen(false), mode: "picker", onSelect: handleAssetReady }), aspectRatio !== undefined && (_jsx(CropStep, { opened: cropRequest !== null, onClose: () => setCropRequest(null), imageSrc: cropImageSrc, aspect: aspectRatio, initialCrop: cropInitial, onConfirm: handleCropConfirm }))] }));
125
120
  };
126
- export default ImageField;
@@ -13,4 +13,3 @@ export interface InlineGroupFieldProps {
13
13
  path: Array<string | number>;
14
14
  }
15
15
  export declare const InlineGroupField: React.FC<InlineGroupFieldProps>;
16
- export default InlineGroupField;
@@ -12,4 +12,3 @@ export const InlineGroupField = ({ label, description, fields, value, onChange,
12
12
  return (_jsx("div", { children: renderField(field, value[field.name], (next) => onChange({ ...value, [field.name]: next }), fieldPath) }, formatCanopyPath(fieldPath)));
13
13
  }) })] }) }));
14
14
  };
15
- export default InlineGroupField;
@@ -7,4 +7,3 @@ export interface MarkdownFieldProps {
7
7
  dataCanopyField?: string;
8
8
  }
9
9
  export declare const MarkdownField: React.FC<MarkdownFieldProps>;
10
- export default MarkdownField;
@@ -8,15 +8,14 @@ import { useApiClient } from '../context/index.js';
8
8
  import { uploadAsset } from '../media/upload-asset.js';
9
9
  const MDXEditorLazy = React.lazy(async () => {
10
10
  const [{ MDXEditor }, { headingsPlugin, listsPlugin, quotePlugin, thematicBreakPlugin, markdownShortcutPlugin, linkPlugin, linkDialogPlugin, imagePlugin, tablePlugin, toolbarPlugin, codeBlockPlugin, codeMirrorPlugin, BoldItalicUnderlineToggles, BlockTypeSelect, ListsToggle, CreateLink, InsertImage, InsertTable, InsertThematicBreak, CodeToggle, InsertCodeBlock, UndoRedo, Separator, insertMarkdown$, usePublisher, useCellValues, saveImage$, closeImageDialog$, imageDialogState$, },] = await Promise.all([import('@mdxeditor/editor'), import('@mdxeditor/editor')]);
11
- /** Toolbar wrapper that provides insertMarkdown to InsertEntryLink */
12
11
  const EntryLinkToolbarButton = () => {
13
12
  const insertMarkdown = usePublisher(insertMarkdown$);
14
13
  return _jsx(InsertEntryLink, { onInsert: insertMarkdown });
15
14
  };
16
15
  /**
17
- * Bridges mdxeditor's realm cells (only reachable once this lazy chunk has
16
+ * Bridges mdxeditor's realm cells (reachable only once this lazy chunk has
18
17
  * loaded) into MdxImageDialog's plain-props interface, so that component
19
- * itself never imports `@mdxeditor/editor` at runtime. Same pattern as
18
+ * never imports `@mdxeditor/editor` at runtime — same pattern as
20
19
  * `EntryLinkToolbarButton` above.
21
20
  */
22
21
  const MdxImageDialogBridge = () => {
@@ -60,7 +59,6 @@ const MDXEditorLazy = React.lazy(async () => {
60
59
  };
61
60
  return { default: WrappedEditor };
62
61
  });
63
- /** Style the editor wrapper with a white background and border so it's visually distinct from the form background. */
64
62
  const editorWrapperStyle = {
65
63
  background: '#fff',
66
64
  border: '1px solid var(--mantine-color-gray-4, #ced4da)',
@@ -102,12 +100,10 @@ export const MarkdownField = ({ id, label, value, onChange, dataCanopyField, })
102
100
  const editorRef = useRef(null);
103
101
  const lastExternalValue = useRef(value);
104
102
  const apiClient = useApiClient();
105
- // Drives both MDXEditor's own drag/drop/paste upload flow and the Upload
106
- // tab in our custom image dialog (MdxImageDialog) via the SAME presign/
107
- // finalize-or-proxied pipeline used everywhere else in the editor (see
108
- // media/upload-asset.ts). Stable across renders (memoized on the API
109
- // client, which ApiClientProvider itself memoizes) so MDXEditor's plugin
110
- // list doesn't churn on every keystroke.
103
+ // Drives both MDXEditor's drag/drop/paste upload and the custom image
104
+ // dialog's Upload tab via the same presign/finalize-or-proxied pipeline
105
+ // (media/upload-asset.ts). Memoized on the API client (itself memoized by
106
+ // ApiClientProvider) so MDXEditor's plugin list doesn't churn per keystroke.
111
107
  const imageUploadHandler = useCallback(async (file) => {
112
108
  const asset = await uploadAsset(apiClient, file);
113
109
  return asset.src;
@@ -125,4 +121,3 @@ export const MarkdownField = ({ id, label, value, onChange, dataCanopyField, })
125
121
  }, [onChange]);
126
122
  return (_jsxs("div", { id: inputId, "data-canopy-field": dataCanopyField, className: "canopy-markdown-field", children: [label && (_jsx(Text, { size: "sm", fw: 500, mb: 4, children: label })), _jsx(EditorContentStyles, {}), _jsx("div", { style: editorWrapperStyle, children: _jsx(Suspense, { fallback: _jsx(FallbackTextarea, { value: value, onChange: onChange }), children: _jsx(MDXEditorLazy, { markdown: value, onChange: handleChange, editorRef: editorRef, imageUploadHandler: imageUploadHandler }) }) })] }));
127
123
  };
128
- export default MarkdownField;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { EditingImageDialogState, InactiveImageDialogState, NewImageDialogState, SaveImageParameters } from '@mdxeditor/editor';
3
+ /** @internal Exported for tests. */
3
4
  export type MdxImageDialogState = InactiveImageDialogState | NewImageDialogState | EditingImageDialogState;
4
5
  export interface MdxImageDialogProps {
5
6
  state: MdxImageDialogState;
@@ -12,4 +13,3 @@ export interface MdxImageDialogProps {
12
13
  * in MarkdownField.tsx.
13
14
  */
14
15
  export declare const MdxImageDialog: React.FC<MdxImageDialogProps>;
15
- export default MdxImageDialog;
@@ -69,4 +69,3 @@ export const MdxImageDialog = ({ state, onSave, onClose }) => {
69
69
  }, children: [_jsxs(Tabs.List, { children: [_jsx(Tabs.Tab, { value: "upload", "data-testid": "mdx-image-dialog-tab-upload", children: "Upload" }), _jsx(Tabs.Tab, { value: "library", "data-testid": "mdx-image-dialog-tab-library", children: "From library" }), _jsx(Tabs.Tab, { value: "url", "data-testid": "mdx-image-dialog-tab-url", children: "By URL" })] }), _jsx(Tabs.Panel, { value: "upload", pt: "sm", children: _jsxs(Stack, { gap: "xs", children: [_jsx(Dropzone, { onDrop: (files) => void handleDrop(files), onReject: handleReject, maxSize: MAX_UPLOAD_BYTES, accept: ACCEPTED_IMAGE_MIME_TYPES, loading: upload.uploading, multiple: false, "data-testid": "mdx-image-dialog-dropzone", children: _jsxs(Group, { justify: "center", gap: "xs", py: "sm", style: { pointerEvents: 'none' }, children: [_jsx(IconUpload, { size: 20 }), _jsx(Text, { size: "sm", children: "Drop an image here, or click to browse" })] }) }), upload.uploading &&
70
70
  (upload.progress !== null ? (_jsx(Progress, { value: upload.progress * 100, size: "sm" })) : (_jsx(Progress, { value: 100, size: "sm", animated: true }))), (upload.error || dropError) && (_jsx(Alert, { icon: _jsx(IconAlertCircle, { size: 16 }), color: "red", children: upload.error || dropError }))] }) }), _jsx(Tabs.Panel, { value: "library", pt: "sm", children: _jsx("div", { style: { height: LIBRARY_PANEL_HEIGHT }, children: _jsx(MediaLibraryBody, { opened: tab === 'library', mode: "picker", onSelect: handlePickFromLibrary }) }) }), _jsx(Tabs.Panel, { value: "url", pt: "sm", children: _jsxs(Stack, { gap: "xs", children: [_jsx(TextInput, { label: "Image URL", placeholder: "https://example.com/image.png", value: urlValue, onChange: (event) => setUrlValue(event.currentTarget.value), "data-testid": "mdx-image-dialog-url" }), _jsx(Group, { justify: "flex-end", children: _jsx(Button, { onClick: handleUrlSubmit, disabled: !urlValue.trim(), "data-testid": "mdx-image-dialog-url-submit", children: "Insert" }) })] }) })] }), _jsx(Group, { justify: "flex-end", children: _jsx(Button, { variant: "default", onClick: onClose, children: "Cancel" }) })] }) }));
71
71
  };
72
- export default MdxImageDialog;
@@ -9,25 +9,15 @@ export interface NumberFieldProps {
9
9
  /**
10
10
  * Editor for `type: 'number'` fields.
11
11
  *
12
- * `undefined` means "not filled in" and is distinct from `0`: an empty
13
- * input must not silently become `0` (that would make a required numeric
14
- * field with value `0` look correct while an actually-empty field also
15
- * looks fine), and `0` must not be mistaken for "absent". Mantine's
16
- * `NumberInput` reports an empty input as `''`; we translate that to
17
- * `undefined` so `validation/entry-validator.ts`'s required check (which
18
- * treats only `undefined`/`null` as empty for numbers) agrees with what the
19
- * form displays.
12
+ * `undefined` (not `0`) means "not filled in": Mantine's `NumberInput` reports
13
+ * an empty input as `''`, which this field translates to `undefined` so
14
+ * `validation/entry-validator.ts`'s required check agrees with the form.
20
15
  *
21
- * IN-PROGRESS TEXT IS MIRRORED BACK, NOT THE PARSED NUMBER, and that is
22
- * load-bearing rather than stylistic. Mantine reports an entry as a STRING
23
- * exactly when the text and its numeric value disagree (`'-0'`, `'0.'`,
24
- * `'-0.0'`, leading zeros) and as a number otherwise. Handing the PARSED
25
- * number back as the controlled value re-renders the input from
26
- * `String(number)` — and `String(-0)` is `'0'`, so typing `-0.5` lost its
27
- * minus after the second keystroke and the `.5` appended to a POSITIVE
28
- * zero: the user typed `-0.5` and `0.5` was stored, silently. Keeping the
29
- * text Mantine itself reported keeps the sign on screen until the entry is
30
- * a complete number. See NumberField.test.tsx's keystroke matrix.
16
+ * The in-progress TEXT is mirrored back, not the parsed number. Mantine
17
+ * reports the entry as a string exactly when text and numeric value disagree
18
+ * (`'-0'`, `'0.'`, leading zeros); re-rendering from `String(parsedNumber)`
19
+ * instead loses that distinction — `String(-0)` is `'0'`, so typing `-0.5`
20
+ * would silently store `0.5` after the second keystroke. See
21
+ * NumberField.test.tsx's keystroke matrix.
31
22
  */
32
23
  export declare const NumberField: React.FC<NumberFieldProps>;
33
- export default NumberField;
@@ -16,37 +16,26 @@ const toNumericValue = (raw) => {
16
16
  /**
17
17
  * Editor for `type: 'number'` fields.
18
18
  *
19
- * `undefined` means "not filled in" and is distinct from `0`: an empty
20
- * input must not silently become `0` (that would make a required numeric
21
- * field with value `0` look correct while an actually-empty field also
22
- * looks fine), and `0` must not be mistaken for "absent". Mantine's
23
- * `NumberInput` reports an empty input as `''`; we translate that to
24
- * `undefined` so `validation/entry-validator.ts`'s required check (which
25
- * treats only `undefined`/`null` as empty for numbers) agrees with what the
26
- * form displays.
19
+ * `undefined` (not `0`) means "not filled in": Mantine's `NumberInput` reports
20
+ * an empty input as `''`, which this field translates to `undefined` so
21
+ * `validation/entry-validator.ts`'s required check agrees with the form.
27
22
  *
28
- * IN-PROGRESS TEXT IS MIRRORED BACK, NOT THE PARSED NUMBER, and that is
29
- * load-bearing rather than stylistic. Mantine reports an entry as a STRING
30
- * exactly when the text and its numeric value disagree (`'-0'`, `'0.'`,
31
- * `'-0.0'`, leading zeros) and as a number otherwise. Handing the PARSED
32
- * number back as the controlled value re-renders the input from
33
- * `String(number)` — and `String(-0)` is `'0'`, so typing `-0.5` lost its
34
- * minus after the second keystroke and the `.5` appended to a POSITIVE
35
- * zero: the user typed `-0.5` and `0.5` was stored, silently. Keeping the
36
- * text Mantine itself reported keeps the sign on screen until the entry is
37
- * a complete number. See NumberField.test.tsx's keystroke matrix.
23
+ * The in-progress TEXT is mirrored back, not the parsed number. Mantine
24
+ * reports the entry as a string exactly when text and numeric value disagree
25
+ * (`'-0'`, `'0.'`, leading zeros); re-rendering from `String(parsedNumber)`
26
+ * instead loses that distinction — `String(-0)` is `'0'`, so typing `-0.5`
27
+ * would silently store `0.5` after the second keystroke. See
28
+ * NumberField.test.tsx's keystroke matrix.
38
29
  */
39
30
  export const NumberField = ({ id, label, value, onChange, dataCanopyField, }) => {
40
31
  const generatedId = useId();
41
32
  const inputId = id ?? generatedId;
42
33
  const [inputValue, setInputValue] = useState(value ?? '');
43
- // Show the in-progress text only while it still means what the parent
44
- // holds. Once the parent's value diverges (entry loaded, draft discarded,
45
- // "Reload File"), that value wins and the stale text is dropped.
34
+ // Shows the in-progress text only while it still matches the parent's
35
+ // value; once the parent's value diverges (load, discard, reload), that value wins.
46
36
  const displayValue = toNumericValue(inputValue) === value ? inputValue : (value ?? '');
47
37
  return (_jsx(NumberInput, { id: inputId, label: label, value: displayValue, size: "sm", onChange: (next) => {
48
38
  setInputValue(next);
49
39
  onChange(toNumericValue(next));
50
40
  }, "data-canopy-field": dataCanopyField }));
51
41
  };
52
- export default NumberField;
@@ -9,16 +9,13 @@ export interface NumberListFieldProps {
9
9
  /**
10
10
  * Editor for `type: 'number', list: true` fields.
11
11
  *
12
- * Mirrors `StringListField`'s approach (Mantine's `TagsInput`: type + Enter
13
- * adds an item, Backspace on an empty input removes the last one) since
14
- * there is no numeric equivalent in Mantine. Tags are parsed to numbers on
15
- * change; a tag that doesn't parse to a finite number is not stored (it
16
- * would be `NaN`, or a spurious `0` for a blank one).
12
+ * Mirrors `StringListField`'s `TagsInput` approach (type + Enter adds an
13
+ * item, Backspace on empty removes the last) since Mantine has no numeric
14
+ * equivalent. A tag that doesn't parse to a finite number is dropped rather
15
+ * than stored as `NaN`.
17
16
  *
18
- * A rejected tag is REPORTED, not silently swallowed. Dropping it quietly
19
- * looked identical to accepting it - the tag vanished on Enter with no
20
- * error, no value, and nothing distinguishing "typo" from "the field
21
- * doesn't work" - so the rejected text is named in the field's error slot.
17
+ * A dropped tag is reported, not silently swallowed — otherwise it vanished
18
+ * on Enter indistinguishably from being accepted, with nothing to tell a
19
+ * typo from a broken field — so rejected text is named in the error slot.
22
20
  */
23
21
  export declare const NumberListField: React.FC<NumberListFieldProps>;
24
- export default NumberListField;
@@ -18,16 +18,14 @@ const parseTag = (tag) => {
18
18
  /**
19
19
  * Editor for `type: 'number', list: true` fields.
20
20
  *
21
- * Mirrors `StringListField`'s approach (Mantine's `TagsInput`: type + Enter
22
- * adds an item, Backspace on an empty input removes the last one) since
23
- * there is no numeric equivalent in Mantine. Tags are parsed to numbers on
24
- * change; a tag that doesn't parse to a finite number is not stored (it
25
- * would be `NaN`, or a spurious `0` for a blank one).
21
+ * Mirrors `StringListField`'s `TagsInput` approach (type + Enter adds an
22
+ * item, Backspace on empty removes the last) since Mantine has no numeric
23
+ * equivalent. A tag that doesn't parse to a finite number is dropped rather
24
+ * than stored as `NaN`.
26
25
  *
27
- * A rejected tag is REPORTED, not silently swallowed. Dropping it quietly
28
- * looked identical to accepting it - the tag vanished on Enter with no
29
- * error, no value, and nothing distinguishing "typo" from "the field
30
- * doesn't work" - so the rejected text is named in the field's error slot.
26
+ * A dropped tag is reported, not silently swallowed — otherwise it vanished
27
+ * on Enter indistinguishably from being accepted, with nothing to tell a
28
+ * typo from a broken field — so rejected text is named in the error slot.
31
29
  */
32
30
  export const NumberListField = ({ id, label, value, onChange, dataCanopyField, }) => {
33
31
  const generatedId = useId();
@@ -49,4 +47,3 @@ export const NumberListField = ({ id, label, value, onChange, dataCanopyField, }
49
47
  onChange(parsed);
50
48
  }, splitChars: [], allowDuplicates: true, "data-canopy-field": dataCanopyField }));
51
49
  };
52
- export default NumberListField;
@@ -10,15 +10,12 @@ export interface ObjectFieldProps {
10
10
  path: Array<string | number>;
11
11
  dataCanopyField?: string;
12
12
  /**
13
- * When provided, renders a "Clear" affordance next to the label that
14
- * resets this object field back to its unset (`undefined`) state.
15
- * Used by FormRenderer's non-list 'object' case so a non-list object with
16
- * a required child can't get stuck present-but-invalid with no way back
17
- * to "not filled in" (see FormRenderer.tsx's `case 'object'`). Omitted
18
- * for object-list items, which are removed via the list's own per-item
19
- * Remove button instead.
13
+ * When set, shows a "Clear" affordance that resets this field to unset
14
+ * (`undefined`) — used by `FormRenderer.tsx`'s non-list `case 'object'` so
15
+ * a required child can't strand the field present-but-invalid with no way
16
+ * back to "not filled in". Omitted for object-list items, which remove via
17
+ * the list's own per-item button.
20
18
  */
21
19
  onRemove?: () => void;
22
20
  }
23
21
  export declare const ObjectField: React.FC<ObjectFieldProps>;
24
- export default ObjectField;
@@ -8,4 +8,3 @@ export const ObjectField = ({ label, fields, value, onChange, renderField, path,
8
8
  return (_jsx("div", { children: renderField(field, current[field.name], (next) => onChange({ ...current, [field.name]: next }), fieldPath) }, formatCanopyPath(fieldPath)));
9
9
  }) })] }) }));
10
10
  };
11
- export default ObjectField;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ /** @internal Exported for tests. */
2
3
  export interface ReferenceOption {
3
4
  value: string;
4
5
  label: string;
@@ -17,4 +18,3 @@ export interface ReferenceFieldProps {
17
18
  dataCanopyField?: string;
18
19
  }
19
20
  export declare const ReferenceField: React.FC<ReferenceFieldProps>;
20
- export default ReferenceField;
@@ -7,10 +7,10 @@ import { createApiClient } from '../../api/client.js';
7
7
  import { useOptionalApiClient } from '../context/index.js';
8
8
  import { getErrorMessage } from '../../utils/error.js';
9
9
  export const ReferenceField = ({ id, label, options: staticOptions, collections, entryTypes, displayField = 'title', branch = 'main', value, onChange, multiple, dataCanopyField, }) => {
10
- // Context-provided client (configured with the deployment's basePath) when rendered inside an
11
- // ApiClientProvider -- which it always is in the real Editor tree. `null` outside one (e.g.
12
- // FormRenderer.stories.tsx has no provider), in which case the fetch effect below falls back
13
- // to a default-configured client.
10
+ // Configured with the deployment's basePath when rendered inside an
11
+ // ApiClientProvider (always true in the real Editor tree); `null` outside one
12
+ // (e.g. FormRenderer.stories.tsx), so the fetch effect falls back to a
13
+ // default-configured client.
14
14
  const contextApiClient = useOptionalApiClient();
15
15
  const hasCollections = !!collections && collections.length > 0;
16
16
  const hasEntryTypes = !!entryTypes && entryTypes.length > 0;
@@ -19,7 +19,6 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
19
19
  const [loading, setLoading] = useState(needsFetch);
20
20
  const [error, setError] = useState(null);
21
21
  const [retryCount, setRetryCount] = useState(0);
22
- // Extract ID from value - handle both string IDs and resolved objects
23
22
  const extractId = (val) => {
24
23
  if (typeof val === 'string')
25
24
  return val;
@@ -46,17 +45,14 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
46
45
  setError(null);
47
46
  }
48
47
  }
49
- // Load options from API if collections or entryTypes are provided and no static options.
48
+ // Keyed on the derived `fetchKey`, not the raw `collections`/`entryTypes`
49
+ // arrays: the parent rebuilds those on every render (including every
50
+ // `refreshEntries()` after a save), so depending on them directly fired
51
+ // this fetch far more often than the inputs actually changed.
50
52
  //
51
- // Keyed on the derived `fetchKey` (not the raw `collections`/`entryTypes`
52
- // arrays): the parent rebuilds those arrays on every render -- including
53
- // every `refreshEntries()` after a save -- so depending on them directly
54
- // fired this fetch far more often than the inputs actually changed.
55
- //
56
- // `active` guards against a stale response: if the key changes again (or
57
- // the field unmounts) before this request settles, the loser's `.then`/
58
- // `.catch`/`.finally` must not overwrite state a newer request already
59
- // owns.
53
+ // `active` guards against a stale response: if the key changes again or the
54
+ // field unmounts before this request settles, the loser's `.then`/`.catch`/
55
+ // `.finally` must not overwrite state a newer request already owns.
60
56
  useEffect(() => {
61
57
  if (!needsFetch)
62
58
  return;
@@ -112,4 +108,3 @@ export const ReferenceField = ({ id, label, options: staticOptions, collections,
112
108
  }
113
109
  return (_jsx(Stack, { gap: 4, "data-canopy-field": dataCanopyField, "data-testid": `reference-field-${dataCanopyField}`, children: multiple ? (_jsx(MultiSelect, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next), searchable: true, placeholder: "Select reference\u2026", size: "sm" })) : (_jsx(Select, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next ?? ''), searchable: true, clearable: true, placeholder: "Select reference\u2026", size: "sm" })) }));
114
110
  };
115
- export default ReferenceField;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export interface SelectOption {
2
+ interface SelectOption {
3
3
  label: string;
4
4
  value: string;
5
5
  }
@@ -14,4 +14,4 @@ export interface SelectFieldProps {
14
14
  dataCanopyField?: string;
15
15
  }
16
16
  export declare const SelectField: React.FC<SelectFieldProps>;
17
- export default SelectField;
17
+ export {};
@@ -13,4 +13,3 @@ export const SelectField = ({ id, label, options, value, onChange, multiple, pla
13
13
  const inputId = id ?? generatedId;
14
14
  return (_jsxs(Stack, { gap: 4, "data-canopy-field": dataCanopyField, children: [multiple ? (_jsx(MultiSelect, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next), searchable: true, placeholder: placeholder, size: "sm" })) : (_jsx(Select, { id: inputId, label: label, data: options, value: normalizedValue, onChange: (next) => onChange(next ?? ''), searchable: true, clearable: true, placeholder: placeholder, size: "sm" })), multiple && (_jsx(Text, { size: "xs", c: "dimmed", children: "Searchable multi-select; start typing to filter." }))] }));
15
15
  };
16
- export default SelectField;
@@ -11,9 +11,5 @@ export interface StringListFieldProps {
11
11
  *
12
12
  * Uses Mantine's TagsInput: type + Enter adds an item, each item renders as a
13
13
  * removable pill, and Backspace on an empty input removes the last item.
14
- * (Before this component existed, string-list fields fell through to the
15
- * single-value TextField, which coerced the array to a comma-joined string —
16
- * effectively unsupported.)
17
14
  */
18
15
  export declare const StringListField: React.FC<StringListFieldProps>;
19
- export default StringListField;
@@ -6,19 +6,14 @@ import { TagsInput } from '@mantine/core';
6
6
  *
7
7
  * Uses Mantine's TagsInput: type + Enter adds an item, each item renders as a
8
8
  * removable pill, and Backspace on an empty input removes the last item.
9
- * (Before this component existed, string-list fields fell through to the
10
- * single-value TextField, which coerced the array to a comma-joined string —
11
- * effectively unsupported.)
12
9
  */
13
10
  export const StringListField = ({ id, label, value, onChange, dataCanopyField, }) => {
14
11
  const generatedId = useId();
15
12
  const inputId = id ?? generatedId;
16
13
  return (_jsx(TagsInput, { id: inputId, label: label, value: value, size: "sm", onChange: onChange,
17
- // Faithful generic-list semantics, not tag ergonomics: no comma
18
- // splitting ("New York, NY" stays one item — TagsInput's default
19
- // splitChars would break it in two) and duplicates are legitimate
20
- // list data (the default silently drops them, so existing file data
21
- // couldn't round-trip).
14
+ // Faithful generic-list semantics, not tag ergonomics: no comma-splitting
15
+ // ("New York, NY" stays one item) and duplicates are legitimate list
16
+ // data — TagsInput's defaults would break both, so existing file data
17
+ // couldn't round-trip.
22
18
  splitChars: [], allowDuplicates: true, "data-canopy-field": dataCanopyField }));
23
19
  };
24
- export default StringListField;
@@ -7,4 +7,3 @@ export interface TextFieldProps {
7
7
  dataCanopyField?: string;
8
8
  }
9
9
  export declare const TextField: React.FC<TextFieldProps>;
10
- export default TextField;
@@ -6,4 +6,3 @@ export const TextField = ({ id, label, value, onChange, dataCanopyField, }) => {
6
6
  const inputId = id ?? generatedId;
7
7
  return (_jsx(TextInput, { id: inputId, label: label, value: value, size: "sm", onChange: (e) => onChange(e.currentTarget.value), "data-canopy-field": dataCanopyField }));
8
8
  };
9
- export default TextField;
@@ -8,4 +8,3 @@ export interface ToggleFieldProps {
8
8
  testId?: string;
9
9
  }
10
10
  export declare const ToggleField: React.FC<ToggleFieldProps>;
11
- export default ToggleField;
@@ -6,4 +6,3 @@ export const ToggleField = ({ id, label, value, onChange, dataCanopyField, testI
6
6
  const inputId = id ?? generatedId;
7
7
  return (_jsx(Switch, { id: inputId, label: label, checked: value, onChange: (e) => onChange(e.currentTarget.checked), size: "md", "data-canopy-field": dataCanopyField, wrapperProps: testId ? { 'data-testid': testId } : undefined }));
8
8
  };
9
- export default ToggleField;
@@ -1,9 +1,7 @@
1
1
  'use client';
2
2
  /**
3
- * React context for providing entry data to the InsertEntryLink toolbar button.
4
- *
5
- * The MarkdownField is lazy-loaded and its toolbar components don't have direct
6
- * access to the editor's entry list. This context bridges that gap.
3
+ * Bridges entry data to MarkdownField's lazy-loaded toolbar components (e.g.
4
+ * InsertEntryLink), which have no direct access to the editor's entry list.
7
5
  */
8
6
  import { createContext, useContext } from 'react';
9
7
  export const EntryLinkContext = createContext({ entries: [] });
@@ -1,9 +1,6 @@
1
1
  /**
2
2
  * MDXEditor toolbar button for inserting entry links.
3
3
  *
4
- * Opens a modal with a searchable list of entries. When the user selects
5
- * an entry, inserts [Entry Title](entry:CONTENT_ID) into the editor.
6
- *
7
4
  * Must be rendered inside an MDXEditor toolbar (uses usePublisher from gurx).
8
5
  */
9
6
  import React from 'react';
@@ -3,9 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  /**
4
4
  * MDXEditor toolbar button for inserting entry links.
5
5
  *
6
- * Opens a modal with a searchable list of entries. When the user selects
7
- * an entry, inserts [Entry Title](entry:CONTENT_ID) into the editor.
8
- *
9
6
  * Must be rendered inside an MDXEditor toolbar (uses usePublisher from gurx).
10
7
  */
11
8
  import { useState, useMemo } from 'react';
@@ -27,7 +24,6 @@ export const InsertEntryLink = ({ onInsert }) => {
27
24
  e.slug?.toLowerCase().includes(lower) ||
28
25
  e.collectionName?.toLowerCase().includes(lower));
29
26
  }, [entries, search]);
30
- // Group entries by collection
31
27
  const grouped = useMemo(() => {
32
28
  const groups = new Map();
33
29
  for (const entry of filtered) {