betterstart-cli 0.0.100 → 0.0.102

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 (417) hide show
  1. package/README.md +1 -5
  2. package/dist/assets/adapters/next/integrations/_shared/actions/object-key.ts +1 -4
  3. package/dist/assets/adapters/next/integrations/_shared/actions/sanitize-filename.ts +3 -0
  4. package/dist/assets/adapters/next/integrations/r2/actions/get-client.ts +22 -0
  5. package/dist/assets/adapters/next/integrations/r2/actions/get-config.ts +9 -0
  6. package/dist/assets/adapters/next/integrations/r2/actions/{r2.ts → provider.ts} +3 -31
  7. package/dist/assets/adapters/next/integrations/r2/integration.ts +13 -1
  8. package/dist/assets/adapters/next/integrations/railway-bucket/actions/get-client.ts +20 -0
  9. package/dist/assets/adapters/next/integrations/railway-bucket/actions/get-config.ts +10 -0
  10. package/dist/assets/adapters/next/integrations/railway-bucket/actions/{railway-bucket.ts → provider.ts} +4 -34
  11. package/dist/assets/adapters/next/integrations/railway-bucket/actions/stable-read-url.ts +3 -0
  12. package/dist/assets/adapters/next/integrations/railway-bucket/integration.ts +17 -1
  13. package/dist/assets/adapters/next/integrations/resend/actions/escape-html.ts +8 -0
  14. package/dist/assets/adapters/next/integrations/resend/actions/get-env-value.ts +4 -0
  15. package/dist/assets/adapters/next/integrations/resend/actions/get-from-address.ts +5 -0
  16. package/dist/assets/adapters/next/integrations/resend/actions/get-resend-client.ts +19 -0
  17. package/dist/assets/adapters/next/integrations/resend/actions/html-to-text.ts +16 -0
  18. package/dist/assets/adapters/next/integrations/resend/actions/is-configured.ts +6 -0
  19. package/dist/assets/adapters/next/integrations/resend/actions/provider.ts +17 -0
  20. package/dist/assets/adapters/next/integrations/resend/actions/render-password-reset-email.ts +25 -0
  21. package/dist/assets/adapters/next/integrations/resend/actions/send-email.ts +43 -0
  22. package/dist/assets/adapters/next/integrations/resend/integration.ts +33 -1
  23. package/dist/assets/adapters/next/integrations/vercel-blob/actions/get-token.ts +3 -0
  24. package/dist/assets/adapters/next/integrations/vercel-blob/actions/{vercel-blob.ts → provider.ts} +1 -4
  25. package/dist/assets/adapters/next/integrations/vercel-blob/integration.ts +9 -1
  26. package/dist/assets/adapters/next/templates/init/api/storage-read-route.ts +2 -14
  27. package/dist/assets/adapters/next/templates/init/api/upload-route.ts +6 -5
  28. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-version-item.tsx +1 -1
  29. package/dist/assets/adapters/next/templates/init/components/shared/entity-versions/entity-versions-current-row.tsx +1 -1
  30. package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +3 -2
  31. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-blockquote.ts +6 -8
  32. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-code-block.ts +6 -8
  33. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-color-highlight.ts +6 -10
  34. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-media-insertion.ts +4 -6
  35. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-slash-menu.ts +4 -6
  36. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +22 -23
  37. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-table-add-controls.ts +8 -9
  38. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor.ts +16 -22
  39. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-heading.ts +6 -8
  40. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-link-popover.ts +3 -1
  41. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-list-dropdown-menu.ts +1 -1
  42. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-list.ts +6 -8
  43. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-mark.ts +2 -1
  44. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-table-button.ts +1 -1
  45. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-undo-redo.ts +1 -1
  46. package/dist/assets/adapters/next/templates/init/hooks/use-table-utils.ts +2 -1
  47. package/dist/assets/adapters/next/templates/init/hooks/use-upload.ts +3 -3
  48. package/dist/assets/adapters/next/templates/init/lib/actions/audit/clamp-page.ts +6 -0
  49. package/dist/assets/adapters/next/templates/init/lib/actions/audit/cleanup-audit-logs.ts +4 -9
  50. package/dist/assets/adapters/next/templates/init/lib/actions/audit/first-header-value.ts +3 -0
  51. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-log-order-by.ts +25 -0
  52. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-logs.ts +2 -109
  53. package/dist/assets/adapters/next/templates/init/lib/actions/audit/{request-metadata.ts → get-audit-request-metadata.ts} +3 -7
  54. package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-retention-days.ts +5 -0
  55. package/dist/assets/adapters/next/templates/init/lib/actions/audit/max-ip-length.ts +1 -0
  56. package/dist/assets/adapters/next/templates/init/lib/actions/audit/max-user-agent-length.ts +1 -0
  57. package/dist/assets/adapters/next/templates/init/lib/actions/audit/normalize-changed-fields.ts +3 -0
  58. package/dist/assets/adapters/next/templates/init/lib/actions/audit/normalize-page-size.ts +12 -0
  59. package/dist/assets/adapters/next/templates/init/lib/actions/audit/query-audit-logs.ts +71 -0
  60. package/dist/assets/adapters/next/templates/init/lib/actions/audit/record-audit-event.ts +3 -6
  61. package/dist/assets/adapters/next/templates/init/lib/actions/auth/middleware.ts +2 -1
  62. package/dist/assets/adapters/next/templates/init/lib/actions/email/form-email-delivery-input.ts +1 -0
  63. package/dist/assets/adapters/next/templates/init/lib/actions/email/queued-form-email.ts +6 -0
  64. package/dist/assets/adapters/next/templates/init/lib/actions/email/{form-delivery.ts → send-form-emails.ts} +7 -34
  65. package/dist/assets/adapters/next/templates/init/lib/actions/email/send-queued-email.ts +19 -0
  66. package/dist/assets/adapters/next/templates/init/lib/actions/forms/upsert-form-settings.ts +1 -1
  67. package/dist/assets/adapters/next/templates/init/lib/actions/media/clamp-media-page-size.ts +9 -0
  68. package/dist/assets/adapters/next/templates/init/lib/actions/media/clamp-media-page.ts +9 -0
  69. package/dist/assets/adapters/next/templates/init/lib/actions/media/create-media.ts +3 -3
  70. package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media-bulk.ts +2 -2
  71. package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media.ts +2 -2
  72. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media-by-id.ts +2 -1
  73. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media-by-ids.ts +2 -1
  74. package/dist/assets/adapters/next/templates/init/lib/actions/media/get-media.ts +5 -21
  75. package/dist/assets/adapters/next/templates/init/lib/actions/media/update-media.ts +3 -3
  76. package/dist/assets/adapters/next/templates/init/lib/actions/profile/change-own-password.ts +2 -2
  77. package/dist/assets/adapters/next/templates/init/lib/actions/profile/update-email.ts +2 -2
  78. package/dist/assets/adapters/next/templates/init/lib/actions/storage/local.ts +1 -1
  79. package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-media-from-url.ts +4 -6
  80. package/dist/assets/adapters/next/templates/init/lib/actions/users/change-user-password.ts +2 -2
  81. package/dist/assets/adapters/next/templates/init/lib/actions/users/create-user.ts +3 -3
  82. package/dist/assets/adapters/next/templates/init/lib/actions/users/delete-user.ts +2 -2
  83. package/dist/assets/adapters/next/templates/init/lib/actions/users/get-cached-users.ts +40 -0
  84. package/dist/assets/adapters/next/templates/init/lib/actions/users/get-users.ts +2 -40
  85. package/dist/assets/adapters/next/templates/init/lib/actions/users/update-user-role.ts +2 -2
  86. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/create-webhook.ts +2 -2
  87. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/delete-webhook.ts +1 -1
  88. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/deliver-to-endpoint.ts +55 -0
  89. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/deliver-webhook-event.ts +19 -0
  90. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/emit-webhook-event.ts +22 -0
  91. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/entity-event-payload.ts +20 -0
  92. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-deliveries.ts +1 -1
  93. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-secret.ts +1 -1
  94. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhook-subscriptions.ts +2 -18
  95. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/get-webhooks.ts +1 -1
  96. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/prune-webhook-deliveries.ts +26 -0
  97. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/read-webhook-subscriptions.ts +18 -0
  98. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/record-webhook-delivery.ts +24 -0
  99. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/regenerate-webhook-secret.ts +2 -2
  100. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/{register.ts → register-webhook-hooks.ts} +2 -14
  101. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/send-test-webhook.ts +3 -2
  102. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/update-webhook.ts +1 -1
  103. package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/register.ts +1 -1
  104. package/dist/assets/adapters/next/templates/init/pages/account-shell-rsc.tsx +1 -1
  105. package/dist/assets/adapters/next/templates/init/pages/login-form.tsx +1 -1
  106. package/dist/assets/adapters/next/templates/init/pages/login-page-rsc.tsx +1 -1
  107. package/dist/assets/adapters/next/templates/init/pages/users/columns.tsx +1 -1
  108. package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +1 -1
  109. package/dist/assets/adapters/next/templates/init/utils/audit/get-changed-field-names.ts +18 -0
  110. package/dist/assets/adapters/next/templates/init/utils/audit/get-touched-field-names.ts +9 -0
  111. package/dist/assets/adapters/next/templates/init/utils/audit/normalize-comparable-value.ts +14 -0
  112. package/dist/assets/adapters/next/templates/init/utils/audit/should-track-field.ts +15 -0
  113. package/dist/assets/adapters/next/templates/init/utils/auth/can-access-admin.ts +7 -0
  114. package/dist/assets/adapters/next/templates/init/utils/auth/get-admin-post-login-path.ts +5 -0
  115. package/dist/assets/adapters/next/templates/init/utils/auth/has-required-role.ts +5 -0
  116. package/dist/assets/adapters/next/templates/init/utils/auth/is-user-role.ts +5 -0
  117. package/dist/assets/adapters/next/templates/init/utils/date/build-date-range.ts +14 -0
  118. package/dist/assets/adapters/next/templates/init/utils/date/date-range-end-time.ts +1 -0
  119. package/dist/assets/adapters/next/templates/init/utils/date/date-range-input-format.ts +1 -0
  120. package/dist/assets/adapters/next/templates/init/utils/date/date-range-start-time.ts +1 -0
  121. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-input-date.ts +6 -0
  122. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-param-date.ts +7 -0
  123. package/dist/assets/adapters/next/templates/init/utils/date/format-date-range-trigger-date.ts +5 -0
  124. package/dist/assets/adapters/next/templates/init/utils/date/get-date-range-trigger-label.ts +24 -0
  125. package/dist/assets/adapters/next/templates/init/utils/date/get-exclusive-date-upper-bound.ts +9 -0
  126. package/dist/assets/adapters/next/templates/init/utils/date/get-ordered-date-range.ts +12 -0
  127. package/dist/assets/adapters/next/templates/init/utils/date/normalize-date-range-time.ts +5 -0
  128. package/dist/assets/adapters/next/templates/init/utils/date/parse-date-input-value.ts +6 -0
  129. package/dist/assets/adapters/next/templates/init/utils/date/parse-editable-date-range-date.ts +17 -0
  130. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-cell-class.ts +1 -0
  131. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-cell.ts +36 -0
  132. package/dist/assets/adapters/next/templates/init/utils/editor/active-table-wrapper-class.ts +1 -0
  133. package/dist/assets/adapters/next/templates/init/utils/editor/append-column-to-table.ts +13 -0
  134. package/dist/assets/adapters/next/templates/init/utils/editor/append-row-to-table.ts +13 -0
  135. package/dist/assets/adapters/next/templates/init/utils/editor/apply-cursor-change-if-available.ts +8 -0
  136. package/dist/assets/adapters/next/templates/init/utils/editor/apply-cursor-change.ts +10 -0
  137. package/dist/assets/adapters/next/templates/init/utils/editor/can-insert-content-editor-media-placeholder.ts +10 -0
  138. package/dist/assets/adapters/next/templates/init/utils/editor/checkbox-label-factory.ts +5 -0
  139. package/dist/assets/adapters/next/templates/init/utils/editor/clear-table-part-preview.ts +11 -0
  140. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-name-pattern.ts +3 -0
  141. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-option.ts +6 -0
  142. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color-options.ts +68 -0
  143. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-color.ts +3 -0
  144. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight-colors.ts +12 -0
  145. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-highlight.ts +33 -0
  146. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-inline-math-delimiter.ts +1 -0
  147. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-inline-math.ts +105 -0
  148. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-keyboard.ts +5 -0
  149. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-math-kind.ts +1 -0
  150. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-math-value.ts +9 -0
  151. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-media-placeholder-node.ts +1 -0
  152. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-media-shortcut-key.ts +1 -0
  153. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-mode.ts +1 -0
  154. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-raw-content-block.ts +95 -0
  155. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-selected-math.ts +12 -0
  156. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-selection-request.ts +4 -0
  157. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-subscript.ts +5 -0
  158. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-superscript.ts +5 -0
  159. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-table-alignment.ts +1 -0
  160. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-underline.ts +26 -0
  161. package/dist/assets/adapters/next/templates/init/utils/editor/create-content-editor-table-node.ts +27 -0
  162. package/dist/assets/adapters/next/templates/init/utils/editor/create-html-mark.ts +28 -0
  163. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-image-text.ts +5 -0
  164. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-plain-text-offset-map.ts +126 -0
  165. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-table-text.ts +15 -0
  166. package/dist/assets/adapters/next/templates/init/utils/editor/create-markdown-text-from-url.ts +6 -0
  167. package/dist/assets/adapters/next/templates/init/utils/editor/default-content-editor-table-cols.ts +1 -0
  168. package/dist/assets/adapters/next/templates/init/utils/editor/default-content-editor-table-rows.ts +1 -0
  169. package/dist/assets/adapters/next/templates/init/utils/editor/doc-position-from-plain-text-offset.ts +27 -0
  170. package/dist/assets/adapters/next/templates/init/utils/editor/escape-html.ts +10 -0
  171. package/dist/assets/adapters/next/templates/init/utils/editor/find-highlight-span-range.ts +25 -0
  172. package/dist/assets/adapters/next/templates/init/utils/editor/find-inline-math-start.ts +12 -0
  173. package/dist/assets/adapters/next/templates/init/utils/editor/find-markdown-link-range.ts +40 -0
  174. package/dist/assets/adapters/next/templates/init/utils/editor/find-node-at-position.ts +15 -0
  175. package/dist/assets/adapters/next/templates/init/utils/editor/find-node-position.ts +48 -0
  176. package/dist/assets/adapters/next/templates/init/utils/editor/find-raw-content-start.ts +16 -0
  177. package/dist/assets/adapters/next/templates/init/utils/editor/find-unescaped-character.ts +13 -0
  178. package/dist/assets/adapters/next/templates/init/utils/editor/find-unescaped-sequence.ts +14 -0
  179. package/dist/assets/adapters/next/templates/init/utils/editor/focus-next-node.ts +28 -0
  180. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-blockquote-line.ts +5 -0
  181. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-heading-line.ts +7 -0
  182. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown-list-line.ts +14 -0
  183. package/dist/assets/adapters/next/templates/init/utils/editor/format-markdown.ts +7 -0
  184. package/dist/assets/adapters/next/templates/init/utils/editor/format-shortcut-key.ts +10 -0
  185. package/dist/assets/adapters/next/templates/init/utils/editor/get-active-table-column-alignment.ts +31 -0
  186. package/dist/assets/adapters/next/templates/init/utils/editor/get-block-math-expression.ts +15 -0
  187. package/dist/assets/adapters/next/templates/init/utils/editor/get-closest-table-cell.ts +10 -0
  188. package/dist/assets/adapters/next/templates/init/utils/editor/get-content-editor-highlight-color-name.ts +42 -0
  189. package/dist/assets/adapters/next/templates/init/utils/editor/get-content-editor-highlight-color-value.ts +6 -0
  190. package/dist/assets/adapters/next/templates/init/utils/editor/get-editor-element.ts +7 -0
  191. package/dist/assets/adapters/next/templates/init/utils/editor/get-editor-scroll-element.ts +8 -0
  192. package/dist/assets/adapters/next/templates/init/utils/editor/get-event-table-cell.ts +7 -0
  193. package/dist/assets/adapters/next/templates/init/utils/editor/get-inline-math-delimiter.ts +7 -0
  194. package/dist/assets/adapters/next/templates/init/utils/editor/get-markdown-heading-fallback.ts +5 -0
  195. package/dist/assets/adapters/next/templates/init/utils/editor/get-markdown-list-fallback.ts +7 -0
  196. package/dist/assets/adapters/next/templates/init/utils/editor/get-media-label.ts +5 -0
  197. package/dist/assets/adapters/next/templates/init/utils/editor/get-number-attr.ts +3 -0
  198. package/dist/assets/adapters/next/templates/init/utils/editor/get-plain-text-offset-before-doc-position.ts +8 -0
  199. package/dist/assets/adapters/next/templates/init/utils/editor/get-plain-text-offset-before-markdown-offset.ts +11 -0
  200. package/dist/assets/adapters/next/templates/init/utils/editor/get-raw-content-kind.ts +7 -0
  201. package/dist/assets/adapters/next/templates/init/utils/editor/get-raw-content-token.ts +13 -0
  202. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-block-nodes.ts +23 -0
  203. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-content-editor-math.ts +43 -0
  204. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-nodes-of-type.ts +50 -0
  205. package/dist/assets/adapters/next/templates/init/utils/editor/get-selected-table-column-cell-positions.ts +21 -0
  206. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table-cell.ts +10 -0
  207. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table-element.ts +19 -0
  208. package/dist/assets/adapters/next/templates/init/utils/editor/get-selection-table.ts +17 -0
  209. package/dist/assets/adapters/next/templates/init/utils/editor/get-slash-menu-state.ts +47 -0
  210. package/dist/assets/adapters/next/templates/init/utils/editor/get-string-attr.ts +5 -0
  211. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-element.ts +5 -0
  212. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-from-event-target.ts +19 -0
  213. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-from-wrapper.ts +15 -0
  214. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-position-for-element.ts +24 -0
  215. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-rect-at-position.ts +20 -0
  216. package/dist/assets/adapters/next/templates/init/utils/editor/get-table-wrapper-element.ts +11 -0
  217. package/dist/assets/adapters/next/templates/init/utils/editor/{task-item.ts → get-task-item-checkbox-label.ts} +1 -7
  218. package/dist/assets/adapters/next/templates/init/utils/editor/has-own-attribute.ts +3 -0
  219. package/dist/assets/adapters/next/templates/init/utils/editor/highlight-span-pattern.ts +6 -0
  220. package/dist/assets/adapters/next/templates/init/utils/editor/inline-math-delimiter.ts +3 -0
  221. package/dist/assets/adapters/next/templates/init/utils/editor/inline-math-node-view.ts +51 -0
  222. package/dist/assets/adapters/next/templates/init/utils/editor/insert-component-at-cursor.ts +28 -0
  223. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-math.ts +35 -0
  224. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-media-placeholder.ts +20 -0
  225. package/dist/assets/adapters/next/templates/init/utils/editor/insert-content-editor-table.ts +12 -0
  226. package/dist/assets/adapters/next/templates/init/utils/editor/insert-markdown-text-at-position.ts +14 -0
  227. package/dist/assets/adapters/next/templates/init/utils/editor/insert-result.ts +4 -0
  228. package/dist/assets/adapters/next/templates/init/utils/editor/insert-text-at-cursor.ts +37 -0
  229. package/dist/assets/adapters/next/templates/init/utils/editor/is-allowed-uri.ts +42 -0
  230. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-highlight-color.ts +6 -0
  231. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-media-placeholder-active.ts +8 -0
  232. package/dist/assets/adapters/next/templates/init/utils/editor/is-content-editor-table-alignment.ts +7 -0
  233. package/dist/assets/adapters/next/templates/init/utils/editor/is-element-visible-in-editor.ts +17 -0
  234. package/dist/assets/adapters/next/templates/init/utils/editor/is-escaped.ts +11 -0
  235. package/dist/assets/adapters/next/templates/init/utils/editor/is-extension-available.ts +22 -0
  236. package/dist/assets/adapters/next/templates/init/utils/editor/is-mac.ts +3 -0
  237. package/dist/assets/adapters/next/templates/init/utils/editor/is-mark-in-schema.ts +6 -0
  238. package/dist/assets/adapters/next/templates/init/utils/editor/is-markdown-line-start.ts +3 -0
  239. package/dist/assets/adapters/next/templates/init/utils/editor/is-node-in-schema.ts +6 -0
  240. package/dist/assets/adapters/next/templates/init/utils/editor/is-node-type-selected.ts +30 -0
  241. package/dist/assets/adapters/next/templates/init/utils/editor/is-same-slash-menu-state.ts +17 -0
  242. package/dist/assets/adapters/next/templates/init/utils/editor/is-selected-table-visible.ts +8 -0
  243. package/dist/assets/adapters/next/templates/init/utils/editor/is-task-item-checked.ts +5 -0
  244. package/dist/assets/adapters/next/templates/init/utils/editor/is-valid-dollar-inline-math.ts +13 -0
  245. package/dist/assets/adapters/next/templates/init/utils/editor/is-valid-position.ts +3 -0
  246. package/dist/assets/adapters/next/templates/init/utils/editor/is-word-character.ts +3 -0
  247. package/dist/assets/adapters/next/templates/init/utils/editor/mac-symbols.ts +15 -0
  248. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-level.ts +1 -0
  249. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-option.ts +6 -0
  250. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-heading-options.ts +9 -0
  251. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-image-upload-result.ts +4 -0
  252. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-option.ts +6 -0
  253. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-options.ts +7 -0
  254. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-list-type.ts +1 -0
  255. package/dist/assets/adapters/next/templates/init/utils/editor/markdown-offset-from-plain-text-offset.ts +8 -0
  256. package/dist/assets/adapters/next/templates/init/utils/editor/match-block-math.ts +54 -0
  257. package/dist/assets/adapters/next/templates/init/utils/editor/match-code-fence-start.ts +8 -0
  258. package/dist/assets/adapters/next/templates/init/utils/editor/match-html-block.ts +31 -0
  259. package/dist/assets/adapters/next/templates/init/utils/editor/match-html-mark-syntax.ts +16 -0
  260. package/dist/assets/adapters/next/templates/init/utils/editor/match-inline-math.ts +49 -0
  261. package/dist/assets/adapters/next/templates/init/utils/editor/match-markdown-block-prefix.ts +11 -0
  262. package/dist/assets/adapters/next/templates/init/utils/editor/match-markdown-mark-syntax.ts +27 -0
  263. package/dist/assets/adapters/next/templates/init/utils/editor/match-raw-content-block.ts +9 -0
  264. package/dist/assets/adapters/next/templates/init/utils/editor/mounted-editor-view.ts +3 -0
  265. package/dist/assets/adapters/next/templates/init/utils/editor/normalize-editor-markdown.ts +3 -0
  266. package/dist/assets/adapters/next/templates/init/utils/editor/parse-content-editor-math-input.ts +98 -0
  267. package/dist/assets/adapters/next/templates/init/utils/editor/parse-shortcut-keys.ts +17 -0
  268. package/dist/assets/adapters/next/templates/init/utils/editor/prepare-markdown-for-rich-mode.ts +3 -0
  269. package/dist/assets/adapters/next/templates/init/utils/editor/protocol-config.ts +7 -0
  270. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-block-node-view.ts +120 -0
  271. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-kind.ts +3 -0
  272. package/dist/assets/adapters/next/templates/init/utils/editor/raw-content-match.ts +8 -0
  273. package/dist/assets/adapters/next/templates/init/utils/editor/raw-html-block-tags.ts +14 -0
  274. package/dist/assets/adapters/next/templates/init/utils/editor/remove-highlight-span-at-cursor.ts +59 -0
  275. package/dist/assets/adapters/next/templates/init/utils/editor/remove-markdown-link-at-cursor.ts +43 -0
  276. package/dist/assets/adapters/next/templates/init/utils/editor/remove-selected-content-editor-math.ts +20 -0
  277. package/dist/assets/adapters/next/templates/init/utils/editor/render-details-preview.ts +22 -0
  278. package/dist/assets/adapters/next/templates/init/utils/editor/render-latex.ts +20 -0
  279. package/dist/assets/adapters/next/templates/init/utils/editor/render-raw-content-preview.ts +19 -0
  280. package/dist/assets/adapters/next/templates/init/utils/editor/render-simple-markdown-body.ts +46 -0
  281. package/dist/assets/adapters/next/templates/init/utils/editor/run-slash-command.ts +12 -0
  282. package/dist/assets/adapters/next/templates/init/utils/editor/runnable-slash-command.ts +5 -0
  283. package/dist/assets/adapters/next/templates/init/utils/editor/sanitize-html-preview.ts +41 -0
  284. package/dist/assets/adapters/next/templates/init/utils/editor/sanitize-url.ts +13 -0
  285. package/dist/assets/adapters/next/templates/init/utils/editor/select-current-block-content.ts +38 -0
  286. package/dist/assets/adapters/next/templates/init/utils/editor/selection-within-convertible-types.ts +29 -0
  287. package/dist/assets/adapters/next/templates/init/utils/editor/self-closing-html-block-tags.ts +3 -0
  288. package/dist/assets/adapters/next/templates/init/utils/editor/serialize-raw-content-preview.ts +12 -0
  289. package/dist/assets/adapters/next/templates/init/utils/editor/set-active-table-column-alignment.ts +39 -0
  290. package/dist/assets/adapters/next/templates/init/utils/editor/set-element-attribute.ts +13 -0
  291. package/dist/assets/adapters/next/templates/init/utils/editor/set-markdown-link-at-cursor.ts +50 -0
  292. package/dist/assets/adapters/next/templates/init/utils/editor/show-table-part-preview.ts +59 -0
  293. package/dist/assets/adapters/next/templates/init/utils/editor/slash-commands.ts +2 -1
  294. package/dist/assets/adapters/next/templates/init/utils/editor/slash-menu-state.ts +6 -0
  295. package/dist/assets/adapters/next/templates/init/utils/editor/sr-only.ts +11 -0
  296. package/dist/assets/adapters/next/templates/init/utils/editor/strip-html.ts +5 -0
  297. package/dist/assets/adapters/next/templates/init/utils/editor/strip-markdown-block-prefix.ts +6 -0
  298. package/dist/assets/adapters/next/templates/init/utils/editor/table-add-controls-state.ts +4 -0
  299. package/dist/assets/adapters/next/templates/init/utils/editor/table-part-preview-class.ts +1 -0
  300. package/dist/assets/adapters/next/templates/init/utils/editor/table-part.ts +1 -0
  301. package/dist/assets/adapters/next/templates/init/utils/editor/table-wrapper-class.ts +1 -0
  302. package/dist/assets/adapters/next/templates/init/utils/editor/transform-selected-markdown-lines.ts +38 -0
  303. package/dist/assets/adapters/next/templates/init/utils/editor/update-nodes-attr.ts +36 -0
  304. package/dist/assets/adapters/next/templates/init/utils/editor/update-selected-content-editor-math.ts +36 -0
  305. package/dist/assets/adapters/next/templates/init/utils/email/escape-html.ts +8 -0
  306. package/dist/assets/adapters/next/templates/init/utils/email/form-email-delivery-input.ts +8 -0
  307. package/dist/assets/adapters/next/templates/init/utils/email/format-email-value.ts +19 -0
  308. package/dist/assets/adapters/next/templates/init/utils/email/is-valid-email.ts +3 -0
  309. package/dist/assets/adapters/next/templates/init/utils/email/normalize-email-list.ts +5 -0
  310. package/dist/assets/adapters/next/templates/init/utils/email/render-form-submission-rows.ts +16 -0
  311. package/dist/assets/adapters/next/templates/init/utils/email/render-notification-email.ts +32 -0
  312. package/dist/assets/adapters/next/templates/init/utils/email/render-thank-you-email.ts +18 -0
  313. package/dist/assets/adapters/next/templates/init/utils/error/read-string-property.ts +5 -0
  314. package/dist/assets/adapters/next/templates/init/utils/error/{action-error.ts → recognize.ts} +3 -12
  315. package/dist/assets/adapters/next/templates/init/utils/error/to-action-error.ts +6 -0
  316. package/dist/assets/adapters/next/templates/init/utils/form/{list-field.ts → clone-default-value.ts} +0 -5
  317. package/dist/assets/adapters/next/templates/init/utils/form/create-list-item-key.ts +4 -0
  318. package/dist/assets/adapters/next/templates/init/utils/media/admin-media-type.ts +1 -0
  319. package/dist/assets/adapters/next/templates/init/utils/media/{fallback.ts → create-admin-media-from-url.ts} +1 -14
  320. package/dist/assets/adapters/next/templates/init/utils/media/create-preview-url.ts +3 -0
  321. package/dist/assets/adapters/next/templates/init/utils/media/get-filename-from-url.ts +9 -0
  322. package/dist/assets/adapters/next/templates/init/utils/media/get-media-type.ts +19 -0
  323. package/dist/assets/adapters/next/templates/init/utils/media/get-media-url-help-text.ts +10 -0
  324. package/dist/assets/adapters/next/templates/init/utils/media/get-media-url-placeholder.ts +7 -0
  325. package/dist/assets/adapters/next/templates/init/utils/media/image-extensions.ts +1 -0
  326. package/dist/assets/adapters/next/templates/init/utils/media/image-mime-types.ts +7 -0
  327. package/dist/assets/adapters/next/templates/init/utils/media/infer-media-content-type.ts +13 -0
  328. package/dist/assets/adapters/next/templates/init/utils/media/is-document-only-accept.ts +19 -0
  329. package/dist/assets/adapters/next/templates/init/utils/media/{query.ts → map-media-row.ts} +0 -39
  330. package/dist/assets/adapters/next/templates/init/utils/media/media-mime-types.ts +4 -0
  331. package/dist/assets/adapters/next/templates/init/utils/media/revoke-preview-url.ts +3 -0
  332. package/dist/assets/adapters/next/templates/init/utils/media/select-media.ts +39 -0
  333. package/dist/assets/adapters/next/templates/init/utils/media/video-extensions.ts +1 -0
  334. package/dist/assets/adapters/next/templates/init/utils/media/video-mime-types.ts +7 -0
  335. package/dist/assets/adapters/next/templates/init/utils/seo/{seo.ts → create-metadata.ts} +0 -36
  336. package/dist/assets/adapters/next/templates/init/utils/seo/generate-article-schema.ts +31 -0
  337. package/dist/assets/adapters/next/templates/init/utils/seo/schema-to-json.ts +3 -0
  338. package/dist/assets/adapters/next/templates/init/utils/storage/{local.ts → build-local-storage-key.ts} +1 -4
  339. package/dist/assets/adapters/next/templates/init/utils/storage/decode-storage-key.ts +9 -0
  340. package/dist/assets/adapters/next/templates/init/utils/storage/sanitize-filename.ts +3 -0
  341. package/dist/assets/adapters/next/templates/init/utils/storage/storage-error.ts +5 -0
  342. package/dist/assets/adapters/next/templates/init/utils/table/{table.ts → default-get-id.ts} +0 -4
  343. package/dist/assets/adapters/next/templates/init/utils/table/is-string.ts +3 -0
  344. package/dist/assets/adapters/next/templates/init/utils/upload/default-remote-accept.ts +1 -0
  345. package/dist/assets/adapters/next/templates/init/utils/upload/dropzone-accept.ts +1 -0
  346. package/dist/assets/adapters/next/templates/init/utils/upload/get-fallback-extension.ts +12 -0
  347. package/dist/assets/adapters/next/templates/init/utils/upload/get-remote-filename.ts +15 -0
  348. package/dist/assets/adapters/next/templates/init/utils/upload/is-accepted-remote-type.ts +25 -0
  349. package/dist/assets/adapters/next/templates/init/utils/upload/is-wildcard-accept.ts +4 -0
  350. package/dist/assets/adapters/next/templates/init/utils/upload/parse-accept-types.ts +7 -0
  351. package/dist/assets/adapters/next/templates/init/utils/upload/parse-dropzone-accept.ts +14 -0
  352. package/dist/assets/adapters/next/templates/init/utils/upload/remote-fetch-timeout-ms.ts +1 -0
  353. package/dist/assets/adapters/next/templates/init/utils/user/compare-user-sort-values.ts +4 -0
  354. package/dist/assets/adapters/next/templates/init/utils/user/get-user-initials.ts +11 -0
  355. package/dist/assets/adapters/next/templates/init/utils/user/get-user-sort-value.ts +8 -0
  356. package/dist/assets/adapters/next/templates/init/utils/user/{user.ts → get-users-page.ts} +3 -28
  357. package/dist/assets/adapters/next/templates/init/utils/user/normalize-user-filter-value.ts +3 -0
  358. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-config.ts +5 -0
  359. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-error.ts +4 -0
  360. package/dist/assets/adapters/next/templates/init/utils/validation/file-validation-result.ts +6 -0
  361. package/dist/assets/adapters/next/templates/init/utils/validation/format-file-size.ts +18 -0
  362. package/dist/assets/adapters/next/templates/init/utils/validation/is-file-type-allowed.ts +13 -0
  363. package/dist/assets/adapters/next/templates/init/utils/validation/is-valid-url.ts +8 -0
  364. package/dist/assets/adapters/next/templates/init/utils/validation/slugify.ts +9 -0
  365. package/dist/assets/adapters/next/templates/init/utils/validation/validate-files.ts +39 -0
  366. package/dist/assets/adapters/next/templates/init/utils/webhook/create-webhook-event-id.ts +5 -0
  367. package/dist/assets/adapters/next/templates/init/utils/webhook/generate-webhook-secret.ts +5 -0
  368. package/dist/assets/adapters/next/templates/init/utils/webhook/sign-webhook-payload.ts +5 -0
  369. package/dist/assets/shared-assets/react-admin/custom/content-editor/index.tsx +1 -1
  370. package/dist/assets/shared-assets/react-admin/custom/content-editor/math-bubble-menu.tsx +3 -5
  371. package/dist/assets/shared-assets/react-admin/custom/content-editor/math-popover-button.tsx +1 -1
  372. package/dist/assets/shared-assets/react-admin/custom/content-editor/mobile-toolbar-content.tsx +1 -1
  373. package/dist/assets/shared-assets/react-admin/custom/content-editor/slash-command-menu.tsx +1 -1
  374. package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +6 -4
  375. package/dist/assets/shared-assets/react-admin/custom/content-editor/table-bubble-menu.tsx +11 -15
  376. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-extension/node-background-extension.ts +2 -1
  377. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/media-gallery-placeholder-node/media-gallery-placeholder-node.tsx +3 -2
  378. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/removable-image-node/removable-image-node.tsx +5 -3
  379. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-node/task-item-node/task-item-node-extension.tsx +4 -2
  380. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/blockquote-button/blockquote-button.tsx +1 -1
  381. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/code-block-button/code-block-button.tsx +1 -1
  382. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-button/color-highlight-button.tsx +1 -1
  383. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/mark-button/mark-button.tsx +1 -1
  384. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/undo-redo-button/undo-redo-button.tsx +1 -1
  385. package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +10 -12
  386. package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +1 -1
  387. package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +2 -1
  388. package/dist/assets/shared-assets/react-admin/custom/upload-dropzone.tsx +1 -1
  389. package/dist/{chunk-45Z6XDG5.js → chunk-TIJEHWRF.js} +150 -165
  390. package/dist/chunk-TIJEHWRF.js.map +1 -0
  391. package/dist/cli.js +27813 -24313
  392. package/dist/cli.js.map +1 -1
  393. package/dist/read-namespaced-template-UXU7OCY3.js +13 -0
  394. package/dist/read-namespaced-template-UXU7OCY3.js.map +1 -0
  395. package/package.json +1 -1
  396. package/dist/assets/adapters/next/integrations/resend/actions/resend.ts +0 -138
  397. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/dispatch.ts +0 -134
  398. package/dist/assets/adapters/next/templates/init/utils/audit/audit.ts +0 -54
  399. package/dist/assets/adapters/next/templates/init/utils/auth/roles.ts +0 -17
  400. package/dist/assets/adapters/next/templates/init/utils/date/date.ts +0 -100
  401. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor-rich-extensions.ts +0 -824
  402. package/dist/assets/adapters/next/templates/init/utils/editor/content-editor.ts +0 -389
  403. package/dist/assets/adapters/next/templates/init/utils/editor/markdown.ts +0 -545
  404. package/dist/assets/adapters/next/templates/init/utils/editor/node-attrs.ts +0 -25
  405. package/dist/assets/adapters/next/templates/init/utils/editor/source-media.ts +0 -11
  406. package/dist/assets/adapters/next/templates/init/utils/editor/table-add-controls.ts +0 -91
  407. package/dist/assets/adapters/next/templates/init/utils/editor/table-bubble.ts +0 -172
  408. package/dist/assets/adapters/next/templates/init/utils/editor/tiptap.ts +0 -847
  409. package/dist/assets/adapters/next/templates/init/utils/email/form-delivery.ts +0 -104
  410. package/dist/assets/adapters/next/templates/init/utils/media/media.ts +0 -91
  411. package/dist/assets/adapters/next/templates/init/utils/upload/remote.ts +0 -55
  412. package/dist/assets/adapters/next/templates/init/utils/upload/upload.ts +0 -26
  413. package/dist/assets/adapters/next/templates/init/utils/validation/validation.ts +0 -102
  414. package/dist/assets/adapters/next/templates/init/utils/webhook/signature.ts +0 -13
  415. package/dist/chunk-45Z6XDG5.js.map +0 -1
  416. package/dist/template-reader-J6G7N5V6.js +0 -13
  417. package/dist/template-reader-J6G7N5V6.js.map +0 -1
@@ -1,824 +0,0 @@
1
- 'use client'
2
-
3
- import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
4
- import type { EditorView } from '@tiptap/pm/view'
5
- import {
6
- getContentEditorHighlightColorName,
7
- getContentEditorHighlightColorValue,
8
- isContentEditorHighlightColor
9
- } from '@admin/utils/editor/content-editor'
10
- import { Mark, mergeAttributes, Node as TiptapNode } from '@tiptap/core'
11
- import { Highlight } from '@tiptap/extension-highlight'
12
- import katex from 'katex'
13
-
14
- type RawContentKind = 'html' | 'math'
15
- type InlineMathDelimiter = '$' | '\\('
16
-
17
- interface RawContentMatch {
18
- kind: RawContentKind
19
- raw: string
20
- }
21
-
22
- interface InlineMathMatch {
23
- raw: string
24
- text: string
25
- delimiter: InlineMathDelimiter
26
- }
27
-
28
- interface RawContentToken {
29
- raw?: string
30
- text?: string
31
- delimiter?: string
32
- kind?: string
33
- }
34
-
35
- interface RawContentBlockNodeViewOptions {
36
- getPos: () => number | undefined
37
- node: ProseMirrorNode
38
- view: EditorView
39
- }
40
-
41
- const rawHtmlBlockTags = [
42
- 'article',
43
- 'aside',
44
- 'audio',
45
- 'details',
46
- 'div',
47
- 'figure',
48
- 'iframe',
49
- 'section',
50
- 'table',
51
- 'video'
52
- ].join('|')
53
-
54
- const selfClosingHtmlBlockTags = ['br', 'hr', 'img'].join('|')
55
-
56
- const mathBlockEnvironmentNames = new Set([
57
- 'align',
58
- 'align*',
59
- 'aligned',
60
- 'alignedat',
61
- 'alignedat*',
62
- 'array',
63
- 'bmatrix',
64
- 'cases',
65
- 'equation',
66
- 'equation*',
67
- 'gather',
68
- 'gather*',
69
- 'gathered',
70
- 'matrix',
71
- 'multline',
72
- 'multline*',
73
- 'pmatrix',
74
- 'smallmatrix',
75
- 'split',
76
- 'vmatrix'
77
- ])
78
-
79
- const blockedHtmlPreviewTags = new Set(['embed', 'link', 'meta', 'object', 'script', 'style'])
80
-
81
- const urlAttributes = new Set(['href', 'src'])
82
-
83
- export const ContentEditorUnderline = Mark.create({
84
- name: 'underline',
85
-
86
- parseHTML() {
87
- return [{ tag: 'u' }]
88
- },
89
-
90
- renderHTML({ HTMLAttributes }) {
91
- return ['u', mergeAttributes(HTMLAttributes), 0]
92
- },
93
-
94
- markdownOptions: {
95
- htmlReopen: {
96
- open: '<u>',
97
- close: '</u>'
98
- }
99
- },
100
-
101
- renderMarkdown: (node, helpers) => {
102
- return `<u>${helpers.renderChildren(node)}</u>`
103
- }
104
- })
105
-
106
- export const ContentEditorHighlight = Highlight.extend({
107
- parseHTML() {
108
- return [
109
- {
110
- tag: 'span[data-highlight-color]',
111
- getAttrs: (element) => {
112
- if (!(element instanceof HTMLElement)) return false
113
-
114
- const color = element.getAttribute('data-highlight-color')
115
- if (!color || !isContentEditorHighlightColor(color)) return false
116
-
117
- return {
118
- color: getContentEditorHighlightColorValue(color)
119
- }
120
- }
121
- }
122
- ]
123
- },
124
-
125
- renderMarkdown: (node, helpers) => {
126
- const color = getContentEditorHighlightColorName(node.attrs?.color)
127
- return `<span data-highlight-color="${color}">${helpers.renderChildren(node)}</span>`
128
- },
129
- parseMarkdown: null as never,
130
- markdownTokenizer: null as never
131
- })
132
-
133
- export const ContentEditorSubscript = createHtmlMark('subscript', 'sub')
134
- export const ContentEditorSuperscript = createHtmlMark('superscript', 'sup')
135
- export const ContentEditorKeyboard = createHtmlMark('keyboard', 'kbd')
136
-
137
- export const ContentEditorInlineMath = TiptapNode.create({
138
- name: 'inlineMath',
139
- group: 'inline',
140
- inline: true,
141
- atom: true,
142
- selectable: true,
143
-
144
- addAttributes() {
145
- return {
146
- raw: {
147
- default: ''
148
- },
149
- delimiter: {
150
- default: '$'
151
- }
152
- }
153
- },
154
-
155
- parseHTML() {
156
- return [
157
- {
158
- tag: 'span[data-content-editor-inline-math]',
159
- getAttrs: (element) => {
160
- if (!(element instanceof HTMLElement)) return false
161
-
162
- return {
163
- raw: element.dataset.raw ?? element.textContent ?? '',
164
- delimiter: element.dataset.delimiter === '\\(' ? '\\(' : '$'
165
- }
166
- }
167
- }
168
- ]
169
- },
170
-
171
- renderHTML({ HTMLAttributes, node }) {
172
- const raw = getStringAttr(node.attrs.raw)
173
- const delimiter = getInlineMathDelimiter(node.attrs.delimiter)
174
-
175
- return [
176
- 'span',
177
- mergeAttributes(HTMLAttributes, {
178
- 'data-content-editor-inline-math': '',
179
- 'data-raw': raw,
180
- 'data-delimiter': delimiter
181
- }),
182
- raw
183
- ]
184
- },
185
-
186
- parseMarkdown: (token) => {
187
- const mathToken = getRawContentToken(token)
188
-
189
- return {
190
- type: 'inlineMath',
191
- attrs: {
192
- raw: mathToken.text ?? mathToken.raw ?? '',
193
- delimiter: getInlineMathDelimiter(mathToken.delimiter)
194
- }
195
- }
196
- },
197
-
198
- renderMarkdown: (node) => {
199
- const raw = getStringAttr(node.attrs?.raw)
200
- const delimiter = getInlineMathDelimiter(node.attrs?.delimiter)
201
-
202
- if (delimiter === '\\(') {
203
- return `\\(${raw}\\)`
204
- }
205
-
206
- return `$${raw}$`
207
- },
208
-
209
- markdownTokenizer: {
210
- name: 'inlineMath',
211
- level: 'inline',
212
- start: findInlineMathStart,
213
- tokenize(src) {
214
- const match = matchInlineMath(src)
215
- if (!match) return undefined
216
-
217
- return {
218
- type: 'inlineMath',
219
- raw: match.raw,
220
- text: match.text,
221
- delimiter: match.delimiter
222
- }
223
- }
224
- },
225
-
226
- addNodeView() {
227
- return ({ node }) => {
228
- return new InlineMathNodeView(node)
229
- }
230
- }
231
- })
232
-
233
- export const ContentEditorRawContentBlock = TiptapNode.create({
234
- name: 'rawContentBlock',
235
- group: 'block',
236
- atom: true,
237
- selectable: true,
238
-
239
- addAttributes() {
240
- return {
241
- kind: {
242
- default: 'html'
243
- },
244
- raw: {
245
- default: ''
246
- }
247
- }
248
- },
249
-
250
- parseHTML() {
251
- return [
252
- {
253
- tag: 'div[data-content-editor-raw-block]',
254
- getAttrs: (element) => {
255
- if (!(element instanceof HTMLElement)) return false
256
-
257
- return {
258
- kind: getRawContentKind(element.dataset.contentEditorRawBlock),
259
- raw: element.dataset.raw ?? ''
260
- }
261
- }
262
- }
263
- ]
264
- },
265
-
266
- renderHTML({ HTMLAttributes, node }) {
267
- const raw = getStringAttr(node.attrs.raw)
268
- const kind = getRawContentKind(node.attrs.kind)
269
-
270
- return [
271
- 'div',
272
- mergeAttributes(HTMLAttributes, {
273
- 'data-content-editor-raw-block': kind,
274
- 'data-raw': raw
275
- })
276
- ]
277
- },
278
-
279
- parseMarkdown: (token) => {
280
- const rawToken = getRawContentToken(token)
281
-
282
- return {
283
- type: 'rawContentBlock',
284
- attrs: {
285
- kind: getRawContentKind(rawToken.kind),
286
- raw: rawToken.raw ?? rawToken.text ?? ''
287
- }
288
- }
289
- },
290
-
291
- renderMarkdown: (node) => {
292
- return getStringAttr(node.attrs?.raw)
293
- },
294
-
295
- markdownTokenizer: {
296
- name: 'rawContentBlock',
297
- level: 'block',
298
- start: findRawContentStart,
299
- tokenize(src) {
300
- const match = matchRawContentBlock(src)
301
- if (!match) return undefined
302
-
303
- return {
304
- type: 'rawContentBlock',
305
- raw: match.raw,
306
- text: match.raw,
307
- kind: match.kind
308
- }
309
- }
310
- },
311
-
312
- addNodeView() {
313
- return ({ getPos, node, view }) => {
314
- return new RawContentBlockNodeView({ getPos, node, view })
315
- }
316
- }
317
- })
318
-
319
- class RawContentBlockNodeView {
320
- readonly dom: HTMLElement
321
- private readonly preview: HTMLElement
322
- private readonly abortController = new AbortController()
323
- private currentRaw: string
324
- private node: ProseMirrorNode
325
-
326
- constructor(private readonly options: RawContentBlockNodeViewOptions) {
327
- this.node = options.node
328
- this.currentRaw = getStringAttr(options.node.attrs.raw)
329
-
330
- const kind = getRawContentKind(options.node.attrs.kind)
331
- this.dom = document.createElement('div')
332
- this.dom.dataset.contentEditorRawBlock = kind
333
- this.dom.dataset.raw = this.currentRaw
334
- this.dom.contentEditable = 'false'
335
- this.dom.className =
336
- 'content-editor-raw-block not-prose my-4 overflow-hidden rounded-md border bg-muted/20'
337
-
338
- this.preview = document.createElement('div')
339
- this.preview.contentEditable = 'true'
340
- this.preview.dataset.contentEditorRawEditable = 'true'
341
- this.preview.setAttribute('role', 'textbox')
342
- this.preview.setAttribute('aria-label', 'Editable rendered HTML')
343
- this.preview.spellcheck = true
344
- this.preview.className =
345
- 'content-editor-raw-block-preview overflow-auto p-4 outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50'
346
- this.render(this.currentRaw, kind)
347
-
348
- this.preview.addEventListener('input', this.handleInput, {
349
- signal: this.abortController.signal
350
- })
351
- this.preview.addEventListener('blur', this.handleInput, {
352
- signal: this.abortController.signal
353
- })
354
- this.dom.append(this.preview)
355
- }
356
-
357
- update(node: ProseMirrorNode) {
358
- if (node.type !== this.node.type) return false
359
-
360
- this.node = node
361
- const nextKind = getRawContentKind(node.attrs.kind)
362
- const nextRaw = getStringAttr(node.attrs.raw)
363
- this.dom.dataset.contentEditorRawBlock = nextKind
364
- this.dom.dataset.raw = nextRaw
365
-
366
- if (nextRaw !== this.currentRaw) {
367
- this.currentRaw = nextRaw
368
- this.render(nextRaw, nextKind)
369
- }
370
-
371
- return true
372
- }
373
-
374
- stopEvent(event: Event) {
375
- const kind = getRawContentKind(this.node.attrs.kind)
376
-
377
- return (
378
- kind !== 'math' &&
379
- event.target instanceof globalThis.Node &&
380
- this.preview.contains(event.target)
381
- )
382
- }
383
-
384
- ignoreMutation() {
385
- return true
386
- }
387
-
388
- destroy() {
389
- this.abortController.abort()
390
- }
391
-
392
- private readonly handleInput = () => {
393
- const kind = getRawContentKind(this.node.attrs.kind)
394
- if (kind === 'math') return
395
-
396
- const nextRaw = serializeRawContentPreview(this.preview, kind)
397
-
398
- if (nextRaw === this.currentRaw) return
399
-
400
- this.currentRaw = nextRaw
401
- this.dom.dataset.raw = nextRaw
402
-
403
- const position = this.options.getPos()
404
- if (typeof position !== 'number') return
405
-
406
- this.options.view.dispatch(
407
- this.options.view.state.tr.setNodeMarkup(position, undefined, {
408
- ...this.node.attrs,
409
- raw: nextRaw
410
- })
411
- )
412
- }
413
-
414
- private render(raw: string, kind: RawContentKind) {
415
- this.preview.contentEditable = kind === 'math' ? 'false' : 'true'
416
- this.preview.setAttribute(
417
- 'aria-label',
418
- kind === 'math' ? 'Rendered LaTeX' : 'Editable rendered HTML'
419
- )
420
- this.preview.innerHTML = renderRawContentPreview(raw, kind)
421
- }
422
- }
423
-
424
- class InlineMathNodeView {
425
- readonly dom: HTMLElement
426
- private currentRaw: string
427
- private currentDelimiter: InlineMathDelimiter
428
- private node: ProseMirrorNode
429
-
430
- constructor(node: ProseMirrorNode) {
431
- this.node = node
432
- this.currentRaw = getStringAttr(node.attrs.raw)
433
- this.currentDelimiter = getInlineMathDelimiter(node.attrs.delimiter)
434
- this.dom = document.createElement('span')
435
- this.dom.dataset.contentEditorInlineMath = ''
436
- this.dom.contentEditable = 'false'
437
- this.dom.className = 'content-editor-inline-math rounded-[3px] px-0.5'
438
- this.render()
439
- }
440
-
441
- update(node: ProseMirrorNode) {
442
- if (node.type !== this.node.type) return false
443
-
444
- this.node = node
445
- const nextRaw = getStringAttr(node.attrs.raw)
446
- const nextDelimiter = getInlineMathDelimiter(node.attrs.delimiter)
447
-
448
- if (nextRaw !== this.currentRaw || nextDelimiter !== this.currentDelimiter) {
449
- this.currentRaw = nextRaw
450
- this.currentDelimiter = nextDelimiter
451
- this.render()
452
- }
453
-
454
- return true
455
- }
456
-
457
- ignoreMutation() {
458
- return true
459
- }
460
-
461
- private render() {
462
- this.dom.dataset.raw = this.currentRaw
463
- this.dom.dataset.delimiter = this.currentDelimiter
464
- this.dom.innerHTML = renderLatex(this.currentRaw, false)
465
- }
466
- }
467
-
468
- function createHtmlMark(name: string, tag: 'kbd' | 'sub' | 'sup') {
469
- return Mark.create({
470
- name,
471
-
472
- parseHTML() {
473
- return [{ tag }]
474
- },
475
-
476
- renderHTML({ HTMLAttributes }) {
477
- return [tag, mergeAttributes(HTMLAttributes), 0]
478
- },
479
-
480
- markdownOptions: {
481
- htmlReopen: {
482
- open: `<${tag}>`,
483
- close: `</${tag}>`
484
- }
485
- },
486
-
487
- renderMarkdown: (node, helpers) => {
488
- return `<${tag}>${helpers.renderChildren(node)}</${tag}>`
489
- }
490
- })
491
- }
492
-
493
- function findRawContentStart(src: string) {
494
- const indexes = [
495
- src.search(/^\\\[/m),
496
- src.search(/^\$\$/m),
497
- src.search(/^\\begin\{/m),
498
- src.search(new RegExp(`^<(${rawHtmlBlockTags})\\b`, 'im')),
499
- src.search(new RegExp(`^<(${selfClosingHtmlBlockTags})\\b`, 'im'))
500
- ].filter((index) => index >= 0)
501
-
502
- return indexes.length > 0 ? Math.min(...indexes) : -1
503
- }
504
-
505
- function matchRawContentBlock(src: string): RawContentMatch | null {
506
- return matchBlockMath(src) ?? matchHtmlBlock(src) ?? null
507
- }
508
-
509
- function matchBlockMath(src: string): RawContentMatch | null {
510
- const bracketMatch = /^\\\[[\s\S]*?\\\][ \t]*(?:\n|$)/.exec(src)
511
- if (bracketMatch) {
512
- return {
513
- kind: 'math',
514
- raw: bracketMatch[0].trimEnd()
515
- }
516
- }
517
-
518
- const dollarMatch = /^\$\$[\s\S]*?\$\$[ \t]*(?:\n|$)/.exec(src)
519
- if (dollarMatch) {
520
- return {
521
- kind: 'math',
522
- raw: dollarMatch[0].trimEnd()
523
- }
524
- }
525
-
526
- const environmentMatch = /^\\begin\{([^}]+)\}[\s\S]*?\\end\{\1\}[ \t]*(?:\n|$)/.exec(src)
527
- if (environmentMatch && mathBlockEnvironmentNames.has(environmentMatch[1])) {
528
- return {
529
- kind: 'math',
530
- raw: environmentMatch[0].trimEnd()
531
- }
532
- }
533
-
534
- return null
535
- }
536
-
537
- function matchHtmlBlock(src: string): RawContentMatch | null {
538
- const pairedTagMatch = new RegExp(
539
- `^<(${rawHtmlBlockTags})\\b[\\s\\S]*?<\\/\\1>[ \\t]*(?:\\n|$)`,
540
- 'i'
541
- ).exec(src)
542
-
543
- if (pairedTagMatch) {
544
- return {
545
- kind: 'html',
546
- raw: pairedTagMatch[0].trimEnd()
547
- }
548
- }
549
-
550
- const selfClosingMatch = new RegExp(
551
- `^<(${selfClosingHtmlBlockTags})\\b[^>]*(?:\\/?>)[ \\t]*(?:\\n|$)`,
552
- 'i'
553
- ).exec(src)
554
-
555
- if (!selfClosingMatch) return null
556
-
557
- return {
558
- kind: 'html',
559
- raw: selfClosingMatch[0].trimEnd()
560
- }
561
- }
562
-
563
- function renderRawContentPreview(raw: string, kind: RawContentKind) {
564
- if (kind === 'math') {
565
- return renderLatex(getBlockMathExpression(raw), true)
566
- }
567
-
568
- if (/^<details\b/i.test(raw.trim())) {
569
- return renderDetailsPreview(raw)
570
- }
571
-
572
- return sanitizeHtmlPreview(raw)
573
- }
574
-
575
- function serializeRawContentPreview(preview: HTMLElement, kind: RawContentKind) {
576
- if (kind === 'math') {
577
- return ''
578
- }
579
-
580
- return sanitizeHtmlPreview(preview.innerHTML).trim()
581
- }
582
-
583
- function findInlineMathStart(src: string) {
584
- const dollarIndex = findUnescapedCharacter(src, '$', 0)
585
- const parenIndex = findUnescapedSequence(src, '\\(', 0)
586
- const indexes = [dollarIndex, parenIndex].filter((index) => index >= 0)
587
-
588
- return indexes.length > 0 ? Math.min(...indexes) : -1
589
- }
590
-
591
- function matchInlineMath(src: string): InlineMathMatch | null {
592
- if (src.startsWith('\\(')) {
593
- const closingIndex = findUnescapedSequence(src, '\\)', 2)
594
- if (closingIndex === -1) return null
595
-
596
- return {
597
- raw: src.slice(0, closingIndex + 2),
598
- text: src.slice(2, closingIndex),
599
- delimiter: '\\('
600
- }
601
- }
602
-
603
- if (!src.startsWith('$') || src.startsWith('$$')) return null
604
-
605
- if (src[1] && /\s/u.test(src[1])) return null
606
-
607
- let closingIndex = 1
608
-
609
- while (closingIndex < src.length) {
610
- closingIndex = findUnescapedCharacter(src, '$', closingIndex)
611
- if (closingIndex === -1) return null
612
-
613
- const text = src.slice(1, closingIndex)
614
- if (isValidDollarInlineMath(src, text, closingIndex)) {
615
- return {
616
- raw: src.slice(0, closingIndex + 1),
617
- text,
618
- delimiter: '$'
619
- }
620
- }
621
-
622
- closingIndex++
623
- }
624
-
625
- return null
626
- }
627
-
628
- function isValidDollarInlineMath(src: string, text: string, closingIndex: number) {
629
- if (!text.trim() || text.includes('\n')) return false
630
- if (/^\s|\s$/u.test(text)) return false
631
-
632
- const nextCharacter = src[closingIndex + 1]
633
- if (nextCharacter && nextCharacter.trim() !== '' && !Number.isNaN(Number(nextCharacter))) {
634
- return false
635
- }
636
-
637
- return true
638
- }
639
-
640
- function findUnescapedCharacter(value: string, character: string, start: number) {
641
- for (let index = start; index < value.length; index++) {
642
- if (value[index] !== character) continue
643
- if (isEscaped(value, index)) continue
644
- return index
645
- }
646
-
647
- return -1
648
- }
649
-
650
- function findUnescapedSequence(value: string, sequence: string, start: number) {
651
- let index = value.indexOf(sequence, start)
652
-
653
- while (index !== -1) {
654
- if (!isEscaped(value, index)) return index
655
- index = value.indexOf(sequence, index + sequence.length)
656
- }
657
-
658
- return -1
659
- }
660
-
661
- function isEscaped(value: string, index: number) {
662
- let slashCount = 0
663
-
664
- for (let offset = index - 1; offset >= 0 && value[offset] === '\\'; offset--) {
665
- slashCount++
666
- }
667
-
668
- return slashCount % 2 === 1
669
- }
670
-
671
- function getBlockMathExpression(raw: string) {
672
- const value = raw.trim()
673
-
674
- if (value.startsWith('\\[') && value.endsWith('\\]')) {
675
- return value.slice(2, -2).trim()
676
- }
677
-
678
- if (value.startsWith('$$') && value.endsWith('$$')) {
679
- return value.slice(2, -2).trim()
680
- }
681
-
682
- return value
683
- }
684
-
685
- function renderLatex(expression: string, displayMode: boolean) {
686
- if (!expression.trim()) return ''
687
-
688
- try {
689
- return katex.renderToString(expression, {
690
- displayMode,
691
- output: 'htmlAndMathml',
692
- strict: 'ignore',
693
- throwOnError: false,
694
- trust: false
695
- })
696
- } catch {
697
- return `<span class="text-destructive">${escapeHtml(expression)}</span>`
698
- }
699
- }
700
-
701
- function renderDetailsPreview(raw: string) {
702
- const match =
703
- /^<details\b[^>]*>\s*<summary\b[^>]*>([\s\S]*?)<\/summary>([\s\S]*?)<\/details>$/i.exec(
704
- raw.trim()
705
- )
706
-
707
- if (!match) {
708
- return sanitizeHtmlPreview(raw)
709
- }
710
-
711
- const summary = escapeHtml(stripHtml(match[1]).trim())
712
- const body = renderSimpleMarkdownBody(match[2])
713
-
714
- return sanitizeHtmlPreview(`<details><summary>${summary}</summary>${body}</details>`)
715
- }
716
-
717
- function renderSimpleMarkdownBody(markdown: string) {
718
- const lines = markdown.trim().split('\n')
719
- const blocks: string[] = []
720
- let paragraph: string[] = []
721
- let listItems: string[] = []
722
-
723
- const flushParagraph = () => {
724
- if (paragraph.length === 0) return
725
- blocks.push(`<p>${escapeHtml(paragraph.join(' ').trim())}</p>`)
726
- paragraph = []
727
- }
728
-
729
- const flushList = () => {
730
- if (listItems.length === 0) return
731
- blocks.push(`<ul>${listItems.map((item) => `<li>${escapeHtml(item)}</li>`).join('')}</ul>`)
732
- listItems = []
733
- }
734
-
735
- for (const line of lines) {
736
- const trimmedLine = line.trim()
737
- if (!trimmedLine) {
738
- flushParagraph()
739
- flushList()
740
- continue
741
- }
742
-
743
- const listMatch = /^[-*]\s+(.+)$/.exec(trimmedLine)
744
- if (listMatch) {
745
- flushParagraph()
746
- listItems.push(listMatch[1])
747
- continue
748
- }
749
-
750
- flushList()
751
- paragraph.push(trimmedLine)
752
- }
753
-
754
- flushParagraph()
755
- flushList()
756
-
757
- return blocks.join('')
758
- }
759
-
760
- function sanitizeHtmlPreview(html: string) {
761
- const template = document.createElement('template')
762
- template.innerHTML = html
763
- const elementsToRemove: Element[] = []
764
- const walker = document.createTreeWalker(template.content, NodeFilter.SHOW_ELEMENT)
765
-
766
- while (walker.nextNode()) {
767
- const element = walker.currentNode as HTMLElement
768
- const tagName = element.tagName.toLowerCase()
769
-
770
- if (blockedHtmlPreviewTags.has(tagName)) {
771
- elementsToRemove.push(element)
772
- continue
773
- }
774
-
775
- for (const attr of Array.from(element.attributes)) {
776
- const attrName = attr.name.toLowerCase()
777
- const attrValue = attr.value.trim().toLowerCase()
778
-
779
- if (
780
- attrName.startsWith('on') ||
781
- attrName === 'srcdoc' ||
782
- (urlAttributes.has(attrName) && attrValue.startsWith('javascript:'))
783
- ) {
784
- element.removeAttribute(attr.name)
785
- }
786
- }
787
- }
788
-
789
- for (const element of elementsToRemove) {
790
- element.remove()
791
- }
792
-
793
- return template.innerHTML
794
- }
795
-
796
- function stripHtml(value: string) {
797
- return value.replace(/<[^>]+>/g, '')
798
- }
799
-
800
- function getRawContentToken(token: unknown): RawContentToken {
801
- if (!token || typeof token !== 'object') return {}
802
- return token as RawContentToken
803
- }
804
-
805
- function getInlineMathDelimiter(value: unknown): InlineMathDelimiter {
806
- return value === '\\(' ? '\\(' : '$'
807
- }
808
-
809
- function getRawContentKind(value: unknown): RawContentKind {
810
- return value === 'math' ? value : 'html'
811
- }
812
-
813
- function getStringAttr(value: unknown) {
814
- return typeof value === 'string' ? value : ''
815
- }
816
-
817
- function escapeHtml(value: string) {
818
- return value
819
- .replaceAll('&', '&amp;')
820
- .replaceAll('<', '&lt;')
821
- .replaceAll('>', '&gt;')
822
- .replaceAll('"', '&quot;')
823
- .replaceAll("'", '&#39;')
824
- }