@carlonicora/nextjs-jsonapi 4.1.2 → 4.2.1

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 (285) hide show
  1. package/dist/{AssistantMessageInterface-CubxuBIJ.d.ts → AssistantMessageInterface-DHJJO_Z_.d.ts} +1 -1
  2. package/dist/{AssistantMessageInterface-sHjI2zPN.d.mts → AssistantMessageInterface-S7oyERTT.d.mts} +1 -1
  3. package/dist/{BlockNoteEditor-VOYKZOP5.mjs → BlockNoteEditor-HXAHDJA7.mjs} +34 -27
  4. package/dist/BlockNoteEditor-HXAHDJA7.mjs.map +1 -0
  5. package/dist/{BlockNoteEditor-BENYTTCZ.js → BlockNoteEditor-LLCZDFLZ.js} +50 -43
  6. package/dist/BlockNoteEditor-LLCZDFLZ.js.map +1 -0
  7. package/dist/{BlockNoteViewer-USLR4Y7C.js → BlockNoteViewer-77CCTC2U.js} +3 -3
  8. package/dist/{BlockNoteViewer-USLR4Y7C.js.map → BlockNoteViewer-77CCTC2U.js.map} +1 -1
  9. package/dist/{BlockNoteViewer-Y2ZM4ESA.mjs → BlockNoteViewer-MDPO6BXN.mjs} +2 -2
  10. package/dist/{auth.interface-Df4vXbNz.d.mts → auth.interface-CeFCz9NU.d.mts} +1 -1
  11. package/dist/{auth.interface-BzI4onI_.d.ts → auth.interface-D1R7VVky.d.ts} +1 -1
  12. package/dist/billing/index.d.mts +40 -6
  13. package/dist/billing/index.d.ts +40 -6
  14. package/dist/billing/index.js +806 -774
  15. package/dist/billing/index.js.map +1 -1
  16. package/dist/billing/index.mjs +494 -462
  17. package/dist/billing/index.mjs.map +1 -1
  18. package/dist/{chunk-6ISF5KNQ.mjs → chunk-2VXDZRYY.mjs} +1103 -816
  19. package/dist/chunk-2VXDZRYY.mjs.map +1 -0
  20. package/dist/{chunk-4BZJ4LAB.js → chunk-4ORLPEK7.js} +136 -104
  21. package/dist/chunk-4ORLPEK7.js.map +1 -0
  22. package/dist/{chunk-ZZ6E33FO.mjs → chunk-6DRSSW5O.mjs} +36 -4
  23. package/dist/chunk-6DRSSW5O.mjs.map +1 -0
  24. package/dist/{chunk-KS6WZP2E.js → chunk-6SMJRAE3.js} +4 -4
  25. package/dist/{chunk-KS6WZP2E.js.map → chunk-6SMJRAE3.js.map} +1 -1
  26. package/dist/{chunk-WQ77CUUZ.js → chunk-GPXYQMOZ.js} +7 -7
  27. package/dist/{chunk-WQ77CUUZ.js.map → chunk-GPXYQMOZ.js.map} +1 -1
  28. package/dist/{chunk-46S3KPLU.mjs → chunk-ILFFC6BG.mjs} +2 -2
  29. package/dist/{chunk-HZVVRIJQ.mjs → chunk-IUS2RHCX.mjs} +2 -2
  30. package/dist/{chunk-F7RNBGHS.js → chunk-KJMMBUOA.js} +3 -3
  31. package/dist/{chunk-F7RNBGHS.js.map → chunk-KJMMBUOA.js.map} +1 -1
  32. package/dist/{chunk-ZO3QQ5CQ.mjs → chunk-MQDR6MEE.mjs} +2 -2
  33. package/dist/{chunk-ORU7KLCY.js → chunk-VDVIUDY5.js} +1445 -1158
  34. package/dist/chunk-VDVIUDY5.js.map +1 -0
  35. package/dist/client/index.d.mts +20 -6
  36. package/dist/client/index.d.ts +20 -6
  37. package/dist/client/index.js +6 -4
  38. package/dist/client/index.js.map +1 -1
  39. package/dist/client/index.mjs +5 -3
  40. package/dist/components/index.d.mts +59 -21
  41. package/dist/components/index.d.ts +59 -21
  42. package/dist/components/index.js +4 -4
  43. package/dist/components/index.mjs +3 -3
  44. package/dist/{config-CEAq4Ozy.d.mts → config-BP2vyddw.d.mts} +5 -0
  45. package/dist/{config-DydDHCfb.d.ts → config-BhW2QrRD.d.ts} +5 -0
  46. package/dist/contexts/index.d.mts +4 -4
  47. package/dist/contexts/index.d.ts +4 -4
  48. package/dist/contexts/index.js +4 -4
  49. package/dist/contexts/index.mjs +3 -3
  50. package/dist/core/index.d.mts +17 -9
  51. package/dist/core/index.d.ts +17 -9
  52. package/dist/core/index.js +4 -2
  53. package/dist/core/index.js.map +1 -1
  54. package/dist/core/index.mjs +3 -1
  55. package/dist/features/analytics/index.d.mts +1 -1
  56. package/dist/features/analytics/index.d.ts +1 -1
  57. package/dist/features/analytics/index.js +122 -122
  58. package/dist/features/analytics/index.mjs +4 -4
  59. package/dist/features/analytics/server.js +4 -4
  60. package/dist/features/analytics/server.mjs +2 -2
  61. package/dist/features/help/index.d.mts +1 -1
  62. package/dist/features/help/index.d.ts +1 -1
  63. package/dist/features/help/index.js +42 -40
  64. package/dist/features/help/index.js.map +1 -1
  65. package/dist/features/help/index.mjs +8 -6
  66. package/dist/features/help/index.mjs.map +1 -1
  67. package/dist/features/tokenusage/index.js +125 -125
  68. package/dist/features/tokenusage/index.mjs +4 -4
  69. package/dist/index.d.mts +7 -7
  70. package/dist/index.d.ts +7 -7
  71. package/dist/index.js +5 -3
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +4 -2
  74. package/dist/{notification.interface-P_pNfzZQ.d.mts → notification.interface-BB6GPpZY.d.mts} +1 -1
  75. package/dist/{notification.interface-BNCvnVCW.d.ts → notification.interface-CmAGrijJ.d.ts} +1 -1
  76. package/dist/{s3.service-CbUa6a-8.d.ts → s3.service-C-4YpEMu.d.ts} +7 -3
  77. package/dist/{s3.service-DAp8FbuG.d.mts → s3.service-dVj-nxMl.d.mts} +7 -3
  78. package/dist/server/index.d.mts +4 -4
  79. package/dist/server/index.d.ts +4 -4
  80. package/dist/server/index.js +3 -3
  81. package/dist/server/index.mjs +2 -2
  82. package/dist/{useSocket-BHVIyigI.d.ts → useSocket-B0H9pmmH.d.ts} +1 -1
  83. package/dist/{useSocket-B9gTbuCj.d.mts → useSocket-B5RQb6v2.d.mts} +1 -1
  84. package/dist/{user.interface-CrmwJLYW.d.ts → user.interface-C0ZdsBZj.d.ts} +2 -0
  85. package/dist/{user.interface-CSaGWFbg.d.mts → user.interface-CIWGlbqM.d.mts} +2 -0
  86. package/package.json +1 -1
  87. package/src/components/containers/RoundPageContainer.tsx +3 -1
  88. package/src/components/containers/RoundPageContainerTitle.tsx +5 -2
  89. package/src/components/editors/BlockNoteEditor.tsx +31 -15
  90. package/src/components/editors/BlockNoteEditorAiActions.tsx +11 -7
  91. package/src/components/editors/__tests__/{BlockNoteEditorAiActions.test.ts → BlockNoteEditorAiActions.spec.ts} +10 -3
  92. package/src/components/errors/ErrorDetails.tsx +5 -2
  93. package/src/components/forms/CommonAssociationForm.tsx +1 -1
  94. package/src/components/forms/EntityMultiSelector.tsx +6 -2
  95. package/src/components/forms/EntitySelector.tsx +4 -1
  96. package/src/components/forms/FileUploader.tsx +3 -2
  97. package/src/components/forms/MultiFileUploader.tsx +3 -1
  98. package/src/components/navigations/Breadcrumb.tsx +3 -2
  99. package/src/components/navigations/Header.tsx +3 -1
  100. package/src/components/navigations/MobileNavigationBar.tsx +3 -1
  101. package/src/components/navigations/__tests__/Header.spec.tsx +2 -2
  102. package/src/components/tables/__tests__/ContentListTable.spec.tsx +1 -1
  103. package/src/components/tables/cells/cell.id.tsx +13 -2
  104. package/src/core/abstracts/AbstractService.ts +3 -3
  105. package/src/core/abstracts/ClientAbstractService.ts +3 -2
  106. package/src/features/assistant-action/components/ApprovalActionCard.tsx +74 -5
  107. package/src/features/assistant-action/components/__tests__/ApprovalActionCard.spec.tsx +81 -0
  108. package/src/features/assistant-message/components/parts/RelevanceMeter.tsx +4 -1
  109. package/src/features/assistant-message/components/parts/tabs/UsersTab.tsx +2 -1
  110. package/src/features/auth/components/buttons/GoogleSignInButton.tsx +4 -1
  111. package/src/features/auth/components/details/LandingComponent.tsx +1 -1
  112. package/src/features/auth/components/forms/ForgotPassword.tsx +1 -1
  113. package/src/features/auth/components/forms/Login.tsx +1 -1
  114. package/src/features/auth/components/forms/Register.tsx +1 -1
  115. package/src/features/auth/components/forms/ResetPassword.tsx +2 -2
  116. package/src/features/auth/components/two-factor/BackupCodesDialog.tsx +1 -1
  117. package/src/features/auth/components/two-factor/PasskeyButton.tsx +1 -1
  118. package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +21 -11
  119. package/src/features/billing/components/cards/CustomerInfoCard.tsx +16 -13
  120. package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +33 -21
  121. package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +20 -10
  122. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +35 -22
  123. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +24 -24
  124. package/src/features/billing/components/utils/__tests__/billing-formatters.spec.ts +63 -0
  125. package/src/features/billing/components/utils/currency.ts +67 -10
  126. package/src/features/billing/components/utils/date.ts +9 -4
  127. package/src/features/billing/components/utils/format-options.ts +20 -0
  128. package/src/features/billing/components/utils/index.ts +3 -1
  129. package/src/features/billing/components/utils/useBillingFormatOptions.ts +11 -0
  130. package/src/features/billing/components/widgets/BillingAlertBanner.tsx +8 -9
  131. package/src/features/billing/contexts/PriceContext.tsx +18 -6
  132. package/src/features/billing/i18n-keys.ts +212 -0
  133. package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +8 -8
  134. package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +11 -9
  135. package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +4 -4
  136. package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +9 -7
  137. package/src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx +10 -8
  138. package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +34 -29
  139. package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +12 -9
  140. package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +9 -6
  141. package/src/features/billing/stripe-price/components/details/PriceDetails.tsx +4 -3
  142. package/src/features/billing/stripe-price/components/forms/PriceArchiver.tsx +3 -1
  143. package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +3 -1
  144. package/src/features/billing/stripe-price/hooks/useStripePriceTableStructure.tsx +6 -5
  145. package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +12 -7
  146. package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.service.ts +3 -1
  147. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +10 -6
  148. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +44 -29
  149. package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +14 -11
  150. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +20 -17
  151. package/src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx +4 -2
  152. package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +16 -7
  153. package/src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx +3 -1
  154. package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +3 -1
  155. package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +12 -7
  156. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +11 -8
  157. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +13 -10
  158. package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +8 -6
  159. package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +7 -4
  160. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +4 -2
  161. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx +3 -1
  162. package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +37 -28
  163. package/src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts +9 -7
  164. package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +20 -9
  165. package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +6 -6
  166. package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +24 -9
  167. package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +16 -12
  168. package/src/features/company/components/details/TokenStatusIndicator.tsx +7 -5
  169. package/src/features/company/components/forms/CompanyEditor.tsx +2 -2
  170. package/src/features/help/components/HelpArticleBody.tsx +1 -1
  171. package/src/features/help/components/HelpHeader.tsx +1 -1
  172. package/src/features/help/components/HelpSideNav.tsx +1 -1
  173. package/src/features/help/i18n-keys.ts +2 -0
  174. package/src/features/notification/components/common/NotificationErrorBoundary.tsx +17 -12
  175. package/src/features/notification/components/containers/NotificationsListContainer.tsx +4 -2
  176. package/src/features/notification/components/notifications/Notification.tsx +6 -3
  177. package/src/features/notification/contexts/NotificationContext.tsx +9 -4
  178. package/src/features/notification/contexts/__tests__/NotificationContext.spec.tsx +13 -0
  179. package/src/features/notification/hooks/useNotificationTableStructure.tsx +4 -2
  180. package/src/features/oauth/components/OAuthClientCard.tsx +13 -7
  181. package/src/features/oauth/components/OAuthClientDetail.tsx +34 -30
  182. package/src/features/oauth/components/OAuthClientForm.tsx +24 -24
  183. package/src/features/oauth/components/OAuthClientList.tsx +10 -6
  184. package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +10 -8
  185. package/src/features/oauth/components/OAuthRedirectUriInput.tsx +9 -13
  186. package/src/features/oauth/components/OAuthScopeSelector.tsx +15 -6
  187. package/src/features/oauth/components/__tests__/OAuthClientForm.spec.tsx +11 -9
  188. package/src/features/oauth/components/consent/OAuthScopeList.tsx +4 -2
  189. package/src/features/oauth/hooks/__tests__/useOAuthScopeText.spec.ts +30 -0
  190. package/src/features/oauth/hooks/index.ts +1 -0
  191. package/src/features/oauth/hooks/useOAuthClient.ts +11 -5
  192. package/src/features/oauth/hooks/useOAuthClients.ts +9 -3
  193. package/src/features/oauth/hooks/useOAuthConsent.ts +11 -5
  194. package/src/features/oauth/hooks/useOAuthScopeText.ts +33 -0
  195. package/src/features/rbac/components/RbacByRoleContainer.tsx +7 -6
  196. package/src/features/rbac/components/RbacContainer.tsx +7 -6
  197. package/src/features/rbac/contexts/RbacContext.tsx +3 -3
  198. package/src/features/user/components/containers/UserContainer.tsx +3 -1
  199. package/src/features/user/data/__tests__/user.spec.ts +66 -0
  200. package/src/features/user/data/user.interface.ts +2 -0
  201. package/src/features/user/data/user.service.ts +9 -0
  202. package/src/features/user/data/user.ts +7 -0
  203. package/src/features/waitlist/components/forms/WaitlistForm.tsx +1 -1
  204. package/src/features/waitlist/components/lists/WaitlistList.tsx +1 -1
  205. package/src/i18n/__tests__/{config.test.ts → config.spec.ts} +21 -1
  206. package/src/i18n/config.ts +13 -0
  207. package/src/i18n/index.ts +1 -0
  208. package/src/shadcnui/custom/multi-select.tsx +47 -14
  209. package/src/shadcnui/custom/multiple-selector.tsx +14 -2
  210. package/src/shadcnui/ui/__tests__/{confirm-dialog.test.tsx → confirm-dialog.spec.tsx} +1 -1
  211. package/src/shadcnui/ui/__tests__/{cursor-controls.test.tsx → cursor-controls.spec.tsx} +1 -1
  212. package/src/shadcnui/ui/__tests__/{cursor-menu-items.test.tsx → cursor-menu-items.spec.tsx} +1 -1
  213. package/src/shadcnui/ui/__tests__/{empty-state.test.tsx → empty-state.spec.tsx} +1 -1
  214. package/src/shadcnui/ui/__tests__/{spinner.test.tsx → spinner.spec.tsx} +1 -1
  215. package/src/shadcnui/ui/__tests__/use-ui-text.spec.tsx +76 -0
  216. package/src/shadcnui/ui/breadcrumb.tsx +9 -2
  217. package/src/shadcnui/ui/carousel.tsx +15 -4
  218. package/src/shadcnui/ui/dialog.tsx +15 -2
  219. package/src/shadcnui/ui/sheet.tsx +6 -1
  220. package/src/shadcnui/ui/sidebar.tsx +33 -7
  221. package/src/shadcnui/ui/spinner.tsx +6 -1
  222. package/src/shadcnui/ui/use-ui-text.ts +49 -0
  223. package/src/utils/__tests__/{date-formatter.test.ts → date-formatter.spec.ts} +24 -1
  224. package/src/utils/date-formatter.ts +16 -0
  225. package/src/utils/index.ts +1 -1
  226. package/dist/BlockNoteEditor-BENYTTCZ.js.map +0 -1
  227. package/dist/BlockNoteEditor-VOYKZOP5.mjs.map +0 -1
  228. package/dist/chunk-4BZJ4LAB.js.map +0 -1
  229. package/dist/chunk-6ISF5KNQ.mjs.map +0 -1
  230. package/dist/chunk-ORU7KLCY.js.map +0 -1
  231. package/dist/chunk-ZZ6E33FO.mjs.map +0 -1
  232. /package/dist/{BlockNoteViewer-Y2ZM4ESA.mjs.map → BlockNoteViewer-MDPO6BXN.mjs.map} +0 -0
  233. /package/dist/{chunk-46S3KPLU.mjs.map → chunk-ILFFC6BG.mjs.map} +0 -0
  234. /package/dist/{chunk-HZVVRIJQ.mjs.map → chunk-IUS2RHCX.mjs.map} +0 -0
  235. /package/dist/{chunk-ZO3QQ5CQ.mjs.map → chunk-MQDR6MEE.mjs.map} +0 -0
  236. /package/scripts/{check-rtl-classes.test.ts → check-rtl-classes.spec.ts} +0 -0
  237. /package/src/client/__tests__/{JsonApiClient.test.ts → JsonApiClient.spec.ts} +0 -0
  238. /package/src/client/__tests__/{request.test.ts → request.spec.ts} +0 -0
  239. /package/src/client/hooks/__tests__/{useJsonApiGet.test.tsx → useJsonApiGet.spec.tsx} +0 -0
  240. /package/src/client/hooks/__tests__/{useJsonApiMutation.test.tsx → useJsonApiMutation.spec.tsx} +0 -0
  241. /package/src/client/hooks/__tests__/{useRehydration.test.ts → useRehydration.spec.ts} +0 -0
  242. /package/src/components/editors/__tests__/{BlockNoteEditorMentionInlineContent.test.ts → BlockNoteEditorMentionInlineContent.spec.ts} +0 -0
  243. /package/src/components/forms/__tests__/{CommonEditorDiscardDialog.test.tsx → CommonEditorDiscardDialog.spec.tsx} +0 -0
  244. /package/src/components/forms/__tests__/{EditorSheet.test.tsx → EditorSheet.spec.tsx} +0 -0
  245. /package/src/components/forms/__tests__/{FormCheckbox.test.tsx → FormCheckbox.spec.tsx} +0 -0
  246. /package/src/components/forms/__tests__/{FormDate.test.tsx → FormDate.spec.tsx} +0 -0
  247. /package/src/components/forms/__tests__/{FormInput.test.tsx → FormInput.spec.tsx} +0 -0
  248. /package/src/components/forms/__tests__/{FormSelect.test.tsx → FormSelect.spec.tsx} +0 -0
  249. /package/src/components/forms/__tests__/{useEditorDialog.test.ts → useEditorDialog.spec.ts} +0 -0
  250. /package/src/components/grids/__tests__/{ContentListGrid.test.tsx → ContentListGrid.spec.tsx} +0 -0
  251. /package/src/components/tables/__tests__/{ContentListTable.test.tsx → ContentListTable.rendering.spec.tsx} +0 -0
  252. /package/src/contexts/__tests__/{DirectionContext.test.tsx → DirectionContext.spec.tsx} +0 -0
  253. /package/src/contexts/__tests__/{SessionContext.test.tsx → SessionContext.spec.tsx} +0 -0
  254. /package/src/contexts/__tests__/{SocketContext.session.test.tsx → SocketContext.session.spec.tsx} +0 -0
  255. /package/src/core/abstracts/__tests__/{AbstractService.locale.test.ts → AbstractService.locale.spec.ts} +0 -0
  256. /package/src/core/endpoint/__tests__/{EndpointCreator.test.ts → EndpointCreator.spec.ts} +0 -0
  257. /package/src/core/factories/__tests__/{JsonApiDataFactory.test.ts → JsonApiDataFactory.spec.ts} +0 -0
  258. /package/src/core/factories/__tests__/{RehydrationFactory.test.ts → RehydrationFactory.spec.ts} +0 -0
  259. /package/src/core/registry/__tests__/{DataClassRegistry.test.ts → DataClassRegistry.spec.ts} +0 -0
  260. /package/src/core/registry/__tests__/{ModuleRegistrar.test.ts → ModuleRegistrar.spec.ts} +0 -0
  261. /package/src/core/registry/__tests__/{viewportStore.test.ts → viewportStore.spec.ts} +0 -0
  262. /package/src/core/utils/__tests__/{translateResponse.test.ts → translateResponse.spec.ts} +0 -0
  263. /package/src/features/ai-connection/data/__tests__/{ai-connection.test.ts → ai-connection.spec.ts} +0 -0
  264. /package/src/features/company/data/{company.test.ts → company.spec.ts} +0 -0
  265. /package/src/features/company/hooks/{useSubscriptionStatus.test.ts → useSubscriptionStatus.spec.ts} +0 -0
  266. /package/src/hooks/__tests__/{useDataListRetriever.test.ts → useDataListRetriever.spec.ts} +0 -0
  267. /package/src/hooks/__tests__/{useDebounce.test.ts → useDebounce.spec.ts} +0 -0
  268. /package/src/hooks/__tests__/{useSocket.render.test.ts → useSocket.render.spec.ts} +0 -0
  269. /package/src/lib/__tests__/{direction.test.ts → direction.spec.ts} +0 -0
  270. /package/src/next-config/__tests__/{createNextConfig.test.ts → createNextConfig.spec.ts} +0 -0
  271. /package/src/server/__tests__/{JsonApiServer.test.ts → JsonApiServer.spec.ts} +0 -0
  272. /package/src/server/__tests__/{ServerSession.read.test.ts → ServerSession.read.spec.ts} +0 -0
  273. /package/src/server/__tests__/{cache.test.ts → cache.spec.ts} +0 -0
  274. /package/src/server/__tests__/{cachedGet.test.ts → cachedGet.spec.ts} +0 -0
  275. /package/src/server/__tests__/{request.test.ts → request.spec.ts} +0 -0
  276. /package/src/shadcnui/ui/__tests__/{sidebar.menu-skeleton.test.tsx → sidebar.menu-skeleton.spec.tsx} +0 -0
  277. /package/src/shadcnui/ui/__tests__/{sidebar.session.test.tsx → sidebar.session.spec.tsx} +0 -0
  278. /package/src/unified/__tests__/{JsonApiGet.cache.test.ts → JsonApiGet.cache.spec.ts} +0 -0
  279. /package/src/unified/__tests__/{JsonApiRequest.test.ts → JsonApiRequest.spec.ts} +0 -0
  280. /package/src/utils/__tests__/{exists.test.ts → exists.spec.ts} +0 -0
  281. /package/src/utils/__tests__/{italian-validators.test.ts → italian-validators.spec.ts} +0 -0
  282. /package/src/utils/__tests__/{map-thenable.test.ts → map-thenable.spec.ts} +0 -0
  283. /package/src/utils/__tests__/{use-mobile.test.tsx → use-mobile.spec.tsx} +0 -0
  284. /package/src/utils/{cn.test.ts → cn.spec.ts} +0 -0
  285. /package/src/utils/{isRemoteImageSrc.test.ts → isRemoteImageSrc.spec.ts} +0 -0
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
2
 
3
3
 
4
4
 
@@ -6,10 +6,10 @@
6
6
 
7
7
 
8
8
 
9
- var _chunkORU7KLCYjs = require('./chunk-ORU7KLCY.js');
9
+ var _chunkVDVIUDY5js = require('./chunk-VDVIUDY5.js');
10
10
 
11
11
 
12
- var _chunkWQ77CUUZjs = require('./chunk-WQ77CUUZ.js');
12
+ var _chunkGPXYQMOZjs = require('./chunk-GPXYQMOZ.js');
13
13
  require('./chunk-G4JR3SFV.js');
14
14
 
15
15
 
@@ -17,7 +17,7 @@ require('./chunk-G4JR3SFV.js');
17
17
 
18
18
 
19
19
 
20
- var _chunk4BZJ4LABjs = require('./chunk-4BZJ4LAB.js');
20
+ var _chunk4ORLPEK7js = require('./chunk-4ORLPEK7.js');
21
21
 
22
22
 
23
23
  var _chunkLXKSUWAVjs = require('./chunk-LXKSUWAV.js');
@@ -30,7 +30,7 @@ var _chunk7QVYU63Ejs = require('./chunk-7QVYU63E.js');
30
30
 
31
31
  // src/components/editors/BlockNoteEditor.tsx
32
32
  var _core = require('@blocknote/core');
33
- var _locales = require('@blocknote/core/locales');
33
+ var _locales = require('@blocknote/core/locales'); var coreLocales = _interopRequireWildcard(_locales);
34
34
 
35
35
 
36
36
 
@@ -50,7 +50,7 @@ require('@blocknote/shadcn/style.css');
50
50
 
51
51
 
52
52
  var _xlai = require('@blocknote/xl-ai');
53
- var _locales3 = require('@blocknote/xl-ai/locales');
53
+ var _locales2 = require('@blocknote/xl-ai/locales'); var aiLocales = _interopRequireWildcard(_locales2);
54
54
  require('@blocknote/xl-ai/style.css');
55
55
  var _ai = require('ai');
56
56
  var _lucidereact = require('lucide-react');
@@ -65,24 +65,24 @@ var DEFAULT_AI_GENERATE_ACTIONS = ["fill-template"];
65
65
  var ITEMS = {
66
66
  "fill-template": {
67
67
  key: "generate_from_template",
68
- title: "Generate from Template",
68
+ titleKey: "ui.editor.ai.generate_from_template",
69
69
  aliases: ["generate", "template", "fill"],
70
70
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LayoutTemplateIcon, { size: 18 }),
71
71
  size: "small"
72
72
  },
73
73
  "draft-impression": {
74
74
  key: "suggest_impression",
75
- title: "Suggest impression",
75
+ titleKey: "ui.editor.ai.suggest_impression",
76
76
  aliases: ["suggest", "impression"],
77
77
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { size: 18 }),
78
78
  size: "small"
79
79
  }
80
80
  };
81
- function generateActionItems(actions, invoke) {
82
- return (_nullishCoalesce(actions, () => ( DEFAULT_AI_GENERATE_ACTIONS))).map((type) => ({
83
- ...ITEMS[type],
84
- onItemClick: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => invoke(type), "onItemClick")
85
- }));
81
+ function generateActionItems(actions, invoke, translate) {
82
+ return (_nullishCoalesce(actions, () => ( DEFAULT_AI_GENERATE_ACTIONS))).map((type) => {
83
+ const { titleKey, ...item } = ITEMS[type];
84
+ return { ...item, title: translate(titleKey), onItemClick: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => invoke(type), "onItemClick") };
85
+ });
86
86
  }
87
87
  _chunk7QVYU63Ejs.__name.call(void 0, generateActionItems, "generateActionItems");
88
88
 
@@ -150,7 +150,7 @@ function isDocumentEmpty(blocks) {
150
150
  return blocks.every(isBlockEmpty);
151
151
  }
152
152
  _chunk7QVYU63Ejs.__name.call(void 0, isDocumentEmpty, "isDocumentEmpty");
153
- var createDiffActionsInlineContentSpec = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (handleAcceptChange, handleRejectChange) => {
153
+ var createDiffActionsInlineContentSpec = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (handleAcceptChange, handleRejectChange, labels) => {
154
154
  return _react.createReactInlineContentSpec.call(void 0,
155
155
  {
156
156
  type: "diffActions",
@@ -166,9 +166,9 @@ var createDiffActionsInlineContentSpec = /* @__PURE__ */ _chunk7QVYU63Ejs.__name
166
166
  const diffIds = props.inlineContent.props.diffIds;
167
167
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "diff-actions-container mx-2 inline-flex items-center gap-1 align-middle", children: [
168
168
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
169
- _chunkORU7KLCYjs.Button,
169
+ _chunkVDVIUDY5js.Button,
170
170
  {
171
- title: "Accept change",
171
+ title: labels.accept,
172
172
  onClick: (e) => {
173
173
  e.preventDefault();
174
174
  e.stopPropagation();
@@ -178,9 +178,9 @@ var createDiffActionsInlineContentSpec = /* @__PURE__ */ _chunk7QVYU63Ejs.__name
178
178
  }
179
179
  ),
180
180
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
181
- _chunkORU7KLCYjs.Button,
181
+ _chunkVDVIUDY5js.Button,
182
182
  {
183
- title: "Reject change",
183
+ title: labels.reject,
184
184
  className: "mx-2 p-0",
185
185
  onClick: (e) => {
186
186
  e.preventDefault();
@@ -196,6 +196,7 @@ var createDiffActionsInlineContentSpec = /* @__PURE__ */ _chunk7QVYU63Ejs.__name
196
196
  );
197
197
  }, "createDiffActionsInlineContentSpec");
198
198
  function NarrAIMenu({ actions }) {
199
+ const t = _nextintl.useTranslations.call(void 0, );
199
200
  const editor = _react.useBlockNoteEditor.call(void 0, );
200
201
  const ai = _react.useExtension.call(void 0, _xlai.AIExtension);
201
202
  const dict = _xlai.useAIDictionary.call(void 0, );
@@ -238,13 +239,13 @@ function NarrAIMenu({ actions }) {
238
239
  chatRequestOptions: { body: { type } }
239
240
  });
240
241
  }, "invokeGenerate");
241
- const generateItems = generateActionItems(actions, invokeGenerate);
242
+ const generateItems = generateActionItems(actions, invokeGenerate, t);
242
243
  if (hasSelection) {
243
244
  return [
244
245
  ...generateItems,
245
246
  {
246
247
  key: "improve_writing",
247
- title: "Improve Writing",
248
+ title: t("ui.editor.ai.improve_writing"),
248
249
  aliases: ["improve", "rewrite", "polish"],
249
250
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { size: 18 }),
250
251
  size: "small",
@@ -259,7 +260,7 @@ function NarrAIMenu({ actions }) {
259
260
  },
260
261
  {
261
262
  key: "fix_spelling",
262
- title: "Fix Spelling",
263
+ title: t("ui.editor.ai.fix_spelling"),
263
264
  aliases: ["spelling", "grammar", "typo"],
264
265
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.TypeIcon, { size: 18 }),
265
266
  size: "small",
@@ -274,7 +275,7 @@ function NarrAIMenu({ actions }) {
274
275
  },
275
276
  {
276
277
  key: "translate",
277
- title: "Translate\u2026",
278
+ title: t("ui.editor.ai.translate"),
278
279
  aliases: ["translate", "language"],
279
280
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LanguagesIcon, { size: 18 }),
280
281
  size: "small",
@@ -286,12 +287,12 @@ function NarrAIMenu({ actions }) {
286
287
  onItemClick: /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
287
288
  expandSelectionToBlocks();
288
289
  pendingTypeRef.current = "translate";
289
- setPrompt("Translate to ");
290
+ setPrompt(t("ui.editor.ai.translate_prefill"));
290
291
  }, "onItemClick")
291
292
  },
292
293
  {
293
294
  key: "simplify",
294
- title: "Simplify",
295
+ title: t("ui.editor.ai.simplify"),
295
296
  aliases: ["simplify", "easier", "plain"],
296
297
  icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.WandSparklesIcon, { size: 18 }),
297
298
  size: "small",
@@ -307,7 +308,7 @@ function NarrAIMenu({ actions }) {
307
308
  ];
308
309
  }
309
310
  return generateItems;
310
- }, [editor, status, prompt, ai, expandSelectionToBlocks, actions]);
311
+ }, [editor, status, prompt, ai, expandSelectionToBlocks, actions, t]);
311
312
  const handleSubmit = _react3.useCallback.call(void 0,
312
313
  async (userPrompt) => {
313
314
  if (!userPrompt.trim()) return;
@@ -365,9 +366,9 @@ function BlockNoteEditor({
365
366
  aiHandleRef
366
367
  }) {
367
368
  const t = _nextintl.useTranslations.call(void 0, );
368
- const locale = _chunk4BZJ4LABjs.useI18nLocale.call(void 0, );
369
+ const locale = _chunk4ORLPEK7js.useI18nLocale.call(void 0, );
369
370
  const { resolvedTheme } = _nextthemes.useTheme.call(void 0, );
370
- const company = _nullishCoalesce(_optionalChain([_chunkORU7KLCYjs.useCurrentUserContextOptional.call(void 0, ), 'optionalAccess', _6 => _6.company]), () => ( null));
371
+ const company = _nullishCoalesce(_optionalChain([_chunkVDVIUDY5js.useCurrentUserContextOptional.call(void 0, ), 'optionalAccess', _6 => _6.company]), () => ( null));
371
372
  const [acceptedChanges, setAcceptedChanges] = _react3.useState.call(void 0, /* @__PURE__ */ new Set());
372
373
  const [rejectedChanges, setRejectedChanges] = _react3.useState.call(void 0, /* @__PURE__ */ new Set());
373
374
  const editorRef = _react3.useRef.call(void 0, null);
@@ -401,11 +402,14 @@ function BlockNoteEditor({
401
402
  });
402
403
  }, []);
403
404
  const DiffActionsInlineContent = _react3.useMemo.call(void 0,
404
- () => createDiffActionsInlineContentSpec(handleAcceptChange, handleRejectChange),
405
- [handleAcceptChange, handleRejectChange]
405
+ () => createDiffActionsInlineContentSpec(handleAcceptChange, handleRejectChange, {
406
+ accept: t("ui.editor.accept_change"),
407
+ reject: t("ui.editor.reject_change")
408
+ }),
409
+ [handleAcceptChange, handleRejectChange, t]
406
410
  );
407
411
  const mentionSpec = _react3.useMemo.call(void 0,
408
- () => _chunkORU7KLCYjs.createMentionInlineContentSpec.call(void 0, mentionResolveFn, disableMentions, mentionNameResolver),
412
+ () => _chunkVDVIUDY5js.createMentionInlineContentSpec.call(void 0, mentionResolveFn, disableMentions, mentionNameResolver),
409
413
  [disableMentions, mentionResolveFn, mentionNameResolver]
410
414
  );
411
415
  const schema = _react3.useMemo.call(void 0,
@@ -424,7 +428,7 @@ function BlockNoteEditor({
424
428
  const companyId = _optionalChain([company, 'optionalAccess', _12 => _12.id]);
425
429
  const aiExtension = _react3.useMemo.call(void 0, () => {
426
430
  if (!aiConfig || !aiEnabled) return void 0;
427
- const base = _chunkWQ77CUUZjs.getPublicApiUrl.call(void 0, );
431
+ const base = _chunkGPXYQMOZjs.getPublicApiUrl.call(void 0, );
428
432
  const url = new URL(aiConfig.endpoint, base.endsWith("/") ? base : base + "/").toString();
429
433
  return _xlai.AIExtension.call(void 0, {
430
434
  transport: new (0, _ai.DefaultChatTransport)({
@@ -466,7 +470,7 @@ function BlockNoteEditor({
466
470
  const uploadImage = _react3.useCallback.call(void 0,
467
471
  async (file) => {
468
472
  if (!company) {
469
- _chunkORU7KLCYjs.errorToast.call(void 0, {
473
+ _chunkVDVIUDY5js.errorToast.call(void 0, {
470
474
  title: t(`common.errors.upload`),
471
475
  error: t(`common.errors.upload_description`)
472
476
  });
@@ -474,7 +478,7 @@ function BlockNoteEditor({
474
478
  }
475
479
  const fileType = file.type;
476
480
  const key = `companies/${company.id}/${type}/${id}/${file.name}`;
477
- const s3 = await _chunk4BZJ4LABjs.S3Service.getPreSignedUrl({
481
+ const s3 = await _chunk4ORLPEK7js.S3Service.getPreSignedUrl({
478
482
  key,
479
483
  contentType: fileType,
480
484
  isPublic: true
@@ -484,7 +488,7 @@ function BlockNoteEditor({
484
488
  headers: s3.headers,
485
489
  body: file
486
490
  });
487
- const signedImage = await _chunk4BZJ4LABjs.S3Service.getSignedUrl({
491
+ const signedImage = await _chunk4ORLPEK7js.S3Service.getSignedUrl({
488
492
  key,
489
493
  isPublic: true
490
494
  });
@@ -513,8 +517,8 @@ function BlockNoteEditor({
513
517
  const processedContent = _react3.useMemo.call(void 0, () => {
514
518
  if (diffContent && initialContent) {
515
519
  try {
516
- const diffResult = _chunk4BZJ4LABjs.BlockNoteDiffUtil.diff(initialContent, diffContent);
517
- const renderedDiff = _chunk4BZJ4LABjs.BlockNoteWordDiffRendererUtil.renderWordDiffs(
520
+ const diffResult = _chunk4ORLPEK7js.BlockNoteDiffUtil.diff(initialContent, diffContent);
521
+ const renderedDiff = _chunk4ORLPEK7js.BlockNoteWordDiffRendererUtil.renderWordDiffs(
518
522
  diffResult.blocks,
519
523
  handleAcceptChange,
520
524
  handleRejectChange,
@@ -553,6 +557,9 @@ function BlockNoteEditor({
553
557
  }
554
558
  return void 0;
555
559
  }, [processedContent]);
560
+ const language = locale.split("-")[0];
561
+ const coreDictionary = _nullishCoalesce(coreLocales[language], () => ( coreLocales.en));
562
+ const aiDictionary = _nullishCoalesce(aiLocales[language], () => ( aiLocales.en));
556
563
  const editor = _react.useCreateBlockNote.call(void 0,
557
564
  _react3.useMemo.call(void 0,
558
565
  () => ({
@@ -563,9 +570,9 @@ function BlockNoteEditor({
563
570
  initialContent: validatedInitialContent,
564
571
  uploadFile: uploadImage,
565
572
  extensions: aiExtension ? [aiExtension] : void 0,
566
- dictionary: aiExtension ? { ..._locales.en, ai: _locales3.en } : void 0
573
+ dictionary: aiExtension ? { ...coreDictionary, ai: aiDictionary } : coreDictionary === coreLocales.en ? void 0 : coreDictionary
567
574
  }),
568
- [placeholder, t, schema, validatedInitialContent, uploadImage, aiExtension]
575
+ [placeholder, t, schema, validatedInitialContent, uploadImage, aiExtension, coreDictionary, aiDictionary]
569
576
  )
570
577
  );
571
578
  _react3.useEffect.call(void 0, () => {
@@ -721,7 +728,7 @@ function BlockNoteEditor({
721
728
  "div",
722
729
  {
723
730
  ref: editorRef,
724
- className: _chunk4BZJ4LABjs.cn.call(void 0,
731
+ className: _chunk4ORLPEK7js.cn.call(void 0,
725
732
  bordered ? "rounded-md border border-input bg-input/20 dark:bg-input/30" : "",
726
733
  "flex flex-col w-full",
727
734
  // Pin BlockNote's font-size so it doesn't jump from 14→16px when the
@@ -744,7 +751,7 @@ function BlockNoteEditor({
744
751
  formattingToolbar: false,
745
752
  slashMenu: !aiConfig || !aiEnabled,
746
753
  theme: resolvedTheme === "dark" ? "dark" : "light",
747
- className: _chunk4BZJ4LABjs.cn.call(void 0,
754
+ className: _chunk4ORLPEK7js.cn.call(void 0,
748
755
  "BlockNoteView flex-1",
749
756
  onChange && "[&.bn-container]:p-4",
750
757
  // In stretch mode the parent chain caps our height via flex; without
@@ -765,7 +772,7 @@ function BlockNoteEditor({
765
772
  children: [
766
773
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BlockNoteEditorFormattingToolbar, { showAI: !!aiConfig && aiEnabled }),
767
774
  enableMentions && mentionSearchFn && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
768
- _chunkORU7KLCYjs.BlockNoteEditorMentionSuggestionMenu,
775
+ _chunkVDVIUDY5js.BlockNoteEditorMentionSuggestionMenu,
769
776
  {
770
777
  editor,
771
778
  mentionSearchFn,
@@ -774,7 +781,7 @@ function BlockNoteEditor({
774
781
  }
775
782
  ),
776
783
  _optionalChain([renderOverlays, 'optionalCall', _24 => _24(editor)]),
777
- enableMentions && mentionResolveFn && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkORU7KLCYjs.BlockNoteEditorMentionHoverCard, { containerRef: editorRef, mentionResolveFn }),
784
+ enableMentions && mentionResolveFn && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkVDVIUDY5js.BlockNoteEditorMentionHoverCard, { containerRef: editorRef, mentionResolveFn }),
778
785
  aiConfig && aiEnabled && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
779
786
  _react.SuggestionMenuController,
780
787
  {
@@ -793,4 +800,4 @@ _chunk7QVYU63Ejs.__name.call(void 0, BlockNoteEditor, "BlockNoteEditor");
793
800
 
794
801
 
795
802
  exports.default = BlockNoteEditor;
796
- //# sourceMappingURL=BlockNoteEditor-BENYTTCZ.js.map
803
+ //# sourceMappingURL=BlockNoteEditor-LLCZDFLZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteEditor-LLCZDFLZ.js","../src/components/editors/BlockNoteEditor.tsx","../src/components/editors/BlockNoteEditorAiActions.tsx","../src/components/editors/BlockNoteEditorFormattingToolbar.tsx"],"names":["jsx","jsxs","SparklesIcon","type"],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteEditor-LLCZDFLZ.js","sourcesContent":[null,"\"use client\";\n\nimport { BlockNoteSchema, defaultInlineContentSpecs, filterSuggestionItems, PartialBlock } from \"@blocknote/core\";\nimport * as coreLocales from \"@blocknote/core/locales\";\nimport {\n createReactInlineContentSpec,\n DefaultReactSuggestionItem,\n getDefaultReactSlashMenuItems,\n SuggestionMenuController,\n SuggestionMenuProps,\n useBlockNoteEditor,\n useCreateBlockNote,\n useExtension,\n useExtensionState,\n} from \"@blocknote/react\";\nimport { BlockNoteView } from \"@blocknote/shadcn\";\nimport \"@blocknote/shadcn/style.css\";\nimport {\n AIExtension,\n AIMenuController,\n getAISlashMenuItems,\n getDefaultAIMenuItems,\n PromptSuggestionMenu,\n useAIDictionary,\n} from \"@blocknote/xl-ai\";\nimport * as aiLocales from \"@blocknote/xl-ai/locales\";\nimport \"@blocknote/xl-ai/style.css\";\nimport { DefaultChatTransport } from \"ai\";\nimport { CheckIcon, LanguagesIcon, SparklesIcon, TypeIcon, WandSparklesIcon, XIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useTheme } from \"next-themes\";\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getPublicApiUrl } from \"../../client/config\";\nimport { getClientToken } from \"../../client/token\";\nimport { useCurrentUserContextOptional } from \"../../contexts\";\nimport { S3Interface } from \"../../features/s3/data\";\nimport { S3Service } from \"../../features/s3/data/s3.service\";\nimport { UserInterface } from \"../../features/user/data\";\nimport { useI18nLocale } from \"../../i18n/config\";\nimport { Button } from \"../../shadcnui\";\nimport { BlockNoteDiffUtil, BlockNoteWordDiffRendererUtil, cn } from \"../../utils\";\nimport { errorToast } from \"../errors\";\nimport { BlockNoteAiGenerateAction, generateActionItems } from \"./BlockNoteEditorAiActions\";\nimport { BlockNoteEditorFormattingToolbar } from \"./BlockNoteEditorFormattingToolbar\";\nimport { BlockNoteEditorMentionHoverCard } from \"./BlockNoteEditorMentionHoverCard\";\nimport {\n createMentionInlineContentSpec,\n type MentionNameResolver,\n type MentionResolveFn,\n} from \"./BlockNoteEditorMentionInlineContent\";\nimport { BlockNoteEditorMentionSuggestionMenu } from \"./BlockNoteEditorSuggestionMenuController\";\n\n/**\n * Lets app code trigger a whole-document AI action from OUTSIDE the editor\n * (a visible button next to the field label, for instance) without owning the\n * BlockNote instance. Delivered through a plain prop, not a React `ref`:\n * `BlockNoteEditorContainer` is a `next/dynamic` import wrapped in\n * `React.memo`, and refs do not pass through that reliably.\n */\nexport type BlockNoteAiHandle = { invokeAi: (type: BlockNoteAiGenerateAction) => void };\n\nexport type BlockNoteAiConfig = {\n endpoint: string;\n entityType: string;\n entityId?: string;\n /** Whole-document actions shown when nothing is selected. Default: [\"fill-template\"]. */\n actions?: BlockNoteAiGenerateAction[];\n};\n\nexport type BlockNoteEditorProps = {\n id: string;\n type: string;\n initialContent?: PartialBlock[];\n onChange?: (content: any, isEmpty: boolean, hasUnresolvedDiff: boolean) => void;\n size?: \"sm\" | \"md\";\n className?: string;\n markdownContent?: string;\n diffContent?: PartialBlock[];\n placeholder?: string;\n bordered?: boolean;\n inlineContentSpecs?: Record<string, any>;\n renderOverlays?: (editor: any) => React.ReactNode;\n enableMentions?: boolean;\n disableMentions?: boolean;\n mentionSearchFn?: (\n query: string,\n params?: Record<string, string>,\n ) => Promise<import(\"./BlockNoteEditorSuggestionMenuController\").MentionItem[]>;\n mentionSearchParams?: Record<string, string>;\n mentionResolveFn?: MentionResolveFn;\n suggestionMenuComponent?: React.FC<SuggestionMenuProps<DefaultReactSuggestionItem>>;\n mentionNameResolver?: MentionNameResolver;\n onWarmMentions?: (blocks: PartialBlock[]) => void;\n aiConfig?: BlockNoteAiConfig;\n // When the editor is inside a bounded flex column (parent gives it a real\n // height via flex-1+min-h-0), set this so `.bn-container` shrinks to that\n // height and scrolls internally. Without it the editor grows to fit its\n // content and pushes the surrounding form to scroll instead.\n stretch?: boolean;\n // Gates AI on top of `aiConfig` (credit availability, etc.). Defaults to\n // true so existing callers that only pass `aiConfig` are unaffected. When\n // false, no AI extension is created, the AI toolbar button and AI slash\n // items are hidden, and the editor falls back to the plain slash menu.\n aiEnabled?: boolean;\n // Filled with a {@link BlockNoteAiHandle} while the editor is mounted and AI\n // is on, so a control outside the editor can run a whole-document AI action.\n // Cleared on unmount and whenever AI is unavailable.\n aiHandleRef?: React.MutableRefObject<BlockNoteAiHandle | null>;\n};\n\nfunction isBlockEmpty(block: any): boolean {\n if (!block || typeof block !== \"object\") return true;\n if (block.type !== \"paragraph\") return false;\n if (Array.isArray(block.children) && block.children.length > 0 && !isDocumentEmpty(block.children)) {\n return false;\n }\n if (Array.isArray(block.content)) {\n for (const inline of block.content) {\n if (typeof inline === \"string\") {\n if (inline.trim()) return false;\n } else if (inline && typeof inline === \"object\") {\n if (inline.type !== \"text\") return false;\n if (typeof inline.text === \"string\" && inline.text.trim()) return false;\n }\n }\n } else if (typeof block.content === \"string\" && block.content.trim()) {\n return false;\n }\n return true;\n}\n\nfunction isDocumentEmpty(blocks: any[]): boolean {\n if (!Array.isArray(blocks) || blocks.length === 0) return true;\n return blocks.every(isBlockEmpty);\n}\n\nconst createDiffActionsInlineContentSpec = (\n handleAcceptChange: (diffId: string) => void,\n handleRejectChange: (diffId: string) => void,\n labels: { accept: string; reject: string },\n) => {\n return createReactInlineContentSpec(\n {\n type: \"diffActions\",\n propSchema: {\n diffIds: {\n default: \"\",\n },\n },\n content: \"none\",\n },\n {\n render: (props) => {\n const diffIds = props.inlineContent.props.diffIds;\n\n return (\n <span className=\"diff-actions-container mx-2 inline-flex items-center gap-1 align-middle\">\n <Button\n title={labels.accept}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n diffIds.split(\",\").forEach((id: string) => handleAcceptChange(id.trim()));\n }}\n >\n <CheckIcon className=\"text-success h-3 w-3\" />\n </Button>\n <Button\n title={labels.reject}\n className=\"mx-2 p-0\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n diffIds.split(\",\").forEach((id: string) => handleRejectChange(id.trim()));\n }}\n >\n <XIcon className=\"text-destructive h-3 w-3\" />\n </Button>\n </span>\n );\n },\n },\n );\n};\n\n/**\n * Custom AI menu wrapper. Surfaces our backend-driven action items\n * (Improve Writing, Fix Spelling) above the free-form prompt input.\n *\n * Why a custom wrapper instead of `<AIMenu items={…}>` with the BlockNote\n * defaults: BlockNote's `PromptSuggestionMenu` hijacks Enter to pick the\n * highlighted item whenever `items.length > 0`. We gate items on\n * - status === \"user-input\"\n * - editor has a selection\n * - prompt input is empty\n * so the moment the user types, items disappear and Enter falls back to\n * free-form submission. Outside `user-input` (review / error states) we\n * keep BlockNote's default review buttons (accept/revert/retry/cancel).\n *\n * Each custom item passes a `type` discriminator on `chatRequestOptions.body`.\n * That field flows through `chat.sendMessage(msg, opts)` to the transport's\n * `prepareSendMessagesRequest({messages, body})` (see types.ts in\n * `@blocknote/xl-ai` — `ChatRequestOptions = Parameters<Chat[\"sendMessage\"]>[1]`).\n * The backend dispatcher reads `body.type` and routes to a per-type handler\n * with its own canonical prompt. NO prompt text lives in this file.\n */\nfunction NarrAIMenu({ actions }: { actions?: BlockNoteAiGenerateAction[] }) {\n const t = useTranslations();\n const editor = useBlockNoteEditor();\n const ai = useExtension(AIExtension);\n const dict = useAIDictionary();\n const status = useExtensionState(AIExtension, {\n selector: (s) => (s.aiMenuState !== \"closed\" ? s.aiMenuState.status : \"closed\"),\n });\n const [prompt, setPrompt] = useState(\"\");\n // Set by items that pre-fill the input (Translate) so handleSubmit knows\n // which `type` to attach when the user submits the captured text. Cleared\n // after submit or on status change.\n const pendingTypeRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (status === \"ai-writing\" || status === \"user-reviewing\" || status === \"error\" || status === \"closed\") {\n setPrompt(\"\");\n pendingTypeRef.current = null;\n }\n }, [status]);\n\n // Selection-edit ops operate per-block. If the user's selection only\n // covers part of a block (cursor mid-paragraph dragged to mid-next), the\n // rewrite would silently replace the WHOLE containing blocks — beyond\n // what the user highlighted. Expand the selection to whole-block bounds\n // BEFORE invokeAI so the user sees exactly what will be rewritten.\n const expandSelectionToBlocks = useCallback(() => {\n const sel = editor.getSelection?.();\n const blocks = (sel as any)?.blocks;\n if (!Array.isArray(blocks) || blocks.length === 0) return;\n const first = blocks[0];\n const last = blocks[blocks.length - 1];\n try {\n (editor as any).setSelection?.(first, last);\n } catch {\n // If BlockNote's setSelection signature changes, fail silently — the\n // backend still operates per-block, so we just lose the visual hint.\n }\n }, [editor]);\n\n const items = useMemo(() => {\n // Outside user-input (reviewing / error), use BlockNote's default\n // review buttons (accept/revert/retry/cancel). Need to wrap onItemClick\n // because the default items expect a setPrompt argument.\n if (status !== \"user-input\") {\n return getDefaultAIMenuItems(editor, status).map((item) => ({\n ...item,\n onItemClick: () => item.onItemClick(setPrompt),\n }));\n }\n const hasSelection = editor.getSelection() !== undefined;\n const hasTyped = prompt.trim().length > 0;\n // Once the user starts typing, hide all items so Enter submits the\n // free-form (or pending-type) prompt instead of being hijacked.\n if (hasTyped) return [];\n\n const invokeGenerate = (type: BlockNoteAiGenerateAction) => {\n void ai.invokeAI({\n userPrompt: type,\n useSelection: false,\n chatRequestOptions: { body: { type } },\n });\n };\n // Whole-document items are shown in BOTH contexts (with and without\n // selection) because they operate on the whole document — they ignore any\n // active selection. Listed first so the first one is the\n // default-highlighted item.\n const generateItems = generateActionItems(actions, invokeGenerate, t);\n\n if (hasSelection) {\n // Selection-edit items + the always-available whole-document items.\n // Each selection item invokes ai.invokeAI with chatRequestOptions\n // carrying the `type` body field. The userPrompt is a short tag — the\n // backend ignores it and uses the canonical prompt for the type instead.\n return [\n ...generateItems,\n {\n key: \"improve_writing\",\n title: t(\"ui.editor.ai.improve_writing\"),\n aliases: [\"improve\", \"rewrite\", \"polish\"],\n icon: <SparklesIcon size={18} />,\n size: \"small\" as const,\n onItemClick: () => {\n expandSelectionToBlocks();\n void ai.invokeAI({\n userPrompt: \"improve-writing\",\n useSelection: true,\n chatRequestOptions: { body: { type: \"improve-writing\" } },\n });\n },\n },\n {\n key: \"fix_spelling\",\n title: t(\"ui.editor.ai.fix_spelling\"),\n aliases: [\"spelling\", \"grammar\", \"typo\"],\n icon: <TypeIcon size={18} />,\n size: \"small\" as const,\n onItemClick: () => {\n expandSelectionToBlocks();\n void ai.invokeAI({\n userPrompt: \"fix-spelling\",\n useSelection: true,\n chatRequestOptions: { body: { type: \"fix-spelling\" } },\n });\n },\n },\n {\n key: \"translate\",\n title: t(\"ui.editor.ai.translate\"),\n aliases: [\"translate\", \"language\"],\n icon: <LanguagesIcon size={18} />,\n size: \"small\" as const,\n // Pre-fills the input with a placeholder. User appends/replaces\n // with the target language and submits via Enter. handleSubmit\n // reads pendingTypeRef and forwards `type: \"translate\"`. We\n // expand the selection now so the user sees the scope before\n // typing the language — handleSubmit doesn't re-expand.\n onItemClick: () => {\n expandSelectionToBlocks();\n pendingTypeRef.current = \"translate\";\n setPrompt(t(\"ui.editor.ai.translate_prefill\"));\n },\n },\n {\n key: \"simplify\",\n title: t(\"ui.editor.ai.simplify\"),\n aliases: [\"simplify\", \"easier\", \"plain\"],\n icon: <WandSparklesIcon size={18} />,\n size: \"small\" as const,\n onItemClick: () => {\n expandSelectionToBlocks();\n void ai.invokeAI({\n userPrompt: \"simplify\",\n useSelection: true,\n chatRequestOptions: { body: { type: \"simplify\" } },\n });\n },\n },\n ];\n }\n\n // No selection (the /ai slash menu path): just the whole-document items.\n // Free-form typing still works — once the user types, items hide and\n // Enter submits with no type (backend defaults to fill-template).\n return generateItems;\n }, [editor, status, prompt, ai, expandSelectionToBlocks, actions, t]);\n\n const handleSubmit = useCallback(\n async (userPrompt: string) => {\n if (!userPrompt.trim()) return;\n const pendingType = pendingTypeRef.current;\n pendingTypeRef.current = null;\n const body = pendingType ? { type: pendingType } : undefined;\n await ai.invokeAI({\n userPrompt,\n useSelection: editor.getSelection() !== undefined,\n ...(body ? { chatRequestOptions: { body } } : {}),\n });\n },\n [ai, editor],\n );\n\n const placeholder =\n status === \"thinking\"\n ? dict.ai_menu.status.thinking\n : status === \"ai-writing\"\n ? dict.ai_menu.status.editing\n : status === \"error\"\n ? dict.ai_menu.status.error\n : dict.ai_menu.input_placeholder;\n\n const disabled = status === \"thinking\" || status === \"ai-writing\";\n\n return (\n <PromptSuggestionMenu\n items={items}\n onManualPromptSubmit={handleSubmit}\n promptText={prompt}\n onPromptTextChange={setPrompt}\n placeholder={placeholder}\n disabled={disabled}\n icon={\n <div className=\"bn-combobox-icon\">\n <SparklesIcon size={16} />\n </div>\n }\n />\n );\n}\n\nexport default function BlockNoteEditor({\n id,\n type,\n initialContent,\n onChange,\n size,\n className,\n markdownContent,\n diffContent,\n placeholder,\n bordered,\n inlineContentSpecs,\n renderOverlays,\n enableMentions,\n disableMentions,\n mentionSearchFn,\n mentionSearchParams,\n mentionResolveFn,\n suggestionMenuComponent,\n mentionNameResolver,\n onWarmMentions,\n aiConfig,\n stretch,\n aiEnabled = true,\n aiHandleRef,\n}: BlockNoteEditorProps): React.JSX.Element {\n const t = useTranslations();\n const locale = useI18nLocale();\n const { resolvedTheme } = useTheme();\n // Optional on purpose: a host app may mount its own user context instead of\n // this package's, and the editor already degrades without a company — image\n // upload reports it (`uploadImage`) and the AI transport simply omits the\n // company header. Throwing here would take the whole page down instead.\n const company = useCurrentUserContextOptional<UserInterface>()?.company ?? null;\n\n const [acceptedChanges, setAcceptedChanges] = useState<Set<string>>(new Set());\n const [rejectedChanges, setRejectedChanges] = useState<Set<string>>(new Set());\n\n const editorRef = useRef<HTMLDivElement>(null);\n\n // Ensure side menu buttons don't trigger form submission\n useEffect(() => {\n if (!editorRef.current) return;\n const setButtonTypes = () => {\n editorRef.current?.querySelectorAll(\".bn-side-menu button\").forEach((btn) => {\n if (!btn.getAttribute(\"type\")) {\n btn.setAttribute(\"type\", \"button\");\n }\n });\n };\n const observer = new MutationObserver(setButtonTypes);\n observer.observe(editorRef.current, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, []);\n\n const handleAcceptChange = useCallback((diffId: string) => {\n setAcceptedChanges((prev) => new Set([...prev, diffId]));\n setRejectedChanges((prev) => {\n const newSet = new Set(prev);\n newSet.delete(diffId);\n return newSet;\n });\n }, []);\n\n const handleRejectChange = useCallback((diffId: string) => {\n setRejectedChanges((prev) => new Set([...prev, diffId]));\n setAcceptedChanges((prev) => {\n const newSet = new Set(prev);\n newSet.delete(diffId);\n return newSet;\n });\n }, []);\n\n const DiffActionsInlineContent = useMemo(\n () =>\n createDiffActionsInlineContentSpec(handleAcceptChange, handleRejectChange, {\n accept: t(\"ui.editor.accept_change\"),\n reject: t(\"ui.editor.reject_change\"),\n }),\n [handleAcceptChange, handleRejectChange, t],\n );\n\n const mentionSpec = useMemo(\n () => createMentionInlineContentSpec(mentionResolveFn, disableMentions, mentionNameResolver),\n [disableMentions, mentionResolveFn, mentionNameResolver],\n );\n\n const schema = useMemo(\n () =>\n BlockNoteSchema.create({\n inlineContentSpecs: {\n ...defaultInlineContentSpecs,\n diffActions: DiffActionsInlineContent,\n mention: mentionSpec,\n ...inlineContentSpecs,\n },\n } as any),\n [DiffActionsInlineContent, mentionSpec, inlineContentSpecs],\n );\n\n const docRef = useRef<{ getDoc: () => any[] }>({ getDoc: () => [] });\n // Selection getter used by the AI transport to attach `selectionBlocks` to\n // the outgoing request metadata. Populated in a useEffect once the editor\n // instance exists; reads the current BlockNote selection on every send.\n const selectionRef = useRef<{ getSelectedBlocks: () => any[] }>({ getSelectedBlocks: () => [] });\n\n const companyId = company?.id;\n const aiExtension = useMemo(() => {\n if (!aiConfig || !aiEnabled) return undefined;\n const base = getPublicApiUrl();\n const url = new URL(aiConfig.endpoint, base.endsWith(\"/\") ? base : base + \"/\").toString();\n return AIExtension({\n transport: new DefaultChatTransport({\n api: url,\n credentials: \"include\",\n headers: async () => {\n const headers: Record<string, string> = { \"x-language\": locale };\n const token = await getClientToken();\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n if (companyId) headers[\"x-companyid\"] = companyId;\n return headers;\n },\n prepareSendMessagesRequest: ({ messages, body }: any) => {\n let lastUserIdx = -1;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]?.role === \"user\") {\n lastUserIdx = i;\n break;\n }\n }\n const selectedBlocks = selectionRef.current.getSelectedBlocks();\n const augmented = messages.map((m: any, i: number) =>\n i === lastUserIdx\n ? {\n ...m,\n metadata: {\n ...(m.metadata ?? {}),\n entityType: aiConfig.entityType,\n entityId: aiConfig.entityId,\n blocks: docRef.current.getDoc(),\n selectionBlocks: selectedBlocks,\n },\n }\n : m,\n );\n return { body: { ...(body ?? {}), messages: augmented } };\n },\n }),\n });\n }, [aiConfig, aiEnabled, companyId, locale]);\n\n const uploadImage = useCallback(\n async (file: File): Promise<string> => {\n if (!company) {\n errorToast({\n title: t(`common.errors.upload`),\n error: t(`common.errors.upload_description`),\n });\n throw new Error(t(`common.errors.upload`));\n }\n\n const fileType = file.type;\n const key = `companies/${company.id}/${type}/${id}/${file.name}`;\n\n const s3: S3Interface = await S3Service.getPreSignedUrl({\n key: key,\n contentType: fileType,\n isPublic: true,\n });\n\n await fetch(s3.url, {\n method: \"PUT\",\n headers: s3.headers,\n body: file,\n });\n\n const signedImage: S3Interface = await S3Service.getSignedUrl({\n key: key,\n isPublic: true,\n });\n\n return signedImage.url;\n },\n [company, id, t],\n );\n\n // Utility: Remove trailing empty blocks for read-only display\n const removeTrailingEmptyBlocks = useCallback(\n (blocks: PartialBlock[]): PartialBlock[] => {\n if (!blocks || blocks.length === 0) return blocks;\n\n // Only remove trailing empty blocks in read-only mode\n if (onChange !== undefined) return blocks;\n\n const result = [...blocks];\n\n // Remove trailing empty paragraph blocks, but keep at least one block\n while (result.length > 1) {\n const lastBlock = result[result.length - 1];\n\n // Check if it's an empty paragraph\n const isEmptyParagraph =\n lastBlock.type === \"paragraph\" &&\n (!lastBlock.content ||\n lastBlock.content.length === 0 ||\n (Array.isArray(lastBlock.content) && lastBlock.content.every((c: any) => !c.text || c.text.trim() === \"\")));\n\n if (isEmptyParagraph) {\n result.pop();\n } else {\n break;\n }\n }\n\n return result;\n },\n [onChange],\n );\n\n const processedContent = useMemo(() => {\n if (diffContent && initialContent) {\n try {\n const diffResult = BlockNoteDiffUtil.diff(initialContent, diffContent);\n const renderedDiff = BlockNoteWordDiffRendererUtil.renderWordDiffs(\n diffResult.blocks,\n handleAcceptChange,\n handleRejectChange,\n acceptedChanges,\n rejectedChanges,\n );\n return removeTrailingEmptyBlocks(renderedDiff);\n } catch (_error) {\n return initialContent && Array.isArray(initialContent) && initialContent.length > 0\n ? removeTrailingEmptyBlocks(initialContent)\n : [];\n }\n }\n\n if (!initialContent) {\n return [];\n }\n\n if (!Array.isArray(initialContent)) {\n return [];\n }\n\n return initialContent.length > 0 ? removeTrailingEmptyBlocks(initialContent) : [];\n }, [\n initialContent,\n diffContent,\n handleAcceptChange,\n handleRejectChange,\n acceptedChanges,\n rejectedChanges,\n removeTrailingEmptyBlocks,\n ]);\n\n const validatedInitialContent = useMemo(() => {\n if (processedContent && Array.isArray(processedContent) && processedContent.length > 0) {\n const validatedContent = processedContent.filter((block) => {\n if (!block || typeof block !== \"object\") return false;\n if (!(block as any).type) return false;\n return true;\n });\n return validatedContent.length > 0 ? (validatedContent as PartialBlock[]) : undefined;\n }\n return undefined;\n }, [processedContent]);\n\n // BlockNote's own UI text (slash menu, toolbar, AI menu) in the active\n // language; English when BlockNote has no dictionary for it.\n const language = locale.split(\"-\")[0];\n const coreDictionary = (coreLocales as Record<string, typeof coreLocales.en>)[language] ?? coreLocales.en;\n const aiDictionary = (aiLocales as Record<string, typeof aiLocales.en>)[language] ?? aiLocales.en;\n\n const editor = useCreateBlockNote(\n useMemo(\n () => ({\n placeholders: {\n emptyDocument: placeholder || t(`common.blocknote.placeholder`),\n },\n schema,\n initialContent: validatedInitialContent,\n uploadFile: uploadImage,\n extensions: aiExtension ? [aiExtension] : undefined,\n dictionary: aiExtension\n ? { ...coreDictionary, ai: aiDictionary }\n : coreDictionary === coreLocales.en\n ? undefined\n : coreDictionary,\n }),\n [placeholder, t, schema, validatedInitialContent, uploadImage, aiExtension, coreDictionary, aiDictionary],\n ),\n );\n\n // Publish the outside-the-editor AI trigger. `editor.getExtension(AIExtension)`\n // is BlockNote 0.54's documented lookup by extension factory (core's\n // `getExtension` resolves a function argument through `extensionFactories`),\n // so the instance is reachable without the `useExtension` hook that only\n // works inside the BlockNote context (NarrAIMenu). The menu MUST be opened\n // first: `invokeAI` routes every status update through `setAIResponseStatus`,\n // which is a no-op while `aiMenuState === \"closed\"` — without the open menu\n // the request runs but the accept / reject UI never appears.\n useEffect(() => {\n if (!aiHandleRef) return;\n if (!aiConfig || !aiEnabled) {\n aiHandleRef.current = null;\n return;\n }\n aiHandleRef.current = {\n invokeAi: (type: BlockNoteAiGenerateAction) => {\n const ai = editor.getExtension(AIExtension);\n if (!ai) return;\n editor.focus();\n const blocks = editor.document;\n const anchor = blocks?.[blocks.length - 1];\n if (anchor?.id) ai.openAIMenuAtBlock(anchor.id);\n void ai.invokeAI({\n userPrompt: type,\n useSelection: false,\n chatRequestOptions: { body: { type } },\n });\n },\n };\n return () => {\n aiHandleRef.current = null;\n };\n }, [aiHandleRef, aiConfig, aiEnabled, editor]);\n\n // Tracks the hash of the document the editor itself just emitted via onChange.\n // The sync effect below uses it to skip replaceBlocks when the parent's\n // initialContent is just an echo of our own emission (form-controlled flow).\n const lastEmittedHashRef = useRef<string | null>(null);\n\n const handleChange = useCallback(async () => {\n if (!onChange) return;\n const newBlocks = editor.document;\n lastEmittedHashRef.current = JSON.stringify(newBlocks);\n const isEmpty = isDocumentEmpty(newBlocks);\n\n function hasUnresolvedDiffsRecursive(block: any): boolean {\n if (!block || typeof block !== \"object\") return false;\n let diffId = undefined;\n if (block.props && block.props.diffId) diffId = block.props.diffId;\n if (!diffId && block.attrs && block.attrs.diffId) diffId = block.attrs.diffId;\n if (diffId && !acceptedChanges.has(diffId) && !rejectedChanges.has(diffId)) {\n return true;\n }\n\n if (block.content) {\n const contentArr = Array.isArray(block.content) ? block.content : [block.content];\n for (const inline of contentArr) {\n if (inline && typeof inline === \"object\") {\n if (inline.type === \"diffActions\" && inline.props && inline.props.diffIds) {\n const ids =\n typeof inline.props.diffIds === \"string\" ? inline.props.diffIds.split(\",\") : inline.props.diffIds;\n for (const id of ids) {\n const trimmed = (id || \"\").toString().trim();\n if (trimmed && !acceptedChanges.has(trimmed) && !rejectedChanges.has(trimmed)) {\n return true;\n }\n }\n }\n if (inline.props && inline.props.diffId) {\n const diffIdInline = inline.props.diffId;\n if (diffIdInline && !acceptedChanges.has(diffIdInline) && !rejectedChanges.has(diffIdInline)) {\n return true;\n }\n }\n if (inline.children && Array.isArray(inline.children)) {\n for (const child of inline.children) {\n if (hasUnresolvedDiffsRecursive(child)) return true;\n }\n }\n }\n }\n }\n if (Array.isArray(block.children)) {\n for (const child of block.children) {\n if (hasUnresolvedDiffsRecursive(child)) return true;\n }\n }\n return false;\n }\n\n let hasUnresolvedDiff = false;\n if (Array.isArray(newBlocks)) {\n hasUnresolvedDiff = newBlocks.some((block: any) => hasUnresolvedDiffsRecursive(block));\n }\n\n onChange(newBlocks, isEmpty, hasUnresolvedDiff);\n }, [editor, onChange, id, acceptedChanges, rejectedChanges]);\n\n // Utility: deep equality for arrays of blocks\n const areBlocksEqual = (a: any[], b: any[]): boolean => {\n return JSON.stringify(a) === JSON.stringify(b);\n };\n\n // Only initialize from markdownContent once per value, and only if different\n const hasInitializedFromMarkdown = useRef<string | null>(null);\n useEffect(() => {\n const updateContent = async (markdown: string) => {\n const blocks = await editor.tryParseMarkdownToBlocks(markdown);\n if (!areBlocksEqual(blocks, editor.document)) {\n editor.replaceBlocks(editor.document, blocks);\n }\n };\n\n if (markdownContent && hasInitializedFromMarkdown.current !== markdownContent) {\n hasInitializedFromMarkdown.current = markdownContent;\n updateContent(markdownContent).then(() => handleChange());\n }\n }, [markdownContent, editor]);\n\n // Update editor content when diff content changes, but only if different\n // Prevent unnecessary replaceBlocks calls that reset scroll/cursor.\n const previousContentHashRef = useRef<string | null>(null);\n useEffect(() => {\n if (!processedContent || !editor) return;\n const hash = JSON.stringify(processedContent);\n if (previousContentHashRef.current === hash) return; // no changes\n // Skip replaceBlocks when the new initialContent is just an echo of what\n // the editor itself emitted. Without this, a form-controlled parent\n // (FormBlockNote) round-trips field.value back as initialContent on every\n // keystroke and triggers replaceBlocks, which resets the cursor and can\n // strip just-inserted inline content like mentions.\n if (lastEmittedHashRef.current === hash) {\n previousContentHashRef.current = hash;\n return;\n }\n const currentHash = JSON.stringify(editor.document);\n if (currentHash === hash) {\n previousContentHashRef.current = hash;\n return; // already in sync\n }\n editor.replaceBlocks(editor.document, processedContent as PartialBlock[]);\n previousContentHashRef.current = hash;\n }, [processedContent, editor]);\n\n useEffect(() => {\n if (!onWarmMentions || !initialContent || !Array.isArray(initialContent) || initialContent.length === 0) return;\n onWarmMentions(initialContent);\n }, [onWarmMentions, initialContent]);\n\n useEffect(() => {\n docRef.current.getDoc = () => editor?.document ?? [];\n selectionRef.current.getSelectedBlocks = () => {\n const sel = editor?.getSelection?.();\n const blocks = (sel as any)?.blocks;\n return Array.isArray(blocks) ? blocks : [];\n };\n }, [editor]);\n\n // Handle audio received from whisper transcription\n const _handleAudioReceived = useCallback(\n (message: string) => {\n try {\n // Ensure the editor has focus\n const editorElement = editorRef.current?.querySelector('[contenteditable=\"true\"]') as HTMLElement;\n if (editorElement && document.activeElement !== editorElement) {\n editorElement.focus();\n }\n\n // Insert the transcribed text at the current cursor position\n editor.insertInlineContent(message);\n } catch (error) {\n console.error(\"Error inserting transcribed text:\", error);\n // Fallback: try to insert at the end of the document\n try {\n const blocks = editor.document;\n if (blocks.length > 0) {\n const lastBlock = blocks[blocks.length - 1];\n editor.setTextCursorPosition(lastBlock.id, \"end\");\n editor.insertInlineContent(message);\n }\n } catch (fallbackError) {\n console.error(\"Fallback insertion also failed:\", fallbackError);\n }\n }\n },\n [editor],\n );\n\n return (\n <div\n ref={editorRef}\n className={cn(\n bordered ? \"rounded-md border border-input bg-input/20 dark:bg-input/30\" : \"\",\n \"flex flex-col w-full\",\n // Pin BlockNote's font-size so it doesn't jump from 14→16px when the\n // xl-ai AIMenu mounts. The shadcn theme sets `.bn-default-styles {\n // font-size: 16px }` explicitly; outside AI mode the form's text-sm\n // wins via cascade, but ForkYDocExtension re-evaluates the style\n // context on AI activation and the explicit 16px takes over.\n // Phone: an editable field types at 16px, or iPhone Safari zooms the\n // page in on focus. The two ranges never overlap, so neither depends on\n // CSS source order to win.\n onChange\n ? \"md:[&_.bn-default-styles]:!text-sm max-md:[&_.bn-default-styles]:!text-base\"\n : \"[&_.bn-default-styles]:!text-sm\",\n className,\n )}\n >\n <BlockNoteView\n editor={editor}\n onChange={handleChange}\n editable={onChange !== undefined}\n formattingToolbar={false}\n slashMenu={!aiConfig || !aiEnabled}\n // Follow the app theme: hardcoding \"light\" leaves dark (light-theme)\n // text on the dark card, which is nearly unreadable in dark mode.\n theme={resolvedTheme === \"dark\" ? \"dark\" : \"light\"}\n // `className` is applied by BlockNote to both the main `.bn-container`\n // AND `editor.portalElement` (the floating-UI portal root). Gate `p-4`\n // on `.bn-container` so it doesn't add padding to the empty portal\n // element and produce a phantom scrollbar on the wrapper.\n className={cn(\n \"BlockNoteView flex-1\",\n onChange && \"[&.bn-container]:p-4\",\n // In stretch mode the parent chain caps our height via flex; without\n // these two classes the `.bn-container` keeps `min-height: auto`\n // (its content's intrinsic height) and pushes the bordered wrapper\n // — and the surrounding EditorSheet form — to scroll instead of\n // scrolling internally.\n onChange && stretch && \"[&.bn-container]:min-h-0 [&.bn-container]:overflow-y-auto\",\n // Phone — these reach the floating menus because BlockNote puts this\n // className on its portal root too. The formatting toolbar (~450px)\n // scrolls sideways instead of losing alignment and link off-screen;\n // the slash menu is capped to the screen and drops its keyboard\n // shortcut badges, which mean nothing on a touch screen.\n \"max-md:[&_.bn-formatting-toolbar]:max-w-[calc(100vw-1rem)] max-md:[&_.bn-formatting-toolbar]:overflow-x-auto max-md:[&_.bn-formatting-toolbar>*]:shrink-0\",\n \"max-md:[&_.bn-suggestion-menu]:max-w-[calc(100vw-1rem)] max-md:[&_.bn-suggestion-menu_[role=option]>[data-position=right]]:hidden\",\n size === \"sm\" && \"small\",\n )}\n >\n <BlockNoteEditorFormattingToolbar showAI={!!aiConfig && aiEnabled} />\n {enableMentions && mentionSearchFn && (\n <BlockNoteEditorMentionSuggestionMenu\n editor={editor}\n mentionSearchFn={mentionSearchFn}\n mentionSearchParams={mentionSearchParams}\n suggestionMenuComponent={suggestionMenuComponent}\n />\n )}\n {renderOverlays?.(editor)}\n {enableMentions && mentionResolveFn && (\n <BlockNoteEditorMentionHoverCard containerRef={editorRef} mentionResolveFn={mentionResolveFn} />\n )}\n {aiConfig && aiEnabled && (\n <SuggestionMenuController\n triggerCharacter=\"/\"\n getItems={async (query: string) =>\n filterSuggestionItems([...getDefaultReactSlashMenuItems(editor), ...getAISlashMenuItems(editor)], query)\n }\n />\n )}\n {aiConfig && aiEnabled && <AIMenuController aiMenu={() => <NarrAIMenu actions={aiConfig.actions} />} />}\n </BlockNoteView>\n </div>\n );\n}\n","import { LayoutTemplateIcon, SparklesIcon } from \"lucide-react\";\nimport React from \"react\";\n\n/**\n * Whole-document AI actions an editor can offer in its AI menu when nothing\n * is selected. Each maps to a backend `type` discriminator; NO prompt text\n * lives here. Selection-edit actions (Improve, Fix spelling, …) are separate\n * and always available.\n */\nexport type BlockNoteAiGenerateAction = \"fill-template\" | \"draft-impression\";\n\nexport const DEFAULT_AI_GENERATE_ACTIONS: BlockNoteAiGenerateAction[] = [\"fill-template\"];\n\nexport type AiGenerateMenuItem = {\n key: string;\n title: string;\n aliases: string[];\n /** BlockNote's DefaultReactSuggestionItem types icon as an element, not ReactNode. */\n icon: React.JSX.Element;\n size: \"small\";\n onItemClick: () => void;\n};\n\n/** `titleKey` is a message key; the caller's translator resolves it to the shown title. */\ntype AiGenerateItemDefinition = Omit<AiGenerateMenuItem, \"onItemClick\" | \"title\"> & { titleKey: string };\n\nconst ITEMS: Record<BlockNoteAiGenerateAction, AiGenerateItemDefinition> = {\n \"fill-template\": {\n key: \"generate_from_template\",\n titleKey: \"ui.editor.ai.generate_from_template\",\n aliases: [\"generate\", \"template\", \"fill\"],\n icon: <LayoutTemplateIcon size={18} />,\n size: \"small\",\n },\n \"draft-impression\": {\n key: \"suggest_impression\",\n titleKey: \"ui.editor.ai.suggest_impression\",\n aliases: [\"suggest\", \"impression\"],\n icon: <SparklesIcon size={18} />,\n size: \"small\",\n },\n};\n\nexport function generateActionItems(\n actions: BlockNoteAiGenerateAction[] | undefined,\n invoke: (type: BlockNoteAiGenerateAction) => void,\n translate: (key: string) => string,\n): AiGenerateMenuItem[] {\n return (actions ?? DEFAULT_AI_GENERATE_ACTIONS).map((type) => {\n const { titleKey, ...item } = ITEMS[type];\n return { ...item, title: translate(titleKey), onItemClick: () => invoke(type) };\n });\n}\n","\"use client\";\n\nimport {\n BasicTextStyleButton,\n BlockTypeSelect,\n CreateLinkButton,\n FileCaptionButton,\n FileReplaceButton,\n FormattingToolbar,\n FormattingToolbarController,\n TextAlignButton,\n} from \"@blocknote/react\";\nimport { AIToolbarButton } from \"@blocknote/xl-ai\";\n\nexport function BlockNoteEditorFormattingToolbar({ showAI = false }: { showAI?: boolean }) {\n return (\n <FormattingToolbarController\n formattingToolbar={() => (\n <FormattingToolbar>\n <BlockTypeSelect key={\"blockTypeSelect\"} />\n\n <FileCaptionButton key={\"fileCaptionButton\"} />\n <FileReplaceButton key={\"replaceFileButton\"} />\n\n <BasicTextStyleButton basicTextStyle={\"bold\"} key={\"boldStyleButton\"} />\n <BasicTextStyleButton basicTextStyle={\"italic\"} key={\"italicStyleButton\"} />\n <BasicTextStyleButton basicTextStyle={\"underline\"} key={\"underlineStyleButton\"} />\n <BasicTextStyleButton basicTextStyle={\"strike\"} key={\"strikeStyleButton\"} />\n\n <TextAlignButton textAlignment={\"left\"} key={\"textAlignLeftButton\"} />\n <TextAlignButton textAlignment={\"center\"} key={\"textAlignCenterButton\"} />\n <TextAlignButton textAlignment={\"right\"} key={\"textAlignRightButton\"} />\n\n <CreateLinkButton key={\"createLinkButton\"} />\n\n {showAI ? <AIToolbarButton key={\"aiToolbarButton\"} /> : null}\n </FormattingToolbar>\n )}\n />\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
2
 
3
3
 
4
- var _chunk4BZJ4LABjs = require('./chunk-4BZJ4LAB.js');
4
+ var _chunk4ORLPEK7js = require('./chunk-4ORLPEK7.js');
5
5
  require('./chunk-LXKSUWAV.js');
6
6
  require('./chunk-JTPRJNT2.js');
7
7
  require('./chunk-GHE4VT2R.js');
@@ -36,7 +36,7 @@ function BlockNoteViewer({ content, size }) {
36
36
  editor,
37
37
  editable: false,
38
38
  theme: resolvedTheme === "dark" ? "dark" : "light",
39
- className: _chunk4BZJ4LABjs.cn.call(void 0, "BlockNoteView", size === "sm" && "small")
39
+ className: _chunk4ORLPEK7js.cn.call(void 0, "BlockNoteView", size === "sm" && "small")
40
40
  }
41
41
  );
42
42
  }
@@ -44,4 +44,4 @@ _chunk7QVYU63Ejs.__name.call(void 0, BlockNoteViewer, "BlockNoteViewer");
44
44
 
45
45
 
46
46
  exports.BlockNoteViewer = BlockNoteViewer;
47
- //# sourceMappingURL=BlockNoteViewer-USLR4Y7C.js.map
47
+ //# sourceMappingURL=BlockNoteViewer-77CCTC2U.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteViewer-USLR4Y7C.js","../src/components/viewers/BlockNoteViewer.tsx"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACTA,yCAAmC;AAKnC,2CAA8B;AAC9B,uCAAO;AACP,yCAAyB;AAsBrB,+CAAA;AAnBJ,SAAS,SAAA,CAAU,OAAA,EAA8C;AAC/D,EAAA,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,EAAA,GAAK,OAAA,CAAQ,OAAA,EAAS,CAAA,EAAG,OAAO,OAAA;AACzD,EAAA,GAAA,CAAI,OAAO,QAAA,IAAY,SAAA,GAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,EAAG;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,EAAA,GAAK,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG,OAAO,MAAA;AAAA,IACzD,EAAA,UAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAA;AACT;AAXS,qCAAA,SAAA,EAAA,WAAA,CAAA;AAaF,SAAS,eAAA,CAAgB,EAAE,OAAA,EAAS,KAAK,CAAA,EAAkD;AAChG,EAAA,MAAM,OAAA,EAAS,uCAAA,EAAqB,cAAA,EAAgB,SAAA,CAAU,OAAO,EAAE,CAAC,CAAA;AAGxE,EAAA,MAAM,EAAE,cAAc,EAAA,EAAI,kCAAA,CAAS;AACnC,EAAA,uBACE,6BAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,QAAA,EAAU,KAAA;AAAA,MACV,KAAA,EAAO,cAAA,IAAkB,OAAA,EAAS,OAAA,EAAS,OAAA;AAAA,MAI3C,SAAA,EAAW,iCAAA,eAAG,EAAiB,KAAA,IAAS,KAAA,GAAQ,OAAO;AAAA,IAAA;AAAA,EACzD,CAAA;AAEJ;AAhBgB,qCAAA,eAAA,EAAA,iBAAA,CAAA;ADkBhB;AACE;AACF,0CAAC","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteViewer-USLR4Y7C.js","sourcesContent":[null,"\"use client\";\n\nimport { useCreateBlockNote } from \"@blocknote/react\";\nimport type { PartialBlock } from \"@blocknote/core\";\n// Mirror BlockNoteEditor.tsx's BlockNoteView import + style.css. Default schema\n// only — no useCurrentUserContext, uploadImage, AI, or custom inline specs, so\n// this can render on auth-free public pages.\nimport { BlockNoteView } from \"@blocknote/shadcn\";\nimport \"@blocknote/shadcn/style.css\";\nimport { useTheme } from \"next-themes\";\nimport { cn } from \"../../utils\";\n\nfunction normalize(content: unknown): PartialBlock[] | undefined {\n if (Array.isArray(content) && content.length > 0) return content as PartialBlock[];\n if (typeof content === \"string\" && content.trim()) {\n try {\n const parsed = JSON.parse(content);\n if (Array.isArray(parsed) && parsed.length > 0) return parsed as PartialBlock[];\n } catch {\n /* plain string — fall through to undefined (rendered as empty) */\n }\n }\n return undefined;\n}\n\nexport function BlockNoteViewer({ content, size }: { content: unknown; size?: \"default\" | \"sm\" }) {\n const editor = useCreateBlockNote({ initialContent: normalize(content) });\n // Outside a next-themes ThemeProvider (public pages) resolvedTheme is\n // undefined, so this falls back to \"light\".\n const { resolvedTheme } = useTheme();\n return (\n <BlockNoteView\n editor={editor}\n editable={false}\n theme={resolvedTheme === \"dark\" ? \"dark\" : \"light\"}\n // Same two classes BlockNoteEditor applies for its `size` prop: the app\n // stylesheet keys the compact recipe off `.BlockNoteView.small`, so a\n // viewer that omits them can only ever render at reading-page size.\n className={cn(\"BlockNoteView\", size === \"sm\" && \"small\")}\n />\n );\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteViewer-77CCTC2U.js","../src/components/viewers/BlockNoteViewer.tsx"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACTA,yCAAmC;AAKnC,2CAA8B;AAC9B,uCAAO;AACP,yCAAyB;AAsBrB,+CAAA;AAnBJ,SAAS,SAAA,CAAU,OAAA,EAA8C;AAC/D,EAAA,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,EAAA,GAAK,OAAA,CAAQ,OAAA,EAAS,CAAA,EAAG,OAAO,OAAA;AACzD,EAAA,GAAA,CAAI,OAAO,QAAA,IAAY,SAAA,GAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,EAAG;AACjD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,EAAA,GAAK,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG,OAAO,MAAA;AAAA,IACzD,EAAA,UAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAA;AACT;AAXS,qCAAA,SAAA,EAAA,WAAA,CAAA;AAaF,SAAS,eAAA,CAAgB,EAAE,OAAA,EAAS,KAAK,CAAA,EAAkD;AAChG,EAAA,MAAM,OAAA,EAAS,uCAAA,EAAqB,cAAA,EAAgB,SAAA,CAAU,OAAO,EAAE,CAAC,CAAA;AAGxE,EAAA,MAAM,EAAE,cAAc,EAAA,EAAI,kCAAA,CAAS;AACnC,EAAA,uBACE,6BAAA;AAAA,IAAC,qBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,QAAA,EAAU,KAAA;AAAA,MACV,KAAA,EAAO,cAAA,IAAkB,OAAA,EAAS,OAAA,EAAS,OAAA;AAAA,MAI3C,SAAA,EAAW,iCAAA,eAAG,EAAiB,KAAA,IAAS,KAAA,GAAQ,OAAO;AAAA,IAAA;AAAA,EACzD,CAAA;AAEJ;AAhBgB,qCAAA,eAAA,EAAA,iBAAA,CAAA;ADkBhB;AACE;AACF,0CAAC","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/BlockNoteViewer-77CCTC2U.js","sourcesContent":[null,"\"use client\";\n\nimport { useCreateBlockNote } from \"@blocknote/react\";\nimport type { PartialBlock } from \"@blocknote/core\";\n// Mirror BlockNoteEditor.tsx's BlockNoteView import + style.css. Default schema\n// only — no useCurrentUserContext, uploadImage, AI, or custom inline specs, so\n// this can render on auth-free public pages.\nimport { BlockNoteView } from \"@blocknote/shadcn\";\nimport \"@blocknote/shadcn/style.css\";\nimport { useTheme } from \"next-themes\";\nimport { cn } from \"../../utils\";\n\nfunction normalize(content: unknown): PartialBlock[] | undefined {\n if (Array.isArray(content) && content.length > 0) return content as PartialBlock[];\n if (typeof content === \"string\" && content.trim()) {\n try {\n const parsed = JSON.parse(content);\n if (Array.isArray(parsed) && parsed.length > 0) return parsed as PartialBlock[];\n } catch {\n /* plain string — fall through to undefined (rendered as empty) */\n }\n }\n return undefined;\n}\n\nexport function BlockNoteViewer({ content, size }: { content: unknown; size?: \"default\" | \"sm\" }) {\n const editor = useCreateBlockNote({ initialContent: normalize(content) });\n // Outside a next-themes ThemeProvider (public pages) resolvedTheme is\n // undefined, so this falls back to \"light\".\n const { resolvedTheme } = useTheme();\n return (\n <BlockNoteView\n editor={editor}\n editable={false}\n theme={resolvedTheme === \"dark\" ? \"dark\" : \"light\"}\n // Same two classes BlockNoteEditor applies for its `size` prop: the app\n // stylesheet keys the compact recipe off `.BlockNoteView.small`, so a\n // viewer that omits them can only ever render at reading-page size.\n className={cn(\"BlockNoteView\", size === \"sm\" && \"small\")}\n />\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  cn
4
- } from "./chunk-ZZ6E33FO.mjs";
4
+ } from "./chunk-6DRSSW5O.mjs";
5
5
  import "./chunk-AUXK7QSA.mjs";
6
6
  import "./chunk-PI56A4DG.mjs";
7
7
  import "./chunk-V5MI7RNB.mjs";
@@ -44,4 +44,4 @@ __name(BlockNoteViewer, "BlockNoteViewer");
44
44
  export {
45
45
  BlockNoteViewer
46
46
  };
47
- //# sourceMappingURL=BlockNoteViewer-Y2ZM4ESA.mjs.map
47
+ //# sourceMappingURL=BlockNoteViewer-MDPO6BXN.mjs.map
@@ -1,5 +1,5 @@
1
1
  import { A as ApiDataInterface } from './ApiDataInterface-BcZeXy5X.mjs';
2
- import { U as UserInterface } from './user.interface-CSaGWFbg.mjs';
2
+ import { U as UserInterface } from './user.interface-CIWGlbqM.mjs';
3
3
 
4
4
  type AuthInput = {
5
5
  id?: string;
@@ -1,5 +1,5 @@
1
1
  import { A as ApiDataInterface } from './ApiDataInterface-BcZeXy5X.js';
2
- import { U as UserInterface } from './user.interface-CrmwJLYW.js';
2
+ import { U as UserInterface } from './user.interface-C0ZdsBZj.js';
3
3
 
4
4
  type AuthInput = {
5
5
  id?: string;
@@ -61,26 +61,56 @@ declare function StripeProvider({ children }: {
61
61
  }): React.JSX.Element;
62
62
  declare function isStripeConfigured(): boolean;
63
63
 
64
+ /** A message translator, as returned by `useTranslations()`. */
65
+ type BillingTranslator = (key: string, values?: Record<string, any>) => string;
66
+ /**
67
+ * What the billing formatters need from the caller's React context. The
68
+ * formatters are plain functions and cannot call hooks, so a component reads
69
+ * `useI18nLocale()` and `useTranslations()` and passes both here.
70
+ *
71
+ * Both are optional so existing callers keep their output: without a `locale`
72
+ * the formatters use "en-US", without `t` they return the English literals they
73
+ * always returned.
74
+ */
75
+ type BillingFormatOptions = {
76
+ /** BCP 47 locale for `Intl` (the app's active locale, from `useI18nLocale()`). */
77
+ locale?: string;
78
+ /** Translator for the words the formatters emit. */
79
+ t?: BillingTranslator;
80
+ };
81
+
64
82
  /**
65
83
  * Format price recurring interval for display
66
84
  * @param price - Stripe price object
85
+ * @param options - `t` translates the interval words; without it the output is English
67
86
  * @returns Formatted interval string (e.g., "/month", "/year", "/2 weeks", "one-time")
68
87
  */
69
- declare function formatInterval(price: StripePriceInterface): string;
88
+ declare function formatInterval(price: StripePriceInterface, options?: BillingFormatOptions): string;
70
89
  /**
71
90
  * Format currency amount from cents to localized currency string
72
91
  * @param amount - Amount in cents
73
92
  * @param currency - Currency code (e.g., "USD", "EUR", "GBP")
93
+ * @param options - `locale` drives number formatting; defaults to "en-US"
74
94
  * @returns Formatted currency string (e.g., "$9.99", "€9,99")
75
95
  */
76
- declare function formatCurrency(amount: number | undefined, currency: string): string;
96
+ declare function formatCurrency(amount: number | undefined, currency: string, options?: BillingFormatOptions): string;
97
+ /**
98
+ * `value.toFixed(digits)` with the locale's decimal separator ("12.5" in English,
99
+ * "12,5" in Italian). No grouping, so English output matches `toFixed` exactly.
100
+ */
101
+ declare function formatFixed(value: number, locale: string | undefined, digits: number): string;
77
102
 
78
103
  /**
79
104
  * Format a date to a localized date string
80
105
  * @param date - Date object or ISO string
106
+ * @param options - `locale` drives the date format (default "en-US"); `t` translates the
107
+ * placeholder shown for a missing or invalid date (default English)
81
108
  * @returns Formatted date string (e.g., "Jan 15, 2025")
82
109
  */
83
- declare function formatDate(date: Date | string | undefined): string;
110
+ declare function formatDate(date: Date | string | undefined, options?: BillingFormatOptions): string;
111
+
112
+ /** The active locale and translator, ready to pass to the billing formatters. */
113
+ declare function useBillingFormatOptions(): Required<BillingFormatOptions>;
84
114
 
85
115
  type BillingAlertBannerProps = {
86
116
  subscription: StripeSubscriptionInterface;
@@ -117,8 +147,12 @@ type PriceProviderProps = {
117
147
  /** Required in list mode (the prices tab) so new prices attach to the right product. */
118
148
  productId?: string;
119
149
  };
120
- /** Human label for a price: its nickname, else amount + interval. */
121
- declare function priceLabel(price: StripePriceInterface): string;
150
+ /**
151
+ * Human label for a price: its nickname, else amount + interval. Pass the
152
+ * caller's `useBillingFormatOptions()` so the amount and interval follow the
153
+ * active locale; without it the label is formatted in English.
154
+ */
155
+ declare function priceLabel(price: StripePriceInterface, fmt?: BillingFormatOptions): string;
122
156
  declare const PriceProvider: ({ children, dehydratedPrice, publishChrome, productId: productIdProp, }: PriceProviderProps) => React.JSX.Element;
123
157
  declare const usePriceContext: () => PriceContextType;
124
158
 
@@ -491,4 +525,4 @@ type PromoCodeInputProps = {
491
525
  };
492
526
  declare function PromoCodeInput({ appliedCode, isValidating, error, onApply, onRemove, disabled, }: PromoCodeInputProps): React.JSX.Element;
493
527
 
494
- export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingInterval, BillingUsageSummaryCard, CancelSubscriptionDialog, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, formatCurrency, formatDate, formatInterval, isStripeConfigured, priceLabel, usePriceContext, useProductContext };
528
+ export { BillingAlertBanner, BillingDashboardContainer, BillingDetailModal, type BillingFormatOptions, type BillingInterval, type BillingTranslator, BillingUsageSummaryCard, CancelSubscriptionDialog, CustomerInfoCard, IntervalToggle, type IntervalToggleProps, InvoiceDetails, InvoiceStatusBadge, InvoicesContainer, InvoicesList, InvoicesSummaryCard, PaymentMethodCard, PaymentMethodEditor, PaymentMethodForm, PaymentMethodSummaryCard, PaymentMethodsContainer, PaymentMethodsList, PriceArchiver, PriceContainer, type PriceContextType, PriceDetails, PriceEditor, type PriceEditorProps, PriceProvider, type PriceProviderProps, PricesList, PricingCard, type PricingCardProps, ProductArchiver, ProductContainer, type ProductContextType, ProductDetails, ProductEditor, type ProductEditorProps, ProductPricingList, type ProductPricingListProps, ProductPricingRow, type ProductPricingRowProps, ProductProvider, type ProductProviderProps, ProductsList, ProductsListContainer, PromoCodeInput, ProrationPreview, StripeProvider, SubscriptionConfirmation, SubscriptionDetails, SubscriptionStatusBadge, SubscriptionSummaryCard, SubscriptionWizard, type SubscriptionWizardProps, SubscriptionsContainer, SubscriptionsList, UsageContainer, UsageHistoryTable, UsageSummaryCard, UsageSummaryCards, WizardProgressIndicator, WizardStepPaymentMethod, WizardStepPlanSelection, WizardStepReview, formatCurrency, formatDate, formatFixed, formatInterval, isStripeConfigured, priceLabel, useBillingFormatOptions, usePriceContext, useProductContext };