@lovable.dev/sdk 0.1.5 → 0.1.8
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 +0 -23
- package/dist/index.d.ts +12343 -38
- package/dist/index.js +98 -39
- package/dist/index.js.map +1 -1
- package/package.json +10 -4
package/dist/index.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import createClient from "openapi-fetch";
|
|
3
|
+
|
|
1
4
|
// src/types.ts
|
|
2
5
|
var ApiError = class extends Error {
|
|
3
6
|
status;
|
|
4
7
|
type;
|
|
5
8
|
detail;
|
|
6
|
-
|
|
9
|
+
props;
|
|
10
|
+
constructor(status, message, type, detail, props) {
|
|
7
11
|
super(message);
|
|
8
12
|
this.status = status;
|
|
9
13
|
this.type = type;
|
|
10
14
|
this.detail = detail;
|
|
15
|
+
this.props = props;
|
|
11
16
|
}
|
|
12
17
|
};
|
|
13
18
|
|
|
@@ -21,10 +26,29 @@ function normalizeBaseUrl(url) {
|
|
|
21
26
|
}
|
|
22
27
|
return normalized;
|
|
23
28
|
}
|
|
29
|
+
var errorMiddleware = {
|
|
30
|
+
async onResponse({ response }) {
|
|
31
|
+
if (response.ok) return;
|
|
32
|
+
let errorBody;
|
|
33
|
+
try {
|
|
34
|
+
errorBody = await response.clone().json();
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
const message = buildErrorMessage(errorBody, response.status, response.statusText);
|
|
38
|
+
const type = errorBody?.type ?? errorBody?.title;
|
|
39
|
+
const detail = errorBody?.detail ?? errorBody?.details;
|
|
40
|
+
throw new ApiError(response.status, message, type, detail, errorBody?.props);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
function buildErrorMessage(body, status, statusText) {
|
|
44
|
+
return body?.message || body?.title || (statusText ? `HTTP ${status}: ${statusText}` : `HTTP ${status}`);
|
|
45
|
+
}
|
|
24
46
|
var LovableClient = class {
|
|
25
47
|
authHeaders;
|
|
26
48
|
baseUrl;
|
|
27
49
|
extraHeaders;
|
|
50
|
+
clientSource;
|
|
51
|
+
typedClient;
|
|
28
52
|
constructor(options) {
|
|
29
53
|
const hasApiKey = !!options.apiKey;
|
|
30
54
|
const hasBearerToken = !!options.bearerToken;
|
|
@@ -37,10 +61,33 @@ var LovableClient = class {
|
|
|
37
61
|
this.authHeaders = hasApiKey ? { "Lovable-API-Key": options.apiKey } : { Authorization: `Bearer ${options.bearerToken}` };
|
|
38
62
|
this.baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
39
63
|
this.extraHeaders = options.headers ?? {};
|
|
64
|
+
this.clientSource = options.clientSource ?? "sdk";
|
|
65
|
+
this.typedClient = createClient({
|
|
66
|
+
baseUrl: this.baseUrl,
|
|
67
|
+
headers: {
|
|
68
|
+
"X-Client-Source": this.clientSource,
|
|
69
|
+
...this.authHeaders,
|
|
70
|
+
...this.extraHeaders,
|
|
71
|
+
Accept: "application/json"
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
this.typedClient.use(errorMiddleware);
|
|
40
75
|
}
|
|
41
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Type-safe access to any documented API route, driven by the auto-generated
|
|
78
|
+
* OpenAPI schema. Path / query params and request bodies are checked at compile
|
|
79
|
+
* time; calling an unknown path is a type error.
|
|
80
|
+
*
|
|
81
|
+
* Non-2xx responses throw `ApiError`; on success, `data` is set on the result.
|
|
82
|
+
*/
|
|
83
|
+
get typed() {
|
|
84
|
+
return this.typedClient;
|
|
85
|
+
}
|
|
86
|
+
async rawRequest(method, path, body, init) {
|
|
42
87
|
const url = `${this.baseUrl}${path}`;
|
|
43
88
|
const headers = {
|
|
89
|
+
"X-Client-Source": this.clientSource,
|
|
90
|
+
...init?.headers,
|
|
44
91
|
...this.authHeaders,
|
|
45
92
|
...this.extraHeaders,
|
|
46
93
|
Accept: "application/json"
|
|
@@ -51,7 +98,8 @@ var LovableClient = class {
|
|
|
51
98
|
const response = await fetch(url, {
|
|
52
99
|
method,
|
|
53
100
|
headers,
|
|
54
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
101
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
102
|
+
signal: init?.signal
|
|
55
103
|
});
|
|
56
104
|
if (!response.ok) {
|
|
57
105
|
let errorBody;
|
|
@@ -59,8 +107,10 @@ var LovableClient = class {
|
|
|
59
107
|
errorBody = await response.json();
|
|
60
108
|
} catch {
|
|
61
109
|
}
|
|
62
|
-
const message = errorBody
|
|
63
|
-
|
|
110
|
+
const message = buildErrorMessage(errorBody, response.status, response.statusText);
|
|
111
|
+
const type = errorBody?.type ?? errorBody?.title;
|
|
112
|
+
const detail = errorBody?.detail ?? errorBody?.details;
|
|
113
|
+
throw new ApiError(response.status, message, type, detail, errorBody?.props);
|
|
64
114
|
}
|
|
65
115
|
return response;
|
|
66
116
|
}
|
|
@@ -80,7 +130,8 @@ var LovableClient = class {
|
|
|
80
130
|
* Useful for validating an API key and discovering workspace IDs.
|
|
81
131
|
*/
|
|
82
132
|
async me() {
|
|
83
|
-
|
|
133
|
+
const { data } = await this.typed.GET("/v1/me");
|
|
134
|
+
return { ...data, workspaces: data.workspaces ?? [] };
|
|
84
135
|
}
|
|
85
136
|
/**
|
|
86
137
|
* List all workspaces the authenticated user has access to
|
|
@@ -130,9 +181,11 @@ var LovableClient = class {
|
|
|
130
181
|
}
|
|
131
182
|
const body = {
|
|
132
183
|
description: options.description,
|
|
133
|
-
visibility: options.visibility ?? "private",
|
|
134
184
|
template_project_id: options.templateProjectId
|
|
135
185
|
};
|
|
186
|
+
if (options.visibility) {
|
|
187
|
+
body.visibility = options.visibility;
|
|
188
|
+
}
|
|
136
189
|
if (options.techStack) {
|
|
137
190
|
body.tech_stack = options.techStack;
|
|
138
191
|
}
|
|
@@ -271,19 +324,6 @@ var LovableClient = class {
|
|
|
271
324
|
async queryDatabase(projectId, sql) {
|
|
272
325
|
return this.request("POST", `/v1/projects/${projectId}/database/query`, { sql });
|
|
273
326
|
}
|
|
274
|
-
/**
|
|
275
|
-
* Get database connection info for a project.
|
|
276
|
-
*
|
|
277
|
-
* Returns host, port, user, password, database name, and full connection string
|
|
278
|
-
* that can be used with any PostgreSQL client (psql, pgAdmin, etc.).
|
|
279
|
-
* The database must be enabled first (see enableDatabase).
|
|
280
|
-
*
|
|
281
|
-
* @param projectId - The project ID
|
|
282
|
-
* @returns Database connection details
|
|
283
|
-
*/
|
|
284
|
-
async getDatabaseConnectionInfo(projectId) {
|
|
285
|
-
return this.request("GET", `/v1/projects/${projectId}/database/connection-info`);
|
|
286
|
-
}
|
|
287
327
|
// ---------------------------------------------------------------------------
|
|
288
328
|
// Messages
|
|
289
329
|
// ---------------------------------------------------------------------------
|
|
@@ -294,6 +334,17 @@ var LovableClient = class {
|
|
|
294
334
|
async getMessage(projectId, messageId) {
|
|
295
335
|
return this.request("GET", `/v1/projects/${projectId}/messages/${messageId}`);
|
|
296
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* List recent messages in a project, newest first. Use `before` (a message ID
|
|
339
|
+
* from a prior page) to paginate backwards through history.
|
|
340
|
+
*/
|
|
341
|
+
async listMessages(projectId, params) {
|
|
342
|
+
const qs = new URLSearchParams();
|
|
343
|
+
if (params?.limit !== void 0) qs.set("limit", String(params.limit));
|
|
344
|
+
if (params?.before) qs.set("before", params.before);
|
|
345
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
346
|
+
return this.request("GET", `/v1/projects/${projectId}/messages${suffix}`);
|
|
347
|
+
}
|
|
297
348
|
/**
|
|
298
349
|
* Poll for message completion. Waits until the AI response reaches a terminal
|
|
299
350
|
* status (completed, stopped) or the timeout expires.
|
|
@@ -382,7 +433,10 @@ var LovableClient = class {
|
|
|
382
433
|
// ---------------------------------------------------------------------------
|
|
383
434
|
/** Get workspace knowledge (custom instructions for the AI agent). */
|
|
384
435
|
async getWorkspaceKnowledge(workspaceId) {
|
|
385
|
-
|
|
436
|
+
const { data } = await this.typed.GET("/v1/workspaces/{workspace_id}/knowledge", {
|
|
437
|
+
params: { path: { workspace_id: workspaceId } }
|
|
438
|
+
});
|
|
439
|
+
return data;
|
|
386
440
|
}
|
|
387
441
|
/** Set workspace knowledge. Max 10,000 characters. */
|
|
388
442
|
async setWorkspaceKnowledge(workspaceId, content) {
|
|
@@ -390,7 +444,10 @@ var LovableClient = class {
|
|
|
390
444
|
}
|
|
391
445
|
/** Get project knowledge (custom instructions for the AI agent). */
|
|
392
446
|
async getProjectKnowledge(projectId) {
|
|
393
|
-
|
|
447
|
+
const { data } = await this.typed.GET("/v1/projects/{project_id}/knowledge", {
|
|
448
|
+
params: { path: { project_id: projectId } }
|
|
449
|
+
});
|
|
450
|
+
return data;
|
|
394
451
|
}
|
|
395
452
|
/** Set project knowledge. Max 10,000 characters. */
|
|
396
453
|
async setProjectKnowledge(projectId, content) {
|
|
@@ -470,23 +527,26 @@ var LovableClient = class {
|
|
|
470
527
|
);
|
|
471
528
|
}
|
|
472
529
|
// ---------------------------------------------------------------------------
|
|
473
|
-
// MCP servers
|
|
530
|
+
// Connectors (MCP servers)
|
|
474
531
|
// ---------------------------------------------------------------------------
|
|
475
|
-
/** List all
|
|
476
|
-
async
|
|
477
|
-
return this.request("GET", `/v1/workspaces/${workspaceId}/
|
|
532
|
+
/** List all connectors in a workspace. */
|
|
533
|
+
async listConnectors(workspaceId) {
|
|
534
|
+
return this.request("GET", `/v1/workspaces/${workspaceId}/connectors`);
|
|
478
535
|
}
|
|
479
|
-
/** Add
|
|
480
|
-
async
|
|
481
|
-
return this.request("POST", `/v1/workspaces/${workspaceId}/
|
|
536
|
+
/** Add a connector to a workspace. The server URL is tested before saving. */
|
|
537
|
+
async addConnector(workspaceId, body) {
|
|
538
|
+
return this.request("POST", `/v1/workspaces/${workspaceId}/connectors`, body);
|
|
482
539
|
}
|
|
483
|
-
/** Remove
|
|
484
|
-
async
|
|
485
|
-
return this.request("DELETE", `/v1/workspaces/${workspaceId}/
|
|
540
|
+
/** Remove a connector from a workspace. */
|
|
541
|
+
async removeConnector(workspaceId, connectorId) {
|
|
542
|
+
return this.request("DELETE", `/v1/workspaces/${workspaceId}/connectors/${connectorId}`);
|
|
486
543
|
}
|
|
487
|
-
/** Browse available
|
|
488
|
-
async
|
|
489
|
-
return this.request(
|
|
544
|
+
/** Browse available connector templates. */
|
|
545
|
+
async listAvailableConnectors(workspaceId) {
|
|
546
|
+
return this.request(
|
|
547
|
+
"GET",
|
|
548
|
+
`/v1/workspaces/${workspaceId}/available-connectors`
|
|
549
|
+
);
|
|
490
550
|
}
|
|
491
551
|
// ---------------------------------------------------------------------------
|
|
492
552
|
// Connectors
|
|
@@ -574,8 +634,7 @@ var LovableClient = class {
|
|
|
574
634
|
include_custom_knowledge: options.includeCustomKnowledge,
|
|
575
635
|
project_name: options.projectName,
|
|
576
636
|
skip_initial_remix_message: options.skipInitialRemixMessage,
|
|
577
|
-
skip_integrations: options.skipIntegrations
|
|
578
|
-
include_agent_state: options.includeAgentState
|
|
637
|
+
skip_integrations: options.skipIntegrations
|
|
579
638
|
};
|
|
580
639
|
if (options.messageId) {
|
|
581
640
|
body.message_id = options.messageId;
|
|
@@ -589,7 +648,7 @@ var LovableClient = class {
|
|
|
589
648
|
headless: true
|
|
590
649
|
};
|
|
591
650
|
}
|
|
592
|
-
const response = await this.request("POST", `/projects/${sourceProjectId}/remix/init`, body);
|
|
651
|
+
const response = await this.request("POST", `/v1/projects/${sourceProjectId}/remix/init`, body);
|
|
593
652
|
return response.job_id;
|
|
594
653
|
}
|
|
595
654
|
/**
|
|
@@ -612,7 +671,7 @@ var LovableClient = class {
|
|
|
612
671
|
while (true) {
|
|
613
672
|
const progress = await this.request(
|
|
614
673
|
"GET",
|
|
615
|
-
`/projects/${sourceProjectId}/remix/progress?job_id=${encodeURIComponent(jobId)}`
|
|
674
|
+
`/v1/projects/${sourceProjectId}/remix/progress?job_id=${encodeURIComponent(jobId)}`
|
|
616
675
|
);
|
|
617
676
|
options?.onProgress?.(progress.status, progress.step);
|
|
618
677
|
if (progress.status === "completed" && progress.result) {
|