@carlonicora/nextjs-jsonapi 5.4.0 → 5.6.0
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.
- package/dist/{BlockNoteEditor-4YCAIEPT.js → BlockNoteEditor-AE3ZTEEH.js} +20 -20
- package/dist/{BlockNoteEditor-4YCAIEPT.js.map → BlockNoteEditor-AE3ZTEEH.js.map} +1 -1
- package/dist/{BlockNoteEditor-YQL2SGFR.mjs → BlockNoteEditor-NEYG5L6W.mjs} +5 -5
- package/dist/{BlockNoteViewer-AEJKJ27Q.mjs → BlockNoteViewer-3OUT5UFY.mjs} +3 -3
- package/dist/{BlockNoteViewer-YL3J7J2Y.js → BlockNoteViewer-4CFKQM7U.js} +4 -4
- package/dist/{BlockNoteViewer-YL3J7J2Y.js.map → BlockNoteViewer-4CFKQM7U.js.map} +1 -1
- package/dist/billing/index.d.mts +186 -25
- package/dist/billing/index.d.ts +186 -25
- package/dist/billing/index.js +1149 -588
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +786 -225
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-5PPG6PL7.js → chunk-3I5AAJXV.js} +3 -3
- package/dist/{chunk-5PPG6PL7.js.map → chunk-3I5AAJXV.js.map} +1 -1
- package/dist/{chunk-YW4ZCEWB.js → chunk-53BAULDP.js} +4 -4
- package/dist/{chunk-YW4ZCEWB.js.map → chunk-53BAULDP.js.map} +1 -1
- package/dist/{chunk-XCHSX3VC.mjs → chunk-BTPUYUQ3.mjs} +2 -2
- package/dist/{chunk-WC63PJSC.mjs → chunk-EYA2F6AN.mjs} +756 -24
- package/dist/chunk-EYA2F6AN.mjs.map +1 -0
- package/dist/{chunk-NFBOSPNJ.js → chunk-HKZAESS6.js} +954 -222
- package/dist/chunk-HKZAESS6.js.map +1 -0
- package/dist/{chunk-6DC2WVVB.mjs → chunk-KQHBONL4.mjs} +2 -2
- package/dist/{chunk-3NLAXVIN.js → chunk-LQ4DK4JF.js} +1988 -1089
- package/dist/chunk-LQ4DK4JF.js.map +1 -0
- package/dist/{chunk-YNCQSWQW.js → chunk-RL3PL3KV.js} +8 -8
- package/dist/{chunk-YNCQSWQW.js.map → chunk-RL3PL3KV.js.map} +1 -1
- package/dist/{chunk-EUKTBOI2.mjs → chunk-SFYPXCK4.mjs} +3382 -2483
- package/dist/chunk-SFYPXCK4.mjs.map +1 -0
- package/dist/{chunk-QMYQRPQC.mjs → chunk-Y7RR57EW.mjs} +2 -2
- package/dist/client/index.js +5 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -4
- package/dist/components/editors/server.d.mts +15 -0
- package/dist/components/editors/server.d.ts +15 -0
- package/dist/components/editors/server.js +38 -0
- package/dist/components/editors/server.js.map +1 -0
- package/dist/components/editors/server.mjs +38 -0
- package/dist/components/editors/server.mjs.map +1 -0
- package/dist/components/index.d.mts +33 -10
- package/dist/components/index.d.ts +33 -10
- package/dist/components/index.js +7 -5
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +8 -6
- package/dist/contexts/index.d.mts +9 -1
- package/dist/contexts/index.d.ts +9 -1
- package/dist/contexts/index.js +5 -5
- package/dist/contexts/index.mjs +4 -4
- package/dist/core/index.d.mts +242 -3
- package/dist/core/index.d.ts +242 -3
- package/dist/core/index.js +36 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +35 -3
- package/dist/email-automations/index.d.mts +3 -0
- package/dist/email-automations/index.d.ts +3 -0
- package/dist/email-automations/index.js +99 -95
- package/dist/email-automations/index.js.map +1 -1
- package/dist/email-automations/index.mjs +30 -26
- package/dist/email-automations/index.mjs.map +1 -1
- package/dist/features/analytics/index.d.mts +11 -4
- package/dist/features/analytics/index.d.ts +11 -4
- package/dist/features/analytics/index.js +127 -135
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/index.mjs +16 -24
- package/dist/features/analytics/index.mjs.map +1 -1
- package/dist/features/analytics/server.d.mts +5 -2
- package/dist/features/analytics/server.d.ts +5 -2
- package/dist/features/analytics/server.js +7 -7
- package/dist/features/analytics/server.js.map +1 -1
- package/dist/features/analytics/server.mjs +5 -5
- package/dist/features/analytics/server.mjs.map +1 -1
- package/dist/features/blog/index.d.mts +12 -2
- package/dist/features/blog/index.d.ts +12 -2
- package/dist/features/blog/index.js +206 -195
- package/dist/features/blog/index.js.map +1 -1
- package/dist/features/blog/index.mjs +71 -60
- package/dist/features/blog/index.mjs.map +1 -1
- package/dist/features/blog/server.d.mts +4 -1
- package/dist/features/blog/server.d.ts +4 -1
- package/dist/features/blog/server.js +49 -21
- package/dist/features/blog/server.js.map +1 -1
- package/dist/features/blog/server.mjs +36 -8
- package/dist/features/blog/server.mjs.map +1 -1
- package/dist/features/help/index.js +38 -38
- package/dist/features/help/index.mjs +4 -4
- package/dist/features/tokenusage/index.d.mts +1 -3
- package/dist/features/tokenusage/index.d.ts +1 -3
- package/dist/features/tokenusage/index.js +127 -135
- package/dist/features/tokenusage/index.js.map +1 -1
- package/dist/features/tokenusage/index.mjs +10 -18
- package/dist/features/tokenusage/index.mjs.map +1 -1
- package/dist/{stripe-promotion-code.interface-C3qqh3mi.d.ts → format-options-BtX3o0Yu.d.ts} +104 -1
- package/dist/{stripe-promotion-code.interface-ClZ7DxS9.d.mts → format-options-D6c7FNDi.d.mts} +104 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -4
- package/dist/server/index.js +4 -4
- package/dist/server/index.mjs +3 -3
- package/messages/en.json +125 -3
- package/messages/it.json +125 -3
- package/package.json +9 -1
- package/scripts/validate-messages.mjs +1 -0
- package/src/billing/index.ts +1 -0
- package/src/client/index.ts +4 -0
- package/src/components/editors/server/BlockNoteServerContent.tsx +28 -0
- package/src/components/editors/server/__tests__/renderBlockNoteHTML.spec.ts +44 -0
- package/src/components/editors/server/renderBlockNoteHTML.ts +26 -0
- package/src/components/editors/server-entry.ts +7 -0
- package/src/components/index.ts +1 -0
- package/src/components/viewers/BlockNoteStaticViewer.tsx +44 -0
- package/src/core/index.ts +1 -0
- package/src/core/registry/ModuleRegistry.ts +3 -0
- package/src/features/administration/components/AdminIndexContainer.tsx +61 -33
- package/src/features/administration/components/__tests__/AdminIndexContainer.spec.tsx +61 -1
- package/src/features/administration/components/index.ts +2 -1
- package/src/features/administration/contexts/AdministrationContext.tsx +11 -3
- package/src/features/administration/contexts/__tests__/AdministrationContext.spec.tsx +40 -0
- package/src/features/ai-connection/ai-connection.module.ts +2 -0
- package/src/features/ai-connection/contexts/AiConnectionsContext.tsx +3 -16
- package/src/features/ai-connection/contexts/__tests__/AiConnectionsContext.spec.tsx +33 -0
- package/src/features/analytics/__tests__/server-entry.spec.tsx +2 -1
- package/src/features/analytics/analytics.modules.ts +22 -5
- package/src/features/analytics/components/AnalyticsAdminContainer.tsx +4 -3
- package/src/features/analytics/components/AnalyticsAdminPageContainer.tsx +6 -3
- package/src/features/analytics/components/AnalyticsJourneyContainer.tsx +4 -3
- package/src/features/analytics/components/__tests__/AnalyticsJourneyContainer.spec.tsx +11 -0
- package/src/features/analytics/components/__tests__/AnalyticsPageContainers.spec.tsx +12 -1
- package/src/features/analytics/components/server/AnalyticsAdminPage.tsx +6 -3
- package/src/features/analytics/contexts/AnalyticsAdminContext.tsx +8 -17
- package/src/features/analytics/contexts/__tests__/AnalyticsAdminContext.spec.tsx +17 -0
- package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +3 -2
- package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +4 -3
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +22 -5
- package/src/features/billing/components/utils/__tests__/discount.spec.ts +59 -0
- package/src/features/billing/components/utils/__tests__/url.spec.ts +32 -0
- package/src/features/billing/components/utils/discount.ts +38 -0
- package/src/features/billing/components/utils/index.ts +2 -0
- package/src/features/billing/components/utils/url.ts +12 -0
- package/src/features/billing/contexts/CouponContext.tsx +211 -0
- package/src/features/billing/contexts/index.ts +1 -0
- package/src/features/billing/i18n-keys.ts +79 -0
- package/src/features/billing/stripe-coupon/components/containers/CouponContainer.tsx +38 -0
- package/src/features/billing/stripe-coupon/components/containers/index.ts +1 -0
- package/src/features/billing/stripe-coupon/components/details/CouponDetails.tsx +69 -0
- package/src/features/billing/stripe-coupon/components/details/index.ts +1 -0
- package/src/features/billing/stripe-coupon/components/forms/CouponCodeEditor.tsx +79 -0
- package/src/features/billing/stripe-coupon/components/forms/CouponCodeFields.tsx +192 -0
- package/src/features/billing/stripe-coupon/components/forms/CouponEditor.tsx +333 -0
- package/src/features/billing/stripe-coupon/components/forms/CouponRefresher.tsx +45 -0
- package/src/features/billing/stripe-coupon/components/forms/index.ts +6 -0
- package/src/features/billing/stripe-coupon/components/index.ts +5 -0
- package/src/features/billing/stripe-coupon/components/lists/CouponCodesList.tsx +61 -0
- package/src/features/billing/stripe-coupon/components/lists/CouponsList.tsx +67 -0
- package/src/features/billing/stripe-coupon/components/lists/index.ts +2 -0
- package/src/features/billing/stripe-coupon/components/widgets/CouponCodeActions.tsx +80 -0
- package/src/features/billing/stripe-coupon/components/widgets/index.ts +1 -0
- package/src/features/billing/stripe-coupon/data/__tests__/stripe-coupon-models.spec.ts +114 -0
- package/src/features/billing/stripe-coupon/data/index.ts +10 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-code.fields.ts +8 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-code.interface.ts +44 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-code.service.ts +92 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-code.ts +132 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-offer.interface.ts +17 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon-offer.ts +70 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon.fields.ts +7 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon.interface.ts +51 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon.service.ts +93 -0
- package/src/features/billing/stripe-coupon/data/stripe-coupon.ts +165 -0
- package/src/features/billing/stripe-coupon/hooks/useStripeCouponCodeTableStructure.tsx +154 -0
- package/src/features/billing/stripe-coupon/hooks/useStripeCouponTableStructure.tsx +113 -0
- package/src/features/billing/stripe-coupon/index.ts +5 -0
- package/src/features/billing/stripe-coupon/stripe-coupon-code.module.ts +14 -0
- package/src/features/billing/stripe-coupon/stripe-coupon-offer.module.ts +10 -0
- package/src/features/billing/stripe-coupon/stripe-coupon.module.ts +18 -0
- package/src/features/billing/stripe-coupon/utils/__tests__/coupon-places.spec.ts +19 -0
- package/src/features/billing/stripe-coupon/utils/__tests__/to-promotion-code-result.spec.ts +41 -0
- package/src/features/billing/stripe-coupon/utils/coupon-places.ts +23 -0
- package/src/features/billing/stripe-coupon/utils/format-coupon-discount.ts +36 -0
- package/src/features/billing/stripe-coupon/utils/index.ts +3 -0
- package/src/features/billing/stripe-coupon/utils/to-promotion-code-result.ts +23 -0
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +24 -8
- package/src/features/billing/stripe-price/stripe-price.module.ts +2 -0
- package/src/features/billing/stripe-product/components/containers/ProductsListContainer.tsx +21 -6
- package/src/features/billing/stripe-product/stripe-product.module.ts +2 -0
- package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +60 -19
- package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.interface.ts +2 -0
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -5
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +21 -2
- package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +1 -1
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +1 -1
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +60 -49
- package/src/features/billing/stripe-subscription/components/wizards/__tests__/review-card.spec.ts +34 -0
- package/src/features/billing/stripe-subscription/components/wizards/review-card.ts +24 -0
- package/src/features/billing/stripe-subscription/data/__tests__/stripe-subscription.discount.spec.ts +67 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +14 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.service.ts +39 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +21 -0
- package/src/features/billing/stripe-subscription/hooks/__tests__/wizard-payment.spec.ts +48 -0
- package/src/features/billing/stripe-subscription/hooks/__tests__/wizard-promotion.spec.ts +132 -0
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +138 -12
- package/src/features/billing/stripe-subscription/hooks/wizard-payment.ts +30 -0
- package/src/features/billing/stripe-subscription/hooks/wizard-promotion.ts +54 -0
- package/src/features/blog/components/admin/BlogAdminContainer.tsx +13 -6
- package/src/features/blog/components/admin/BlogCategoriesList.tsx +1 -1
- package/src/features/blog/components/admin/BlogCoverImageField.tsx +1 -1
- package/src/features/blog/components/admin/BlogPostContainer.tsx +0 -1
- package/src/features/blog/components/admin/BlogPostEditor.tsx +42 -33
- package/src/features/blog/components/admin/BlogPostTranslationEditor.tsx +12 -4
- package/src/features/blog/components/admin/BlogPostsList.tsx +1 -1
- package/src/features/blog/components/public/BlogPostCard.tsx +2 -9
- package/src/features/blog/components/public/BlogPostMeta.tsx +2 -2
- package/src/features/blog/components/public/BlogPostView.tsx +9 -3
- package/src/features/blog/components/public/__tests__/BlogList.spec.tsx +2 -0
- package/src/features/blog/components/public/__tests__/BlogPostView.spec.tsx +17 -11
- package/src/features/blog/server/fetchers.ts +57 -8
- package/src/features/email-automation/components/containers/EmailAutomationsListContainer.tsx +12 -3
- package/src/features/rbac/contexts/RbacContext.tsx +4 -7
- package/src/features/rbac/contexts/__tests__/RbacContext.spec.tsx +42 -0
- package/src/features/tokenusage/components/TokenUsageAdminContainer.tsx +4 -3
- package/src/features/tokenusage/contexts/TokenUsageAdminContext.tsx +3 -18
- package/src/features/tokenusage/contexts/__tests__/TokenUsageAdminContext.spec.tsx +17 -0
- package/src/features/tokenusage/tokenusage-admin.module.ts +4 -3
- package/src/features/tokenusage/tokenusage.modules.ts +12 -2
- package/src/features/user/contexts/CurrentUserContext.tsx +25 -0
- package/src/features/user/contexts/UserContext.tsx +18 -3
- package/src/features/user/contexts/__tests__/CurrentUserContext.spec.tsx +121 -2
- package/src/features/user/contexts/__tests__/UserContext.spec.tsx +95 -0
- package/dist/chunk-3NLAXVIN.js.map +0 -1
- package/dist/chunk-EUKTBOI2.mjs.map +0 -1
- package/dist/chunk-NFBOSPNJ.js.map +0 -1
- package/dist/chunk-WC63PJSC.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-YQL2SGFR.mjs.map → BlockNoteEditor-NEYG5L6W.mjs.map} +0 -0
- /package/dist/{BlockNoteViewer-AEJKJ27Q.mjs.map → BlockNoteViewer-3OUT5UFY.mjs.map} +0 -0
- /package/dist/{chunk-XCHSX3VC.mjs.map → chunk-BTPUYUQ3.mjs.map} +0 -0
- /package/dist/{chunk-6DC2WVVB.mjs.map → chunk-KQHBONL4.mjs.map} +0 -0
- /package/dist/{chunk-QMYQRPQC.mjs.map → chunk-Y7RR57EW.mjs.map} +0 -0
package/dist/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunk53BAULDPjs = require('../chunk-53BAULDP.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
var _chunkIK65TDQHjs = require('../chunk-IK65TDQH.js');
|
|
@@ -35,10 +35,10 @@ require('../chunk-G4JR3SFV.js');
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
var
|
|
38
|
+
var _chunkHKZAESS6js = require('../chunk-HKZAESS6.js');
|
|
39
|
+
require('../chunk-GHE4VT2R.js');
|
|
39
40
|
require('../chunk-LXKSUWAV.js');
|
|
40
41
|
require('../chunk-JTPRJNT2.js');
|
|
41
|
-
require('../chunk-GHE4VT2R.js');
|
|
42
42
|
require('../chunk-7QVYU63E.js');
|
|
43
43
|
|
|
44
44
|
|
|
@@ -66,5 +66,5 @@ require('../chunk-7QVYU63E.js');
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
exports.CACHE_PROFILES = _chunkIK65TDQHjs.CACHE_PROFILES; exports.ServerAuthService =
|
|
69
|
+
exports.CACHE_PROFILES = _chunkIK65TDQHjs.CACHE_PROFILES; exports.ServerAuthService = _chunkHKZAESS6js.AuthService; exports.ServerCompanyService = _chunkHKZAESS6js.CompanyService; exports.ServerContentService = _chunkHKZAESS6js.ContentService; exports.ServerFeatureService = _chunkHKZAESS6js.FeatureService; exports.ServerJsonApiDelete = _chunkKSYQEKJXjs.ServerJsonApiDelete; exports.ServerJsonApiGet = _chunkKSYQEKJXjs.ServerJsonApiGet; exports.ServerJsonApiPatch = _chunkKSYQEKJXjs.ServerJsonApiPatch; exports.ServerJsonApiPost = _chunkKSYQEKJXjs.ServerJsonApiPost; exports.ServerJsonApiPut = _chunkKSYQEKJXjs.ServerJsonApiPut; exports.ServerNotificationService = _chunkHKZAESS6js.NotificationService; exports.ServerPushService = _chunkHKZAESS6js.PushService; exports.ServerRoleService = _chunkHKZAESS6js.RoleService; exports.ServerS3Service = _chunkHKZAESS6js.S3Service; exports.ServerSession = _chunk53BAULDPjs.ServerSession; exports.ServerUserService = _chunkHKZAESS6js.UserService; exports.configureServerJsonApi = _chunkKSYQEKJXjs.configureServerJsonApi; exports.getServerApiUrl = _chunkKSYQEKJXjs.getServerApiUrl; exports.getServerAppUrl = _chunkKSYQEKJXjs.getServerAppUrl; exports.getServerToken = _chunkYUO55Q5Ajs.getServerToken; exports.getServerTrackablePages = _chunkKSYQEKJXjs.getServerTrackablePages; exports.invalidateCacheTag = _chunk53BAULDPjs.invalidateCacheTag; exports.invalidateCacheTags = _chunk53BAULDPjs.invalidateCacheTags; exports.serverRequest = _chunk6TUB7Y6Tjs.serverRequest; exports.updateCacheTag = _chunk53BAULDPjs.updateCacheTag;
|
|
70
70
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
invalidateCacheTag,
|
|
4
4
|
invalidateCacheTags,
|
|
5
5
|
updateCacheTag
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-BTPUYUQ3.mjs";
|
|
7
7
|
import {
|
|
8
8
|
CACHE_PROFILES
|
|
9
9
|
} from "../chunk-T7SAW3UW.mjs";
|
|
@@ -35,10 +35,10 @@ import {
|
|
|
35
35
|
RoleService,
|
|
36
36
|
S3Service,
|
|
37
37
|
UserService
|
|
38
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-EYA2F6AN.mjs";
|
|
39
|
+
import "../chunk-V5MI7RNB.mjs";
|
|
39
40
|
import "../chunk-AUXK7QSA.mjs";
|
|
40
41
|
import "../chunk-PI56A4DG.mjs";
|
|
41
|
-
import "../chunk-V5MI7RNB.mjs";
|
|
42
42
|
import "../chunk-PAWJFY3S.mjs";
|
|
43
43
|
export {
|
|
44
44
|
CACHE_PROFILES,
|
package/messages/en.json
CHANGED
|
@@ -297,6 +297,118 @@
|
|
|
297
297
|
},
|
|
298
298
|
"billing": {
|
|
299
299
|
"admin": {
|
|
300
|
+
"coupons": {
|
|
301
|
+
"all_products": "All products",
|
|
302
|
+
"codes": {
|
|
303
|
+
"automatic": "Automatic",
|
|
304
|
+
"deactivate": {
|
|
305
|
+
"confirm": "Deactivate",
|
|
306
|
+
"description": "Nobody will be able to use \"{code}\" until you reactivate it. Subscriptions that already have it keep their discount.",
|
|
307
|
+
"title": "Deactivate code"
|
|
308
|
+
},
|
|
309
|
+
"empty": {
|
|
310
|
+
"description": "Add a code customers can use to get this coupon's discount.",
|
|
311
|
+
"title": "No codes yet"
|
|
312
|
+
},
|
|
313
|
+
"entity": "code",
|
|
314
|
+
"never": "Never",
|
|
315
|
+
"reactivate": {
|
|
316
|
+
"confirm": "Reactivate",
|
|
317
|
+
"description": "\"{code}\" can be used again.",
|
|
318
|
+
"title": "Reactivate code"
|
|
319
|
+
},
|
|
320
|
+
"status": {
|
|
321
|
+
"active": "Active",
|
|
322
|
+
"expired": "Expired",
|
|
323
|
+
"inactive": "Inactive",
|
|
324
|
+
"used_up": "Used up"
|
|
325
|
+
},
|
|
326
|
+
"title": "Codes"
|
|
327
|
+
},
|
|
328
|
+
"discount": {
|
|
329
|
+
"amount": "{amount} off",
|
|
330
|
+
"forever": "forever",
|
|
331
|
+
"once": "once",
|
|
332
|
+
"percent": "{value}% off",
|
|
333
|
+
"repeating": "for {months} months"
|
|
334
|
+
},
|
|
335
|
+
"duration": {
|
|
336
|
+
"forever": "Forever",
|
|
337
|
+
"once": "Once",
|
|
338
|
+
"repeating": "For a number of months"
|
|
339
|
+
},
|
|
340
|
+
"empty": {
|
|
341
|
+
"description": "Create a coupon to offer a discount at checkout.",
|
|
342
|
+
"title": "No coupons yet"
|
|
343
|
+
},
|
|
344
|
+
"entity": "coupon",
|
|
345
|
+
"errors": {
|
|
346
|
+
"amountOff": "Enter an amount above zero",
|
|
347
|
+
"durationInMonths": "Enter at least one month",
|
|
348
|
+
"minimumAmount": "Enter an amount above zero, or leave it empty",
|
|
349
|
+
"name": "A coupon name is required",
|
|
350
|
+
"percentOff": "Enter a percentage between 0.01 and 100"
|
|
351
|
+
},
|
|
352
|
+
"fields": {
|
|
353
|
+
"amountOff": "Amount off",
|
|
354
|
+
"automatic": "Apply automatically",
|
|
355
|
+
"code": "Code",
|
|
356
|
+
"codeMaxRedemptions": "Usage limit for this code",
|
|
357
|
+
"codes": "Codes",
|
|
358
|
+
"currency": "Currency",
|
|
359
|
+
"discount": "Discount",
|
|
360
|
+
"discountType": "Type",
|
|
361
|
+
"duration": "Duration",
|
|
362
|
+
"durationInMonths": "Months",
|
|
363
|
+
"expiresAt": "Expires",
|
|
364
|
+
"firstTimeTransaction": "First-time customers only",
|
|
365
|
+
"first_time_warning": "A GM coming from a trial counts as an existing customer, so leave this off for codes meant for trial GMs.",
|
|
366
|
+
"maxRedemptions": "Total usage limit",
|
|
367
|
+
"minimumAmount": "Minimum order amount",
|
|
368
|
+
"name": "Name",
|
|
369
|
+
"percentOff": "Percentage off",
|
|
370
|
+
"places": "Places",
|
|
371
|
+
"products": "Apply to specific products",
|
|
372
|
+
"redeemBy": "Redeem by",
|
|
373
|
+
"status": "Status",
|
|
374
|
+
"stripeCouponId": "ID",
|
|
375
|
+
"stripeCustomerId": "Limit to one customer",
|
|
376
|
+
"stripeId": "Stripe coupon ID"
|
|
377
|
+
},
|
|
378
|
+
"first_code": "First code",
|
|
379
|
+
"fixed_notice": "Stripe doesn't allow changing the discount, duration or limits of a coupon. Make a new coupon instead.",
|
|
380
|
+
"help": {
|
|
381
|
+
"automatic": "Applied by itself when a GM first pays. Only one code can have it: switching it on here switches it off on the code that had it.",
|
|
382
|
+
"products": "Leave empty to apply the coupon to every product."
|
|
383
|
+
},
|
|
384
|
+
"placeholders": {
|
|
385
|
+
"amountOff": "5.00",
|
|
386
|
+
"code": "Leave empty to let Stripe generate one",
|
|
387
|
+
"durationInMonths": "3",
|
|
388
|
+
"maxRedemptions": "No limit",
|
|
389
|
+
"minimumAmount": "0.00",
|
|
390
|
+
"name": "e.g. Founding GM",
|
|
391
|
+
"percentOff": "20",
|
|
392
|
+
"stripeCouponId": "Leave empty to let Stripe generate one"
|
|
393
|
+
},
|
|
394
|
+
"places": {
|
|
395
|
+
"limited": "{used} / {limit}",
|
|
396
|
+
"no_limit": "No limit",
|
|
397
|
+
"unlimited": "{used} / no limit"
|
|
398
|
+
},
|
|
399
|
+
"refresh": {
|
|
400
|
+
"title": "Refresh counts"
|
|
401
|
+
},
|
|
402
|
+
"status": {
|
|
403
|
+
"active": "Active",
|
|
404
|
+
"ended": "Ended"
|
|
405
|
+
},
|
|
406
|
+
"title": "Coupons",
|
|
407
|
+
"type": {
|
|
408
|
+
"amount_off": "Fixed amount off",
|
|
409
|
+
"percent_off": "Percentage off"
|
|
410
|
+
}
|
|
411
|
+
},
|
|
300
412
|
"prices": {
|
|
301
413
|
"actions": {
|
|
302
414
|
"addFeature": "Add feature",
|
|
@@ -430,7 +542,9 @@
|
|
|
430
542
|
"archived": "Archived"
|
|
431
543
|
},
|
|
432
544
|
"tabs": {
|
|
433
|
-
"
|
|
545
|
+
"codes": "Codes",
|
|
546
|
+
"details": "Details",
|
|
547
|
+
"products": "Products"
|
|
434
548
|
},
|
|
435
549
|
"title": "Products"
|
|
436
550
|
}
|
|
@@ -626,10 +740,12 @@
|
|
|
626
740
|
},
|
|
627
741
|
"promo_code": {
|
|
628
742
|
"apply": "Apply",
|
|
743
|
+
"automatic_label": "Applied automatically",
|
|
629
744
|
"duration_forever": "Applied to all payments",
|
|
630
745
|
"duration_once": "Applied to first payment only",
|
|
631
746
|
"duration_repeating": "Applied for {months} months",
|
|
632
|
-
"placeholder": "Enter promo code"
|
|
747
|
+
"placeholder": "Enter promo code",
|
|
748
|
+
"use_different": "Have a different code?"
|
|
633
749
|
},
|
|
634
750
|
"proration": {
|
|
635
751
|
"net_due_today": "Net Due Today",
|
|
@@ -698,8 +814,10 @@
|
|
|
698
814
|
"change_title": "Change Subscription Plan",
|
|
699
815
|
"errors": {
|
|
700
816
|
"already_subscribed": "You already have an active subscription. Please change your existing plan instead.",
|
|
817
|
+
"discount_unavailable": "This discount is no longer available. You have not been charged.",
|
|
701
818
|
"invalid_promo_code": "Invalid promotion code",
|
|
702
819
|
"payment_method_required": "A payment method is required to upgrade from your trial.",
|
|
820
|
+
"payment_not_confirmed": "The payment was not completed. {reason} Nothing was charged: try again, or add another card.",
|
|
703
821
|
"prepare_review": "Failed to prepare review",
|
|
704
822
|
"process_subscription": "Failed to process subscription",
|
|
705
823
|
"validate_promo_code": "Failed to validate promotion code"
|
|
@@ -708,6 +826,7 @@
|
|
|
708
826
|
"payment_description": "Enter your card details to complete your subscription",
|
|
709
827
|
"review": {
|
|
710
828
|
"amount_off": "{amount} off",
|
|
829
|
+
"card_on_file": "{brand} ending in {last4}",
|
|
711
830
|
"charge_now": "Amount to charge now:",
|
|
712
831
|
"confirm_change": "Confirm Plan Change",
|
|
713
832
|
"due_now": "Amount due now:",
|
|
@@ -725,7 +844,10 @@
|
|
|
725
844
|
"selected_plan": "Selected Plan",
|
|
726
845
|
"subscribe_now": "Subscribe Now",
|
|
727
846
|
"trial_upgrade": "Trial Upgrade",
|
|
728
|
-
"trial_upgrade_description": "Your trial will end immediately and you will be charged the full price."
|
|
847
|
+
"trial_upgrade_description": "Your trial will end immediately and you will be charged the full price.",
|
|
848
|
+
"trial_upgrade_description_discounted": "Your trial will end immediately and you will be charged the discounted price.",
|
|
849
|
+
"use_another_card": "Use another card",
|
|
850
|
+
"discount_carries_over": "Your current discount carries over to the new plan."
|
|
729
851
|
},
|
|
730
852
|
"steps": {
|
|
731
853
|
"payment": "Payment",
|
package/messages/it.json
CHANGED
|
@@ -297,6 +297,118 @@
|
|
|
297
297
|
},
|
|
298
298
|
"billing": {
|
|
299
299
|
"admin": {
|
|
300
|
+
"coupons": {
|
|
301
|
+
"all_products": "Tutti i prodotti",
|
|
302
|
+
"codes": {
|
|
303
|
+
"automatic": "Automatico",
|
|
304
|
+
"deactivate": {
|
|
305
|
+
"confirm": "Disattiva",
|
|
306
|
+
"description": "Nessuno potrà usare \"{code}\" finché non lo riattivi. Gli abbonamenti che lo hanno già mantengono lo sconto.",
|
|
307
|
+
"title": "Disattiva codice"
|
|
308
|
+
},
|
|
309
|
+
"empty": {
|
|
310
|
+
"description": "Aggiungi un codice che i clienti possono usare per avere lo sconto di questo coupon.",
|
|
311
|
+
"title": "Ancora nessun codice"
|
|
312
|
+
},
|
|
313
|
+
"entity": "codice",
|
|
314
|
+
"never": "Mai",
|
|
315
|
+
"reactivate": {
|
|
316
|
+
"confirm": "Riattiva",
|
|
317
|
+
"description": "\"{code}\" potrà essere usato di nuovo.",
|
|
318
|
+
"title": "Riattiva codice"
|
|
319
|
+
},
|
|
320
|
+
"status": {
|
|
321
|
+
"active": "Attivo",
|
|
322
|
+
"expired": "Scaduto",
|
|
323
|
+
"inactive": "Inattivo",
|
|
324
|
+
"used_up": "Esaurito"
|
|
325
|
+
},
|
|
326
|
+
"title": "Codici"
|
|
327
|
+
},
|
|
328
|
+
"discount": {
|
|
329
|
+
"amount": "{amount} di sconto",
|
|
330
|
+
"forever": "per sempre",
|
|
331
|
+
"once": "una volta",
|
|
332
|
+
"percent": "{value}% di sconto",
|
|
333
|
+
"repeating": "per {months} mesi"
|
|
334
|
+
},
|
|
335
|
+
"duration": {
|
|
336
|
+
"forever": "Per sempre",
|
|
337
|
+
"once": "Una volta",
|
|
338
|
+
"repeating": "Per un numero di mesi"
|
|
339
|
+
},
|
|
340
|
+
"empty": {
|
|
341
|
+
"description": "Crea un coupon per offrire uno sconto al pagamento.",
|
|
342
|
+
"title": "Ancora nessun coupon"
|
|
343
|
+
},
|
|
344
|
+
"entity": "coupon",
|
|
345
|
+
"errors": {
|
|
346
|
+
"amountOff": "Inserisci un importo maggiore di zero",
|
|
347
|
+
"durationInMonths": "Inserisci almeno un mese",
|
|
348
|
+
"minimumAmount": "Inserisci un importo maggiore di zero, o lascia vuoto",
|
|
349
|
+
"name": "Il nome del coupon è obbligatorio",
|
|
350
|
+
"percentOff": "Inserisci una percentuale tra 0,01 e 100"
|
|
351
|
+
},
|
|
352
|
+
"fields": {
|
|
353
|
+
"amountOff": "Importo dello sconto",
|
|
354
|
+
"automatic": "Applica automaticamente",
|
|
355
|
+
"code": "Codice",
|
|
356
|
+
"codeMaxRedemptions": "Limite di utilizzo per questo codice",
|
|
357
|
+
"codes": "Codici",
|
|
358
|
+
"currency": "Valuta",
|
|
359
|
+
"discount": "Sconto",
|
|
360
|
+
"discountType": "Tipo",
|
|
361
|
+
"duration": "Durata",
|
|
362
|
+
"durationInMonths": "Mesi",
|
|
363
|
+
"expiresAt": "Scadenza",
|
|
364
|
+
"firstTimeTransaction": "Solo nuovi clienti",
|
|
365
|
+
"first_time_warning": "Un GM che arriva da una prova conta come cliente esistente, quindi lascia disattivato per i codici pensati per i GM in prova.",
|
|
366
|
+
"maxRedemptions": "Limite di utilizzo totale",
|
|
367
|
+
"minimumAmount": "Importo minimo dell'ordine",
|
|
368
|
+
"name": "Nome",
|
|
369
|
+
"percentOff": "Percentuale di sconto",
|
|
370
|
+
"places": "Posti",
|
|
371
|
+
"products": "Applica a prodotti specifici",
|
|
372
|
+
"redeemBy": "Utilizzabile fino al",
|
|
373
|
+
"status": "Stato",
|
|
374
|
+
"stripeCouponId": "ID",
|
|
375
|
+
"stripeCustomerId": "Limita a un solo cliente",
|
|
376
|
+
"stripeId": "ID coupon Stripe"
|
|
377
|
+
},
|
|
378
|
+
"first_code": "Primo codice",
|
|
379
|
+
"fixed_notice": "Stripe non permette di cambiare sconto, durata o limiti di un coupon. Crea un nuovo coupon.",
|
|
380
|
+
"help": {
|
|
381
|
+
"automatic": "Si applica da solo quando un GM paga la prima volta. Solo un codice può averlo: attivarlo qui lo disattiva sul codice che lo aveva.",
|
|
382
|
+
"products": "Lascia vuoto per applicare il coupon a tutti i prodotti."
|
|
383
|
+
},
|
|
384
|
+
"placeholders": {
|
|
385
|
+
"amountOff": "5,00",
|
|
386
|
+
"code": "Lascia vuoto per farlo generare a Stripe",
|
|
387
|
+
"durationInMonths": "3",
|
|
388
|
+
"maxRedemptions": "Nessun limite",
|
|
389
|
+
"minimumAmount": "0,00",
|
|
390
|
+
"name": "es. GM fondatore",
|
|
391
|
+
"percentOff": "20",
|
|
392
|
+
"stripeCouponId": "Lascia vuoto per farlo generare a Stripe"
|
|
393
|
+
},
|
|
394
|
+
"places": {
|
|
395
|
+
"limited": "{used} / {limit}",
|
|
396
|
+
"no_limit": "Nessun limite",
|
|
397
|
+
"unlimited": "{used} / nessun limite"
|
|
398
|
+
},
|
|
399
|
+
"refresh": {
|
|
400
|
+
"title": "Aggiorna conteggi"
|
|
401
|
+
},
|
|
402
|
+
"status": {
|
|
403
|
+
"active": "Attivo",
|
|
404
|
+
"ended": "Terminato"
|
|
405
|
+
},
|
|
406
|
+
"title": "Coupon",
|
|
407
|
+
"type": {
|
|
408
|
+
"amount_off": "Importo fisso",
|
|
409
|
+
"percent_off": "Percentuale"
|
|
410
|
+
}
|
|
411
|
+
},
|
|
300
412
|
"prices": {
|
|
301
413
|
"actions": {
|
|
302
414
|
"addFeature": "Aggiungi caratteristica",
|
|
@@ -430,7 +542,9 @@
|
|
|
430
542
|
"archived": "Archiviato"
|
|
431
543
|
},
|
|
432
544
|
"tabs": {
|
|
433
|
-
"
|
|
545
|
+
"codes": "Codici",
|
|
546
|
+
"details": "Dettagli",
|
|
547
|
+
"products": "Prodotti"
|
|
434
548
|
},
|
|
435
549
|
"title": "Prodotti"
|
|
436
550
|
}
|
|
@@ -626,10 +740,12 @@
|
|
|
626
740
|
},
|
|
627
741
|
"promo_code": {
|
|
628
742
|
"apply": "Applica",
|
|
743
|
+
"automatic_label": "Applicato automaticamente",
|
|
629
744
|
"duration_forever": "Applicato a tutti i pagamenti",
|
|
630
745
|
"duration_once": "Applicato solo al primo pagamento",
|
|
631
746
|
"duration_repeating": "Applicato per {months} mesi",
|
|
632
|
-
"placeholder": "Inserisci il codice promozionale"
|
|
747
|
+
"placeholder": "Inserisci il codice promozionale",
|
|
748
|
+
"use_different": "Hai un altro codice?"
|
|
633
749
|
},
|
|
634
750
|
"proration": {
|
|
635
751
|
"net_due_today": "Netto dovuto oggi",
|
|
@@ -698,8 +814,10 @@
|
|
|
698
814
|
"change_title": "Cambia piano di abbonamento",
|
|
699
815
|
"errors": {
|
|
700
816
|
"already_subscribed": "Hai già un abbonamento attivo. Cambia invece il piano attuale.",
|
|
817
|
+
"discount_unavailable": "Questo sconto non è più disponibile. Non ti è stato addebitato nulla.",
|
|
701
818
|
"invalid_promo_code": "Codice promozionale non valido",
|
|
702
819
|
"payment_method_required": "Per passare dalla prova a un piano a pagamento serve un metodo di pagamento.",
|
|
820
|
+
"payment_not_confirmed": "Il pagamento non è stato completato. {reason} Non ti è stato addebitato nulla: riprova o aggiungi un'altra carta.",
|
|
703
821
|
"prepare_review": "Impossibile preparare il riepilogo",
|
|
704
822
|
"process_subscription": "Impossibile elaborare l'abbonamento",
|
|
705
823
|
"validate_promo_code": "Impossibile verificare il codice promozionale"
|
|
@@ -708,6 +826,7 @@
|
|
|
708
826
|
"payment_description": "Inserisci i dati della carta per completare l'abbonamento",
|
|
709
827
|
"review": {
|
|
710
828
|
"amount_off": "{amount} di sconto",
|
|
829
|
+
"card_on_file": "{brand} che termina con {last4}",
|
|
711
830
|
"charge_now": "Importo da addebitare ora:",
|
|
712
831
|
"confirm_change": "Conferma il cambio di piano",
|
|
713
832
|
"due_now": "Importo dovuto ora:",
|
|
@@ -725,7 +844,10 @@
|
|
|
725
844
|
"selected_plan": "Piano selezionato",
|
|
726
845
|
"subscribe_now": "Abbonati ora",
|
|
727
846
|
"trial_upgrade": "Passaggio dalla prova",
|
|
728
|
-
"trial_upgrade_description": "La tua prova terminerà subito e ti verrà addebitato il prezzo pieno."
|
|
847
|
+
"trial_upgrade_description": "La tua prova terminerà subito e ti verrà addebitato il prezzo pieno.",
|
|
848
|
+
"trial_upgrade_description_discounted": "La tua prova terminerà subito e ti verrà addebitato il prezzo scontato.",
|
|
849
|
+
"use_another_card": "Usa un'altra carta",
|
|
850
|
+
"discount_carries_over": "Il tuo sconto attuale resta valido anche sul nuovo piano."
|
|
729
851
|
},
|
|
730
852
|
"steps": {
|
|
731
853
|
"payment": "Pagamento",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carlonicora/nextjs-jsonapi",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"description": "Next.js JSON:API client with server/client support and caching",
|
|
5
5
|
"author": "Carlo Nicora",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -49,6 +49,11 @@
|
|
|
49
49
|
"require": "./dist/contexts/index.js"
|
|
50
50
|
},
|
|
51
51
|
"./contexts/styles.css": "./dist/contexts/index.css",
|
|
52
|
+
"./blocknote/server": {
|
|
53
|
+
"types": "./dist/components/editors/server.d.ts",
|
|
54
|
+
"import": "./dist/components/editors/server.mjs",
|
|
55
|
+
"require": "./dist/components/editors/server.js"
|
|
56
|
+
},
|
|
52
57
|
"./testing": {
|
|
53
58
|
"types": "./dist/testing/index.d.ts",
|
|
54
59
|
"import": "./dist/testing/index.mjs",
|
|
@@ -164,6 +169,7 @@
|
|
|
164
169
|
"@base-ui/react": "1.8.0",
|
|
165
170
|
"@blocknote/core": "^0.55.0",
|
|
166
171
|
"@blocknote/react": "^0.55.0",
|
|
172
|
+
"@blocknote/server-util": "^0.55.0",
|
|
167
173
|
"@blocknote/shadcn": "^0.55.0",
|
|
168
174
|
"@blocknote/xl-ai": "^0.55.0",
|
|
169
175
|
"@dnd-kit/core": "^6.3.1",
|
|
@@ -213,6 +219,8 @@
|
|
|
213
219
|
"tw-animate-css": "^1.4.0",
|
|
214
220
|
"uuid": "^14.0.2",
|
|
215
221
|
"vaul": "^1.1.2",
|
|
222
|
+
"y-prosemirror": "^1.3.7",
|
|
223
|
+
"y-protocols": "^1.0.6",
|
|
216
224
|
"zod": "^4.6.5"
|
|
217
225
|
},
|
|
218
226
|
"devDependencies": {
|
|
@@ -28,6 +28,7 @@ export const APP_PROVIDED_KEYS = [
|
|
|
28
28
|
/^features\.assistant\.starters\./, // example questions about the app's own domain
|
|
29
29
|
/^features\.assistant\.empty_state\.subtitle$/, // says what the app's assistant knows about
|
|
30
30
|
/^auth\.gdpr\.marketing_consent$/, // a consent must name who sends the news: the app
|
|
31
|
+
/^billing\.ui\.wizard\.errors\.discount_sold_out$/, // names who to contact: the app
|
|
31
32
|
// The app's own entities (CommonDeleter / RecentPagesNavigator render
|
|
32
33
|
// `entities.${type}` for any module). Only the library's own entities ship.
|
|
33
34
|
/^entities\.(?!(?:assistants|companies|howtos|rbac|roles|users)(?:\.|$))/,
|
package/src/billing/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "../features/billing/stripe-customer/components";
|
|
|
5
5
|
export * from "../features/billing/stripe-invoice/components";
|
|
6
6
|
export * from "../features/billing/stripe-price/components";
|
|
7
7
|
export * from "../features/billing/stripe-product/components";
|
|
8
|
+
export * from "../features/billing/stripe-coupon/components";
|
|
8
9
|
export * from "../features/billing/stripe-subscription/components";
|
|
9
10
|
export * from "../features/billing/stripe-usage/components";
|
|
10
11
|
export * from "../features/billing/stripe-promotion-code/components";
|
package/src/client/index.ts
CHANGED
|
@@ -21,6 +21,8 @@ import { useRoleTableStructure } from "../features/role/hooks";
|
|
|
21
21
|
import { useUserTableStructure } from "../features/user/hooks";
|
|
22
22
|
import { useStripePriceTableStructure } from "../features/billing/stripe-price/hooks/useStripePriceTableStructure";
|
|
23
23
|
import { useStripeProductTableStructure } from "../features/billing/stripe-product/hooks/useStripeProductTableStructure";
|
|
24
|
+
import { useStripeCouponTableStructure } from "../features/billing/stripe-coupon/hooks/useStripeCouponTableStructure";
|
|
25
|
+
import { useStripeCouponCodeTableStructure } from "../features/billing/stripe-coupon/hooks/useStripeCouponCodeTableStructure";
|
|
24
26
|
import { useWaitlistTableStructure } from "../features/waitlist/hooks/useWaitlistTableStructure";
|
|
25
27
|
import { registerTableGenerator } from "../hooks";
|
|
26
28
|
|
|
@@ -35,5 +37,7 @@ registerTableGenerator("users", useUserTableStructure);
|
|
|
35
37
|
registerTableGenerator("companies", useCompanyTableStructure);
|
|
36
38
|
registerTableGenerator("stripe-products", useStripeProductTableStructure);
|
|
37
39
|
registerTableGenerator("stripe-prices", useStripePriceTableStructure);
|
|
40
|
+
registerTableGenerator("stripe-coupons", useStripeCouponTableStructure);
|
|
41
|
+
registerTableGenerator("stripe-coupon-codes", useStripeCouponCodeTableStructure);
|
|
38
42
|
registerTableGenerator("waitlists", useWaitlistTableStructure);
|
|
39
43
|
// Note: Content registration moved to app-level to support app-specific cellTopic
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PartialBlock } from "@blocknote/core";
|
|
2
|
+
import "@blocknote/shadcn/style.css";
|
|
3
|
+
// Imported through the package's own client subpath, like the analytics server
|
|
4
|
+
// pages: the built server entry must reach the viewer through the "use client"
|
|
5
|
+
// bundle, not inline it.
|
|
6
|
+
import { BlockNoteStaticViewer } from "@carlonicora/nextjs-jsonapi/components";
|
|
7
|
+
import { renderBlockNoteHTML } from "./renderBlockNoteHTML";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Read-only rich text rendered on the server, so the text is in the HTML that
|
|
11
|
+
* crawlers read. For public read-only pages only: everywhere else, display goes
|
|
12
|
+
* through BlockNoteEditorContainer.
|
|
13
|
+
*/
|
|
14
|
+
export async function BlockNoteServerContent({
|
|
15
|
+
content,
|
|
16
|
+
size,
|
|
17
|
+
className,
|
|
18
|
+
}: {
|
|
19
|
+
content?: PartialBlock[];
|
|
20
|
+
size?: "default" | "sm";
|
|
21
|
+
className?: string;
|
|
22
|
+
}) {
|
|
23
|
+
if (!Array.isArray(content) || content.length === 0) return null;
|
|
24
|
+
|
|
25
|
+
const html = await renderBlockNoteHTML(content);
|
|
26
|
+
|
|
27
|
+
return <BlockNoteStaticViewer html={html} size={size} className={className} />;
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
// The server render runs in Node, where there is no window or document of our own:
|
|
3
|
+
// BlockNote's ServerBlockNoteEditor brings its JSDOM.
|
|
4
|
+
import type { PartialBlock } from "@blocknote/core";
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
import { renderBlockNoteHTML } from "../renderBlockNoteHTML";
|
|
7
|
+
|
|
8
|
+
const blocks: PartialBlock[] = [
|
|
9
|
+
{ type: "heading", props: { level: 2 }, content: "Prep situations" },
|
|
10
|
+
{
|
|
11
|
+
type: "paragraph",
|
|
12
|
+
content: [
|
|
13
|
+
{ type: "text", text: "A scene that can go ", styles: {} },
|
|
14
|
+
{ type: "text", text: "three ways", styles: { bold: true } },
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
{ type: "bulletListItem", content: "First clue" },
|
|
18
|
+
{ type: "bulletListItem", content: "Second clue" },
|
|
19
|
+
{
|
|
20
|
+
type: "paragraph",
|
|
21
|
+
content: [{ type: "link", href: "https://example.com/guide", content: "Read the guide" }],
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
describe("renderBlockNoteHTML", () => {
|
|
26
|
+
it("renders the blocks' text into HTML on the server", async () => {
|
|
27
|
+
const html = await renderBlockNoteHTML(blocks);
|
|
28
|
+
|
|
29
|
+
expect(html).toContain("Prep situations");
|
|
30
|
+
expect(html).toMatch(/<h2[^>]*>.*Prep situations.*<\/h2>/s);
|
|
31
|
+
expect(html).toMatch(/<strong[^>]*>three ways<\/strong>/);
|
|
32
|
+
expect(html).toContain("First clue");
|
|
33
|
+
expect(html).toContain("Second clue");
|
|
34
|
+
expect(html).toContain('href="https://example.com/guide"');
|
|
35
|
+
expect(html).toContain("Read the guide");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("leaves the server globals as they were", async () => {
|
|
39
|
+
await Promise.all([renderBlockNoteHTML(blocks), renderBlockNoteHTML(blocks)]);
|
|
40
|
+
|
|
41
|
+
expect(typeof (globalThis as { window?: unknown }).window).toBe("undefined");
|
|
42
|
+
expect(typeof (globalThis as { document?: unknown }).document).toBe("undefined");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PartialBlock } from "@blocknote/core";
|
|
2
|
+
import { ServerBlockNoteEditor } from "@blocknote/server-util";
|
|
3
|
+
|
|
4
|
+
// Default schema only, the same one BlockNoteViewer uses: the editor's mention
|
|
5
|
+
// and diff inline specs are React specs from "use client" modules (next/link,
|
|
6
|
+
// hover cards), so they cannot run here.
|
|
7
|
+
let editor: ServerBlockNoteEditor | undefined;
|
|
8
|
+
|
|
9
|
+
// ServerBlockNoteEditor swaps globalThis.window/document for its JSDOM around
|
|
10
|
+
// each call and restores them after an await. Two overlapping calls would
|
|
11
|
+
// restore each other's values and could leave the JSDOM window on the server's
|
|
12
|
+
// globals, so calls run one at a time.
|
|
13
|
+
let queue: Promise<unknown> = Promise.resolve();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Renders a BlockNote blocks array to the HTML the editor itself would render,
|
|
17
|
+
* through BlockNote's own server editor (`blocksToFullHTML`). Server only.
|
|
18
|
+
*/
|
|
19
|
+
export function renderBlockNoteHTML(blocks: PartialBlock[]): Promise<string> {
|
|
20
|
+
const run = queue.then(() => {
|
|
21
|
+
editor ??= ServerBlockNoteEditor.create();
|
|
22
|
+
return editor.blocksToFullHTML(blocks);
|
|
23
|
+
});
|
|
24
|
+
queue = run.catch(() => undefined);
|
|
25
|
+
return run;
|
|
26
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Server-only barrel for BlockNote rendering.
|
|
2
|
+
// Consumed via `@carlonicora/nextjs-jsonapi/blocknote/server`. Must NOT receive a
|
|
3
|
+
// "use client" directive: it loads @blocknote/server-util (and its JSDOM), which
|
|
4
|
+
// must never reach a client bundle. The app lists @blocknote/server-util in
|
|
5
|
+
// `serverExternalPackages` so Node loads it instead of the bundler.
|
|
6
|
+
|
|
7
|
+
export { BlockNoteServerContent } from "./server/BlockNoteServerContent";
|
package/src/components/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./contents";
|
|
|
7
7
|
export * from "./details";
|
|
8
8
|
export * from "./editors";
|
|
9
9
|
export { BlockNoteViewerContainer } from "./viewers/BlockNoteViewerContainer";
|
|
10
|
+
export { BlockNoteStaticViewer } from "./viewers/BlockNoteStaticViewer";
|
|
10
11
|
export * from "./errors";
|
|
11
12
|
export * from "./forms";
|
|
12
13
|
export * from "./navigations";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useTheme } from "next-themes";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { cn } from "../../utils";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Shows HTML produced by BlockNoteServerContent inside the same container
|
|
9
|
+
* markup BlockNoteView renders, so BlockNote's stylesheet and the app's
|
|
10
|
+
* `.BlockNoteView` rules apply as they do to BlockNoteViewer.
|
|
11
|
+
*/
|
|
12
|
+
export function BlockNoteStaticViewer({
|
|
13
|
+
html,
|
|
14
|
+
size,
|
|
15
|
+
className,
|
|
16
|
+
}: {
|
|
17
|
+
html: string;
|
|
18
|
+
size?: "default" | "sm";
|
|
19
|
+
className?: string;
|
|
20
|
+
}) {
|
|
21
|
+
// The server cannot know the theme: render light until mounted, then follow
|
|
22
|
+
// the app theme like BlockNoteViewer, so hydration never mismatches.
|
|
23
|
+
const [mounted, setMounted] = useState(false);
|
|
24
|
+
const { resolvedTheme } = useTheme();
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
setMounted(true);
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const theme = mounted && resolvedTheme === "dark" ? "dark" : "light";
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
className={cn("bn-root bn-container", theme, "bn-shadcn BlockNoteView", size === "sm" && "small", className)}
|
|
35
|
+
data-color-scheme={theme}
|
|
36
|
+
>
|
|
37
|
+
<div
|
|
38
|
+
className="bn-editor bn-default-styles ProseMirror"
|
|
39
|
+
contentEditable={false}
|
|
40
|
+
dangerouslySetInnerHTML={{ __html: html }}
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
package/src/core/index.ts
CHANGED
|
@@ -56,6 +56,7 @@ export * from "../features/billing/stripe-product";
|
|
|
56
56
|
export * from "../features/billing/stripe-subscription";
|
|
57
57
|
export * from "../features/billing/stripe-usage";
|
|
58
58
|
export * from "../features/billing/stripe-promotion-code";
|
|
59
|
+
export * from "../features/billing/stripe-coupon";
|
|
59
60
|
// AI connection administration: data + module only, NOT the feature barrel —
|
|
60
61
|
// that one also re-exports the feature's client components, and core must stay
|
|
61
62
|
// importable from the server (same rationale as the tokenusage entries below).
|