@carlonicora/nextjs-jsonapi 1.131.1 → 1.132.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 (79) hide show
  1. package/dist/{BlockNoteEditor-BR3IRGJW.js → BlockNoteEditor-JAELO23S.js} +19 -19
  2. package/dist/{BlockNoteEditor-BR3IRGJW.js.map → BlockNoteEditor-JAELO23S.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-PVBZYPMF.mjs → BlockNoteEditor-WZFEJS2B.mjs} +4 -4
  4. package/dist/billing/index.js +357 -357
  5. package/dist/billing/index.mjs +3 -3
  6. package/dist/{chunk-LBMNRFCY.js → chunk-5IE6DZ2D.js} +153 -77
  7. package/dist/chunk-5IE6DZ2D.js.map +1 -0
  8. package/dist/{chunk-MDXT47V4.mjs → chunk-67LIVKYU.mjs} +198 -203
  9. package/dist/chunk-67LIVKYU.mjs.map +1 -0
  10. package/dist/{chunk-5MNE72ZE.mjs → chunk-DZL2G7NB.mjs} +77 -1
  11. package/dist/chunk-DZL2G7NB.mjs.map +1 -0
  12. package/dist/{chunk-XTLTQQ7X.js → chunk-F6KBHC2X.js} +7 -7
  13. package/dist/{chunk-XTLTQQ7X.js.map → chunk-F6KBHC2X.js.map} +1 -1
  14. package/dist/{chunk-5SQFK35K.js → chunk-MP5VURBB.js} +1028 -1033
  15. package/dist/chunk-MP5VURBB.js.map +1 -0
  16. package/dist/{chunk-NATPK5ME.mjs → chunk-VSAAVVHY.mjs} +2 -2
  17. package/dist/client/index.js +4 -4
  18. package/dist/client/index.mjs +3 -3
  19. package/dist/components/index.d.mts +3 -2
  20. package/dist/components/index.d.ts +3 -2
  21. package/dist/components/index.js +4 -4
  22. package/dist/components/index.mjs +3 -3
  23. package/dist/contexts/index.d.mts +9 -2
  24. package/dist/contexts/index.d.ts +9 -2
  25. package/dist/contexts/index.js +6 -4
  26. package/dist/contexts/index.js.map +1 -1
  27. package/dist/contexts/index.mjs +5 -3
  28. package/dist/core/index.d.mts +11 -1
  29. package/dist/core/index.d.ts +11 -1
  30. package/dist/core/index.js +12 -2
  31. package/dist/core/index.js.map +1 -1
  32. package/dist/core/index.mjs +13 -3
  33. package/dist/features/help/index.js +39 -39
  34. package/dist/features/help/index.js.map +1 -1
  35. package/dist/features/help/index.mjs +5 -5
  36. package/dist/features/help/index.mjs.map +1 -1
  37. package/dist/index.d.mts +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.js +13 -3
  40. package/dist/index.js.map +1 -1
  41. package/dist/index.mjs +14 -4
  42. package/dist/server/index.js +3 -3
  43. package/dist/server/index.mjs +1 -1
  44. package/package.json +1 -1
  45. package/src/components/containers/ReactMarkdownContainer.tsx +1 -1
  46. package/src/components/containers/RoundPageContainer.tsx +7 -0
  47. package/src/components/forms/EditorSheet.tsx +24 -1
  48. package/src/components/forms/FormDateTime.tsx +5 -0
  49. package/src/components/navigations/Breadcrumb.tsx +13 -11
  50. package/src/components/navigations/Header.tsx +3 -1
  51. package/src/contexts/HeaderChildrenContext.tsx +17 -2
  52. package/src/features/assistant-message/components/MessageItem.tsx +1 -1
  53. package/src/features/auth/components/GdprConsentSection.tsx +2 -2
  54. package/src/features/auth/components/forms/Register.tsx +2 -2
  55. package/src/features/help/components/HelpArticleBody.tsx +2 -2
  56. package/src/features/notification/components/common/NotificationErrorBoundary.tsx +1 -4
  57. package/src/features/notification/contexts/__tests__/NotificationContext.spec.tsx +34 -8
  58. package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +2 -2
  59. package/src/features/user/contexts/CurrentUserContext.tsx +43 -9
  60. package/src/features/user/contexts/__tests__/CurrentUserContext.spec.tsx +149 -6
  61. package/src/features/waitlist/components/forms/WaitlistForm.tsx +2 -2
  62. package/src/features/waitlist/components/lists/WaitlistList.tsx +13 -2
  63. package/src/shadcnui/custom/link.tsx +1 -1
  64. package/src/shadcnui/ui/accordion.tsx +1 -1
  65. package/src/shadcnui/ui/alert-dialog.tsx +1 -1
  66. package/src/shadcnui/ui/alert.tsx +2 -5
  67. package/src/shadcnui/ui/badge.tsx +1 -1
  68. package/src/shadcnui/ui/button.tsx +1 -1
  69. package/src/shadcnui/ui/dialog.tsx +1 -4
  70. package/src/shadcnui/ui/field.tsx +1 -1
  71. package/src/utils/__tests__/italian-validators.test.ts +63 -0
  72. package/src/utils/index.ts +8 -0
  73. package/src/utils/italian-validators.ts +18 -5
  74. package/dist/chunk-5MNE72ZE.mjs.map +0 -1
  75. package/dist/chunk-5SQFK35K.js.map +0 -1
  76. package/dist/chunk-LBMNRFCY.js.map +0 -1
  77. package/dist/chunk-MDXT47V4.mjs.map +0 -1
  78. /package/dist/{BlockNoteEditor-PVBZYPMF.mjs.map → BlockNoteEditor-WZFEJS2B.mjs.map} +0 -0
  79. /package/dist/{chunk-NATPK5ME.mjs.map → chunk-VSAAVVHY.mjs.map} +0 -0
@@ -27,10 +27,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
27
27
  return (
28
28
  <div
29
29
  data-slot="alert-title"
30
- className={cn(
31
- "text-sm font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
32
- className,
33
- )}
30
+ className={cn("text-sm font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground", className)}
34
31
  {...props}
35
32
  />
36
33
  );
@@ -41,7 +38,7 @@ function AlertDescription({ className, ...props }: React.ComponentProps<"div">)
41
38
  <div
42
39
  data-slot="alert-description"
43
40
  className={cn(
44
- "text-muted-foreground text-xs/relaxed text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
41
+ "text-muted-foreground text-xs/relaxed text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground",
45
42
  className,
46
43
  )}
47
44
  {...props}
@@ -16,7 +16,7 @@ const badgeVariants = cva(
16
16
  outline:
17
17
  "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/20 dark:bg-input/30",
18
18
  ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
19
- link: "text-primary underline-offset-4 hover:underline",
19
+ link: "text-primary",
20
20
  warning: "bg-warning text-warning-foreground [a]:hover:bg-warning/80",
21
21
  softGreen: "bg-green-500/10 text-green-700 dark:bg-green-500/15 dark:text-green-400",
22
22
  softRed: "bg-red-500/10 text-red-700 dark:bg-red-500/15 dark:text-red-400",
@@ -17,7 +17,7 @@ const buttonVariants = cva(
17
17
  "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
18
18
  destructive:
19
19
  "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
20
- link: "text-primary underline-offset-4 hover:underline",
20
+ link: "text-primary",
21
21
  },
22
22
  size: {
23
23
  default:
@@ -102,10 +102,7 @@ function DialogDescription({ className, ...props }: DialogPrimitive.Description.
102
102
  return (
103
103
  <DialogPrimitive.Description
104
104
  data-slot="dialog-description"
105
- className={cn(
106
- "text-muted-foreground *:[a]:hover:text-foreground text-xs/relaxed *:[a]:underline *:[a]:underline-offset-3",
107
- className,
108
- )}
105
+ className={cn("text-muted-foreground *:[a]:hover:text-foreground text-xs/relaxed", className)}
109
106
  {...props}
110
107
  />
111
108
  );
@@ -123,7 +123,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
123
123
  className={cn(
124
124
  "text-muted-foreground text-left text-xs/relaxed [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
125
125
  "last:mt-0 nth-last-2:-mt-1",
126
- "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
126
+ "[&>a:hover]:text-primary",
127
127
  className,
128
128
  )}
129
129
  {...props}
@@ -0,0 +1,63 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { validateCodiceFiscale, validateItalianTaxCode, validatePartitaIva } from "../italian-validators";
4
+
5
+ const VALID_CODICE_FISCALE = "RSSMRA85M01H501Q";
6
+ const VALID_PARTITA_IVA = "00743110157";
7
+
8
+ describe("validatePartitaIva", () => {
9
+ it("accepts a valid partita iva", () => {
10
+ expect(validatePartitaIva(VALID_PARTITA_IVA)).toBe(true);
11
+ });
12
+
13
+ it("rejects a partita iva with a wrong check digit", () => {
14
+ expect(validatePartitaIva("00743110158")).toBe(false);
15
+ });
16
+
17
+ it("rejects a codice fiscale", () => {
18
+ expect(validatePartitaIva(VALID_CODICE_FISCALE)).toBe(false);
19
+ });
20
+ });
21
+
22
+ describe("validateCodiceFiscale", () => {
23
+ it("accepts a valid codice fiscale", () => {
24
+ expect(validateCodiceFiscale(VALID_CODICE_FISCALE)).toBe(true);
25
+ });
26
+
27
+ it("rejects a partita iva by default", () => {
28
+ expect(validateCodiceFiscale(VALID_PARTITA_IVA)).toBe(false);
29
+ });
30
+
31
+ it("accepts a partita iva when allowPartitaIva is set", () => {
32
+ expect(validateCodiceFiscale(VALID_PARTITA_IVA, { allowPartitaIva: true })).toBe(true);
33
+ });
34
+
35
+ it("still accepts a codice fiscale when allowPartitaIva is set", () => {
36
+ expect(validateCodiceFiscale(VALID_CODICE_FISCALE, { allowPartitaIva: true })).toBe(true);
37
+ });
38
+
39
+ it("rejects a value that is neither, even when allowPartitaIva is set", () => {
40
+ expect(validateCodiceFiscale("NOT-A-CODE", { allowPartitaIva: true })).toBe(false);
41
+ expect(validateCodiceFiscale("00743110158", { allowPartitaIva: true })).toBe(false);
42
+ });
43
+
44
+ it("ignores whitespace", () => {
45
+ expect(validateCodiceFiscale("0074 3110 157", { allowPartitaIva: true })).toBe(true);
46
+ });
47
+
48
+ it("rejects empty values", () => {
49
+ expect(validateCodiceFiscale("", { allowPartitaIva: true })).toBe(false);
50
+ });
51
+ });
52
+
53
+ describe("validateItalianTaxCode", () => {
54
+ it("forwards the options to the codice fiscale validator", () => {
55
+ expect(validateItalianTaxCode(VALID_PARTITA_IVA, "codiceFiscale")).toBe(false);
56
+ expect(validateItalianTaxCode(VALID_PARTITA_IVA, "codiceFiscale", { allowPartitaIva: true })).toBe(true);
57
+ });
58
+
59
+ it("leaves partita iva validation unchanged", () => {
60
+ expect(validateItalianTaxCode(VALID_PARTITA_IVA, "partitaIva")).toBe(true);
61
+ expect(validateItalianTaxCode(VALID_CODICE_FISCALE, "partitaIva")).toBe(false);
62
+ });
63
+ });
@@ -12,6 +12,14 @@ export { getTableComponents, getTableOptions, TableOptions } from "./table-optio
12
12
  export { entityObjectSchema, userObjectSchema, type EntityObject, type UserObject } from "./schemas";
13
13
 
14
14
  export { getInitials } from "./getInitials";
15
+ export {
16
+ validatePartitaIva,
17
+ validateCodiceFiscale,
18
+ validateItalianTaxCode,
19
+ formatPartitaIva,
20
+ formatCodiceFiscale,
21
+ type CodiceFiscaleValidationOptions,
22
+ } from "./italian-validators";
15
23
  export * from "./blocknote-diff.util";
16
24
  export * from "./blocknote-word-diff-renderer.util";
17
25
  export * from "./icons";
@@ -29,7 +29,12 @@ export function validatePartitaIva(partitaIva: string): boolean {
29
29
  return totalSum % 10 === 0;
30
30
  }
31
31
 
32
- export function validateCodiceFiscale(codiceFiscale: string): boolean {
32
+ export type CodiceFiscaleValidationOptions = {
33
+ /** When true, a valid Partita IVA is also accepted as a valid value. */
34
+ allowPartitaIva?: boolean;
35
+ };
36
+
37
+ export function validateCodiceFiscale(codiceFiscale: string, options?: CodiceFiscaleValidationOptions): boolean {
33
38
  if (!codiceFiscale || typeof codiceFiscale !== "string") {
34
39
  return false;
35
40
  }
@@ -37,13 +42,21 @@ export function validateCodiceFiscale(codiceFiscale: string): boolean {
37
42
  const cleaned = codiceFiscale.replace(/\s/g, "").toUpperCase();
38
43
 
39
44
  try {
40
- return CodiceFiscale.check(cleaned);
45
+ if (CodiceFiscale.check(cleaned)) {
46
+ return true;
47
+ }
41
48
  } catch (error) {
42
- return false;
49
+ // fall through to the optional Partita IVA check
43
50
  }
51
+
52
+ return options?.allowPartitaIva === true && validatePartitaIva(cleaned);
44
53
  }
45
54
 
46
- export function validateItalianTaxCode(value: string, type: "partitaIva" | "codiceFiscale"): boolean {
55
+ export function validateItalianTaxCode(
56
+ value: string,
57
+ type: "partitaIva" | "codiceFiscale",
58
+ options?: CodiceFiscaleValidationOptions,
59
+ ): boolean {
47
60
  if (!value || typeof value !== "string") {
48
61
  return false;
49
62
  }
@@ -52,7 +65,7 @@ export function validateItalianTaxCode(value: string, type: "partitaIva" | "codi
52
65
  case "partitaIva":
53
66
  return validatePartitaIva(value);
54
67
  case "codiceFiscale":
55
- return validateCodiceFiscale(value);
68
+ return validateCodiceFiscale(value, options);
56
69
  default:
57
70
  return false;
58
71
  }