@carlonicora/nextjs-jsonapi 3.22.0 → 3.24.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/{AssistantMessageInterface-CuaMDs2i.d.ts → AssistantMessageInterface-1Kbz8RVs.d.ts} +34 -1
  2. package/dist/{AssistantMessageInterface-Du3ShThp.d.mts → AssistantMessageInterface-CoxJyuFM.d.mts} +34 -1
  3. package/dist/{BlockNoteEditor-VEEMWB2J.js → BlockNoteEditor-PTD2V4CH.js} +19 -19
  4. package/dist/{BlockNoteEditor-VEEMWB2J.js.map → BlockNoteEditor-PTD2V4CH.js.map} +1 -1
  5. package/dist/{BlockNoteEditor-5QBGVWE7.mjs → BlockNoteEditor-Q2WEDMKJ.mjs} +4 -4
  6. package/dist/{BlockNoteViewer-ZY4ZF3HO.mjs → BlockNoteViewer-WO6GTDSI.mjs} +2 -2
  7. package/dist/{BlockNoteViewer-XCGBX4ST.js → BlockNoteViewer-WOXEJ6RM.js} +3 -3
  8. package/dist/{BlockNoteViewer-XCGBX4ST.js.map → BlockNoteViewer-WOXEJ6RM.js.map} +1 -1
  9. package/dist/{HandbookSectionInterface-DqU_d0sy.d.mts → HandbookSectionInterface-BYsmnPEz.d.mts} +36 -0
  10. package/dist/{HandbookSectionInterface-DFj2zErb.d.ts → HandbookSectionInterface-OePKPbqN.d.ts} +36 -0
  11. package/dist/billing/index.js +401 -401
  12. package/dist/billing/index.mjs +3 -3
  13. package/dist/{chunk-CK47KSFV.mjs → chunk-2O3SFHQ7.mjs} +91 -39
  14. package/dist/chunk-2O3SFHQ7.mjs.map +1 -0
  15. package/dist/{chunk-SYQMVTIC.js → chunk-3D2MCVRZ.js} +7 -7
  16. package/dist/{chunk-SYQMVTIC.js.map → chunk-3D2MCVRZ.js.map} +1 -1
  17. package/dist/{chunk-XYSWOW5G.js → chunk-3YJF7QY4.js} +1358 -1116
  18. package/dist/chunk-3YJF7QY4.js.map +1 -0
  19. package/dist/{chunk-5G7I3OUB.mjs → chunk-GJHKOG5L.mjs} +1419 -1177
  20. package/dist/chunk-GJHKOG5L.mjs.map +1 -0
  21. package/dist/{chunk-U55JQ4NY.mjs → chunk-HAI7G6MD.mjs} +2 -2
  22. package/dist/{chunk-MWZCCOTS.js → chunk-IV4DTYXN.js} +91 -39
  23. package/dist/chunk-IV4DTYXN.js.map +1 -0
  24. package/dist/client/index.d.mts +13 -2
  25. package/dist/client/index.d.ts +13 -2
  26. package/dist/client/index.js +4 -4
  27. package/dist/client/index.mjs +3 -3
  28. package/dist/components/index.d.mts +90 -31
  29. package/dist/components/index.d.ts +90 -31
  30. package/dist/components/index.js +8 -4
  31. package/dist/components/index.js.map +1 -1
  32. package/dist/components/index.mjs +7 -3
  33. package/dist/contexts/index.d.mts +11 -2
  34. package/dist/contexts/index.d.ts +11 -2
  35. package/dist/contexts/index.js +4 -4
  36. package/dist/contexts/index.mjs +3 -3
  37. package/dist/core/index.d.mts +29 -7
  38. package/dist/core/index.d.ts +29 -7
  39. package/dist/core/index.js +2 -2
  40. package/dist/core/index.mjs +1 -1
  41. package/dist/features/help/index.js +37 -37
  42. package/dist/features/help/index.mjs +3 -3
  43. package/dist/features/tokenusage/index.js +101 -101
  44. package/dist/features/tokenusage/index.mjs +3 -3
  45. package/dist/index.d.mts +3 -4
  46. package/dist/index.d.ts +3 -4
  47. package/dist/index.js +3 -3
  48. package/dist/index.mjs +2 -2
  49. package/dist/{oauth.interface-CD90ycYz.d.ts → oauth.interface-BZKZAPRw.d.ts} +8 -1
  50. package/dist/{oauth.interface-DRE3NAKc.d.mts → oauth.interface-nVwnzxJw.d.mts} +8 -1
  51. package/dist/server/index.js +3 -3
  52. package/dist/server/index.mjs +1 -1
  53. package/package.json +1 -1
  54. package/src/components/forms/__tests__/EditorSheet.test.tsx +5 -3
  55. package/src/core/utils/__tests__/translateResponse.test.ts +3 -1
  56. package/src/features/ai-connection/components/forms/AiConnectionEditor.tsx +1 -0
  57. package/src/features/ai-connection/components/lists/AiConnectionTypeCard.tsx +9 -0
  58. package/src/features/ai-connection/data/__tests__/ai-connection.test.ts +51 -0
  59. package/src/features/ai-connection/data/ai-connection.interface.ts +18 -0
  60. package/src/features/ai-connection/data/ai-connection.ts +63 -0
  61. package/src/features/ai-connection/i18n-keys.ts +9 -0
  62. package/src/features/assistant/components/containers/AssistantContainer.tsx +105 -36
  63. package/src/features/assistant/components/containers/__tests__/AssistantContainer.spec.tsx +163 -1
  64. package/src/features/assistant/components/parts/AssistantComposer.tsx +38 -15
  65. package/src/features/assistant/components/parts/AssistantEmptyState.tsx +5 -3
  66. package/src/features/assistant/components/parts/AssistantSidebar.tsx +26 -7
  67. package/src/features/assistant/components/parts/__tests__/AssistantComposer.spec.tsx +8 -0
  68. package/src/features/assistant/components/parts/__tests__/AssistantSidebar.spec.tsx +7 -0
  69. package/src/features/assistant/contexts/AssistantContext.tsx +91 -7
  70. package/src/features/assistant/contexts/__tests__/AssistantContext.spec.tsx +196 -0
  71. package/src/features/assistant-action/components/AssistantContainerWithApprovals.tsx +23 -1
  72. package/src/features/assistant-message/components/EntityMentionLink.tsx +28 -0
  73. package/src/features/assistant-message/components/__tests__/EntityMentionLink.spec.tsx +58 -0
  74. package/src/features/assistant-message/components/index.ts +1 -0
  75. package/src/features/assistant-message/components/parts/tabs/ContentsTab.tsx +1 -1
  76. package/src/features/assistant-message/components/parts/tabs/ReferencesTab.tsx +2 -2
  77. package/src/features/auth/components/forms/__tests__/Logout.spec.tsx +3 -2
  78. package/src/features/oauth/components/OAuthClientForm.tsx +21 -4
  79. package/src/features/oauth/components/__tests__/OAuthClientForm.spec.tsx +63 -0
  80. package/src/features/oauth/components/consent/OAuthCompanySelector.tsx +54 -0
  81. package/src/features/oauth/components/consent/OAuthConsentActions.tsx +5 -2
  82. package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +10 -6
  83. package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +33 -13
  84. package/src/features/oauth/components/consent/OAuthScopeList.tsx +4 -1
  85. package/src/features/oauth/components/consent/__tests__/OAuthConsentHeader.spec.tsx +25 -0
  86. package/src/features/oauth/components/consent/__tests__/OAuthConsentScreen.spec.tsx +126 -0
  87. package/src/features/oauth/components/consent/index.ts +1 -0
  88. package/src/features/oauth/data/__tests__/oauth.service.spec.ts +103 -0
  89. package/src/features/oauth/data/oauth.service.ts +3 -13
  90. package/src/features/oauth/data/oauth.ts +30 -1
  91. package/src/features/oauth/hooks/useOAuthConsent.ts +34 -3
  92. package/src/features/oauth/interfaces/oauth.interface.ts +11 -25
  93. package/src/hooks/__tests__/useDataListRetriever.test.ts +1 -1
  94. package/dist/AssistantInterface-RvZzlcA_.d.ts +0 -36
  95. package/dist/AssistantInterface-jL56dyNc.d.mts +0 -36
  96. package/dist/chunk-5G7I3OUB.mjs.map +0 -1
  97. package/dist/chunk-CK47KSFV.mjs.map +0 -1
  98. package/dist/chunk-MWZCCOTS.js.map +0 -1
  99. package/dist/chunk-XYSWOW5G.js.map +0 -1
  100. /package/dist/{BlockNoteEditor-5QBGVWE7.mjs.map → BlockNoteEditor-Q2WEDMKJ.mjs.map} +0 -0
  101. /package/dist/{BlockNoteViewer-ZY4ZF3HO.mjs.map → BlockNoteViewer-WO6GTDSI.mjs.map} +0 -0
  102. /package/dist/{chunk-U55JQ4NY.mjs.map → chunk-HAI7G6MD.mjs.map} +0 -0
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useEffect, useState } from "react";
4
4
  import { OAuthConsentInfo, OAuthConsentRequest } from "../interfaces/oauth.interface";
5
5
  import { OAuthService } from "../data/oauth.service";
6
+ import { useCurrentUserContextOptional } from "../../user/contexts/CurrentUserContext";
6
7
 
7
8
  export interface UseOAuthConsentReturn {
8
9
  /** Client and scope info for consent display */
@@ -17,6 +18,10 @@ export interface UseOAuthConsentReturn {
17
18
  deny: () => Promise<void>;
18
19
  /** Whether approve/deny is in progress */
19
20
  isSubmitting: boolean;
21
+ /** The studio (company) the authorization is granted for */
22
+ companyId: string | undefined;
23
+ /** Select the studio (company) the authorization is granted for */
24
+ setCompanyId: (id: string) => void;
20
25
  }
21
26
 
22
27
  /**
@@ -37,11 +42,35 @@ export interface UseOAuthConsentReturn {
37
42
  * // On button click: approve() or deny()
38
43
  * ```
39
44
  */
40
- export function useOAuthConsent(params: OAuthConsentRequest): UseOAuthConsentReturn {
45
+ export function useOAuthConsent(
46
+ params: OAuthConsentRequest,
47
+ options?: {
48
+ /**
49
+ * The studio open in the host app's session. Apps that keep the signed-in
50
+ * user in their own context (not the package UserProvider) pass it here;
51
+ * it wins over the package context.
52
+ */
53
+ defaultCompanyId?: string;
54
+ },
55
+ ): UseOAuthConsentReturn {
41
56
  const [clientInfo, setClientInfo] = useState<OAuthConsentInfo | null>(null);
42
57
  const [isLoading, setIsLoading] = useState(true);
43
58
  const [error, setError] = useState<Error | null>(null);
44
59
  const [isSubmitting, setIsSubmitting] = useState(false);
60
+ const [companyId, setCompanyId] = useState<string | undefined>(undefined);
61
+ const contextCompanyId = useCurrentUserContextOptional()?.company?.id;
62
+ const currentCompanyId = options?.defaultCompanyId ?? contextCompanyId;
63
+
64
+ // Seed the studio choice once the user's companies arrive: the studio open in
65
+ // the web session when it is in the list, otherwise the first one.
66
+ useEffect(() => {
67
+ const companies = clientInfo?.companies ?? [];
68
+ if (companies.length === 0) return;
69
+ if (companyId && companies.some((company) => company.id === companyId)) return;
70
+
71
+ const current = currentCompanyId ? companies.find((company) => company.id === currentCompanyId) : undefined;
72
+ setCompanyId(current?.id ?? companies[0]?.id);
73
+ }, [clientInfo, currentCompanyId, companyId]);
45
74
 
46
75
  // Fetch client info on mount
47
76
  useEffect(() => {
@@ -83,7 +112,7 @@ export function useOAuthConsent(params: OAuthConsentRequest): UseOAuthConsentRet
83
112
  setError(null);
84
113
 
85
114
  try {
86
- const result = await OAuthService.approveAuthorization(params);
115
+ const result = await OAuthService.approveAuthorization({ ...params, companyId });
87
116
 
88
117
  // Redirect to client with authorization code
89
118
  if (result.redirectUrl) {
@@ -95,7 +124,7 @@ export function useOAuthConsent(params: OAuthConsentRequest): UseOAuthConsentRet
95
124
  setIsSubmitting(false);
96
125
  }
97
126
  // Note: Don't set isSubmitting to false on success - we're redirecting
98
- }, [params]);
127
+ }, [params, companyId]);
99
128
 
100
129
  const deny = useCallback(async (): Promise<void> => {
101
130
  setIsSubmitting(true);
@@ -123,5 +152,7 @@ export function useOAuthConsent(params: OAuthConsentRequest): UseOAuthConsentRet
123
152
  approve,
124
153
  deny,
125
154
  isSubmitting,
155
+ companyId,
156
+ setCompanyId,
126
157
  };
127
158
  }
@@ -89,13 +89,15 @@ export interface OAuthConsentRequest {
89
89
  codeChallenge?: string;
90
90
  /** PKCE method: 'S256' (recommended) or 'plain' */
91
91
  codeChallengeMethod?: string;
92
+ /** The studio (company) the issued tokens are bound to; sent as `company_id` on approve */
93
+ companyId?: string;
92
94
  }
93
95
 
94
96
  /**
95
97
  * Scope information for display in consent screen
96
98
  */
97
99
  export interface OAuthScopeInfo {
98
- /** The scope identifier (e.g., 'photographs:read') */
100
+ /** The scope identifier (e.g., 'read', 'mcp') */
99
101
  scope: string;
100
102
  /** Human-readable scope name */
101
103
  name: string;
@@ -111,6 +113,8 @@ export interface OAuthScopeInfo {
111
113
  export interface OAuthConsentInfo {
112
114
  client: OAuthClientInterface;
113
115
  scopes: OAuthScopeInfo[];
116
+ /** The caller's companies, ordered by name; the user picks one when there is more than one */
117
+ companies?: Array<{ id: string; name: string }>;
114
118
  }
115
119
 
116
120
  /**
@@ -130,36 +134,18 @@ export const OAUTH_SCOPE_DISPLAY: Record<string, OAuthScopeInfo> = {
130
134
  description: "Write access to your data",
131
135
  icon: "pencil",
132
136
  },
133
- "photographs:read": {
134
- scope: "photographs:read",
135
- name: "View Photographs",
136
- description: "Access and download your photo library",
137
- icon: "image",
138
- },
139
- "photographs:write": {
140
- scope: "photographs:write",
141
- name: "Upload Photographs",
142
- description: "Add new photos to your rolls",
143
- icon: "upload",
144
- },
145
- "rolls:read": {
146
- scope: "rolls:read",
147
- name: "View Rolls",
148
- description: "See your film rolls and collections",
149
- icon: "film",
150
- },
151
- "rolls:write": {
152
- scope: "rolls:write",
153
- name: "Manage Rolls",
154
- description: "Create and modify film rolls",
155
- icon: "folder-plus",
156
- },
157
137
  profile: {
158
138
  scope: "profile",
159
139
  name: "View Profile",
160
140
  description: "Access your name and email",
161
141
  icon: "user",
162
142
  },
143
+ mcp: {
144
+ scope: "mcp",
145
+ name: "MCP Server Access",
146
+ description: "Let an AI assistant read and act on your data through the MCP server",
147
+ icon: "shield",
148
+ },
163
149
  admin: {
164
150
  scope: "admin",
165
151
  name: "Administrative Access",
@@ -243,7 +243,7 @@ describe("useDataListRetriever", () => {
243
243
  const retriever = vi.fn().mockResolvedValue(mockData);
244
244
 
245
245
  const { result } = renderHook(() =>
246
- useDataListRetriever({
246
+ useDataListRetriever<(typeof mockData)[number]>({
247
247
  retriever,
248
248
  module: mockModule,
249
249
  }),
@@ -1,36 +0,0 @@
1
- import { A as ApiDataInterface } from './ApiDataInterface-BcZeXy5X.js';
2
-
3
- type AssistantInput = {
4
- firstMessage: string;
5
- title?: string;
6
- howToMode?: boolean;
7
- limitToHowToId?: string;
8
- handbookMode?: boolean;
9
- limitToHandbookPageId?: string;
10
- /**
11
- * BlockNote document behind `firstMessage`. Sent alongside the flattened
12
- * text so the server can re-derive the content and read `@`-mentions from
13
- * the inline nodes; the flattened text is never trusted on its own.
14
- */
15
- contentBlocks?: unknown[];
16
- /**
17
- * Resource the thread is bound to (e.g. a campaign). Confines every agent
18
- * data-access point in the run to that resource's scope.
19
- */
20
- boundContent?: {
21
- type: string;
22
- id: string;
23
- };
24
- };
25
- interface AssistantInterface extends ApiDataInterface {
26
- get title(): string;
27
- get messageCount(): number;
28
- /** Agent engine the thread runs on — `"operator"` or undefined (responder). */
29
- get engine(): string | undefined;
30
- /** JSON:API type of the resource this thread is bound to, when bound. */
31
- get boundContentType(): string | undefined;
32
- /** Id of the resource this thread is bound to, when bound. */
33
- get boundContentId(): string | undefined;
34
- }
35
-
36
- export type { AssistantInput as A, AssistantInterface as a };
@@ -1,36 +0,0 @@
1
- import { A as ApiDataInterface } from './ApiDataInterface-BcZeXy5X.mjs';
2
-
3
- type AssistantInput = {
4
- firstMessage: string;
5
- title?: string;
6
- howToMode?: boolean;
7
- limitToHowToId?: string;
8
- handbookMode?: boolean;
9
- limitToHandbookPageId?: string;
10
- /**
11
- * BlockNote document behind `firstMessage`. Sent alongside the flattened
12
- * text so the server can re-derive the content and read `@`-mentions from
13
- * the inline nodes; the flattened text is never trusted on its own.
14
- */
15
- contentBlocks?: unknown[];
16
- /**
17
- * Resource the thread is bound to (e.g. a campaign). Confines every agent
18
- * data-access point in the run to that resource's scope.
19
- */
20
- boundContent?: {
21
- type: string;
22
- id: string;
23
- };
24
- };
25
- interface AssistantInterface extends ApiDataInterface {
26
- get title(): string;
27
- get messageCount(): number;
28
- /** Agent engine the thread runs on — `"operator"` or undefined (responder). */
29
- get engine(): string | undefined;
30
- /** JSON:API type of the resource this thread is bound to, when bound. */
31
- get boundContentType(): string | undefined;
32
- /** Id of the resource this thread is bound to, when bound. */
33
- get boundContentId(): string | undefined;
34
- }
35
-
36
- export type { AssistantInput as A, AssistantInterface as a };