@carlonicora/nextjs-jsonapi 1.79.0 → 1.81.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 (84) hide show
  1. package/dist/{AssistantMessageInterface-DWnbd6J7.d.ts → AssistantMessageInterface-BpEhx2pC.d.ts} +18 -1
  2. package/dist/{AssistantMessageInterface-Mla6kgPe.d.mts → AssistantMessageInterface-DJ3Me16Y.d.mts} +18 -1
  3. package/dist/{BlockNoteEditor-6CBDTVKV.mjs → BlockNoteEditor-DCQA2PNW.mjs} +4 -4
  4. package/dist/{BlockNoteEditor-EH4HWI7H.js → BlockNoteEditor-ZISJ4KYX.js} +14 -14
  5. package/dist/{BlockNoteEditor-EH4HWI7H.js.map → BlockNoteEditor-ZISJ4KYX.js.map} +1 -1
  6. package/dist/billing/index.js +346 -346
  7. package/dist/billing/index.mjs +3 -3
  8. package/dist/{chunk-BKM5U3DE.mjs → chunk-6UMB5LTQ.mjs} +98 -7
  9. package/dist/chunk-6UMB5LTQ.mjs.map +1 -0
  10. package/dist/{chunk-ENRSFVOS.mjs → chunk-FZFJLDJY.mjs} +1290 -701
  11. package/dist/chunk-FZFJLDJY.mjs.map +1 -0
  12. package/dist/{chunk-5IEWLLLD.js → chunk-N4YZ45SK.js} +115 -24
  13. package/dist/chunk-N4YZ45SK.js.map +1 -0
  14. package/dist/{chunk-MEWXQEVE.mjs → chunk-PV5V6CVW.mjs} +2 -2
  15. package/dist/{chunk-ZDP3MBUI.js → chunk-TZJFHXDU.js} +1329 -740
  16. package/dist/chunk-TZJFHXDU.js.map +1 -0
  17. package/dist/{chunk-TWDSDTHU.js → chunk-ZEJSPTHS.js} +7 -7
  18. package/dist/{chunk-TWDSDTHU.js.map → chunk-ZEJSPTHS.js.map} +1 -1
  19. package/dist/client/index.js +4 -4
  20. package/dist/client/index.mjs +3 -3
  21. package/dist/components/index.d.mts +27 -7
  22. package/dist/components/index.d.ts +27 -7
  23. package/dist/components/index.js +8 -4
  24. package/dist/components/index.js.map +1 -1
  25. package/dist/components/index.mjs +7 -3
  26. package/dist/contexts/index.d.mts +1 -1
  27. package/dist/contexts/index.d.ts +1 -1
  28. package/dist/contexts/index.js +4 -4
  29. package/dist/contexts/index.mjs +3 -3
  30. package/dist/core/index.d.mts +35 -3
  31. package/dist/core/index.d.ts +35 -3
  32. package/dist/core/index.js +6 -2
  33. package/dist/core/index.js.map +1 -1
  34. package/dist/core/index.mjs +5 -1
  35. package/dist/index.d.mts +2 -2
  36. package/dist/index.d.ts +2 -2
  37. package/dist/index.js +7 -3
  38. package/dist/index.js.map +1 -1
  39. package/dist/index.mjs +6 -2
  40. package/dist/server/index.js +3 -3
  41. package/dist/server/index.mjs +1 -1
  42. package/package.json +1 -1
  43. package/src/components/index.ts +1 -0
  44. package/src/core/index.ts +2 -0
  45. package/src/core/registry/ModuleRegistry.ts +1 -0
  46. package/src/features/assistant/components/parts/AssistantThread.tsx +1 -1
  47. package/src/features/assistant-message/AssistantMessageModule.ts +4 -0
  48. package/src/features/assistant-message/components/MessageItem.tsx +7 -7
  49. package/src/features/assistant-message/components/MessageList.tsx +1 -1
  50. package/src/features/assistant-message/components/__tests__/MessageItem.spec.tsx +11 -7
  51. package/src/features/assistant-message/components/index.ts +1 -0
  52. package/src/features/assistant-message/components/parts/MessageSourcesContainer.tsx +135 -0
  53. package/src/features/assistant-message/components/parts/MessageSourcesPanel.tsx +151 -0
  54. package/src/features/assistant-message/components/parts/RelevanceMeter.tsx +29 -0
  55. package/src/features/assistant-message/components/parts/__tests__/MessageSourcesPanel.spec.tsx +70 -0
  56. package/src/features/assistant-message/components/parts/tabs/CitationsTab.tsx +105 -0
  57. package/src/features/assistant-message/components/parts/tabs/ContentsTab.tsx +88 -0
  58. package/src/features/assistant-message/components/parts/tabs/ReferencesTab.tsx +51 -0
  59. package/src/features/assistant-message/components/parts/tabs/SuggestedQuestionsTab.tsx +24 -0
  60. package/src/features/assistant-message/components/parts/tabs/UsersTab.tsx +142 -0
  61. package/src/features/assistant-message/data/AssistantMessage.ts +20 -0
  62. package/src/features/assistant-message/data/AssistantMessageInterface.ts +2 -0
  63. package/src/features/assistant-message/data/AssistantMessageService.ts +13 -4
  64. package/src/features/assistant-message/data/__tests__/AssistantMessage.citations.spec.ts +65 -0
  65. package/src/features/assistant-message/data/__tests__/AssistantMessage.spec.ts +8 -0
  66. package/src/features/chunk/ChunkModule.ts +18 -0
  67. package/src/features/chunk/data/Chunk.ts +49 -0
  68. package/src/features/chunk/data/ChunkInput.ts +3 -0
  69. package/src/features/chunk/data/ChunkInterface.ts +18 -0
  70. package/src/features/chunk/data/__tests__/Chunk.spec.ts +83 -0
  71. package/src/features/chunk/data/index.ts +3 -0
  72. package/src/features/chunk/index.ts +2 -0
  73. package/src/features/rbac/components/RbacByRoleContainer.tsx +270 -0
  74. package/src/features/rbac/index.ts +1 -0
  75. package/dist/chunk-5IEWLLLD.js.map +0 -1
  76. package/dist/chunk-BKM5U3DE.mjs.map +0 -1
  77. package/dist/chunk-ENRSFVOS.mjs.map +0 -1
  78. package/dist/chunk-ZDP3MBUI.js.map +0 -1
  79. package/src/features/assistant-message/components/parts/ReferenceBadges.tsx +0 -46
  80. package/src/features/assistant-message/components/parts/SuggestedFollowUps.tsx +0 -52
  81. package/src/features/assistant-message/components/parts/__tests__/ReferenceBadges.spec.tsx +0 -59
  82. package/src/features/assistant-message/components/parts/__tests__/SuggestedFollowUps.spec.tsx +0 -29
  83. /package/dist/{BlockNoteEditor-6CBDTVKV.mjs.map → BlockNoteEditor-DCQA2PNW.mjs.map} +0 -0
  84. /package/dist/{chunk-MEWXQEVE.mjs.map → chunk-PV5V6CVW.mjs.map} +0 -0
@@ -1,46 +0,0 @@
1
- "use client";
2
-
3
- import Link from "next/link";
4
- import { useTranslations } from "next-intl";
5
- import type { ApiDataInterface } from "../../../../core";
6
- import { usePageUrlGenerator } from "../../../../hooks";
7
- import { ModuleRegistry } from "../../../../core/registry/ModuleRegistry";
8
-
9
- interface Props {
10
- references: ApiDataInterface[];
11
- }
12
-
13
- export function ReferenceBadges({ references }: Props) {
14
- const t = useTranslations();
15
- const generate = usePageUrlGenerator();
16
-
17
- if (references.length === 0) return null;
18
-
19
- return (
20
- <div className="mt-2 flex flex-wrap items-center gap-2">
21
- <span className="text-muted-foreground text-xs">{t("features.assistant.references_label")}</span>
22
- {references.map((ref) => {
23
- // ref.type is the JSON:API type string (same as module.name)
24
- let module;
25
- try {
26
- module = ModuleRegistry.findByName(ref.type);
27
- } catch {
28
- return null;
29
- }
30
- const href = generate({ page: module, id: ref.id });
31
- return (
32
- <Link
33
- key={`${ref.type}/${ref.id}`}
34
- href={href}
35
- target="_blank"
36
- rel="noopener noreferrer"
37
- className="bg-background border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs"
38
- >
39
- <span className="text-muted-foreground text-[10px]">{module.name}</span>
40
- <span className="font-medium">{ref.identifier}</span>
41
- </Link>
42
- );
43
- })}
44
- </div>
45
- );
46
- }
@@ -1,52 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
- import { useTranslations } from "next-intl";
5
- import { ChevronRight, ChevronDown } from "lucide-react";
6
-
7
- interface Props {
8
- questions: string[];
9
- onSelect: (q: string) => void;
10
- }
11
-
12
- export function SuggestedFollowUps({ questions, onSelect }: Props) {
13
- const t = useTranslations();
14
- const [open, setOpen] = useState(false);
15
- if (questions.length === 0) return null;
16
-
17
- return (
18
- <div className="mt-2">
19
- <button
20
- type="button"
21
- onClick={() => setOpen((v) => !v)}
22
- className="text-primary inline-flex items-center gap-1 text-xs font-medium"
23
- >
24
- {open ? (
25
- <>
26
- <ChevronDown className="h-3 w-3" />
27
- {t("features.assistant.hide_suggestions")}
28
- </>
29
- ) : (
30
- <>
31
- <ChevronRight className="h-3 w-3" />
32
- {t("features.assistant.show_suggestions", { count: questions.length })}
33
- </>
34
- )}
35
- </button>
36
- {open && (
37
- <div className="mt-2 flex flex-col gap-1">
38
- {questions.map((q) => (
39
- <button
40
- key={q}
41
- type="button"
42
- onClick={() => onSelect(q)}
43
- className="border-border bg-muted/30 hover:bg-muted rounded-md border px-3 py-1.5 text-left text-sm"
44
- >
45
- {q}
46
- </button>
47
- ))}
48
- </div>
49
- )}
50
- </div>
51
- );
52
- }
@@ -1,59 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from "vitest";
2
- import { render, screen } from "@testing-library/react";
3
- import type { ApiDataInterface } from "../../../../../core";
4
- import { AbstractApiData } from "../../../../../core/abstracts/AbstractApiData";
5
- import { DataClassRegistry } from "../../../../../core/registry/DataClassRegistry";
6
- import { ModuleRegistry } from "../../../../../core/registry/ModuleRegistry";
7
- import type { ApiRequestDataTypeInterface } from "../../../../../core/interfaces/ApiRequestDataTypeInterface";
8
- import { ReferenceBadges } from "../ReferenceBadges";
9
-
10
- class TestAccount extends AbstractApiData {
11
- static identifierFields: string[] = ["name"];
12
- rehydrate(data: any): this {
13
- super.rehydrate(data);
14
- return this;
15
- }
16
- createJsonApi(): any {
17
- return {};
18
- }
19
- }
20
-
21
- const testAccountModule = {
22
- name: "test-accounts",
23
- pageUrl: "/accounts",
24
- model: TestAccount,
25
- } as unknown as ApiRequestDataTypeInterface;
26
-
27
- beforeAll(() => {
28
- DataClassRegistry.clear();
29
- DataClassRegistry.registerObjectClass(testAccountModule, TestAccount);
30
- ModuleRegistry.register("TestAccount" as any, testAccountModule as any);
31
- });
32
-
33
- afterAll(() => {
34
- DataClassRegistry.clear();
35
- });
36
-
37
- function makeRehydratedAccount({ id, name }: { id: string; name: string }): ApiDataInterface {
38
- const acct = new TestAccount();
39
- acct.rehydrate({
40
- jsonApi: { type: "test-accounts", id, attributes: { name } },
41
- included: [],
42
- });
43
- return acct as unknown as ApiDataInterface;
44
- }
45
-
46
- describe("ReferenceBadges", () => {
47
- it("renders a chip per reference with type label + identifier", () => {
48
- const references = [makeRehydratedAccount({ id: "acc-1", name: "Acme" })];
49
- render(<ReferenceBadges references={references} />);
50
- const link = screen.getByRole("link", { name: /acme/i });
51
- expect(link).toBeInTheDocument();
52
- expect(link.getAttribute("href")).toContain("/accounts/acc-1");
53
- });
54
-
55
- it("renders nothing for empty references", () => {
56
- const { container } = render(<ReferenceBadges references={[]} />);
57
- expect(container.firstChild).toBeNull();
58
- });
59
- });
@@ -1,29 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { render, screen } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { SuggestedFollowUps } from "../SuggestedFollowUps";
5
-
6
- describe("SuggestedFollowUps", () => {
7
- it("is collapsed by default; toggling reveals the buttons", async () => {
8
- render(<SuggestedFollowUps questions={["q1", "q2", "q3"]} onSelect={vi.fn()} />);
9
- expect(screen.queryByRole("button", { name: "q1" })).not.toBeInTheDocument();
10
- const toggle = screen.getByRole("button", { name: /show_suggestions/ });
11
- await userEvent.click(toggle);
12
- expect(screen.getByRole("button", { name: "q1" })).toBeInTheDocument();
13
- expect(screen.getByRole("button", { name: "q2" })).toBeInTheDocument();
14
- expect(screen.getByRole("button", { name: "q3" })).toBeInTheDocument();
15
- });
16
-
17
- it("clicking a question calls onSelect immediately", async () => {
18
- const onSelect = vi.fn();
19
- render(<SuggestedFollowUps questions={["q1"]} onSelect={onSelect} />);
20
- await userEvent.click(screen.getByRole("button", { name: /show_suggestions/ }));
21
- await userEvent.click(screen.getByRole("button", { name: "q1" }));
22
- expect(onSelect).toHaveBeenCalledWith("q1");
23
- });
24
-
25
- it("renders nothing for empty list", () => {
26
- const { container } = render(<SuggestedFollowUps questions={[]} onSelect={vi.fn()} />);
27
- expect(container.firstChild).toBeNull();
28
- });
29
- });