lemma-sdk 0.2.41 → 0.2.43
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/README.md +5 -2
- package/dist/browser/lemma-client.js +22 -61
- package/dist/namespaces/conversations.d.ts +6 -0
- package/dist/namespaces/conversations.js +2 -0
- package/dist/namespaces/files.js +12 -21
- package/dist/openapi_client/index.d.ts +2 -1
- package/dist/openapi_client/index.js +2 -1
- package/dist/openapi_client/models/ConversationResponse.d.ts +5 -0
- package/dist/openapi_client/models/ConversationStatus.d.ts +11 -0
- package/dist/openapi_client/models/ConversationStatus.js +16 -0
- package/dist/openapi_client/models/ConversationType.d.ts +7 -0
- package/dist/openapi_client/models/ConversationType.js +12 -0
- package/dist/openapi_client/models/CreateConversationRequest.d.ts +3 -0
- package/dist/openapi_client/models/CreateFolderRequest.d.ts +0 -3
- package/dist/openapi_client/models/DatastoreFileUploadRequest.d.ts +0 -2
- package/dist/openapi_client/models/FileResponse.d.ts +0 -2
- package/dist/openapi_client/models/UpdateConversationRequest.d.ts +1 -0
- package/dist/openapi_client/models/update.d.ts +0 -3
- package/dist/openapi_client/services/AgentConversationsService.d.ts +5 -1
- package/dist/openapi_client/services/AgentConversationsService.js +5 -1
- package/dist/openapi_client/services/FilesService.d.ts +8 -17
- package/dist/openapi_client/services/FilesService.js +8 -25
- package/dist/react/AuthGuard.d.ts +2 -16
- package/dist/react/AuthGuard.js +130 -169
- package/dist/react/useAssistantSession.d.ts +6 -0
- package/dist/react/useAssistantSession.js +4 -0
- package/dist/react/useConversations.d.ts +7 -1
- package/dist/react/useConversations.js +10 -4
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/openapi_client/models/FileNamespace.d.ts +0 -4
- package/dist/openapi_client/models/FileNamespace.js +0 -9
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ConversationListResponse } from '../models/ConversationListResponse.js';
|
|
2
2
|
import type { ConversationResponse } from '../models/ConversationResponse.js';
|
|
3
|
+
import type { ConversationStatus } from '../models/ConversationStatus.js';
|
|
4
|
+
import type { ConversationType } from '../models/ConversationType.js';
|
|
3
5
|
import type { CreateConversationRequest } from '../models/CreateConversationRequest.js';
|
|
4
6
|
import type { MessageListResponse } from '../models/MessageListResponse.js';
|
|
5
7
|
import type { SendMessageRequest } from '../models/SendMessageRequest.js';
|
|
@@ -11,12 +13,14 @@ export declare class AgentConversationsService {
|
|
|
11
13
|
* List root conversations for the current user in a pod. Use agent_name to list conversations for a specific pod agent; omit it to list default pod assistant conversations. Child conversations are omitted from this root list.
|
|
12
14
|
* @param podId
|
|
13
15
|
* @param agentName
|
|
16
|
+
* @param status
|
|
17
|
+
* @param type
|
|
14
18
|
* @param pageToken
|
|
15
19
|
* @param limit
|
|
16
20
|
* @returns ConversationListResponse Successful Response
|
|
17
21
|
* @throws ApiError
|
|
18
22
|
*/
|
|
19
|
-
static agentConversationList(podId: string, agentName?: (string | null), pageToken?: (string | null), limit?: number): CancelablePromise<ConversationListResponse>;
|
|
23
|
+
static agentConversationList(podId: string, agentName?: (string | null), status?: (ConversationStatus | null), type?: (ConversationType | null), pageToken?: (string | null), limit?: number): CancelablePromise<ConversationListResponse>;
|
|
20
24
|
/**
|
|
21
25
|
* Create Pod Agent Conversation
|
|
22
26
|
* Create a new pod-scoped conversation. When agent_name is omitted, the conversation uses the default pod assistant. Workflow and sub-agent executions also use conversations as their external execution handle.
|
|
@@ -6,12 +6,14 @@ export class AgentConversationsService {
|
|
|
6
6
|
* List root conversations for the current user in a pod. Use agent_name to list conversations for a specific pod agent; omit it to list default pod assistant conversations. Child conversations are omitted from this root list.
|
|
7
7
|
* @param podId
|
|
8
8
|
* @param agentName
|
|
9
|
+
* @param status
|
|
10
|
+
* @param type
|
|
9
11
|
* @param pageToken
|
|
10
12
|
* @param limit
|
|
11
13
|
* @returns ConversationListResponse Successful Response
|
|
12
14
|
* @throws ApiError
|
|
13
15
|
*/
|
|
14
|
-
static agentConversationList(podId, agentName, pageToken, limit = 20) {
|
|
16
|
+
static agentConversationList(podId, agentName, status, type, pageToken, limit = 20) {
|
|
15
17
|
return __request(OpenAPI, {
|
|
16
18
|
method: 'GET',
|
|
17
19
|
url: '/pods/{pod_id}/conversations',
|
|
@@ -20,6 +22,8 @@ export class AgentConversationsService {
|
|
|
20
22
|
},
|
|
21
23
|
query: {
|
|
22
24
|
'agent_name': agentName,
|
|
25
|
+
'status': status,
|
|
26
|
+
'type': type,
|
|
23
27
|
'page_token': pageToken,
|
|
24
28
|
'limit': limit,
|
|
25
29
|
},
|
|
@@ -4,7 +4,6 @@ import type { DatastoreFileUploadRequest } from '../models/DatastoreFileUploadRe
|
|
|
4
4
|
import type { DatastoreMessageResponse } from '../models/DatastoreMessageResponse.js';
|
|
5
5
|
import type { DirectoryTreeResponse } from '../models/DirectoryTreeResponse.js';
|
|
6
6
|
import type { FileListResponse } from '../models/FileListResponse.js';
|
|
7
|
-
import { FileNamespace } from '../models/FileNamespace.js';
|
|
8
7
|
import type { FileResponse } from '../models/FileResponse.js';
|
|
9
8
|
import type { FileSearchRequest } from '../models/FileSearchRequest.js';
|
|
10
9
|
import type { FileSearchResponse } from '../models/FileSearchResponse.js';
|
|
@@ -15,13 +14,12 @@ export declare class FilesService {
|
|
|
15
14
|
* List Files
|
|
16
15
|
* @param podId
|
|
17
16
|
* @param directoryPath
|
|
18
|
-
* @param namespace
|
|
19
17
|
* @param limit
|
|
20
18
|
* @param pageToken
|
|
21
19
|
* @returns FileListResponse Successful Response
|
|
22
20
|
* @throws ApiError
|
|
23
21
|
*/
|
|
24
|
-
static fileList(podId: string, directoryPath?: string,
|
|
22
|
+
static fileList(podId: string, directoryPath?: string, limit?: number, pageToken?: (string | null)): CancelablePromise<FileListResponse>;
|
|
25
23
|
/**
|
|
26
24
|
* Upload File
|
|
27
25
|
* @param podId
|
|
@@ -34,20 +32,18 @@ export declare class FilesService {
|
|
|
34
32
|
* Delete File Or Folder
|
|
35
33
|
* @param podId
|
|
36
34
|
* @param path
|
|
37
|
-
* @param namespace
|
|
38
35
|
* @returns DatastoreMessageResponse Successful Response
|
|
39
36
|
* @throws ApiError
|
|
40
37
|
*/
|
|
41
|
-
static fileDelete(podId: string, path: string
|
|
38
|
+
static fileDelete(podId: string, path: string): CancelablePromise<DatastoreMessageResponse>;
|
|
42
39
|
/**
|
|
43
40
|
* Get File
|
|
44
41
|
* @param podId
|
|
45
42
|
* @param path
|
|
46
|
-
* @param namespace
|
|
47
43
|
* @returns FileResponse Successful Response
|
|
48
44
|
* @throws ApiError
|
|
49
45
|
*/
|
|
50
|
-
static fileGet(podId: string, path: string
|
|
46
|
+
static fileGet(podId: string, path: string): CancelablePromise<FileResponse>;
|
|
51
47
|
/**
|
|
52
48
|
* Update File
|
|
53
49
|
* @param podId
|
|
@@ -60,39 +56,35 @@ export declare class FilesService {
|
|
|
60
56
|
* Get Converted File Metadata
|
|
61
57
|
* @param podId
|
|
62
58
|
* @param path
|
|
63
|
-
* @param namespace
|
|
64
59
|
* @returns ConvertedFileResponse Successful Response
|
|
65
60
|
* @throws ApiError
|
|
66
61
|
*/
|
|
67
|
-
static fileConvertedGet(podId: string, path: string
|
|
62
|
+
static fileConvertedGet(podId: string, path: string): CancelablePromise<ConvertedFileResponse>;
|
|
68
63
|
/**
|
|
69
64
|
* Download Converted File Artifact
|
|
70
65
|
* @param podId
|
|
71
66
|
* @param path
|
|
72
67
|
* @param artifact
|
|
73
|
-
* @param namespace
|
|
74
68
|
* @returns binary File bytes
|
|
75
69
|
* @throws ApiError
|
|
76
70
|
*/
|
|
77
|
-
static fileConvertedDownload(podId: string, path: string, artifact?: string
|
|
71
|
+
static fileConvertedDownload(podId: string, path: string, artifact?: string): CancelablePromise<Blob>;
|
|
78
72
|
/**
|
|
79
73
|
* Render Converted File As HTML
|
|
80
74
|
* @param podId
|
|
81
75
|
* @param path
|
|
82
|
-
* @param namespace
|
|
83
76
|
* @returns string Rendered HTML
|
|
84
77
|
* @throws ApiError
|
|
85
78
|
*/
|
|
86
|
-
static fileConvertedRender(podId: string, path: string
|
|
79
|
+
static fileConvertedRender(podId: string, path: string): CancelablePromise<string>;
|
|
87
80
|
/**
|
|
88
81
|
* Download File
|
|
89
82
|
* @param podId
|
|
90
83
|
* @param path
|
|
91
|
-
* @param namespace
|
|
92
84
|
* @returns binary File bytes
|
|
93
85
|
* @throws ApiError
|
|
94
86
|
*/
|
|
95
|
-
static fileDownload(podId: string, path: string
|
|
87
|
+
static fileDownload(podId: string, path: string): CancelablePromise<Blob>;
|
|
96
88
|
/**
|
|
97
89
|
* Create Folder
|
|
98
90
|
* @param podId
|
|
@@ -113,10 +105,9 @@ export declare class FilesService {
|
|
|
113
105
|
* Get Directory Tree
|
|
114
106
|
* @param podId
|
|
115
107
|
* @param rootPath
|
|
116
|
-
* @param namespace
|
|
117
108
|
* @param filesPerDirectory
|
|
118
109
|
* @returns DirectoryTreeResponse Successful Response
|
|
119
110
|
* @throws ApiError
|
|
120
111
|
*/
|
|
121
|
-
static fileTree(podId: string, rootPath?: string,
|
|
112
|
+
static fileTree(podId: string, rootPath?: string, filesPerDirectory?: number): CancelablePromise<DirectoryTreeResponse>;
|
|
122
113
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FileNamespace } from '../models/FileNamespace.js';
|
|
2
1
|
import { OpenAPI } from '../core/OpenAPI.js';
|
|
3
2
|
import { request as __request } from '../core/request.js';
|
|
4
3
|
export class FilesService {
|
|
@@ -6,13 +5,12 @@ export class FilesService {
|
|
|
6
5
|
* List Files
|
|
7
6
|
* @param podId
|
|
8
7
|
* @param directoryPath
|
|
9
|
-
* @param namespace
|
|
10
8
|
* @param limit
|
|
11
9
|
* @param pageToken
|
|
12
10
|
* @returns FileListResponse Successful Response
|
|
13
11
|
* @throws ApiError
|
|
14
12
|
*/
|
|
15
|
-
static fileList(podId, directoryPath = '/',
|
|
13
|
+
static fileList(podId, directoryPath = '/', limit = 100, pageToken) {
|
|
16
14
|
return __request(OpenAPI, {
|
|
17
15
|
method: 'GET',
|
|
18
16
|
url: '/pods/{pod_id}/datastore/files',
|
|
@@ -21,7 +19,6 @@ export class FilesService {
|
|
|
21
19
|
},
|
|
22
20
|
query: {
|
|
23
21
|
'directory_path': directoryPath,
|
|
24
|
-
'namespace': namespace,
|
|
25
22
|
'limit': limit,
|
|
26
23
|
'page_token': pageToken,
|
|
27
24
|
},
|
|
@@ -55,11 +52,10 @@ export class FilesService {
|
|
|
55
52
|
* Delete File Or Folder
|
|
56
53
|
* @param podId
|
|
57
54
|
* @param path
|
|
58
|
-
* @param namespace
|
|
59
55
|
* @returns DatastoreMessageResponse Successful Response
|
|
60
56
|
* @throws ApiError
|
|
61
57
|
*/
|
|
62
|
-
static fileDelete(podId, path
|
|
58
|
+
static fileDelete(podId, path) {
|
|
63
59
|
return __request(OpenAPI, {
|
|
64
60
|
method: 'DELETE',
|
|
65
61
|
url: '/pods/{pod_id}/datastore/files/by-path',
|
|
@@ -68,7 +64,6 @@ export class FilesService {
|
|
|
68
64
|
},
|
|
69
65
|
query: {
|
|
70
66
|
'path': path,
|
|
71
|
-
'namespace': namespace,
|
|
72
67
|
},
|
|
73
68
|
errors: {
|
|
74
69
|
422: `Validation Error`,
|
|
@@ -79,11 +74,10 @@ export class FilesService {
|
|
|
79
74
|
* Get File
|
|
80
75
|
* @param podId
|
|
81
76
|
* @param path
|
|
82
|
-
* @param namespace
|
|
83
77
|
* @returns FileResponse Successful Response
|
|
84
78
|
* @throws ApiError
|
|
85
79
|
*/
|
|
86
|
-
static fileGet(podId, path
|
|
80
|
+
static fileGet(podId, path) {
|
|
87
81
|
return __request(OpenAPI, {
|
|
88
82
|
method: 'GET',
|
|
89
83
|
url: '/pods/{pod_id}/datastore/files/by-path',
|
|
@@ -92,7 +86,6 @@ export class FilesService {
|
|
|
92
86
|
},
|
|
93
87
|
query: {
|
|
94
88
|
'path': path,
|
|
95
|
-
'namespace': namespace,
|
|
96
89
|
},
|
|
97
90
|
errors: {
|
|
98
91
|
422: `Validation Error`,
|
|
@@ -124,11 +117,10 @@ export class FilesService {
|
|
|
124
117
|
* Get Converted File Metadata
|
|
125
118
|
* @param podId
|
|
126
119
|
* @param path
|
|
127
|
-
* @param namespace
|
|
128
120
|
* @returns ConvertedFileResponse Successful Response
|
|
129
121
|
* @throws ApiError
|
|
130
122
|
*/
|
|
131
|
-
static fileConvertedGet(podId, path
|
|
123
|
+
static fileConvertedGet(podId, path) {
|
|
132
124
|
return __request(OpenAPI, {
|
|
133
125
|
method: 'GET',
|
|
134
126
|
url: '/pods/{pod_id}/datastore/files/converted/by-path',
|
|
@@ -137,7 +129,6 @@ export class FilesService {
|
|
|
137
129
|
},
|
|
138
130
|
query: {
|
|
139
131
|
'path': path,
|
|
140
|
-
'namespace': namespace,
|
|
141
132
|
},
|
|
142
133
|
errors: {
|
|
143
134
|
422: `Validation Error`,
|
|
@@ -149,11 +140,10 @@ export class FilesService {
|
|
|
149
140
|
* @param podId
|
|
150
141
|
* @param path
|
|
151
142
|
* @param artifact
|
|
152
|
-
* @param namespace
|
|
153
143
|
* @returns binary File bytes
|
|
154
144
|
* @throws ApiError
|
|
155
145
|
*/
|
|
156
|
-
static fileConvertedDownload(podId, path, artifact = 'document.md'
|
|
146
|
+
static fileConvertedDownload(podId, path, artifact = 'document.md') {
|
|
157
147
|
return __request(OpenAPI, {
|
|
158
148
|
method: 'GET',
|
|
159
149
|
url: '/pods/{pod_id}/datastore/files/converted/download',
|
|
@@ -163,7 +153,6 @@ export class FilesService {
|
|
|
163
153
|
query: {
|
|
164
154
|
'path': path,
|
|
165
155
|
'artifact': artifact,
|
|
166
|
-
'namespace': namespace,
|
|
167
156
|
},
|
|
168
157
|
errors: {
|
|
169
158
|
422: `Validation Error`,
|
|
@@ -174,11 +163,10 @@ export class FilesService {
|
|
|
174
163
|
* Render Converted File As HTML
|
|
175
164
|
* @param podId
|
|
176
165
|
* @param path
|
|
177
|
-
* @param namespace
|
|
178
166
|
* @returns string Rendered HTML
|
|
179
167
|
* @throws ApiError
|
|
180
168
|
*/
|
|
181
|
-
static fileConvertedRender(podId, path
|
|
169
|
+
static fileConvertedRender(podId, path) {
|
|
182
170
|
return __request(OpenAPI, {
|
|
183
171
|
method: 'GET',
|
|
184
172
|
url: '/pods/{pod_id}/datastore/files/converted/render',
|
|
@@ -187,7 +175,6 @@ export class FilesService {
|
|
|
187
175
|
},
|
|
188
176
|
query: {
|
|
189
177
|
'path': path,
|
|
190
|
-
'namespace': namespace,
|
|
191
178
|
},
|
|
192
179
|
errors: {
|
|
193
180
|
422: `Validation Error`,
|
|
@@ -198,11 +185,10 @@ export class FilesService {
|
|
|
198
185
|
* Download File
|
|
199
186
|
* @param podId
|
|
200
187
|
* @param path
|
|
201
|
-
* @param namespace
|
|
202
188
|
* @returns binary File bytes
|
|
203
189
|
* @throws ApiError
|
|
204
190
|
*/
|
|
205
|
-
static fileDownload(podId, path
|
|
191
|
+
static fileDownload(podId, path) {
|
|
206
192
|
return __request(OpenAPI, {
|
|
207
193
|
method: 'GET',
|
|
208
194
|
url: '/pods/{pod_id}/datastore/files/download',
|
|
@@ -211,7 +197,6 @@ export class FilesService {
|
|
|
211
197
|
},
|
|
212
198
|
query: {
|
|
213
199
|
'path': path,
|
|
214
|
-
'namespace': namespace,
|
|
215
200
|
},
|
|
216
201
|
errors: {
|
|
217
202
|
422: `Validation Error`,
|
|
@@ -264,12 +249,11 @@ export class FilesService {
|
|
|
264
249
|
* Get Directory Tree
|
|
265
250
|
* @param podId
|
|
266
251
|
* @param rootPath
|
|
267
|
-
* @param namespace
|
|
268
252
|
* @param filesPerDirectory
|
|
269
253
|
* @returns DirectoryTreeResponse Successful Response
|
|
270
254
|
* @throws ApiError
|
|
271
255
|
*/
|
|
272
|
-
static fileTree(podId, rootPath = '/',
|
|
256
|
+
static fileTree(podId, rootPath = '/', filesPerDirectory = 3) {
|
|
273
257
|
return __request(OpenAPI, {
|
|
274
258
|
method: 'GET',
|
|
275
259
|
url: '/pods/{pod_id}/datastore/files/tree',
|
|
@@ -278,7 +262,6 @@ export class FilesService {
|
|
|
278
262
|
},
|
|
279
263
|
query: {
|
|
280
264
|
'root_path': rootPath,
|
|
281
|
-
'namespace': namespace,
|
|
282
265
|
'files_per_directory': filesPerDirectory,
|
|
283
266
|
},
|
|
284
267
|
errors: {
|
|
@@ -3,23 +3,9 @@ import type { LemmaClient } from "../client.js";
|
|
|
3
3
|
export interface AuthGuardProps {
|
|
4
4
|
client: LemmaClient;
|
|
5
5
|
children: ReactNode;
|
|
6
|
-
|
|
6
|
+
appName?: string;
|
|
7
7
|
loadingFallback?: ReactNode;
|
|
8
|
-
/** Optional custom unauthenticated element. Defaults to a centered sign-in page. */
|
|
9
8
|
unauthenticatedFallback?: ReactNode;
|
|
10
|
-
/** Optional custom element shown when user is authenticated but lacks pod membership. */
|
|
11
9
|
accessRequestFallback?: ReactNode;
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
* AuthGuard wraps your application and handles auth state:
|
|
15
|
-
* - Loading: shows loadingFallback (blank by default)
|
|
16
|
-
* - Unauthenticated: shows sign-in page (or custom unauthenticatedFallback)
|
|
17
|
-
* - Authenticated and member: renders children
|
|
18
|
-
* - Authenticated but not pod member: shows request-access page
|
|
19
|
-
*
|
|
20
|
-
* Usage:
|
|
21
|
-
* <AuthGuard client={getClient()}>
|
|
22
|
-
* <App />
|
|
23
|
-
* </AuthGuard>
|
|
24
|
-
*/
|
|
25
|
-
export declare function AuthGuard({ client, children, loadingFallback, unauthenticatedFallback, accessRequestFallback, }: AuthGuardProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function AuthGuard({ client, children, appName, loadingFallback, unauthenticatedFallback, accessRequestFallback, }: AuthGuardProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/react/AuthGuard.js
CHANGED
|
@@ -1,185 +1,146 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback
|
|
3
|
-
import { ApiError } from "../http.js";
|
|
2
|
+
import { useCallback } from "react";
|
|
4
3
|
import { useAuth } from "./useAuth.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { usePodAccess } from "./usePodAccess.js";
|
|
5
|
+
const pageStyle = {
|
|
6
|
+
display: "flex",
|
|
7
|
+
alignItems: "center",
|
|
8
|
+
justifyContent: "center",
|
|
9
|
+
minHeight: "100vh",
|
|
10
|
+
padding: "24px",
|
|
11
|
+
fontFamily: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
|
|
12
|
+
background: "linear-gradient(135deg, #f8fafc 0%, #eef2f7 46%, #f9fafb 100%)",
|
|
13
|
+
color: "#172033",
|
|
14
|
+
};
|
|
15
|
+
const panelStyle = {
|
|
16
|
+
width: "100%",
|
|
17
|
+
maxWidth: "440px",
|
|
18
|
+
border: "1px solid rgba(23, 32, 51, 0.1)",
|
|
19
|
+
borderRadius: "14px",
|
|
20
|
+
backgroundColor: "rgba(255, 255, 255, 0.94)",
|
|
21
|
+
boxShadow: "0 18px 60px rgba(23, 32, 51, 0.12)",
|
|
22
|
+
padding: "28px",
|
|
23
|
+
};
|
|
24
|
+
const eyebrowStyle = {
|
|
25
|
+
margin: "0 0 10px",
|
|
26
|
+
fontSize: "12px",
|
|
27
|
+
fontWeight: 700,
|
|
28
|
+
letterSpacing: "0.08em",
|
|
29
|
+
textTransform: "uppercase",
|
|
30
|
+
color: "#5f6f8a",
|
|
31
|
+
};
|
|
32
|
+
const titleStyle = {
|
|
33
|
+
margin: "0",
|
|
34
|
+
color: "#111827",
|
|
35
|
+
fontSize: "24px",
|
|
36
|
+
fontWeight: 700,
|
|
37
|
+
lineHeight: 1.18,
|
|
38
|
+
};
|
|
39
|
+
const bodyStyle = {
|
|
40
|
+
margin: "12px 0 0",
|
|
41
|
+
color: "#526173",
|
|
42
|
+
fontSize: "14px",
|
|
43
|
+
lineHeight: 1.55,
|
|
44
|
+
};
|
|
45
|
+
const buttonRowStyle = {
|
|
46
|
+
display: "flex",
|
|
47
|
+
gap: "10px",
|
|
48
|
+
marginTop: "24px",
|
|
49
|
+
flexWrap: "wrap",
|
|
50
|
+
};
|
|
51
|
+
function buttonStyle(variant, disabled = false) {
|
|
52
|
+
return {
|
|
53
|
+
flex: "1 1 160px",
|
|
54
|
+
minHeight: "42px",
|
|
55
|
+
border: variant === "primary" ? "1px solid #182235" : "1px solid rgba(23, 32, 51, 0.14)",
|
|
56
|
+
borderRadius: "10px",
|
|
57
|
+
backgroundColor: disabled
|
|
58
|
+
? "#d5dbe5"
|
|
59
|
+
: variant === "primary"
|
|
60
|
+
? "#182235"
|
|
61
|
+
: "#ffffff",
|
|
62
|
+
color: disabled
|
|
63
|
+
? "#6b7280"
|
|
64
|
+
: variant === "primary"
|
|
65
|
+
? "#ffffff"
|
|
66
|
+
: "#172033",
|
|
67
|
+
fontSize: "14px",
|
|
68
|
+
fontWeight: 650,
|
|
69
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function StatusPill({ status }) {
|
|
73
|
+
const label = status === "pending"
|
|
74
|
+
? "Request pending"
|
|
75
|
+
: status === "error"
|
|
76
|
+
? "Needs attention"
|
|
77
|
+
: "Access required";
|
|
78
|
+
return (_jsx("span", { style: {
|
|
79
|
+
display: "inline-flex",
|
|
9
80
|
alignItems: "center",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
width: "100%",
|
|
23
|
-
}, children: [_jsx("div", { style: {
|
|
24
|
-
width: "40px",
|
|
25
|
-
height: "40px",
|
|
26
|
-
borderRadius: "8px",
|
|
27
|
-
backgroundColor: "#111827",
|
|
28
|
-
margin: "0 auto 20px",
|
|
29
|
-
} }), _jsx("h1", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 600, color: "#111827" }, children: "Sign in to continue" }), _jsx("p", { style: { margin: "0 0 24px", fontSize: "14px", color: "#6b7280" }, children: "You need to be signed in to access this app." }), _jsx("button", { onClick: onSignIn, style: {
|
|
30
|
-
width: "100%",
|
|
31
|
-
padding: "10px 16px",
|
|
32
|
-
backgroundColor: "#111827",
|
|
33
|
-
color: "#fff",
|
|
34
|
-
border: "none",
|
|
35
|
-
borderRadius: "8px",
|
|
36
|
-
fontSize: "14px",
|
|
37
|
-
fontWeight: 500,
|
|
38
|
-
cursor: "pointer",
|
|
39
|
-
}, children: "Sign In" })] }) }));
|
|
81
|
+
borderRadius: "999px",
|
|
82
|
+
border: "1px solid rgba(95, 111, 138, 0.24)",
|
|
83
|
+
backgroundColor: "#f5f7fb",
|
|
84
|
+
color: "#526173",
|
|
85
|
+
padding: "5px 9px",
|
|
86
|
+
fontSize: "12px",
|
|
87
|
+
fontWeight: 650,
|
|
88
|
+
marginBottom: "16px",
|
|
89
|
+
}, children: label }));
|
|
90
|
+
}
|
|
91
|
+
function DefaultSignInPage({ appName, onSignIn, }) {
|
|
92
|
+
return (_jsx("div", { style: pageStyle, children: _jsxs("div", { style: panelStyle, children: [_jsx("p", { style: eyebrowStyle, children: appName }), _jsx("h1", { style: titleStyle, children: "Sign in to continue" }), _jsx("p", { style: bodyStyle, children: "Sign in with Lemma to open this workspace." }), _jsx("div", { style: buttonRowStyle, children: _jsx("button", { onClick: onSignIn, style: buttonStyle("primary"), children: "Sign in" }) })] }) }));
|
|
40
93
|
}
|
|
41
|
-
function DefaultRequestAccessPage({
|
|
94
|
+
function DefaultRequestAccessPage({ appName, status, isSubmitting, signedInAs, error, onRequestAccess, onRetry, }) {
|
|
95
|
+
const isPending = status === "pending";
|
|
96
|
+
const isError = status === "error";
|
|
97
|
+
const title = isPending
|
|
98
|
+
? "Your request is waiting for approval"
|
|
99
|
+
: isError
|
|
100
|
+
? "We could not verify access"
|
|
101
|
+
: "Request access to this pod";
|
|
42
102
|
const message = isPending
|
|
43
|
-
? "
|
|
44
|
-
: "You are signed in, but
|
|
45
|
-
return (_jsx("div", { style: {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
gap: "16px",
|
|
54
|
-
}, children: _jsxs("div", { style: {
|
|
55
|
-
backgroundColor: "#fff",
|
|
56
|
-
borderRadius: "12px",
|
|
57
|
-
boxShadow: "0 1px 4px rgba(0,0,0,0.1)",
|
|
58
|
-
padding: "40px 48px",
|
|
59
|
-
textAlign: "center",
|
|
60
|
-
maxWidth: "420px",
|
|
61
|
-
width: "100%",
|
|
62
|
-
}, children: [_jsx("h1", { style: { margin: "0 0 8px", fontSize: "20px", fontWeight: 600, color: "#111827" }, children: "Request pod access" }), _jsx("p", { style: { margin: "0 0 24px", fontSize: "14px", color: "#6b7280" }, children: message }), _jsx("button", { onClick: onRequestAccess, disabled: isSubmitting || isPending, style: {
|
|
63
|
-
width: "100%",
|
|
64
|
-
padding: "10px 16px",
|
|
65
|
-
backgroundColor: isSubmitting || isPending ? "#9ca3af" : "#111827",
|
|
66
|
-
color: "#fff",
|
|
67
|
-
border: "none",
|
|
68
|
-
borderRadius: "8px",
|
|
69
|
-
fontSize: "14px",
|
|
70
|
-
fontWeight: 500,
|
|
71
|
-
cursor: isSubmitting || isPending ? "not-allowed" : "pointer",
|
|
72
|
-
}, children: isSubmitting ? "Submitting..." : isPending ? "Request Sent" : "Request Access" }), error ? (_jsx("p", { style: { margin: "12px 0 0", fontSize: "13px", color: "#b91c1c" }, children: error })) : null] }) }));
|
|
103
|
+
? "An admin can approve your request from pod settings. You can refresh this screen after they add you."
|
|
104
|
+
: "You are signed in, but this pod is gated to members. Send an access request and an admin can let you in.";
|
|
105
|
+
return (_jsx("div", { style: pageStyle, children: _jsxs("div", { style: panelStyle, children: [_jsx("p", { style: eyebrowStyle, children: appName }), _jsx(StatusPill, { status: status }), _jsx("h1", { style: titleStyle, children: title }), _jsx("p", { style: bodyStyle, children: message }), signedInAs ? (_jsxs("p", { style: {
|
|
106
|
+
margin: "18px 0 0",
|
|
107
|
+
borderRadius: "10px",
|
|
108
|
+
backgroundColor: "#f5f7fb",
|
|
109
|
+
padding: "10px 12px",
|
|
110
|
+
color: "#526173",
|
|
111
|
+
fontSize: "13px",
|
|
112
|
+
}, children: ["Signed in as ", _jsx("strong", { style: { color: "#172033" }, children: signedInAs })] })) : null, error ? (_jsx("p", { style: { margin: "14px 0 0", color: "#b42318", fontSize: "13px", lineHeight: 1.45 }, children: error.message })) : null, _jsxs("div", { style: buttonRowStyle, children: [_jsx("button", { onClick: onRequestAccess, disabled: isSubmitting || isPending, style: buttonStyle("primary", isSubmitting || isPending), children: isSubmitting ? "Sending..." : isPending ? "Request sent" : "Request access" }), _jsx("button", { onClick: onRetry, style: buttonStyle("secondary"), children: isError ? "Try again" : "Refresh" })] })] }) }));
|
|
73
113
|
}
|
|
74
|
-
|
|
75
|
-
* AuthGuard wraps your application and handles auth state:
|
|
76
|
-
* - Loading: shows loadingFallback (blank by default)
|
|
77
|
-
* - Unauthenticated: shows sign-in page (or custom unauthenticatedFallback)
|
|
78
|
-
* - Authenticated and member: renders children
|
|
79
|
-
* - Authenticated but not pod member: shows request-access page
|
|
80
|
-
*
|
|
81
|
-
* Usage:
|
|
82
|
-
* <AuthGuard client={getClient()}>
|
|
83
|
-
* <App />
|
|
84
|
-
* </AuthGuard>
|
|
85
|
-
*/
|
|
86
|
-
export function AuthGuard({ client, children, loadingFallback = null, unauthenticatedFallback, accessRequestFallback, }) {
|
|
114
|
+
export function AuthGuard({ client, children, appName = "App", loadingFallback = null, unauthenticatedFallback, accessRequestFallback, }) {
|
|
87
115
|
const { isLoading, isAuthenticated, redirectToAuth } = useAuth(client);
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
await client.podMembers.lookupByUserId(client.podId, currentUser.id);
|
|
102
|
-
setMembershipState("member");
|
|
103
|
-
setJoinRequest(null);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
const apiError = error instanceof ApiError ? error : null;
|
|
108
|
-
const isMissingMembership = apiError?.statusCode === 404 || apiError?.statusCode === 403;
|
|
109
|
-
if (!isMissingMembership) {
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
try {
|
|
114
|
-
const existingRequest = await client.podJoinRequests.me(client.podId);
|
|
115
|
-
setJoinRequest(existingRequest);
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
// non-fatal: request could still be created by the user manually
|
|
119
|
-
}
|
|
120
|
-
setMembershipState("missing");
|
|
121
|
-
}, [client, isAuthenticated]);
|
|
122
|
-
useEffect(() => {
|
|
123
|
-
let cancelled = false;
|
|
124
|
-
const run = async () => {
|
|
125
|
-
if (!isAuthenticated) {
|
|
126
|
-
setMembershipState("idle");
|
|
127
|
-
setJoinRequest(null);
|
|
128
|
-
setMembershipError(null);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
await checkMembership();
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
if (cancelled)
|
|
136
|
-
return;
|
|
137
|
-
const message = error instanceof Error
|
|
138
|
-
? error.message
|
|
139
|
-
: "Failed to verify pod membership. Please try again.";
|
|
140
|
-
setMembershipError(message);
|
|
141
|
-
setMembershipState("missing");
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
void run();
|
|
145
|
-
return () => {
|
|
146
|
-
cancelled = true;
|
|
147
|
-
};
|
|
148
|
-
}, [checkMembership, isAuthenticated]);
|
|
149
|
-
const handleRequestAccess = useCallback(async () => {
|
|
150
|
-
if (!client.podId || isSubmittingJoinRequest || joinRequest?.status === "PENDING") {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
setIsSubmittingJoinRequest(true);
|
|
154
|
-
setMembershipError(null);
|
|
155
|
-
try {
|
|
156
|
-
const request = await client.podJoinRequests.create(client.podId);
|
|
157
|
-
setJoinRequest(request);
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
const message = error instanceof Error
|
|
161
|
-
? error.message
|
|
162
|
-
: "Failed to create access request. Please try again.";
|
|
163
|
-
setMembershipError(message);
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
setIsSubmittingJoinRequest(false);
|
|
167
|
-
}
|
|
168
|
-
}, [client, isSubmittingJoinRequest, joinRequest]);
|
|
169
|
-
if (isLoading || (isAuthenticated && membershipState === "checking")) {
|
|
116
|
+
const hasPodScope = Boolean(client.podId);
|
|
117
|
+
const podAccess = usePodAccess({
|
|
118
|
+
client,
|
|
119
|
+
enabled: isAuthenticated && hasPodScope,
|
|
120
|
+
autoLoad: isAuthenticated && hasPodScope,
|
|
121
|
+
});
|
|
122
|
+
const handleRequestAccess = useCallback(() => {
|
|
123
|
+
void podAccess.requestAccess();
|
|
124
|
+
}, [podAccess]);
|
|
125
|
+
const handleRetry = useCallback(() => {
|
|
126
|
+
void podAccess.refresh();
|
|
127
|
+
}, [podAccess]);
|
|
128
|
+
if (isLoading || (isAuthenticated && hasPodScope && podAccess.status === "checking")) {
|
|
170
129
|
return _jsx(_Fragment, { children: loadingFallback });
|
|
171
130
|
}
|
|
172
131
|
if (!isAuthenticated) {
|
|
173
132
|
if (unauthenticatedFallback !== undefined) {
|
|
174
133
|
return _jsx(_Fragment, { children: unauthenticatedFallback });
|
|
175
134
|
}
|
|
176
|
-
return _jsx(DefaultSignInPage, { onSignIn: redirectToAuth });
|
|
135
|
+
return _jsx(DefaultSignInPage, { appName: appName, onSignIn: redirectToAuth });
|
|
177
136
|
}
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return
|
|
137
|
+
if (!hasPodScope || podAccess.hasAccess) {
|
|
138
|
+
return _jsx(_Fragment, { children: children });
|
|
139
|
+
}
|
|
140
|
+
if (accessRequestFallback !== undefined) {
|
|
141
|
+
return _jsx(_Fragment, { children: accessRequestFallback });
|
|
183
142
|
}
|
|
184
|
-
|
|
143
|
+
const fullName = [podAccess.user?.first_name, podAccess.user?.last_name].filter(Boolean).join(" ");
|
|
144
|
+
const signedInAs = podAccess.user?.email ?? (fullName.length > 0 ? fullName : podAccess.user?.id ?? null);
|
|
145
|
+
return (_jsx(DefaultRequestAccessPage, { appName: appName, status: podAccess.status, isSubmitting: podAccess.isRequestingAccess, signedInAs: signedInAs, error: podAccess.error, onRequestAccess: handleRequestAccess, onRetry: handleRetry }));
|
|
185
146
|
}
|