betterstart-cli 0.0.100 → 0.0.101

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 (416) hide show
  1. package/dist/assets/adapters/next/integrations/_shared/actions/object-key.ts +1 -4
  2. package/dist/assets/adapters/next/integrations/_shared/actions/sanitize-filename.ts +3 -0
  3. package/dist/assets/adapters/next/integrations/r2/actions/get-client.ts +22 -0
  4. package/dist/assets/adapters/next/integrations/r2/actions/get-config.ts +9 -0
  5. package/dist/assets/adapters/next/integrations/r2/actions/{r2.ts → provider.ts} +3 -31
  6. package/dist/assets/adapters/next/integrations/r2/integration.ts +13 -1
  7. package/dist/assets/adapters/next/integrations/railway-bucket/actions/get-client.ts +20 -0
  8. package/dist/assets/adapters/next/integrations/railway-bucket/actions/get-config.ts +10 -0
  9. package/dist/assets/adapters/next/integrations/railway-bucket/actions/{railway-bucket.ts → provider.ts} +4 -34
  10. package/dist/assets/adapters/next/integrations/railway-bucket/actions/stable-read-url.ts +3 -0
  11. package/dist/assets/adapters/next/integrations/railway-bucket/integration.ts +17 -1
  12. package/dist/assets/adapters/next/integrations/resend/actions/escape-html.ts +8 -0
  13. package/dist/assets/adapters/next/integrations/resend/actions/get-env-value.ts +4 -0
  14. package/dist/assets/adapters/next/integrations/resend/actions/get-from-address.ts +5 -0
  15. package/dist/assets/adapters/next/integrations/resend/actions/get-resend-client.ts +19 -0
  16. package/dist/assets/adapters/next/integrations/resend/actions/html-to-text.ts +16 -0
  17. package/dist/assets/adapters/next/integrations/resend/actions/is-configured.ts +6 -0
  18. package/dist/assets/adapters/next/integrations/resend/actions/provider.ts +17 -0
  19. package/dist/assets/adapters/next/integrations/resend/actions/render-password-reset-email.ts +25 -0
  20. package/dist/assets/adapters/next/integrations/resend/actions/send-email.ts +43 -0
  21. package/dist/assets/adapters/next/integrations/resend/integration.ts +33 -1
  22. package/dist/assets/adapters/next/integrations/vercel-blob/actions/get-token.ts +3 -0
  23. package/dist/assets/adapters/next/integrations/vercel-blob/actions/{vercel-blob.ts → provider.ts} +1 -4
  24. package/dist/assets/adapters/next/integrations/vercel-blob/integration.ts +9 -1
  25. package/dist/assets/adapters/next/templates/init/api/storage-read-route.ts +2 -14
  26. package/dist/assets/adapters/next/templates/init/api/upload-route.ts +6 -5
  27. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-version-item.tsx +1 -1
  28. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-current-row.tsx +1 -1
  29. package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +3 -2
  30. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-blockquote.ts +6 -8
  31. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-code-block.ts +6 -8
  32. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-color-highlight.ts +6 -10
  33. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-media-insertion.ts +4 -6
  34. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-slash-menu.ts +4 -6
  35. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +22 -23
  36. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-table-add-controls.ts +8 -9
  37. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor.ts +16 -22
  38. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-heading.ts +6 -8
  39. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-link-popover.ts +3 -1
  40. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-list-dropdown-menu.ts +1 -1
  41. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-list.ts +6 -8
  42. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-mark.ts +2 -1
  43. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-table-button.ts +1 -1
  44. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-undo-redo.ts +1 -1
  45. package/dist/assets/adapters/next/templates/init/hooks/use-table-utils.ts +2 -1
  46. package/dist/assets/adapters/next/templates/init/hooks/use-upload.ts +3 -3
  47. package/dist/assets/adapters/next/templates/init/lib/actions/audit/clamp-page.ts +6 -0
  48. package/dist/assets/adapters/next/templates/init/lib/actions/audit/cleanup-audit-logs.ts +4 -9
  49. package/dist/assets/adapters/next/templates/init/lib/actions/audit/first-header-value.ts +3 -0
  50. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-log-order-by.ts +25 -0
  51. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-logs.ts +2 -109
  52. package/dist/assets/adapters/next/templates/init/lib/actions/audit/{request-metadata.ts → get-audit-request-metadata.ts} +3 -7
  53. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-retention-days.ts +5 -0
  54. package/dist/assets/adapters/next/templates/init/lib/actions/audit/max-ip-length.ts +1 -0
  55. package/dist/assets/adapters/next/templates/init/lib/actions/audit/max-user-agent-length.ts +1 -0
  56. package/dist/assets/adapters/next/templates/init/lib/actions/audit/normalize-changed-fields.ts +3 -0
  57. package/dist/assets/adapters/next/templates/init/lib/actions/audit/normalize-page-size.ts +12 -0
  58. package/dist/assets/adapters/next/templates/init/lib/actions/audit/query-audit-logs.ts +71 -0
  59. package/dist/assets/adapters/next/templates/init/lib/actions/audit/record-audit-event.ts +3 -6
  60. package/dist/assets/adapters/next/templates/init/lib/actions/auth/middleware.ts +2 -1
  61. package/dist/assets/adapters/next/templates/init/lib/actions/email/form-email-delivery-input.ts +1 -0
  62. package/dist/assets/adapters/next/templates/init/lib/actions/email/queued-form-email.ts +6 -0
  63. package/dist/assets/adapters/next/templates/init/lib/actions/email/{form-delivery.ts → send-form-emails.ts} +7 -34
  64. package/dist/assets/adapters/next/templates/init/lib/actions/email/send-queued-email.ts +19 -0
  65. package/dist/assets/adapters/next/templates/init/lib/actions/forms/upsert-form-settings.ts +1 -1
  66. package/dist/assets/adapters/next/templates/init/lib/actions/media/clamp-media-page-size.ts +9 -0
  67. package/dist/assets/adapters/next/templates/init/lib/actions/media/clamp-media-page.ts +9 -0
  68. package/dist/assets/adapters/next/templates/init/lib/actions/media/create-media.ts +3 -3
  69. package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media-bulk.ts +2 -2
  70. package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media.ts +2 -2
  71. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media-by-id.ts +2 -1
  72. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media-by-ids.ts +2 -1
  73. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media.ts +5 -21
  74. package/dist/assets/adapters/next/templates/init/lib/actions/media/update-media.ts +3 -3
  75. package/dist/assets/adapters/next/templates/init/lib/actions/profile/change-own-password.ts +2 -2
  76. package/dist/assets/adapters/next/templates/init/lib/actions/profile/update-email.ts +2 -2
  77. package/dist/assets/adapters/next/templates/init/lib/actions/storage/local.ts +1 -1
  78. package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-media-from-url.ts +4 -6
  79. package/dist/assets/adapters/next/templates/init/lib/actions/users/change-user-password.ts +2 -2
  80. package/dist/assets/adapters/next/templates/init/lib/actions/users/create-user.ts +3 -3
  81. package/dist/assets/adapters/next/templates/init/lib/actions/users/delete-user.ts +2 -2
  82. package/dist/assets/adapters/next/templates/init/lib/actions/users/get-cached-users.ts +40 -0
  83. package/dist/assets/adapters/next/templates/init/lib/actions/users/get-users.ts +2 -40
  84. package/dist/assets/adapters/next/templates/init/lib/actions/users/update-user-role.ts +2 -2
  85. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/create-webhook.ts +2 -2
  86. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/delete-webhook.ts +1 -1
  87. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/deliver-to-endpoint.ts +55 -0
  88. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/deliver-webhook-event.ts +19 -0
  89. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/emit-webhook-event.ts +22 -0
  90. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/entity-event-payload.ts +20 -0
  91. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-deliveries.ts +1 -1
  92. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-secret.ts +1 -1
  93. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-subscriptions.ts +2 -18
  94. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhooks.ts +1 -1
  95. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/prune-webhook-deliveries.ts +26 -0
  96. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/read-webhook-subscriptions.ts +18 -0
  97. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/record-webhook-delivery.ts +24 -0
  98. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/regenerate-webhook-secret.ts +2 -2
  99. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/{register.ts → register-webhook-hooks.ts} +2 -14
  100. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/send-test-webhook.ts +3 -2
  101. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/update-webhook.ts +1 -1
  102. package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/register.ts +1 -1
  103. package/dist/assets/adapters/next/templates/init/pages/account-shell-rsc.tsx +1 -1
  104. package/dist/assets/adapters/next/templates/init/pages/login-form.tsx +1 -1
  105. package/dist/assets/adapters/next/templates/init/pages/login-page-rsc.tsx +1 -1
  106. package/dist/assets/adapters/next/templates/init/pages/users/columns.tsx +1 -1
  107. package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +1 -1
  108. package/dist/assets/adapters/next/templates/init/utils/audit/get-changed-field-names.ts +18 -0
  109. package/dist/assets/adapters/next/templates/init/utils/audit/get-touched-field-names.ts +9 -0
  110. package/dist/assets/adapters/next/templates/init/utils/audit/normalize-comparable-value.ts +14 -0
  111. package/dist/assets/adapters/next/templates/init/utils/audit/should-track-field.ts +15 -0
  112. package/dist/assets/adapters/next/templates/init/utils/auth/can-access-admin.ts +7 -0
  113. package/dist/assets/adapters/next/templates/init/utils/auth/get-admin-post-login-path.ts +5 -0
  114. package/dist/assets/adapters/next/templates/init/utils/auth/has-required-role.ts +5 -0
  115. package/dist/assets/adapters/next/templates/init/utils/auth/is-user-role.ts +5 -0
  116. package/dist/assets/adapters/next/templates/init/utils/date/build-date-range.ts +14 -0
  117. package/dist/assets/adapters/next/templates/init/utils/date/date-range-end-time.ts +1 -0
  118. package/dist/assets/adapters/next/templates/init/utils/date/date-range-input-format.ts +1 -0
  119. package/dist/assets/adapters/next/templates/init/utils/date/date-range-start-time.ts +1 -0
  120. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-input-date.ts +6 -0
  121. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-param-date.ts +7 -0
  122. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-trigger-date.ts +5 -0
  123. package/dist/assets/adapters/next/templates/init/utils/date/get-date-range-trigger-label.ts +24 -0
  124. package/dist/assets/adapters/next/templates/init/utils/date/get-exclusive-date-upper-bound.ts +9 -0
  125. package/dist/assets/adapters/next/templates/init/utils/date/get-ordered-date-range.ts +12 -0
  126. package/dist/assets/adapters/next/templates/init/utils/date/normalize-date-range-time.ts +5 -0
  127. package/dist/assets/adapters/next/templates/init/utils/date/parse-date-input-value.ts +6 -0
  128. package/dist/assets/adapters/next/templates/init/utils/date/parse-editable-date-range-date.ts +17 -0
  129. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-cell-class.ts +1 -0
  130. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-cell.ts +36 -0
  131. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-wrapper-class.ts +1 -0
  132. package/dist/assets/adapters/next/templates/init/utils/editor/append-column-to-table.ts +13 -0
  133. package/dist/assets/adapters/next/templates/init/utils/editor/append-row-to-table.ts +13 -0
  134. package/dist/assets/adapters/next/templates/init/utils/editor/apply-cursor-change-if-available.ts +8 -0
  135. package/dist/assets/adapters/next/templates/init/utils/editor/apply-cursor-change.ts +10 -0
  136. package/dist/assets/adapters/next/templates/init/utils/editor/can-insert-content-editor-media-placeholder.ts +10 -0
  137. package/dist/assets/adapters/next/templates/init/utils/editor/checkbox-label-factory.ts +5 -0
  138. package/dist/assets/adapters/next/templates/init/utils/editor/clear-table-part-preview.ts +11 -0
  139. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-name-pattern.ts +3 -0
  140. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-option.ts +6 -0
  141. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-options.ts +68 -0
  142. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color.ts +3 -0
  143. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-colors.ts +12 -0
  144. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight.ts +33 -0
  145. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-inline-math-delimiter.ts +1 -0
  146. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-inline-math.ts +105 -0
  147. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-keyboard.ts +5 -0
  148. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-math-kind.ts +1 -0
  149. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-math-value.ts +9 -0
  150. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-media-placeholder-node.ts +1 -0
  151. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-media-shortcut-key.ts +1 -0
  152. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-mode.ts +1 -0
  153. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-raw-content-block.ts +95 -0
  154. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-selected-math.ts +12 -0
  155. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-selection-request.ts +4 -0
  156. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-subscript.ts +5 -0
  157. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-superscript.ts +5 -0
  158. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-table-alignment.ts +1 -0
  159. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-underline.ts +26 -0
  160. package/dist/assets/adapters/next/templates/init/utils/editor/create-content-editor-table-node.ts +27 -0
  161. package/dist/assets/adapters/next/templates/init/utils/editor/create-html-mark.ts +28 -0
  162. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-image-text.ts +5 -0
  163. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-plain-text-offset-map.ts +126 -0
  164. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-table-text.ts +15 -0
  165. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-text-from-url.ts +6 -0
  166. package/dist/assets/adapters/next/templates/init/utils/editor/default-content-editor-table-cols.ts +1 -0
  167. package/dist/assets/adapters/next/templates/init/utils/editor/default-content-editor-table-rows.ts +1 -0
  168. package/dist/assets/adapters/next/templates/init/utils/editor/doc-position-from-plain-text-offset.ts +27 -0
  169. package/dist/assets/adapters/next/templates/init/utils/editor/escape-html.ts +10 -0
  170. package/dist/assets/adapters/next/templates/init/utils/editor/find-highlight-span-range.ts +25 -0
  171. package/dist/assets/adapters/next/templates/init/utils/editor/find-inline-math-start.ts +12 -0
  172. package/dist/assets/adapters/next/templates/init/utils/editor/find-markdown-link-range.ts +40 -0
  173. package/dist/assets/adapters/next/templates/init/utils/editor/find-node-at-position.ts +15 -0
  174. package/dist/assets/adapters/next/templates/init/utils/editor/find-node-position.ts +48 -0
  175. package/dist/assets/adapters/next/templates/init/utils/editor/find-raw-content-start.ts +16 -0
  176. package/dist/assets/adapters/next/templates/init/utils/editor/find-unescaped-character.ts +13 -0
  177. package/dist/assets/adapters/next/templates/init/utils/editor/find-unescaped-sequence.ts +14 -0
  178. package/dist/assets/adapters/next/templates/init/utils/editor/focus-next-node.ts +28 -0
  179. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-blockquote-line.ts +5 -0
  180. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-heading-line.ts +7 -0
  181. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-list-line.ts +14 -0
  182. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown.ts +7 -0
  183. package/dist/assets/adapters/next/templates/init/utils/editor/format-shortcut-key.ts +10 -0
  184. package/dist/assets/adapters/next/templates/init/utils/editor/get-active-table-column-alignment.ts +31 -0
  185. package/dist/assets/adapters/next/templates/init/utils/editor/get-block-math-expression.ts +15 -0
  186. package/dist/assets/adapters/next/templates/init/utils/editor/get-closest-table-cell.ts +10 -0
  187. package/dist/assets/adapters/next/templates/init/utils/editor/get-content-editor-highlight-color-name.ts +42 -0
  188. package/dist/assets/adapters/next/templates/init/utils/editor/get-content-editor-highlight-color-value.ts +6 -0
  189. package/dist/assets/adapters/next/templates/init/utils/editor/get-editor-element.ts +7 -0
  190. package/dist/assets/adapters/next/templates/init/utils/editor/get-editor-scroll-element.ts +8 -0
  191. package/dist/assets/adapters/next/templates/init/utils/editor/get-event-table-cell.ts +7 -0
  192. package/dist/assets/adapters/next/templates/init/utils/editor/get-inline-math-delimiter.ts +7 -0
  193. package/dist/assets/adapters/next/templates/init/utils/editor/get-markdown-heading-fallback.ts +5 -0
  194. package/dist/assets/adapters/next/templates/init/utils/editor/get-markdown-list-fallback.ts +7 -0
  195. package/dist/assets/adapters/next/templates/init/utils/editor/get-media-label.ts +5 -0
  196. package/dist/assets/adapters/next/templates/init/utils/editor/get-number-attr.ts +3 -0
  197. package/dist/assets/adapters/next/templates/init/utils/editor/get-plain-text-offset-before-doc-position.ts +8 -0
  198. package/dist/assets/adapters/next/templates/init/utils/editor/get-plain-text-offset-before-markdown-offset.ts +11 -0
  199. package/dist/assets/adapters/next/templates/init/utils/editor/get-raw-content-kind.ts +7 -0
  200. package/dist/assets/adapters/next/templates/init/utils/editor/get-raw-content-token.ts +13 -0
  201. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-block-nodes.ts +23 -0
  202. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-content-editor-math.ts +43 -0
  203. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-nodes-of-type.ts +50 -0
  204. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-table-column-cell-positions.ts +21 -0
  205. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table-cell.ts +10 -0
  206. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table-element.ts +19 -0
  207. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table.ts +17 -0
  208. package/dist/assets/adapters/next/templates/init/utils/editor/get-slash-menu-state.ts +47 -0
  209. package/dist/assets/adapters/next/templates/init/utils/editor/get-string-attr.ts +5 -0
  210. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-element.ts +5 -0
  211. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-from-event-target.ts +19 -0
  212. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-from-wrapper.ts +15 -0
  213. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-position-for-element.ts +24 -0
  214. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-rect-at-position.ts +20 -0
  215. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-wrapper-element.ts +11 -0
  216. package/dist/assets/adapters/next/templates/init/utils/editor/{task-item.ts → get-task-item-checkbox-label.ts} +1 -7
  217. package/dist/assets/adapters/next/templates/init/utils/editor/has-own-attribute.ts +3 -0
  218. package/dist/assets/adapters/next/templates/init/utils/editor/highlight-span-pattern.ts +6 -0
  219. package/dist/assets/adapters/next/templates/init/utils/editor/inline-math-delimiter.ts +3 -0
  220. package/dist/assets/adapters/next/templates/init/utils/editor/inline-math-node-view.ts +51 -0
  221. package/dist/assets/adapters/next/templates/init/utils/editor/insert-component-at-cursor.ts +28 -0
  222. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-math.ts +35 -0
  223. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-media-placeholder.ts +20 -0
  224. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-table.ts +12 -0
  225. package/dist/assets/adapters/next/templates/init/utils/editor/insert-markdown-text-at-position.ts +14 -0
  226. package/dist/assets/adapters/next/templates/init/utils/editor/insert-result.ts +4 -0
  227. package/dist/assets/adapters/next/templates/init/utils/editor/insert-text-at-cursor.ts +37 -0
  228. package/dist/assets/adapters/next/templates/init/utils/editor/is-allowed-uri.ts +42 -0
  229. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-highlight-color.ts +6 -0
  230. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-media-placeholder-active.ts +8 -0
  231. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-table-alignment.ts +7 -0
  232. package/dist/assets/adapters/next/templates/init/utils/editor/is-element-visible-in-editor.ts +17 -0
  233. package/dist/assets/adapters/next/templates/init/utils/editor/is-escaped.ts +11 -0
  234. package/dist/assets/adapters/next/templates/init/utils/editor/is-extension-available.ts +22 -0
  235. package/dist/assets/adapters/next/templates/init/utils/editor/is-mac.ts +3 -0
  236. package/dist/assets/adapters/next/templates/init/utils/editor/is-mark-in-schema.ts +6 -0
  237. package/dist/assets/adapters/next/templates/init/utils/editor/is-markdown-line-start.ts +3 -0
  238. package/dist/assets/adapters/next/templates/init/utils/editor/is-node-in-schema.ts +6 -0
  239. package/dist/assets/adapters/next/templates/init/utils/editor/is-node-type-selected.ts +30 -0
  240. package/dist/assets/adapters/next/templates/init/utils/editor/is-same-slash-menu-state.ts +17 -0
  241. package/dist/assets/adapters/next/templates/init/utils/editor/is-selected-table-visible.ts +8 -0
  242. package/dist/assets/adapters/next/templates/init/utils/editor/is-task-item-checked.ts +5 -0
  243. package/dist/assets/adapters/next/templates/init/utils/editor/is-valid-dollar-inline-math.ts +13 -0
  244. package/dist/assets/adapters/next/templates/init/utils/editor/is-valid-position.ts +3 -0
  245. package/dist/assets/adapters/next/templates/init/utils/editor/is-word-character.ts +3 -0
  246. package/dist/assets/adapters/next/templates/init/utils/editor/mac-symbols.ts +15 -0
  247. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-level.ts +1 -0
  248. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-option.ts +6 -0
  249. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-options.ts +9 -0
  250. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-image-upload-result.ts +4 -0
  251. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-option.ts +6 -0
  252. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-options.ts +7 -0
  253. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-type.ts +1 -0
  254. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-offset-from-plain-text-offset.ts +8 -0
  255. package/dist/assets/adapters/next/templates/init/utils/editor/match-block-math.ts +54 -0
  256. package/dist/assets/adapters/next/templates/init/utils/editor/match-code-fence-start.ts +8 -0
  257. package/dist/assets/adapters/next/templates/init/utils/editor/match-html-block.ts +31 -0
  258. package/dist/assets/adapters/next/templates/init/utils/editor/match-html-mark-syntax.ts +16 -0
  259. package/dist/assets/adapters/next/templates/init/utils/editor/match-inline-math.ts +49 -0
  260. package/dist/assets/adapters/next/templates/init/utils/editor/match-markdown-block-prefix.ts +11 -0
  261. package/dist/assets/adapters/next/templates/init/utils/editor/match-markdown-mark-syntax.ts +27 -0
  262. package/dist/assets/adapters/next/templates/init/utils/editor/match-raw-content-block.ts +9 -0
  263. package/dist/assets/adapters/next/templates/init/utils/editor/mounted-editor-view.ts +3 -0
  264. package/dist/assets/adapters/next/templates/init/utils/editor/normalize-editor-markdown.ts +3 -0
  265. package/dist/assets/adapters/next/templates/init/utils/editor/parse-content-editor-math-input.ts +98 -0
  266. package/dist/assets/adapters/next/templates/init/utils/editor/parse-shortcut-keys.ts +17 -0
  267. package/dist/assets/adapters/next/templates/init/utils/editor/prepare-markdown-for-rich-mode.ts +3 -0
  268. package/dist/assets/adapters/next/templates/init/utils/editor/protocol-config.ts +7 -0
  269. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-block-node-view.ts +120 -0
  270. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-kind.ts +3 -0
  271. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-match.ts +8 -0
  272. package/dist/assets/adapters/next/templates/init/utils/editor/raw-html-block-tags.ts +14 -0
  273. package/dist/assets/adapters/next/templates/init/utils/editor/remove-highlight-span-at-cursor.ts +59 -0
  274. package/dist/assets/adapters/next/templates/init/utils/editor/remove-markdown-link-at-cursor.ts +43 -0
  275. package/dist/assets/adapters/next/templates/init/utils/editor/remove-selected-content-editor-math.ts +20 -0
  276. package/dist/assets/adapters/next/templates/init/utils/editor/render-details-preview.ts +22 -0
  277. package/dist/assets/adapters/next/templates/init/utils/editor/render-latex.ts +20 -0
  278. package/dist/assets/adapters/next/templates/init/utils/editor/render-raw-content-preview.ts +19 -0
  279. package/dist/assets/adapters/next/templates/init/utils/editor/render-simple-markdown-body.ts +46 -0
  280. package/dist/assets/adapters/next/templates/init/utils/editor/run-slash-command.ts +12 -0
  281. package/dist/assets/adapters/next/templates/init/utils/editor/runnable-slash-command.ts +5 -0
  282. package/dist/assets/adapters/next/templates/init/utils/editor/sanitize-html-preview.ts +41 -0
  283. package/dist/assets/adapters/next/templates/init/utils/editor/sanitize-url.ts +13 -0
  284. package/dist/assets/adapters/next/templates/init/utils/editor/select-current-block-content.ts +38 -0
  285. package/dist/assets/adapters/next/templates/init/utils/editor/selection-within-convertible-types.ts +29 -0
  286. package/dist/assets/adapters/next/templates/init/utils/editor/self-closing-html-block-tags.ts +3 -0
  287. package/dist/assets/adapters/next/templates/init/utils/editor/serialize-raw-content-preview.ts +12 -0
  288. package/dist/assets/adapters/next/templates/init/utils/editor/set-active-table-column-alignment.ts +39 -0
  289. package/dist/assets/adapters/next/templates/init/utils/editor/set-element-attribute.ts +13 -0
  290. package/dist/assets/adapters/next/templates/init/utils/editor/set-markdown-link-at-cursor.ts +50 -0
  291. package/dist/assets/adapters/next/templates/init/utils/editor/show-table-part-preview.ts +59 -0
  292. package/dist/assets/adapters/next/templates/init/utils/editor/slash-commands.ts +2 -1
  293. package/dist/assets/adapters/next/templates/init/utils/editor/slash-menu-state.ts +6 -0
  294. package/dist/assets/adapters/next/templates/init/utils/editor/sr-only.ts +11 -0
  295. package/dist/assets/adapters/next/templates/init/utils/editor/strip-html.ts +5 -0
  296. package/dist/assets/adapters/next/templates/init/utils/editor/strip-markdown-block-prefix.ts +6 -0
  297. package/dist/assets/adapters/next/templates/init/utils/editor/table-add-controls-state.ts +4 -0
  298. package/dist/assets/adapters/next/templates/init/utils/editor/table-part-preview-class.ts +1 -0
  299. package/dist/assets/adapters/next/templates/init/utils/editor/table-part.ts +1 -0
  300. package/dist/assets/adapters/next/templates/init/utils/editor/table-wrapper-class.ts +1 -0
  301. package/dist/assets/adapters/next/templates/init/utils/editor/transform-selected-markdown-lines.ts +38 -0
  302. package/dist/assets/adapters/next/templates/init/utils/editor/update-nodes-attr.ts +36 -0
  303. package/dist/assets/adapters/next/templates/init/utils/editor/update-selected-content-editor-math.ts +36 -0
  304. package/dist/assets/adapters/next/templates/init/utils/email/escape-html.ts +8 -0
  305. package/dist/assets/adapters/next/templates/init/utils/email/form-email-delivery-input.ts +8 -0
  306. package/dist/assets/adapters/next/templates/init/utils/email/format-email-value.ts +19 -0
  307. package/dist/assets/adapters/next/templates/init/utils/email/is-valid-email.ts +3 -0
  308. package/dist/assets/adapters/next/templates/init/utils/email/normalize-email-list.ts +5 -0
  309. package/dist/assets/adapters/next/templates/init/utils/email/render-form-submission-rows.ts +16 -0
  310. package/dist/assets/adapters/next/templates/init/utils/email/render-notification-email.ts +32 -0
  311. package/dist/assets/adapters/next/templates/init/utils/email/render-thank-you-email.ts +18 -0
  312. package/dist/assets/adapters/next/templates/init/utils/error/read-string-property.ts +5 -0
  313. package/dist/assets/adapters/next/templates/init/utils/error/{action-error.ts → recognize.ts} +3 -12
  314. package/dist/assets/adapters/next/templates/init/utils/error/to-action-error.ts +6 -0
  315. package/dist/assets/adapters/next/templates/init/utils/form/{list-field.ts → clone-default-value.ts} +0 -5
  316. package/dist/assets/adapters/next/templates/init/utils/form/create-list-item-key.ts +4 -0
  317. package/dist/assets/adapters/next/templates/init/utils/media/admin-media-type.ts +1 -0
  318. package/dist/assets/adapters/next/templates/init/utils/media/{fallback.ts → create-admin-media-from-url.ts} +1 -14
  319. package/dist/assets/adapters/next/templates/init/utils/media/create-preview-url.ts +3 -0
  320. package/dist/assets/adapters/next/templates/init/utils/media/get-filename-from-url.ts +9 -0
  321. package/dist/assets/adapters/next/templates/init/utils/media/get-media-type.ts +19 -0
  322. package/dist/assets/adapters/next/templates/init/utils/media/get-media-url-help-text.ts +10 -0
  323. package/dist/assets/adapters/next/templates/init/utils/media/get-media-url-placeholder.ts +7 -0
  324. package/dist/assets/adapters/next/templates/init/utils/media/image-extensions.ts +1 -0
  325. package/dist/assets/adapters/next/templates/init/utils/media/image-mime-types.ts +7 -0
  326. package/dist/assets/adapters/next/templates/init/utils/media/infer-media-content-type.ts +13 -0
  327. package/dist/assets/adapters/next/templates/init/utils/media/is-document-only-accept.ts +19 -0
  328. package/dist/assets/adapters/next/templates/init/utils/media/{query.ts → map-media-row.ts} +0 -39
  329. package/dist/assets/adapters/next/templates/init/utils/media/media-mime-types.ts +4 -0
  330. package/dist/assets/adapters/next/templates/init/utils/media/revoke-preview-url.ts +3 -0
  331. package/dist/assets/adapters/next/templates/init/utils/media/select-media.ts +39 -0
  332. package/dist/assets/adapters/next/templates/init/utils/media/video-extensions.ts +1 -0
  333. package/dist/assets/adapters/next/templates/init/utils/media/video-mime-types.ts +7 -0
  334. package/dist/assets/adapters/next/templates/init/utils/seo/{seo.ts → create-metadata.ts} +0 -36
  335. package/dist/assets/adapters/next/templates/init/utils/seo/generate-article-schema.ts +31 -0
  336. package/dist/assets/adapters/next/templates/init/utils/seo/schema-to-json.ts +3 -0
  337. package/dist/assets/adapters/next/templates/init/utils/storage/{local.ts → build-local-storage-key.ts} +1 -4
  338. package/dist/assets/adapters/next/templates/init/utils/storage/decode-storage-key.ts +9 -0
  339. package/dist/assets/adapters/next/templates/init/utils/storage/sanitize-filename.ts +3 -0
  340. package/dist/assets/adapters/next/templates/init/utils/storage/storage-error.ts +5 -0
  341. package/dist/assets/adapters/next/templates/init/utils/table/{table.ts → default-get-id.ts} +0 -4
  342. package/dist/assets/adapters/next/templates/init/utils/table/is-string.ts +3 -0
  343. package/dist/assets/adapters/next/templates/init/utils/upload/default-remote-accept.ts +1 -0
  344. package/dist/assets/adapters/next/templates/init/utils/upload/dropzone-accept.ts +1 -0
  345. package/dist/assets/adapters/next/templates/init/utils/upload/get-fallback-extension.ts +12 -0
  346. package/dist/assets/adapters/next/templates/init/utils/upload/get-remote-filename.ts +15 -0
  347. package/dist/assets/adapters/next/templates/init/utils/upload/is-accepted-remote-type.ts +25 -0
  348. package/dist/assets/adapters/next/templates/init/utils/upload/is-wildcard-accept.ts +4 -0
  349. package/dist/assets/adapters/next/templates/init/utils/upload/parse-accept-types.ts +7 -0
  350. package/dist/assets/adapters/next/templates/init/utils/upload/parse-dropzone-accept.ts +14 -0
  351. package/dist/assets/adapters/next/templates/init/utils/upload/remote-fetch-timeout-ms.ts +1 -0
  352. package/dist/assets/adapters/next/templates/init/utils/user/compare-user-sort-values.ts +4 -0
  353. package/dist/assets/adapters/next/templates/init/utils/user/get-user-initials.ts +11 -0
  354. package/dist/assets/adapters/next/templates/init/utils/user/get-user-sort-value.ts +8 -0
  355. package/dist/assets/adapters/next/templates/init/utils/user/{user.ts → get-users-page.ts} +3 -28
  356. package/dist/assets/adapters/next/templates/init/utils/user/normalize-user-filter-value.ts +3 -0
  357. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-config.ts +5 -0
  358. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-error.ts +4 -0
  359. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-result.ts +6 -0
  360. package/dist/assets/adapters/next/templates/init/utils/validation/format-file-size.ts +18 -0
  361. package/dist/assets/adapters/next/templates/init/utils/validation/is-file-type-allowed.ts +13 -0
  362. package/dist/assets/adapters/next/templates/init/utils/validation/is-valid-url.ts +8 -0
  363. package/dist/assets/adapters/next/templates/init/utils/validation/slugify.ts +9 -0
  364. package/dist/assets/adapters/next/templates/init/utils/validation/validate-files.ts +39 -0
  365. package/dist/assets/adapters/next/templates/init/utils/webhook/create-webhook-event-id.ts +5 -0
  366. package/dist/assets/adapters/next/templates/init/utils/webhook/generate-webhook-secret.ts +5 -0
  367. package/dist/assets/adapters/next/templates/init/utils/webhook/sign-webhook-payload.ts +5 -0
  368. package/dist/assets/shared-assets/react-admin/custom/content-editor/index.tsx +1 -1
  369. package/dist/assets/shared-assets/react-admin/custom/content-editor/math-bubble-menu.tsx +3 -5
  370. package/dist/assets/shared-assets/react-admin/custom/content-editor/math-popover-button.tsx +1 -1
  371. package/dist/assets/shared-assets/react-admin/custom/content-editor/mobile-toolbar-content.tsx +1 -1
  372. package/dist/assets/shared-assets/react-admin/custom/content-editor/slash-command-menu.tsx +1 -1
  373. package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +6 -4
  374. package/dist/assets/shared-assets/react-admin/custom/content-editor/table-bubble-menu.tsx +11 -15
  375. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-extension/node-background-extension.ts +2 -1
  376. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/media-gallery-placeholder-node/media-gallery-placeholder-node.tsx +3 -2
  377. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/removable-image-node/removable-image-node.tsx +5 -3
  378. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/task-item-node/task-item-node-extension.tsx +4 -2
  379. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/blockquote-button/blockquote-button.tsx +1 -1
  380. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/code-block-button/code-block-button.tsx +1 -1
  381. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-button/color-highlight-button.tsx +1 -1
  382. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/mark-button/mark-button.tsx +1 -1
  383. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/undo-redo-button/undo-redo-button.tsx +1 -1
  384. package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +10 -12
  385. package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +1 -1
  386. package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +2 -1
  387. package/dist/assets/shared-assets/react-admin/custom/upload-dropzone.tsx +1 -1
  388. package/dist/{chunk-45Z6XDG5.js → chunk-TIJEHWRF.js} +150 -165
  389. package/dist/chunk-TIJEHWRF.js.map +1 -0
  390. package/dist/cli.js +27625 -24121
  391. package/dist/cli.js.map +1 -1
  392. package/dist/read-namespaced-template-UXU7OCY3.js +13 -0
  393. package/dist/read-namespaced-template-UXU7OCY3.js.map +1 -0
  394. package/package.json +1 -1
  395. package/dist/assets/adapters/next/integrations/resend/actions/resend.ts +0 -138
  396. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/dispatch.ts +0 -134
  397. package/dist/assets/adapters/next/templates/init/utils/audit/audit.ts +0 -54
  398. package/dist/assets/adapters/next/templates/init/utils/auth/roles.ts +0 -17
  399. package/dist/assets/adapters/next/templates/init/utils/date/date.ts +0 -100
  400. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-rich-extensions.ts +0 -824
  401. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor.ts +0 -389
  402. package/dist/assets/adapters/next/templates/init/utils/editor/markdown.ts +0 -545
  403. package/dist/assets/adapters/next/templates/init/utils/editor/node-attrs.ts +0 -25
  404. package/dist/assets/adapters/next/templates/init/utils/editor/source-media.ts +0 -11
  405. package/dist/assets/adapters/next/templates/init/utils/editor/table-add-controls.ts +0 -91
  406. package/dist/assets/adapters/next/templates/init/utils/editor/table-bubble.ts +0 -172
  407. package/dist/assets/adapters/next/templates/init/utils/editor/tiptap.ts +0 -847
  408. package/dist/assets/adapters/next/templates/init/utils/email/form-delivery.ts +0 -104
  409. package/dist/assets/adapters/next/templates/init/utils/media/media.ts +0 -91
  410. package/dist/assets/adapters/next/templates/init/utils/upload/remote.ts +0 -55
  411. package/dist/assets/adapters/next/templates/init/utils/upload/upload.ts +0 -26
  412. package/dist/assets/adapters/next/templates/init/utils/validation/validation.ts +0 -102
  413. package/dist/assets/adapters/next/templates/init/utils/webhook/signature.ts +0 -13
  414. package/dist/chunk-45Z6XDG5.js.map +0 -1
  415. package/dist/template-reader-J6G7N5V6.js +0 -13
  416. package/dist/template-reader-J6G7N5V6.js.map +0 -1
@@ -1,847 +0,0 @@
1
- import type { ContentEditorInlineMathDelimiter, ContentEditorMathKind } from './markdown'
2
- import type { JSONContent } from '@tiptap/core'
3
- import type { Node as PMNode } from '@tiptap/pm/model'
4
- import type { Transaction } from '@tiptap/pm/state'
5
- import type { TableRect } from '@tiptap/pm/tables'
6
- import type { Editor, NodeWithPos } from '@tiptap/react'
7
- import { AllSelection, NodeSelection, Selection, TextSelection } from '@tiptap/pm/state'
8
- import {
9
- addColumn,
10
- addRow,
11
- CellSelection,
12
- cellAround,
13
- selectedRect,
14
- TableMap
15
- } from '@tiptap/pm/tables'
16
- import { findParentNodeClosestToPos } from '@tiptap/react'
17
- import { parseContentEditorMathInput } from './markdown'
18
-
19
- export { cn } from '@admin/utils/shared/cn'
20
-
21
- export const MAC_SYMBOLS: Record<string, string> = {
22
- mod: '⌘',
23
- command: '⌘',
24
- meta: '⌘',
25
- ctrl: '⌃',
26
- control: '⌃',
27
- alt: '⌥',
28
- option: '⌥',
29
- shift: '⇧',
30
- backspace: 'Del',
31
- delete: '⌦',
32
- enter: '⏎',
33
- escape: '⎋',
34
- capslock: '⇪'
35
- } as const
36
-
37
- export const SR_ONLY = {
38
- position: 'absolute',
39
- width: '1px',
40
- height: '1px',
41
- padding: 0,
42
- margin: '-1px',
43
- overflow: 'hidden',
44
- clip: 'rect(0, 0, 0, 0)',
45
- whiteSpace: 'nowrap',
46
- borderWidth: 0
47
- } as const
48
-
49
- export interface SlashMenuState {
50
- from: number
51
- to: number
52
- query: string
53
- rect: DOMRect
54
- }
55
-
56
- export interface RunnableSlashCommand {
57
- run: (editor: Editor) => boolean
58
- }
59
-
60
- export type ContentEditorTableAlignment = 'left' | 'center' | 'right'
61
-
62
- export interface ContentEditorSelectedMath {
63
- delimiter?: ContentEditorInlineMathDelimiter
64
- kind: ContentEditorMathKind
65
- node: PMNode
66
- pos: number
67
- raw: string
68
- value: string
69
- }
70
-
71
- const SLASH_QUERY_LIMIT = 48
72
- const DEFAULT_CONTENT_EDITOR_TABLE_ROWS = 3
73
- const DEFAULT_CONTENT_EDITOR_TABLE_COLS = 3
74
- const CONTENT_EDITOR_MEDIA_PLACEHOLDER_NODE = 'mediaGalleryPlaceholder'
75
-
76
- export const CONTENT_EDITOR_MEDIA_SHORTCUT_KEY = 'mod+shift+i'
77
-
78
- export function getSlashMenuState(editor: Editor): SlashMenuState | null {
79
- const { selection } = editor.state
80
-
81
- if (!selection.empty || !editor.isEditable) return null
82
-
83
- const { $from } = selection
84
- const parent = $from.parent
85
-
86
- if (!parent.isTextblock || parent.type.name === 'codeBlock') return null
87
-
88
- const textBeforeCursor = parent.textBetween(0, $from.parentOffset, '\n', '\ufffc')
89
- const slashIndex = textBeforeCursor.lastIndexOf('/')
90
-
91
- if (slashIndex === -1) return null
92
- if (slashIndex > 0 && !/\s/.test(textBeforeCursor[slashIndex - 1])) {
93
- return null
94
- }
95
-
96
- const query = textBeforeCursor.slice(slashIndex + 1)
97
-
98
- if (query.includes('/') || query.length > SLASH_QUERY_LIMIT) return null
99
-
100
- const from = $from.start() + slashIndex
101
- const to = selection.from
102
-
103
- try {
104
- const coords = editor.view.coordsAtPos(from)
105
- return {
106
- from,
107
- to,
108
- query,
109
- rect: new DOMRect(
110
- coords.left,
111
- coords.top,
112
- Math.max(1, coords.right - coords.left),
113
- Math.max(1, coords.bottom - coords.top)
114
- )
115
- }
116
- } catch {
117
- return null
118
- }
119
- }
120
-
121
- export function isSameSlashMenuState(
122
- current: SlashMenuState | null,
123
- next: SlashMenuState | null
124
- ): boolean {
125
- if (current === next) return true
126
- if (!current || !next) return false
127
-
128
- return (
129
- current.from === next.from &&
130
- current.to === next.to &&
131
- current.query === next.query &&
132
- current.rect.x === next.rect.x &&
133
- current.rect.y === next.rect.y
134
- )
135
- }
136
-
137
- export function runSlashCommand(
138
- editor: Editor,
139
- command: RunnableSlashCommand,
140
- slashMenu: SlashMenuState
141
- ): boolean {
142
- editor.chain().focus().deleteRange({ from: slashMenu.from, to: slashMenu.to }).run()
143
- return command.run(editor)
144
- }
145
-
146
- function isContentEditorTableAlignment(value: unknown): value is ContentEditorTableAlignment {
147
- return value === 'left' || value === 'center' || value === 'right'
148
- }
149
-
150
- function getTableRectAtPosition(editor: Editor, tablePos: number): TableRect | null {
151
- const table = editor.state.doc.nodeAt(tablePos)
152
- if (!table || table.type.name !== 'table') return null
153
-
154
- const map = TableMap.get(table)
155
-
156
- return {
157
- bottom: map.height,
158
- left: 0,
159
- map,
160
- right: map.width,
161
- table,
162
- tableStart: tablePos + 1,
163
- top: 0
164
- }
165
- }
166
-
167
- export function createContentEditorTableNode(
168
- rows: number = DEFAULT_CONTENT_EDITOR_TABLE_ROWS,
169
- cols: number = DEFAULT_CONTENT_EDITOR_TABLE_COLS
170
- ): JSONContent {
171
- const rowCount = Math.max(2, Math.floor(rows))
172
- const colCount = Math.max(1, Math.floor(cols))
173
-
174
- return {
175
- type: 'table',
176
- content: Array.from({ length: rowCount }, (_, rowIndex) => ({
177
- type: 'tableRow',
178
- content: Array.from({ length: colCount }, (_, colIndex) => ({
179
- type: rowIndex === 0 ? 'tableHeader' : 'tableCell',
180
- content: [
181
- {
182
- type: 'paragraph',
183
- content: rowIndex === 0 ? [{ type: 'text', text: `Header ${colIndex + 1}` }] : []
184
- }
185
- ]
186
- }))
187
- }))
188
- }
189
- }
190
-
191
- export function insertContentEditorTable(
192
- editor: Editor,
193
- rows: number = DEFAULT_CONTENT_EDITOR_TABLE_ROWS,
194
- cols: number = DEFAULT_CONTENT_EDITOR_TABLE_COLS
195
- ): boolean {
196
- return editor.chain().focus().insertContent(createContentEditorTableNode(rows, cols)).run()
197
- }
198
-
199
- export function canInsertContentEditorMediaPlaceholder(editor: Editor | null): boolean {
200
- if (!editor?.isEditable) return false
201
- if (!isExtensionAvailable(editor, CONTENT_EDITOR_MEDIA_PLACEHOLDER_NODE)) return false
202
-
203
- return editor.can().insertContent({ type: CONTENT_EDITOR_MEDIA_PLACEHOLDER_NODE })
204
- }
205
-
206
- export function isContentEditorMediaPlaceholderActive(editor: Editor | null): boolean {
207
- if (!editor?.isEditable) return false
208
-
209
- return editor.isActive(CONTENT_EDITOR_MEDIA_PLACEHOLDER_NODE)
210
- }
211
-
212
- export function insertContentEditorMediaPlaceholder(editor: Editor | null): boolean {
213
- if (!editor) return false
214
- if (!canInsertContentEditorMediaPlaceholder(editor)) return false
215
-
216
- try {
217
- return editor
218
- .chain()
219
- .focus()
220
- .insertContent({
221
- type: CONTENT_EDITOR_MEDIA_PLACEHOLDER_NODE
222
- })
223
- .run()
224
- } catch {
225
- return false
226
- }
227
- }
228
-
229
- export function getSelectedContentEditorMath(
230
- editor: Editor | null
231
- ): ContentEditorSelectedMath | null {
232
- if (!editor) return null
233
-
234
- const { selection } = editor.state
235
- if (!(selection instanceof NodeSelection)) return null
236
-
237
- const node = selection.node
238
- const pos = selection.from
239
-
240
- if (node.type.name === 'inlineMath') {
241
- const raw = typeof node.attrs.raw === 'string' ? node.attrs.raw : ''
242
- const delimiter = node.attrs.delimiter === '\\(' ? '\\(' : '$'
243
-
244
- return {
245
- delimiter,
246
- kind: 'inline',
247
- node,
248
- pos,
249
- raw,
250
- value: raw
251
- }
252
- }
253
-
254
- if (node.type.name === 'rawContentBlock' && node.attrs.kind === 'math') {
255
- const raw = typeof node.attrs.raw === 'string' ? node.attrs.raw : ''
256
-
257
- return {
258
- kind: 'display',
259
- node,
260
- pos,
261
- raw,
262
- value: raw
263
- }
264
- }
265
-
266
- return null
267
- }
268
-
269
- export function insertContentEditorMath(editor: Editor | null, input: string): boolean {
270
- if (!editor?.isEditable) return false
271
-
272
- const math = parseContentEditorMathInput(input)
273
- if (!math) return false
274
-
275
- if (math.kind === 'display') {
276
- return editor
277
- .chain()
278
- .focus()
279
- .insertContent({
280
- type: 'rawContentBlock',
281
- attrs: {
282
- kind: 'math',
283
- raw: math.markdown
284
- }
285
- })
286
- .run()
287
- }
288
-
289
- return editor
290
- .chain()
291
- .focus()
292
- .insertContent({
293
- type: 'inlineMath',
294
- attrs: {
295
- delimiter: math.delimiter ?? '$',
296
- raw: math.raw
297
- }
298
- })
299
- .run()
300
- }
301
-
302
- export function updateSelectedContentEditorMath(
303
- editor: Editor | null,
304
- input: string,
305
- selectedMathOverride?: ContentEditorSelectedMath | null
306
- ): boolean {
307
- const selectedMath = selectedMathOverride ?? getSelectedContentEditorMath(editor)
308
- if (!editor?.isEditable || !selectedMath) return false
309
-
310
- const math = parseContentEditorMathInput(input, selectedMath.kind)
311
- if (!math) return false
312
-
313
- const attrs =
314
- selectedMath.kind === 'display'
315
- ? {
316
- ...selectedMath.node.attrs,
317
- kind: 'math',
318
- raw: math.markdown
319
- }
320
- : {
321
- ...selectedMath.node.attrs,
322
- delimiter: math.delimiter ?? selectedMath.delimiter ?? '$',
323
- raw: math.raw
324
- }
325
-
326
- const tr = editor.state.tr.setNodeMarkup(selectedMath.pos, undefined, attrs)
327
- tr.setSelection(NodeSelection.create(tr.doc, selectedMath.pos))
328
- editor.view.dispatch(tr.scrollIntoView())
329
- editor.commands.focus()
330
- return true
331
- }
332
-
333
- export function removeSelectedContentEditorMath(
334
- editor: Editor | null,
335
- selectedMathOverride?: ContentEditorSelectedMath | null
336
- ): boolean {
337
- const selectedMath = selectedMathOverride ?? getSelectedContentEditorMath(editor)
338
- if (!editor?.isEditable || !selectedMath) return false
339
-
340
- return editor
341
- .chain()
342
- .focus()
343
- .deleteRange({
344
- from: selectedMath.pos,
345
- to: selectedMath.pos + selectedMath.node.nodeSize
346
- })
347
- .run()
348
- }
349
-
350
- export function appendColumnToTable(editor: Editor, tablePos: number): boolean {
351
- const rect = getTableRectAtPosition(editor, tablePos)
352
- if (!rect) return false
353
-
354
- const tr = addColumn(editor.state.tr, rect, rect.map.width).scrollIntoView()
355
- editor.view.dispatch(tr)
356
- editor.commands.focus()
357
- return true
358
- }
359
-
360
- export function appendRowToTable(editor: Editor, tablePos: number): boolean {
361
- const rect = getTableRectAtPosition(editor, tablePos)
362
- if (!rect) return false
363
-
364
- const tr = addRow(editor.state.tr, rect, rect.map.height).scrollIntoView()
365
- editor.view.dispatch(tr)
366
- editor.commands.focus()
367
- return true
368
- }
369
-
370
- function getSelectedTableColumnCellPositions(editor: Editor): number[] {
371
- if (!editor.isActive('table')) return []
372
-
373
- try {
374
- const rect = selectedRect(editor.state)
375
- const columnIndex = rect.left
376
- const cellPositions = rect.map.cellsInRect({
377
- bottom: rect.map.height,
378
- left: columnIndex,
379
- right: columnIndex + 1,
380
- top: 0
381
- })
382
-
383
- return [...new Set(cellPositions)].map((pos) => rect.tableStart + pos)
384
- } catch {
385
- return []
386
- }
387
- }
388
-
389
- export function getActiveTableColumnAlignment(
390
- editor: Editor | null
391
- ): ContentEditorTableAlignment | null {
392
- if (!editor) return null
393
-
394
- const positions = getSelectedTableColumnCellPositions(editor)
395
- if (!positions.length) return null
396
-
397
- let alignment: ContentEditorTableAlignment | null = null
398
-
399
- for (const position of positions) {
400
- const node = editor.state.doc.nodeAt(position)
401
- const nodeAlignment = isContentEditorTableAlignment(node?.attrs.align)
402
- ? node.attrs.align
403
- : 'left'
404
-
405
- if (alignment === null) {
406
- alignment = nodeAlignment
407
- continue
408
- }
409
-
410
- if (alignment !== nodeAlignment) return null
411
- }
412
-
413
- return alignment
414
- }
415
-
416
- export function setActiveTableColumnAlignment(
417
- editor: Editor,
418
- alignment: ContentEditorTableAlignment
419
- ): boolean {
420
- const positions = getSelectedTableColumnCellPositions(editor)
421
- if (!positions.length) return false
422
-
423
- const tr = editor.state.tr
424
- let changed = false
425
-
426
- for (const position of positions) {
427
- const node = tr.doc.nodeAt(position)
428
- if (!node) continue
429
- if (node.type.name !== 'tableCell' && node.type.name !== 'tableHeader') {
430
- continue
431
- }
432
-
433
- if (node.attrs.align === alignment) continue
434
-
435
- tr.setNodeMarkup(position, undefined, {
436
- ...node.attrs,
437
- align: alignment
438
- })
439
- changed = true
440
- }
441
-
442
- if (!changed) {
443
- editor.commands.focus()
444
- return true
445
- }
446
-
447
- editor.view.dispatch(tr.scrollIntoView())
448
- editor.commands.focus()
449
- return true
450
- }
451
-
452
- export function isMac(): boolean {
453
- return typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('mac')
454
- }
455
-
456
- export const formatShortcutKey = (key: string, isMac: boolean, capitalize: boolean = true) => {
457
- if (isMac) {
458
- const lowerKey = key.toLowerCase()
459
- return MAC_SYMBOLS[lowerKey] || (capitalize ? key.toUpperCase() : key)
460
- }
461
-
462
- return capitalize ? key.charAt(0).toUpperCase() + key.slice(1) : key
463
- }
464
-
465
- export const parseShortcutKeys = (props: {
466
- shortcutKeys: string | undefined
467
- delimiter?: string
468
- capitalize?: boolean
469
- }) => {
470
- const { shortcutKeys, delimiter = '+', capitalize = true } = props
471
-
472
- if (!shortcutKeys) return []
473
-
474
- return shortcutKeys
475
- .split(delimiter)
476
- .map((key) => key.trim())
477
- .map((key) => formatShortcutKey(key, isMac(), capitalize))
478
- }
479
-
480
- export const isMarkInSchema = (markName: string, editor: Editor | null): boolean => {
481
- if (!editor?.schema) return false
482
- return editor.schema.spec.marks.get(markName) !== undefined
483
- }
484
-
485
- export const isNodeInSchema = (nodeName: string, editor: Editor | null): boolean => {
486
- if (!editor?.schema) return false
487
- return editor.schema.spec.nodes.get(nodeName) !== undefined
488
- }
489
-
490
- export function focusNextNode(editor: Editor) {
491
- const { state, view } = editor
492
- const { doc, selection } = state
493
-
494
- const nextSel = Selection.findFrom(selection.$to, 1, true)
495
- if (nextSel) {
496
- view.dispatch(state.tr.setSelection(nextSel).scrollIntoView())
497
- return true
498
- }
499
-
500
- const paragraphType = state.schema.nodes.paragraph
501
- if (!paragraphType) {
502
- console.warn('No paragraph node type found in schema.')
503
- return false
504
- }
505
-
506
- const end = doc.content.size
507
- const para = paragraphType.create()
508
- let tr = state.tr.insert(end, para)
509
-
510
- const $inside = tr.doc.resolve(end + 1)
511
- tr = tr.setSelection(TextSelection.near($inside)).scrollIntoView()
512
- view.dispatch(tr)
513
- return true
514
- }
515
-
516
- export function isValidPosition(pos: number | null | undefined): pos is number {
517
- return typeof pos === 'number' && pos >= 0
518
- }
519
-
520
- export function isExtensionAvailable(
521
- editor: Editor | null,
522
- extensionNames: string | string[]
523
- ): boolean {
524
- if (!editor) return false
525
-
526
- const names = Array.isArray(extensionNames) ? extensionNames : [extensionNames]
527
-
528
- const found = names.some((name) =>
529
- editor.extensionManager.extensions.some((ext) => ext.name === name)
530
- )
531
-
532
- if (!found) {
533
- console.warn(
534
- `None of the extensions [${names.join(', ')}] were found in the editor schema. Ensure they are included in the editor configuration.`
535
- )
536
- }
537
-
538
- return found
539
- }
540
-
541
- export function findNodeAtPosition(editor: Editor, position: number) {
542
- try {
543
- const node = editor.state.doc.nodeAt(position)
544
- if (!node) {
545
- console.warn(`No node found at position ${position}`)
546
- return null
547
- }
548
- return node
549
- } catch (error) {
550
- console.error(`Error getting node at position ${position}:`, error)
551
- return null
552
- }
553
- }
554
-
555
- export function findNodePosition(props: {
556
- editor: Editor | null
557
- node?: PMNode | null
558
- nodePos?: number | null
559
- }): { pos: number; node: PMNode } | null {
560
- const { editor, node, nodePos } = props
561
-
562
- if (!editor || !editor.state?.doc) return null
563
-
564
- const hasValidNode = node !== undefined && node !== null
565
- const hasValidPos = isValidPosition(nodePos)
566
-
567
- if (!hasValidNode && !hasValidPos) {
568
- return null
569
- }
570
-
571
- if (hasValidNode) {
572
- let foundPos = -1
573
- let foundNode: PMNode | null = null
574
-
575
- editor.state.doc.descendants((currentNode, pos) => {
576
- if (currentNode === node) {
577
- foundPos = pos
578
- foundNode = currentNode
579
- return false
580
- }
581
- return true
582
- })
583
-
584
- if (foundPos !== -1 && foundNode !== null) {
585
- return { pos: foundPos, node: foundNode }
586
- }
587
- }
588
-
589
- if (isValidPosition(nodePos)) {
590
- const nodeAtPos = findNodeAtPosition(editor, nodePos)
591
- if (nodeAtPos) {
592
- return { pos: nodePos, node: nodeAtPos }
593
- }
594
- }
595
-
596
- return null
597
- }
598
-
599
- export function isNodeTypeSelected(
600
- editor: Editor | null,
601
- nodeTypeNames: string[] = [],
602
- checkAncestorNodes: boolean = false
603
- ): boolean {
604
- if (!editor || !editor.state.selection) return false
605
-
606
- const { selection } = editor.state
607
- if (selection.empty) return false
608
-
609
- if (selection instanceof NodeSelection) {
610
- const selectedNode = selection.node
611
- return selectedNode ? nodeTypeNames.includes(selectedNode.type.name) : false
612
- }
613
-
614
- if (checkAncestorNodes) {
615
- const { $from } = selection
616
- for (let depth = $from.depth; depth > 0; depth--) {
617
- const ancestorNode = $from.node(depth)
618
- if (nodeTypeNames.includes(ancestorNode.type.name)) {
619
- return true
620
- }
621
- }
622
- }
623
-
624
- return false
625
- }
626
-
627
- export function selectionWithinConvertibleTypes(editor: Editor, types: string[] = []): boolean {
628
- if (!editor || types.length === 0) return false
629
-
630
- const { state } = editor
631
- const { selection } = state
632
- const allowed = new Set(types)
633
-
634
- if (selection instanceof NodeSelection) {
635
- const nodeType = selection.node?.type?.name
636
- return !!nodeType && allowed.has(nodeType)
637
- }
638
-
639
- if (selection instanceof TextSelection || selection instanceof AllSelection) {
640
- let valid = true
641
- state.doc.nodesBetween(selection.from, selection.to, (node) => {
642
- if (node.isTextblock && !allowed.has(node.type.name)) {
643
- valid = false
644
- return false
645
- }
646
- return valid
647
- })
648
- return valid
649
- }
650
-
651
- return false
652
- }
653
-
654
- type ProtocolOptions = {
655
- scheme: string
656
-
657
- optionalSlashes?: boolean
658
- }
659
-
660
- type ProtocolConfig = Array<ProtocolOptions | string>
661
-
662
- const ATTR_WHITESPACE_PATTERN =
663
- '[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]'
664
- const ATTR_WHITESPACE = new RegExp(ATTR_WHITESPACE_PATTERN, 'g')
665
-
666
- export function isAllowedUri(uri: string | undefined, protocols?: ProtocolConfig) {
667
- const allowedProtocols: string[] = [
668
- 'http',
669
- 'https',
670
- 'ftp',
671
- 'ftps',
672
- 'mailto',
673
- 'tel',
674
- 'callto',
675
- 'sms',
676
- 'cid',
677
- 'xmpp'
678
- ]
679
-
680
- if (protocols) {
681
- protocols.forEach((protocol) => {
682
- const nextProtocol = typeof protocol === 'string' ? protocol : protocol.scheme
683
-
684
- if (nextProtocol) {
685
- allowedProtocols.push(nextProtocol)
686
- }
687
- })
688
- }
689
-
690
- return (
691
- !uri ||
692
- uri
693
- .replace(ATTR_WHITESPACE, '')
694
- .match(
695
- new RegExp(
696
- `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,
697
- 'i'
698
- )
699
- )
700
- )
701
- }
702
-
703
- export function sanitizeUrl(inputUrl: string, baseUrl: string, protocols?: ProtocolConfig): string {
704
- try {
705
- const url = new URL(inputUrl, baseUrl)
706
-
707
- if (isAllowedUri(url.href, protocols)) {
708
- return url.href
709
- }
710
- } catch {}
711
- return '#'
712
- }
713
-
714
- export function updateNodesAttr<A extends string = string, V = unknown>(
715
- tr: Transaction,
716
- targets: readonly NodeWithPos[],
717
- attrName: A,
718
- next: V | ((prev: V | undefined) => V | undefined)
719
- ): boolean {
720
- if (!targets.length) return false
721
-
722
- let changed = false
723
-
724
- for (const { pos } of targets) {
725
- const currentNode = tr.doc.nodeAt(pos)
726
- if (!currentNode) continue
727
-
728
- const prevValue = (currentNode.attrs as Record<string, unknown>)[attrName] as V | undefined
729
- const resolvedNext =
730
- typeof next === 'function' ? (next as (p: V | undefined) => V | undefined)(prevValue) : next
731
-
732
- if (prevValue === resolvedNext) continue
733
-
734
- const nextAttrs: Record<string, unknown> = { ...currentNode.attrs }
735
- if (resolvedNext === undefined) {
736
- delete nextAttrs[attrName]
737
- } else {
738
- nextAttrs[attrName] = resolvedNext
739
- }
740
-
741
- tr.setNodeMarkup(pos, undefined, nextAttrs)
742
- changed = true
743
- }
744
-
745
- return changed
746
- }
747
-
748
- export function selectCurrentBlockContent(editor: Editor) {
749
- const { selection, doc } = editor.state
750
-
751
- if (!selection.empty) return
752
-
753
- const $pos = selection.$from
754
- let blockNode = null
755
- let blockPos = -1
756
-
757
- for (let depth = $pos.depth; depth >= 0; depth--) {
758
- const node = $pos.node(depth)
759
- const pos = $pos.start(depth)
760
-
761
- if (node.isBlock && node.textContent.trim()) {
762
- blockNode = node
763
- blockPos = pos
764
- break
765
- }
766
- }
767
-
768
- if (blockNode && blockPos >= 0) {
769
- const from = blockPos
770
- const to = blockPos + blockNode.nodeSize - 2 // -2 to exclude the closing tag
771
-
772
- if (from < to) {
773
- const $from = doc.resolve(from)
774
- const $to = doc.resolve(to)
775
- const newSelection = TextSelection.between($from, $to, 1)
776
-
777
- if (newSelection && !selection.eq(newSelection)) {
778
- editor.view.dispatch(editor.state.tr.setSelection(newSelection))
779
- }
780
- }
781
- }
782
- }
783
-
784
- export function getSelectedNodesOfType(
785
- selection: Selection,
786
- allowedNodeTypes: string[]
787
- ): NodeWithPos[] {
788
- const results: NodeWithPos[] = []
789
- const allowed = new Set(allowedNodeTypes)
790
-
791
- if (selection instanceof CellSelection) {
792
- selection.forEachCell((node: PMNode, pos: number) => {
793
- if (allowed.has(node.type.name)) {
794
- results.push({ node, pos })
795
- }
796
- })
797
- return results
798
- }
799
-
800
- if (selection instanceof NodeSelection) {
801
- const { node, from: pos } = selection
802
- if (node && allowed.has(node.type.name)) {
803
- results.push({ node, pos })
804
- }
805
- return results
806
- }
807
-
808
- const { $anchor } = selection
809
- const cell = cellAround($anchor)
810
-
811
- if (cell) {
812
- const cellNode = selection.$anchor.doc.nodeAt(cell.pos)
813
- if (cellNode && allowed.has(cellNode.type.name)) {
814
- results.push({ node: cellNode, pos: cell.pos })
815
- return results
816
- }
817
- }
818
-
819
- const parentNode = findParentNodeClosestToPos($anchor, (node) => allowed.has(node.type.name))
820
-
821
- if (parentNode) {
822
- results.push({ node: parentNode.node, pos: parentNode.pos })
823
- }
824
-
825
- return results
826
- }
827
-
828
- export function getSelectedBlockNodes(editor: Editor): PMNode[] {
829
- const { doc } = editor.state
830
- const { from, to } = editor.state.selection
831
-
832
- const blocks: PMNode[] = []
833
- const seen = new Set<number>()
834
-
835
- doc.nodesBetween(from, to, (node, pos) => {
836
- if (!node.isBlock) return
837
-
838
- if (!seen.has(pos)) {
839
- seen.add(pos)
840
- blocks.push(node)
841
- }
842
-
843
- return false
844
- })
845
-
846
- return blocks
847
- }