@lastbrain/ai-ui-core 1.0.47 → 1.0.49

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.
@@ -1,4 +1,8 @@
1
1
  import type { ClientConfig, ModelRef, AiTextRequest, AiTextResponse, AiImageRequest, AiImageResponse, AiEmbedRequest, AiEmbedResponse, AiStatus, GatewayModelsResponse } from "../types";
2
+ export declare function getAuthHeaders(config: {
3
+ apiKeyId?: string;
4
+ sessionToken?: string;
5
+ }): Record<string, string>;
2
6
  export declare function createClient(config: ClientConfig): {
3
7
  getModels: () => Promise<ModelRef[]>;
4
8
  getAllAvailableModels: () => Promise<GatewayModelsResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"createClient.d.ts","sourceRoot":"","sources":["../../src/client/createClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,QAAQ,EACR,qBAAqB,EACtB,MAAM,UAAU,CAAC;AA8GlB,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY;qBAsBnB,OAAO,CAAC,QAAQ,EAAE,CAAC;iCAqKP,OAAO,CAAC,qBAAqB,CAAC;wBAhIrC,aAAa,KAAG,OAAO,CAAC,cAAc,CAAC;yBAoCtC,cAAc,KAAG,OAAO,CAAC,eAAe,CAAC;iBAqDjD,cAAc,KAAG,OAAO,CAAC,eAAe,CAAC;qBAkBvC,OAAO,CAAC,QAAQ,CAAC;EAiD9C"}
1
+ {"version":3,"file":"createClient.d.ts","sourceRoot":"","sources":["../../src/client/createClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,QAAQ,EACR,qBAAqB,EACtB,MAAM,UAAU,CAAC;AA4GlB,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBzB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY;qBAoBnB,OAAO,CAAC,QAAQ,EAAE,CAAC;iCA0KP,OAAO,CAAC,qBAAqB,CAAC;wBApIrC,aAAa,KAAG,OAAO,CAAC,cAAc,CAAC;yBAqCtC,cAAc,KAAG,OAAO,CAAC,eAAe,CAAC;iBAsDjD,cAAc,KAAG,OAAO,CAAC,eAAe,CAAC;qBAmBvC,OAAO,CAAC,QAAQ,CAAC;EAmD9C"}
@@ -37,59 +37,73 @@ async function fetchWithRetry(url, options, retryConfig) {
37
37
  throw lastError;
38
38
  }
39
39
  /**
40
- * Build URL for API endpoint with proper routing
41
- * For internal app (baseUrl="/api/ai"): use internal routes like /generate-text, /auth/status
42
- * For external app (baseUrl="/api/lastbrain"): use proxy routes like /text-ai, /status
43
- * For public API (baseUrl="/api/public/v1"): use direct public routes
40
+ * Build URL for API endpoint with unified auth/public routing.
41
+ * Supports base URLs:
42
+ * - /api/ai
43
+ * - /api/lastbrain (external app proxy)
44
+ * - /api/public/v1 (legacy public API)
44
45
  */
46
+ function normalizeBaseUrl(baseUrl) {
47
+ const trimmed = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
48
+ if (trimmed.includes("/api/ai") ||
49
+ trimmed.includes("/api/lastbrain") ||
50
+ trimmed.includes("/api/public/v1")) {
51
+ return trimmed;
52
+ }
53
+ return `${trimmed}/api/ai`;
54
+ }
45
55
  function buildUrl(baseUrl, endpoint) {
46
- const isInternalApp = baseUrl.includes("/api/ai");
47
- const isPublicApi = baseUrl.includes("/api/public/v1");
48
- const isExternalProxy = baseUrl.includes("/api/lastbrain");
49
- // Map endpoints for internal vs external context
50
- // Pour external:
51
- // - text-ai/image-ai utilisent les routes auth (session-based)
52
- // - autres routes: le proxy ajoute /api/ai/ automatiquement
53
- const endpointMap = {
54
- // Text and image generation - utilisent les routes auth avec session
55
- "text-ai": { internal: "/generate-text", external: "auth/text-ai" },
56
- "image-ai": { internal: "/generate-image", external: "auth/image-ai" },
57
- provider: { internal: "/auth/provider", external: "auth/provider" },
58
- "gateway-models": {
59
- internal: "/public/gateway-models",
60
- external: "public/gateway-models",
61
- },
62
- // Other endpoints
63
- "track-usage": { internal: "/track-usage", external: "track-usage" },
64
- "ai/embed": { internal: "/ai/embed", external: "ai/embed" },
56
+ const normalized = normalizeBaseUrl(baseUrl);
57
+ const isPublicV1 = normalized.includes("/api/public/v1");
58
+ const canonicalMap = {
59
+ "text-ai": "/auth/text-ai",
60
+ "image-ai": "/auth/image-ai",
61
+ provider: "/auth/models/users",
62
+ "gateway-models": "/auth/models",
63
+ status: "/auth/user",
64
+ "track-usage": "/track-usage",
65
+ "ai/embed": "/ai/embed",
65
66
  };
66
- const mapping = endpointMap[endpoint];
67
- if (mapping) {
68
- // For public API or external proxy, use external routes
69
- // Only internal app uses internal routes (with / prefix)
70
- const finalEndpoint = isInternalApp && !isPublicApi && !isExternalProxy
71
- ? mapping.internal
72
- : mapping.external;
73
- // Pour external, ne pas ajouter de / car le proxy le fera
74
- if (isExternalProxy && !finalEndpoint.startsWith("/")) {
75
- return `${baseUrl}/${finalEndpoint}`;
76
- }
77
- return `${baseUrl}${finalEndpoint}`;
67
+ const canonicalPath = canonicalMap[endpoint] || `/${endpoint}`;
68
+ if (!isPublicV1) {
69
+ return `${normalized}${canonicalPath}`;
78
70
  }
79
- // Fallback for unmapped endpoints
80
- return `${baseUrl}/${endpoint}`;
71
+ const v1Path = canonicalPath
72
+ .replace("/auth/text-ai", "/text-ai")
73
+ .replace("/auth/image-ai", "/image-ai")
74
+ .replace("/auth/models/users", "/ai/user/models")
75
+ .replace("/auth/models", "/gateway-models")
76
+ .replace("/auth/user", "/status");
77
+ return `${normalized}${v1Path}`;
78
+ }
79
+ export function getAuthHeaders(config) {
80
+ const token = config.apiKeyId?.trim();
81
+ const looksLikeApiKey = Boolean(token && token.startsWith("lb_"));
82
+ const looksLikeJwt = Boolean(token && token.split(".").length === 3);
83
+ if (token && (looksLikeApiKey || looksLikeJwt)) {
84
+ return {
85
+ ...(looksLikeApiKey ? { "x-lb-api-key": token } : {}),
86
+ Authorization: `Bearer ${token}`,
87
+ };
88
+ }
89
+ if (config.sessionToken) {
90
+ return {
91
+ Authorization: `Bearer ${config.sessionToken}`,
92
+ };
93
+ }
94
+ return {};
81
95
  }
82
96
  export function createClient(config) {
83
97
  const timeout = config.timeout ?? DEFAULT_TIMEOUT;
84
98
  const retries = config.retries ?? DEFAULT_RETRIES;
85
99
  function createHeaders() {
86
- const headers = {
100
+ return {
87
101
  "Content-Type": "application/json",
102
+ ...getAuthHeaders({
103
+ apiKeyId: config.apiKeyId || process.env.LB_API_KEY,
104
+ sessionToken: config.sessionToken,
105
+ }),
88
106
  };
89
- if (config.apiKeyId) {
90
- headers.Authorization = `Bearer ${config.apiKeyId}`;
91
- }
92
- return headers;
93
107
  }
94
108
  function createAbortSignal() {
95
109
  const controller = new AbortController();
@@ -102,6 +116,7 @@ export function createClient(config) {
102
116
  const response = await fetchWithRetry(url, {
103
117
  method: "GET",
104
118
  headers: createHeaders(),
119
+ credentials: config.credentials || "include",
105
120
  signal: createAbortSignal(),
106
121
  }, { retries, delay: INITIAL_RETRY_DELAY });
107
122
  // Transform response: extract all models from providers array
@@ -131,6 +146,7 @@ export function createClient(config) {
131
146
  method: "POST",
132
147
  headers: createHeaders(),
133
148
  body: JSON.stringify(req),
149
+ credentials: config.credentials || "include",
134
150
  signal: createAbortSignal(),
135
151
  }, { retries, delay: INITIAL_RETRY_DELAY });
136
152
  // Track prompt usage if promptId is provided
@@ -172,6 +188,7 @@ export function createClient(config) {
172
188
  method: "POST",
173
189
  headers: createHeaders(),
174
190
  body: JSON.stringify(apiRequest),
191
+ credentials: config.credentials || "include",
175
192
  signal: createAbortSignal(),
176
193
  }, { retries, delay: INITIAL_RETRY_DELAY });
177
194
  // Track prompt usage if promptId is provided
@@ -207,6 +224,7 @@ export function createClient(config) {
207
224
  method: "POST",
208
225
  headers: createHeaders(),
209
226
  body: JSON.stringify(req),
227
+ credentials: config.credentials || "include",
210
228
  signal: createAbortSignal(),
211
229
  }, { retries, delay: INITIAL_RETRY_DELAY });
212
230
  }
@@ -220,6 +238,7 @@ export function createClient(config) {
220
238
  return await fetchWithRetry(url, {
221
239
  method: "GET",
222
240
  headers: createHeaders(),
241
+ credentials: config.credentials || "include",
223
242
  signal: createAbortSignal(),
224
243
  }, { retries, delay: INITIAL_RETRY_DELAY });
225
244
  }
@@ -236,6 +255,7 @@ export function createClient(config) {
236
255
  const response = await fetchWithRetry(url, {
237
256
  method: "GET",
238
257
  headers: createHeaders(),
258
+ credentials: config.credentials || "include",
239
259
  signal: createAbortSignal(),
240
260
  }, { retries, delay: INITIAL_RETRY_DELAY });
241
261
  return response;
@@ -1,67 +1,56 @@
1
- /**
2
- * Client LastBrain intelligent
3
- * Supporte deux modes d'authentification :
4
- * - env-key : utilise LB_API_KEY (côté serveur)
5
- * - session : utilise cookie lb_session (user authentifié)
6
- */
7
1
  import type { LBAuthConfig, LBSession, LBLoginResult, LBApiKey, LBSessionResult } from "../types/auth";
2
+ export interface LBUserProfileResponse {
3
+ authType: "api_key" | "lb_session" | "supabase";
4
+ user: {
5
+ id: string;
6
+ email: string;
7
+ };
8
+ apiKeySelected: string | null;
9
+ apiKeyActive: {
10
+ id: string;
11
+ name: string;
12
+ prefix: string;
13
+ scopes: string[];
14
+ env: string;
15
+ } | null;
16
+ apiKeys: LBApiKey[];
17
+ balance?: {
18
+ providerBudgetUsd: number;
19
+ sellValueUsd: number;
20
+ };
21
+ }
22
+ export interface LBClientConfig extends LBAuthConfig {
23
+ sessionToken?: string;
24
+ credentials?: RequestCredentials;
25
+ }
8
26
  export declare class LBClient {
9
- private config;
10
- constructor(config?: LBAuthConfig);
11
- /**
12
- * Détecte le mode d'authentification à utiliser
13
- */
14
- private getAuthMode;
15
- /**
16
- * Construit les headers d'authentification
17
- */
18
- private getAuthHeaders;
19
- /**
20
- * Fait une requête à l'API LastBrain
21
- */
27
+ private readonly baseUrl;
28
+ private readonly apiKey;
29
+ private readonly selectedApiKeyId?;
30
+ private readonly mode;
31
+ private readonly sessionToken?;
32
+ private readonly credentials;
33
+ constructor(config?: LBClientConfig);
34
+ getAuthHeaders(sessionToken?: string): Record<string, string>;
22
35
  private request;
23
- /**
24
- * Login utilisateur (email + password)
25
- * Retourne un access_token temporaire pour récupérer les clés API
26
- */
27
36
  login(email: string, password: string): Promise<LBLoginResult>;
28
- /**
29
- * Récupère les clés API de l'utilisateur
30
- */
37
+ selectApiKey(keyIdOrValue: string, accessToken?: string): Promise<LBSessionResult>;
31
38
  getUserApiKeys(accessToken: string): Promise<LBApiKey[]>;
32
- /**
33
- * Crée une session (72h) avec une clé API sélectionnée
34
- */
35
39
  createSession(accessToken: string, apiKeyId: string): Promise<LBSessionResult>;
36
- /**
37
- * Vérifie si une session est valide
38
- */
39
- verifySession(sessionToken: string): Promise<LBSession | null>;
40
- /**
41
- * Déconnexion (invalide la session)
42
- */
43
- logout(sessionToken: string): Promise<void>;
44
- /**
45
- * Fait un appel IA (génération de texte)
46
- */
47
- generateText(params: {
48
- prompt: string;
49
- model?: string;
50
- sessionToken?: string;
51
- [key: string]: any;
52
- }): Promise<any>;
53
- /**
54
- * Fait un appel IA (génération d'image)
55
- */
56
- generateImage(params: {
57
- prompt: string;
58
- model?: string;
59
- sessionToken?: string;
60
- [key: string]: any;
61
- }): Promise<any>;
40
+ getUser(sessionToken?: string): Promise<LBUserProfileResponse>;
41
+ getModels(sessionToken?: string): Promise<any>;
42
+ getUserModels(sessionToken?: string): Promise<any>;
43
+ getHistory(params?: Record<string, string>, sessionToken?: string): Promise<any>;
44
+ getHistoryItem(id: string, sessionToken?: string): Promise<any>;
45
+ textAI(payload: Record<string, unknown>, sessionToken?: string): Promise<any>;
46
+ imageAI(payload: Record<string, unknown>, sessionToken?: string): Promise<any>;
47
+ getUsage(sessionToken?: string): Promise<any>;
48
+ getStatus(sessionToken?: string): Promise<any>;
49
+ getStorageStatus(sessionToken?: string): Promise<any>;
50
+ verifySession(sessionToken?: string): Promise<LBSession | null>;
51
+ generateText(params: Record<string, unknown>): Promise<any>;
52
+ generateImage(params: Record<string, unknown>): Promise<any>;
53
+ logout(): Promise<void>;
62
54
  }
63
- /**
64
- * Factory pour créer un client LastBrain
65
- */
66
- export declare function createLBClient(config?: LBAuthConfig): LBClient;
55
+ export declare function createLBClient(config?: LBClientConfig): LBClient;
67
56
  //# sourceMappingURL=lb-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lb-client.d.ts","sourceRoot":"","sources":["../../src/client/lb-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EAET,aAAa,EACb,QAAQ,EACR,eAAe,EAChB,MAAM,eAAe,CAAC;AAEvB,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,MAAM,GAAE,YAAiB;IAWrC;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;YACW,cAAc;IAsB5B;;OAEG;YACW,OAAO;IAyCrB;;;OAGG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAOpE;;OAEG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAQ9D;;OAEG;IACG,aAAa,CACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC;IAU3B;;OAEG;IACG,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAYpE;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,GAAG,OAAO,CAAC,GAAG,CAAC;IAWhB;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,GAAG,OAAO,CAAC,GAAG,CAAC;CAUjB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,QAAQ,CAE9D"}
1
+ {"version":3,"file":"lb-client.d.ts","sourceRoot":"","sources":["../../src/client/lb-client.ts"],"names":[],"mappings":"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"}
@@ -1,57 +1,71 @@
1
- /**
2
- * Client LastBrain intelligent
3
- * Supporte deux modes d'authentification :
4
- * - env-key : utilise LB_API_KEY (côté serveur)
5
- * - session : utilise cookie lb_session (user authentifié)
6
- */
1
+ function trimTrailingSlash(value) {
2
+ return value.endsWith("/") ? value.slice(0, -1) : value;
3
+ }
4
+ function normalizeBaseUrl(baseUrl) {
5
+ const raw = baseUrl ||
6
+ process.env.LB_API_URL ||
7
+ process.env.LB_BASE_URL ||
8
+ "https://prompt.lastbrain.io";
9
+ const trimmed = trimTrailingSlash(raw);
10
+ if (trimmed.includes("/api/ai") ||
11
+ trimmed.includes("/api/lastbrain") ||
12
+ trimmed.includes("/api/public/v1")) {
13
+ return trimmed;
14
+ }
15
+ return `${trimmed}/api/ai`;
16
+ }
17
+ function joinPath(baseUrl, endpoint) {
18
+ const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
19
+ if (baseUrl.includes("/api/public/v1")) {
20
+ const mapped = cleanEndpoint
21
+ .replace("/auth/text-ai", "/text-ai")
22
+ .replace("/auth/image-ai", "/image-ai")
23
+ .replace("/auth/history", "/history")
24
+ .replace("/auth/models/users", "/ai/user/models")
25
+ .replace("/auth/models", "/gateway-models")
26
+ .replace("/auth/user", "/status")
27
+ .replace("/public/login", "/connect")
28
+ .replace("/public/status", "/status");
29
+ return `${baseUrl}${mapped}`;
30
+ }
31
+ return `${baseUrl}${cleanEndpoint}`;
32
+ }
7
33
  export class LBClient {
8
- config;
34
+ baseUrl;
35
+ apiKey;
36
+ selectedApiKeyId;
37
+ mode;
38
+ sessionToken;
39
+ credentials;
9
40
  constructor(config = {}) {
10
- this.config = {
11
- baseUrl: config.baseUrl ||
12
- process.env.LB_BASE_URL ||
13
- "https://prompt.lastbrain.io",
14
- apiKey: config.apiKey || process.env.LB_API_KEY || "",
15
- mode: config.mode || "auto",
16
- };
17
- }
18
- /**
19
- * Détecte le mode d'authentification à utiliser
20
- */
21
- getAuthMode() {
22
- if (this.config.mode === "env-key")
23
- return "env-key";
24
- if (this.config.mode === "session")
25
- return "session";
26
- // Mode auto : préfère env-key si disponible
27
- return this.config.apiKey ? "env-key" : "session";
28
- }
29
- /**
30
- * Construit les headers d'authentification
31
- */
32
- async getAuthHeaders(sessionToken) {
33
- const mode = this.getAuthMode();
34
- if (mode === "env-key" && this.config.apiKey) {
35
- return {
36
- Authorization: `Bearer ${this.config.apiKey}`,
37
- };
41
+ this.baseUrl = normalizeBaseUrl(config.baseUrl);
42
+ this.apiKey = config.apiKey || process.env.LB_API_KEY || "";
43
+ this.selectedApiKeyId = config.selectedApiKeyId;
44
+ this.mode = config.mode || "auto";
45
+ this.sessionToken = config.sessionToken;
46
+ this.credentials = config.credentials || "include";
47
+ }
48
+ getAuthHeaders(sessionToken) {
49
+ const headers = {};
50
+ const tokenToUse = sessionToken || this.sessionToken;
51
+ const mode = this.mode === "auto" ? (this.apiKey ? "env-key" : "session") : this.mode;
52
+ if (this.selectedApiKeyId) {
53
+ headers["x-lb-api-key-selected"] = this.selectedApiKeyId;
38
54
  }
39
- // Mode session : utilise le token fourni ou tente de lire le cookie
40
- if (sessionToken) {
41
- return {
42
- Authorization: `Bearer ${sessionToken}`,
43
- };
55
+ if (mode === "env-key" && this.apiKey) {
56
+ headers["x-lb-api-key"] = this.apiKey;
57
+ headers.Authorization = `Bearer ${this.apiKey}`;
58
+ return headers;
44
59
  }
45
- // Si aucun token fourni, la requête échouera (attendu pour déclencher auth)
46
- return {};
60
+ if (tokenToUse) {
61
+ headers.Authorization = `Bearer ${tokenToUse}`;
62
+ }
63
+ return headers;
47
64
  }
48
- /**
49
- * Fait une requête à l'API LastBrain
50
- */
51
65
  async request(endpoint, options = {}) {
52
- const { baseUrl, headers: customHeaders, timeout, ...fetchOptions } = options;
53
- const url = `${baseUrl || this.config.baseUrl}${endpoint}`;
54
- const authHeaders = await this.getAuthHeaders();
66
+ const { baseUrl, headers: customHeaders, timeout, sessionToken, ...fetchOptions } = options;
67
+ const url = joinPath(baseUrl ? normalizeBaseUrl(baseUrl) : this.baseUrl, endpoint);
68
+ const authHeaders = this.getAuthHeaders(sessionToken);
55
69
  const controller = new AbortController();
56
70
  const timeoutId = timeout
57
71
  ? setTimeout(() => controller.abort(), timeout)
@@ -62,107 +76,117 @@ export class LBClient {
62
76
  headers: {
63
77
  "Content-Type": "application/json",
64
78
  ...authHeaders,
65
- ...customHeaders,
79
+ ...(customHeaders || {}),
66
80
  },
81
+ credentials: this.credentials,
67
82
  signal: controller.signal,
68
83
  });
69
84
  if (!response.ok) {
70
- const error = await response.json().catch(() => ({}));
71
- throw new Error(error.message || `HTTP ${response.status}`);
85
+ const payload = await response.json().catch(() => ({}));
86
+ throw new Error(payload.error || payload.message || `HTTP ${response.status}`);
72
87
  }
73
- return await response.json();
88
+ return (await response.json());
74
89
  }
75
90
  finally {
76
- if (timeoutId)
91
+ if (timeoutId) {
77
92
  clearTimeout(timeoutId);
93
+ }
78
94
  }
79
95
  }
80
- /**
81
- * Login utilisateur (email + password)
82
- * Retourne un access_token temporaire pour récupérer les clés API
83
- */
84
96
  async login(email, password) {
85
- return this.request("/auth/login", {
97
+ return this.request("/public/login", {
86
98
  method: "POST",
99
+ headers: {},
87
100
  body: JSON.stringify({ email, password }),
88
101
  });
89
102
  }
90
- /**
91
- * Récupère les clés API de l'utilisateur
92
- */
93
- async getUserApiKeys(accessToken) {
94
- return this.request("/user/api-keys", {
95
- headers: {
96
- Authorization: `Bearer ${accessToken}`,
97
- },
103
+ async selectApiKey(keyIdOrValue, accessToken) {
104
+ const headers = {};
105
+ if (accessToken) {
106
+ headers.Authorization = `Bearer ${accessToken}`;
107
+ }
108
+ return this.request("/auth/select-api-key", {
109
+ method: "POST",
110
+ headers,
111
+ body: JSON.stringify({ api_key_id: keyIdOrValue }),
98
112
  });
99
113
  }
100
- /**
101
- * Crée une session (72h) avec une clé API sélectionnée
102
- */
114
+ async getUserApiKeys(accessToken) {
115
+ const data = await this.getUser(accessToken);
116
+ return data.apiKeys || [];
117
+ }
103
118
  async createSession(accessToken, apiKeyId) {
104
- return this.request("/auth/session", {
119
+ return this.selectApiKey(apiKeyId, accessToken);
120
+ }
121
+ async getUser(sessionToken) {
122
+ return this.request("/auth/user", {
123
+ method: "GET",
124
+ sessionToken,
125
+ });
126
+ }
127
+ async getModels(sessionToken) {
128
+ return this.request("/auth/models", { method: "GET", sessionToken });
129
+ }
130
+ async getUserModels(sessionToken) {
131
+ return this.request("/auth/models/users", { method: "GET", sessionToken });
132
+ }
133
+ async getHistory(params, sessionToken) {
134
+ const search = params ? `?${new URLSearchParams(params).toString()}` : "";
135
+ return this.request(`/auth/history${search}`, { method: "GET", sessionToken });
136
+ }
137
+ async getHistoryItem(id, sessionToken) {
138
+ return this.request(`/auth/history/${id}`, { method: "GET", sessionToken });
139
+ }
140
+ async textAI(payload, sessionToken) {
141
+ return this.request("/auth/text-ai", {
105
142
  method: "POST",
106
- headers: {
107
- Authorization: `Bearer ${accessToken}`,
108
- },
109
- body: JSON.stringify({ api_key_id: apiKeyId }),
143
+ body: JSON.stringify(payload),
144
+ sessionToken,
145
+ });
146
+ }
147
+ async imageAI(payload, sessionToken) {
148
+ return this.request("/auth/image-ai", {
149
+ method: "POST",
150
+ body: JSON.stringify(payload),
151
+ sessionToken,
152
+ });
153
+ }
154
+ async getUsage(sessionToken) {
155
+ return this.request("/auth/usage", { method: "GET", sessionToken });
156
+ }
157
+ async getStatus(sessionToken) {
158
+ return this.request("/auth/status?fast=true", {
159
+ method: "GET",
160
+ sessionToken,
161
+ });
162
+ }
163
+ async getStorageStatus(sessionToken) {
164
+ return this.request("/auth/status/storage", {
165
+ method: "GET",
166
+ sessionToken,
110
167
  });
111
168
  }
112
- /**
113
- * Vérifie si une session est valide
114
- */
115
169
  async verifySession(sessionToken) {
116
170
  try {
117
- return await this.request("/auth/session/verify", {
118
- headers: {
119
- Authorization: `Bearer ${sessionToken}`,
120
- },
121
- });
171
+ const response = await this.request("/auth/session/verify", { method: "GET", sessionToken });
172
+ return response?.session || null;
122
173
  }
123
174
  catch {
124
175
  return null;
125
176
  }
126
177
  }
127
- /**
128
- * Déconnexion (invalide la session)
129
- */
130
- async logout(sessionToken) {
131
- await this.request("/auth/session/logout", {
132
- method: "POST",
133
- headers: {
134
- Authorization: `Bearer ${sessionToken}`,
135
- },
136
- });
137
- }
138
- /**
139
- * Fait un appel IA (génération de texte)
140
- */
141
178
  async generateText(params) {
142
- const { sessionToken, ...body } = params;
143
- const headers = await this.getAuthHeaders(sessionToken);
144
- return this.request("/ai/generate-text", {
145
- method: "POST",
146
- headers,
147
- body: JSON.stringify(body),
148
- });
179
+ const { sessionToken, ...payload } = params;
180
+ return this.textAI(payload, sessionToken);
149
181
  }
150
- /**
151
- * Fait un appel IA (génération d'image)
152
- */
153
182
  async generateImage(params) {
154
- const { sessionToken, ...body } = params;
155
- const headers = await this.getAuthHeaders(sessionToken);
156
- return this.request("/ai/generate-image", {
157
- method: "POST",
158
- headers,
159
- body: JSON.stringify(body),
160
- });
183
+ const { sessionToken, ...payload } = params;
184
+ return this.imageAI(payload, sessionToken);
185
+ }
186
+ async logout() {
187
+ await this.request("/auth/session/logout", { method: "POST" });
161
188
  }
162
189
  }
163
- /**
164
- * Factory pour créer un client LastBrain
165
- */
166
190
  export function createLBClient(config) {
167
191
  return new LBClient(config);
168
192
  }
@@ -1,22 +1,26 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- export declare function GET(request: NextRequest, context: {
1
+ export declare const GET: (request: import("next/server").NextRequest, context?: {
3
2
  params: Promise<{
4
- path: string[];
3
+ path?: string[];
5
4
  }>;
6
- }): Promise<NextResponse<any>>;
7
- export declare function POST(request: NextRequest, context: {
5
+ }) => Promise<import("next/server").NextResponse>;
6
+ export declare const POST: (request: import("next/server").NextRequest, context?: {
8
7
  params: Promise<{
9
- path: string[];
8
+ path?: string[];
10
9
  }>;
11
- }): Promise<NextResponse<any>>;
12
- export declare function PUT(request: NextRequest, context: {
10
+ }) => Promise<import("next/server").NextResponse>;
11
+ export declare const PUT: (request: import("next/server").NextRequest, context?: {
13
12
  params: Promise<{
14
- path: string[];
13
+ path?: string[];
15
14
  }>;
16
- }): Promise<NextResponse<any>>;
17
- export declare function DELETE(request: NextRequest, context: {
15
+ }) => Promise<import("next/server").NextResponse>;
16
+ export declare const DELETE: (request: import("next/server").NextRequest, context?: {
18
17
  params: Promise<{
19
- path: string[];
18
+ path?: string[];
20
19
  }>;
21
- }): Promise<NextResponse<any>>;
20
+ }) => Promise<import("next/server").NextResponse>;
21
+ export declare const PATCH: (request: import("next/server").NextRequest, context?: {
22
+ params: Promise<{
23
+ path?: string[];
24
+ }>;
25
+ }) => Promise<import("next/server").NextResponse>;
22
26
  //# sourceMappingURL=enhanced-gateway.d.ts.map