@carlonicora/nextjs-jsonapi 6.6.0 → 6.7.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.
Files changed (102) hide show
  1. package/dist/{BlockNoteEditor-E4V7AEG2.js → BlockNoteEditor-BSFR2GPI.js} +19 -19
  2. package/dist/{BlockNoteEditor-E4V7AEG2.js.map → BlockNoteEditor-BSFR2GPI.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-MWGVWNSE.mjs → BlockNoteEditor-HWJBQAKG.mjs} +4 -4
  4. package/dist/{BlockNoteViewer-VNU7WVN5.mjs → BlockNoteViewer-IIBUU7J7.mjs} +2 -2
  5. package/dist/{BlockNoteViewer-LGRKM7OA.js → BlockNoteViewer-NHS6CCMS.js} +3 -3
  6. package/dist/{BlockNoteViewer-LGRKM7OA.js.map → BlockNoteViewer-NHS6CCMS.js.map} +1 -1
  7. package/dist/{auth.interface-D5606g19.d.ts → auth.interface-B4tRE0k0.d.ts} +2 -0
  8. package/dist/{auth.interface-tsOuc0Fi.d.mts → auth.interface-DuX87BZ3.d.mts} +2 -0
  9. package/dist/billing/index.js +492 -492
  10. package/dist/billing/index.mjs +3 -3
  11. package/dist/{chunk-AMN2XDN5.js → chunk-3HOJNAZB.js} +8 -8
  12. package/dist/{chunk-AMN2XDN5.js.map → chunk-3HOJNAZB.js.map} +1 -1
  13. package/dist/{chunk-OJAIKQR2.js → chunk-6KE7UBYY.js} +427 -233
  14. package/dist/chunk-6KE7UBYY.js.map +1 -0
  15. package/dist/{chunk-F2MZ7GY6.js → chunk-73XWQA6U.js} +4 -4
  16. package/dist/{chunk-F2MZ7GY6.js.map → chunk-73XWQA6U.js.map} +1 -1
  17. package/dist/{chunk-IQ2XYAB5.mjs → chunk-EC4PQ44E.mjs} +2 -2
  18. package/dist/{chunk-RSMBRI3E.mjs → chunk-OYRJ32KR.mjs} +2 -2
  19. package/dist/{chunk-R2XBVIO5.js → chunk-PCCUPEBU.js} +1066 -873
  20. package/dist/chunk-PCCUPEBU.js.map +1 -0
  21. package/dist/{chunk-AEVLFZRK.js → chunk-PYDDFFQM.js} +3 -3
  22. package/dist/{chunk-AEVLFZRK.js.map → chunk-PYDDFFQM.js.map} +1 -1
  23. package/dist/{chunk-7GB5MR77.mjs → chunk-QNIWATQD.mjs} +195 -1
  24. package/dist/chunk-QNIWATQD.mjs.map +1 -0
  25. package/dist/{chunk-IDV534SJ.mjs → chunk-S4NKWMX5.mjs} +3729 -3536
  26. package/dist/chunk-S4NKWMX5.mjs.map +1 -0
  27. package/dist/{chunk-PDS57QPD.mjs → chunk-XYKDBOCE.mjs} +2 -2
  28. package/dist/client/index.js +4 -4
  29. package/dist/client/index.mjs +3 -3
  30. package/dist/components/index.d.mts +39 -4
  31. package/dist/components/index.d.ts +39 -4
  32. package/dist/components/index.js +12 -4
  33. package/dist/components/index.js.map +1 -1
  34. package/dist/components/index.mjs +11 -3
  35. package/dist/contexts/index.js +4 -4
  36. package/dist/contexts/index.mjs +3 -3
  37. package/dist/core/index.d.mts +115 -5
  38. package/dist/core/index.d.ts +115 -5
  39. package/dist/core/index.js +14 -2
  40. package/dist/core/index.js.map +1 -1
  41. package/dist/core/index.mjs +13 -1
  42. package/dist/email-automations/index.js +92 -92
  43. package/dist/email-automations/index.mjs +3 -3
  44. package/dist/features/analytics/index.js +121 -121
  45. package/dist/features/analytics/index.mjs +4 -4
  46. package/dist/features/analytics/server.js +4 -4
  47. package/dist/features/analytics/server.mjs +2 -2
  48. package/dist/features/blog/index.js +150 -150
  49. package/dist/features/blog/index.mjs +3 -3
  50. package/dist/features/blog/server.js +16 -16
  51. package/dist/features/blog/server.mjs +1 -1
  52. package/dist/features/help/index.js +37 -37
  53. package/dist/features/help/index.mjs +3 -3
  54. package/dist/features/tokenusage/index.js +127 -127
  55. package/dist/features/tokenusage/index.mjs +4 -4
  56. package/dist/index.d.mts +3 -3
  57. package/dist/index.d.ts +3 -3
  58. package/dist/index.js +15 -3
  59. package/dist/index.js.map +1 -1
  60. package/dist/index.mjs +14 -2
  61. package/dist/{s3.service-BNBD9YTg.d.mts → s3.service-CRGJbO-6.d.mts} +1 -1
  62. package/dist/{s3.service-Da7C2gtt.d.ts → s3.service-DZG-VyLY.d.ts} +1 -1
  63. package/dist/server/index.d.mts +2 -2
  64. package/dist/server/index.d.ts +2 -2
  65. package/dist/server/index.js +3 -3
  66. package/dist/server/index.mjs +2 -2
  67. package/messages/en.json +24 -0
  68. package/messages/it.json +24 -0
  69. package/package.json +1 -1
  70. package/src/components/index.ts +1 -0
  71. package/src/core/index.ts +5 -0
  72. package/src/core/registry/ModuleRegistry.ts +13 -0
  73. package/src/features/account-deletion/account-deletion.module.ts +13 -0
  74. package/src/features/account-deletion/components/AccountDeletionAdminTrigger.tsx +183 -0
  75. package/src/features/account-deletion/components/AccountDeletionCancelledNotice.tsx +51 -0
  76. package/src/features/account-deletion/components/AccountDeletionKeepContainer.tsx +74 -0
  77. package/src/features/account-deletion/components/index.ts +3 -0
  78. package/src/features/account-deletion/data/__tests__/AccountDeletion.spec.ts +89 -0
  79. package/src/features/account-deletion/data/account-deletion.interface.ts +22 -0
  80. package/src/features/account-deletion/data/account-deletion.service.ts +69 -0
  81. package/src/features/account-deletion/data/account-deletion.ts +90 -0
  82. package/src/features/account-deletion/data/index.ts +3 -0
  83. package/src/features/account-deletion/index.ts +4 -0
  84. package/src/features/account-deletion/utils/__tests__/account-deletion-notice.spec.ts +40 -0
  85. package/src/features/account-deletion/utils/account-deletion-notice.ts +27 -0
  86. package/src/features/account-deletion/utils/index.ts +1 -0
  87. package/src/features/auth/components/forms/Cookies.tsx +3 -0
  88. package/src/features/auth/components/forms/TwoFactorChallenge.tsx +2 -0
  89. package/src/features/auth/data/__tests__/auth.spec.ts +36 -0
  90. package/src/features/auth/data/auth.interface.ts +2 -0
  91. package/src/features/auth/data/auth.service.ts +4 -0
  92. package/src/features/auth/data/auth.ts +7 -0
  93. package/src/features/user/contexts/UserContext.tsx +8 -0
  94. package/dist/chunk-7GB5MR77.mjs.map +0 -1
  95. package/dist/chunk-IDV534SJ.mjs.map +0 -1
  96. package/dist/chunk-OJAIKQR2.js.map +0 -1
  97. package/dist/chunk-R2XBVIO5.js.map +0 -1
  98. /package/dist/{BlockNoteEditor-MWGVWNSE.mjs.map → BlockNoteEditor-HWJBQAKG.mjs.map} +0 -0
  99. /package/dist/{BlockNoteViewer-VNU7WVN5.mjs.map → BlockNoteViewer-IIBUU7J7.mjs.map} +0 -0
  100. /package/dist/{chunk-IQ2XYAB5.mjs.map → chunk-EC4PQ44E.mjs.map} +0 -0
  101. /package/dist/{chunk-RSMBRI3E.mjs.map → chunk-OYRJ32KR.mjs.map} +0 -0
  102. /package/dist/{chunk-PDS57QPD.mjs.map → chunk-XYKDBOCE.mjs.map} +0 -0
@@ -3,6 +3,7 @@
3
3
  import { useEffect, useState } from "react";
4
4
  import { JsonApiHydratedDataInterface, Modules, rehydrate } from "../../../../core";
5
5
  import { useI18nRouter } from "../../../../i18n";
6
+ import { markAccountDeletionCancelled } from "../../../account-deletion/utils/account-deletion-notice";
6
7
  import { UserInterface } from "../../../user";
7
8
  import { useCurrentUserContext } from "../../../user/contexts";
8
9
  import { AuthInterface } from "../../data";
@@ -18,6 +19,8 @@ export function Cookies({ dehydratedAuth, page }: { dehydratedAuth: JsonApiHydra
18
19
  async function saveTokenOnServer() {
19
20
  await AuthService.saveToken({ dehydratedAuth });
20
21
  const auth: AuthInterface = rehydrate(Modules.Auth, dehydratedAuth) as AuthInterface;
22
+ // Discord / Google path: the flag is on the Auth document from the code exchange.
23
+ if (auth.deletionCancelled) markAccountDeletionCancelled();
21
24
  setUser(auth.user as UserInterface);
22
25
  setHasSaved(true);
23
26
 
@@ -18,6 +18,7 @@ import {
18
18
  TabsList,
19
19
  TabsTrigger,
20
20
  } from "../../../../shadcnui";
21
+ import { markAccountDeletionCancelled } from "../../../account-deletion/utils/account-deletion-notice";
21
22
  import { UserInterface } from "../../../user";
22
23
  import { useCurrentUserContext } from "../../../user/contexts";
23
24
  import { useAuthContext } from "../../contexts";
@@ -46,6 +47,7 @@ export function TwoFactorChallenge() {
46
47
  }
47
48
 
48
49
  const handleSuccess = (auth: AuthInterface) => {
50
+ if (auth.deletionCancelled) markAccountDeletionCancelled();
49
51
  setPendingTwoFactor(undefined);
50
52
  setUser(auth.user);
51
53
 
@@ -0,0 +1,36 @@
1
+ import { beforeAll, describe, expect, it } from "vitest";
2
+ import { ApiRequestDataTypeInterface } from "../../../../core/interfaces/ApiRequestDataTypeInterface";
3
+ import { ModuleRegistry } from "../../../../core/registry/ModuleRegistry";
4
+ import { Auth } from "../auth";
5
+
6
+ // Auth.rehydrate() resolves Modules.User through the real ModuleRegistry (the
7
+ // argument of `_readIncluded`), so it must be registered even though these
8
+ // fixtures carry no included user.
9
+ const registerIfAbsent = (key: string, module: ApiRequestDataTypeInterface) => {
10
+ try {
11
+ ModuleRegistry.get(key as any);
12
+ } catch {
13
+ ModuleRegistry.register(key, module);
14
+ }
15
+ };
16
+
17
+ beforeAll(() => {
18
+ registerIfAbsent("Auth", { name: "auth", model: Auth } as any);
19
+ registerIfAbsent("User", { name: "users", model: class {} } as any);
20
+ });
21
+
22
+ const rehydrateWith = (attributes: Record<string, any>) =>
23
+ new Auth().rehydrate({
24
+ jsonApi: { type: "auth", id: "auth-1", attributes: { token: "t", refreshToken: "r", ...attributes } },
25
+ included: [],
26
+ } as any);
27
+
28
+ describe("Auth", () => {
29
+ describe("rehydrate", () => {
30
+ it("deletionCancelled true when the attribute is true, false otherwise", () => {
31
+ expect(rehydrateWith({ deletionCancelled: true }).deletionCancelled).toBe(true);
32
+ expect(rehydrateWith({ deletionCancelled: false }).deletionCancelled).toBe(false);
33
+ expect(rehydrateWith({}).deletionCancelled).toBe(false);
34
+ });
35
+ });
36
+ });
@@ -35,4 +35,6 @@ export interface AuthInterface extends ApiDataInterface {
35
35
  get token(): string;
36
36
  get refreshToken(): string;
37
37
  get user(): UserInterface;
38
+ /** True on the session created by the login that cancelled a pending account deletion. */
39
+ get deletionCancelled(): boolean;
38
40
  }
@@ -9,6 +9,7 @@ import {
9
9
  rehydrate,
10
10
  } from "../../../core";
11
11
  import { JsonApiDelete, JsonApiGet, JsonApiPost } from "../../../unified";
12
+ import { markAccountDeletionCancelled } from "../../account-deletion/utils/account-deletion-notice";
12
13
  import { UserInterface } from "../../user";
13
14
  import { getTokenHandler } from "../config";
14
15
  import { PendingRegistrationInterface } from "./pending-registration.interface";
@@ -45,6 +46,9 @@ export class AuthService extends AbstractService {
45
46
  // Normal auth response
46
47
  const auth = apiResponse.data as AuthInterface;
47
48
 
49
+ // Login returns only the user to Login.tsx, so the flag is read here.
50
+ if (auth.deletionCancelled) markAccountDeletionCancelled();
51
+
48
52
  // Use injected token handler if configured
49
53
  const handler = getTokenHandler();
50
54
  if (handler) {
@@ -6,6 +6,12 @@ export class Auth extends AbstractApiData implements AuthInterface {
6
6
  private _token?: string;
7
7
  private _refreshToken?: string;
8
8
  private _user?: UserInterface;
9
+ private _deletionCancelled: boolean = false;
10
+
11
+ /** True on the session created by the login that cancelled a pending account deletion. */
12
+ get deletionCancelled(): boolean {
13
+ return this._deletionCancelled;
14
+ }
9
15
 
10
16
  get token(): string {
11
17
  if (!this._token) throw new Error("Token is not defined");
@@ -27,6 +33,7 @@ export class Auth extends AbstractApiData implements AuthInterface {
27
33
 
28
34
  this._token = data.jsonApi.attributes.token ?? undefined;
29
35
  this._refreshToken = data.jsonApi.attributes.refreshToken ?? undefined;
36
+ this._deletionCancelled = data.jsonApi.attributes.deletionCancelled === true;
30
37
 
31
38
  this._user = this._readIncluded(data, "user", Modules.User) as UserInterface;
32
39
 
@@ -8,6 +8,10 @@ import { usePageUrlGenerator } from "../../../hooks";
8
8
  import { BreadcrumbItemData } from "../../../interfaces";
9
9
  import { Action } from "../../../permissions";
10
10
  import { getRoleId } from "../../../roles";
11
+ import {
12
+ AccountDeletionAdminTrigger,
13
+ isAccountDeletionEnabled,
14
+ } from "../../account-deletion/components/AccountDeletionAdminTrigger";
11
15
  import { UserDeleter, UserEditor, UserReactivator, UserResentInvitationEmail } from "../components/forms";
12
16
  import { UserInterface } from "../data";
13
17
  import { useCurrentUserContext } from "./CurrentUserContext";
@@ -83,6 +87,10 @@ export const UserProvider = ({ children, dehydratedUser }: UserProviderProps) =>
83
87
  functions.push(<UserResentInvitationEmail key={`UserResentInvitationEmail`} user={user} />);
84
88
 
85
89
  functions.push(<UserDeleter key={`UserDeleter`} user={user} />);
90
+
91
+ // Opt-in: only apps that registered AccountDeletionModule, platform administrators only.
92
+ if (hasRole(getRoleId().Administrator) && isAccountDeletionEnabled())
93
+ functions.push(<AccountDeletionAdminTrigger key={`AccountDeletionAdminTrigger`} user={user} />);
86
94
  }
87
95
 
88
96
  functions.push(<UserEditor key={`UserEditor`} user={user} propagateChanges={setUser} />);