@lovable.dev/sdk 0.1.7 → 0.1.9
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 +2 -130
- package/dist/index.d.ts +14117 -21
- package/dist/index.js +128 -20
- package/dist/index.js.map +1 -1
- package/package.json +20 -12
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
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;
|
|
@@ -23,10 +26,29 @@ function normalizeBaseUrl(url) {
|
|
|
23
26
|
}
|
|
24
27
|
return normalized;
|
|
25
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
|
+
}
|
|
26
46
|
var LovableClient = class {
|
|
27
47
|
authHeaders;
|
|
28
48
|
baseUrl;
|
|
29
49
|
extraHeaders;
|
|
50
|
+
clientSource;
|
|
51
|
+
typedClient;
|
|
30
52
|
constructor(options) {
|
|
31
53
|
const hasApiKey = !!options.apiKey;
|
|
32
54
|
const hasBearerToken = !!options.bearerToken;
|
|
@@ -39,10 +61,33 @@ var LovableClient = class {
|
|
|
39
61
|
this.authHeaders = hasApiKey ? { "Lovable-API-Key": options.apiKey } : { Authorization: `Bearer ${options.bearerToken}` };
|
|
40
62
|
this.baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
41
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);
|
|
42
75
|
}
|
|
43
|
-
|
|
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) {
|
|
44
87
|
const url = `${this.baseUrl}${path}`;
|
|
45
88
|
const headers = {
|
|
89
|
+
"X-Client-Source": this.clientSource,
|
|
90
|
+
...init?.headers,
|
|
46
91
|
...this.authHeaders,
|
|
47
92
|
...this.extraHeaders,
|
|
48
93
|
Accept: "application/json"
|
|
@@ -53,7 +98,8 @@ var LovableClient = class {
|
|
|
53
98
|
const response = await fetch(url, {
|
|
54
99
|
method,
|
|
55
100
|
headers,
|
|
56
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
101
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
102
|
+
signal: init?.signal
|
|
57
103
|
});
|
|
58
104
|
if (!response.ok) {
|
|
59
105
|
let errorBody;
|
|
@@ -61,7 +107,7 @@ var LovableClient = class {
|
|
|
61
107
|
errorBody = await response.json();
|
|
62
108
|
} catch {
|
|
63
109
|
}
|
|
64
|
-
const message = errorBody
|
|
110
|
+
const message = buildErrorMessage(errorBody, response.status, response.statusText);
|
|
65
111
|
const type = errorBody?.type ?? errorBody?.title;
|
|
66
112
|
const detail = errorBody?.detail ?? errorBody?.details;
|
|
67
113
|
throw new ApiError(response.status, message, type, detail, errorBody?.props);
|
|
@@ -84,7 +130,8 @@ var LovableClient = class {
|
|
|
84
130
|
* Useful for validating an API key and discovering workspace IDs.
|
|
85
131
|
*/
|
|
86
132
|
async me() {
|
|
87
|
-
|
|
133
|
+
const { data } = await this.typed.GET("/v1/me");
|
|
134
|
+
return { ...data, workspaces: data.workspaces ?? [] };
|
|
88
135
|
}
|
|
89
136
|
/**
|
|
90
137
|
* List all workspaces the authenticated user has access to
|
|
@@ -134,9 +181,11 @@ var LovableClient = class {
|
|
|
134
181
|
}
|
|
135
182
|
const body = {
|
|
136
183
|
description: options.description,
|
|
137
|
-
visibility: options.visibility ?? "private",
|
|
138
184
|
template_project_id: options.templateProjectId
|
|
139
185
|
};
|
|
186
|
+
if (options.visibility) {
|
|
187
|
+
body.visibility = options.visibility;
|
|
188
|
+
}
|
|
140
189
|
if (options.techStack) {
|
|
141
190
|
body.tech_stack = options.techStack;
|
|
142
191
|
}
|
|
@@ -275,19 +324,6 @@ var LovableClient = class {
|
|
|
275
324
|
async queryDatabase(projectId, sql) {
|
|
276
325
|
return this.request("POST", `/v1/projects/${projectId}/database/query`, { sql });
|
|
277
326
|
}
|
|
278
|
-
/**
|
|
279
|
-
* Get database connection info for a project.
|
|
280
|
-
*
|
|
281
|
-
* Returns host, port, user, password, database name, and full connection string
|
|
282
|
-
* that can be used with any PostgreSQL client (psql, pgAdmin, etc.).
|
|
283
|
-
* The database must be enabled first (see enableDatabase).
|
|
284
|
-
*
|
|
285
|
-
* @param projectId - The project ID
|
|
286
|
-
* @returns Database connection details
|
|
287
|
-
*/
|
|
288
|
-
async getDatabaseConnectionInfo(projectId) {
|
|
289
|
-
return this.request("GET", `/v1/projects/${projectId}/database/connection-info`);
|
|
290
|
-
}
|
|
291
327
|
// ---------------------------------------------------------------------------
|
|
292
328
|
// Messages
|
|
293
329
|
// ---------------------------------------------------------------------------
|
|
@@ -298,6 +334,17 @@ var LovableClient = class {
|
|
|
298
334
|
async getMessage(projectId, messageId) {
|
|
299
335
|
return this.request("GET", `/v1/projects/${projectId}/messages/${messageId}`);
|
|
300
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
|
+
}
|
|
301
348
|
/**
|
|
302
349
|
* Poll for message completion. Waits until the AI response reaches a terminal
|
|
303
350
|
* status (completed, stopped) or the timeout expires.
|
|
@@ -386,15 +433,76 @@ var LovableClient = class {
|
|
|
386
433
|
// ---------------------------------------------------------------------------
|
|
387
434
|
/** Get workspace knowledge (custom instructions for the AI agent). */
|
|
388
435
|
async getWorkspaceKnowledge(workspaceId) {
|
|
389
|
-
|
|
436
|
+
const { data } = await this.typed.GET("/v1/workspaces/{workspace_id}/knowledge", {
|
|
437
|
+
params: { path: { workspace_id: workspaceId } }
|
|
438
|
+
});
|
|
439
|
+
return data;
|
|
390
440
|
}
|
|
391
441
|
/** Set workspace knowledge. Max 10,000 characters. */
|
|
392
442
|
async setWorkspaceKnowledge(workspaceId, content) {
|
|
393
443
|
return this.request("PUT", `/v1/workspaces/${workspaceId}/knowledge`, { content });
|
|
394
444
|
}
|
|
445
|
+
// ---------------------------------------------------------------------------
|
|
446
|
+
// Workspace skills
|
|
447
|
+
// ---------------------------------------------------------------------------
|
|
448
|
+
/** List workspace skills. */
|
|
449
|
+
async listWorkspaceSkills(workspaceId, options) {
|
|
450
|
+
const qs = new URLSearchParams();
|
|
451
|
+
if (options?.includeMarkdown) qs.set("include_markdown", "true");
|
|
452
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
453
|
+
return this.request("GET", `/v1/workspaces/${workspaceId}/skills${suffix}`);
|
|
454
|
+
}
|
|
455
|
+
/** Get a single workspace skill, including SKILL.md contents. */
|
|
456
|
+
async getWorkspaceSkill(workspaceId, skillName) {
|
|
457
|
+
return this.request(
|
|
458
|
+
"GET",
|
|
459
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(skillName)}`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
/** Create a workspace skill from full SKILL.md markdown. */
|
|
463
|
+
async createWorkspaceSkill(workspaceId, skillName, markdown) {
|
|
464
|
+
return this.request(
|
|
465
|
+
"POST",
|
|
466
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(skillName)}`,
|
|
467
|
+
{ markdown }
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
/** Update a workspace skill by replacing its SKILL.md markdown. */
|
|
471
|
+
async updateWorkspaceSkill(workspaceId, skillName, markdown) {
|
|
472
|
+
return this.request(
|
|
473
|
+
"PUT",
|
|
474
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(skillName)}`,
|
|
475
|
+
{ markdown }
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
/** Delete a workspace skill. */
|
|
479
|
+
async deleteWorkspaceSkill(workspaceId, skillName) {
|
|
480
|
+
return this.request(
|
|
481
|
+
"DELETE",
|
|
482
|
+
`/v1/workspaces/${workspaceId}/skills/${encodeURIComponent(skillName)}`
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
// ---------------------------------------------------------------------------
|
|
486
|
+
// Project skills
|
|
487
|
+
// ---------------------------------------------------------------------------
|
|
488
|
+
/** List project skills, including whether each skill is enabled. */
|
|
489
|
+
async listProjectSkills(projectId) {
|
|
490
|
+
return this.request("GET", `/v1/projects/${projectId}/skills`);
|
|
491
|
+
}
|
|
492
|
+
/** Enable or disable a project skill without removing it from the project repo. */
|
|
493
|
+
async setProjectSkillEnabled(projectId, skillName, enabled) {
|
|
494
|
+
return this.request(
|
|
495
|
+
"PUT",
|
|
496
|
+
`/v1/projects/${projectId}/skills/${encodeURIComponent(skillName)}/enabled`,
|
|
497
|
+
{ enabled }
|
|
498
|
+
);
|
|
499
|
+
}
|
|
395
500
|
/** Get project knowledge (custom instructions for the AI agent). */
|
|
396
501
|
async getProjectKnowledge(projectId) {
|
|
397
|
-
|
|
502
|
+
const { data } = await this.typed.GET("/v1/projects/{project_id}/knowledge", {
|
|
503
|
+
params: { path: { project_id: projectId } }
|
|
504
|
+
});
|
|
505
|
+
return data;
|
|
398
506
|
}
|
|
399
507
|
/** Set project knowledge. Max 10,000 characters. */
|
|
400
508
|
async setProjectKnowledge(projectId, content) {
|