@stack0/sdk 0.3.0 → 0.3.1
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 +33 -10
- package/dist/cdn/index.d.mts +56 -26
- package/dist/cdn/index.d.ts +56 -26
- package/dist/cdn/index.js +84 -23
- package/dist/cdn/index.js.map +1 -1
- package/dist/cdn/index.mjs +84 -23
- package/dist/cdn/index.mjs.map +1 -1
- package/dist/extraction/index.d.mts +1 -1
- package/dist/extraction/index.d.ts +1 -1
- package/dist/extraction/index.js +33 -29
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/index.mjs +33 -29
- package/dist/extraction/index.mjs.map +1 -1
- package/dist/{http-client-DjrRWvXA.d.mts → http-client-Cgie_Rv6.d.mts} +1 -0
- package/dist/{http-client-DjrRWvXA.d.ts → http-client-Cgie_Rv6.d.ts} +1 -0
- package/dist/index.d.mts +475 -3
- package/dist/index.d.ts +475 -3
- package/dist/index.js +512 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +512 -73
- package/dist/index.mjs.map +1 -1
- package/dist/mail/index.d.mts +1 -1
- package/dist/mail/index.d.ts +1 -1
- package/dist/mail/index.js +13 -5
- package/dist/mail/index.js.map +1 -1
- package/dist/mail/index.mjs +13 -5
- package/dist/mail/index.mjs.map +1 -1
- package/dist/screenshots/index.d.mts +1 -1
- package/dist/screenshots/index.d.ts +1 -1
- package/dist/screenshots/index.js +32 -26
- package/dist/screenshots/index.js.map +1 -1
- package/dist/screenshots/index.mjs +32 -26
- package/dist/screenshots/index.mjs.map +1 -1
- package/dist/webdata/index.d.mts +1 -1
- package/dist/webdata/index.d.ts +1 -1
- package/dist/webdata/index.js +37 -8
- package/dist/webdata/index.js.map +1 -1
- package/dist/webdata/index.mjs +37 -8
- package/dist/webdata/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/mail/index.d.mts
CHANGED
package/dist/mail/index.d.ts
CHANGED
package/dist/mail/index.js
CHANGED
|
@@ -8,19 +8,24 @@ var HttpClient = class {
|
|
|
8
8
|
this.apiKey = config.apiKey;
|
|
9
9
|
this.baseUrl = config.baseUrl || "https://api.stack0.dev/v1";
|
|
10
10
|
}
|
|
11
|
-
getHeaders() {
|
|
12
|
-
|
|
13
|
-
"Content-Type": "application/json",
|
|
11
|
+
getHeaders(includeContentType = true) {
|
|
12
|
+
const headers = {
|
|
14
13
|
Authorization: `Bearer ${this.apiKey}`
|
|
15
14
|
};
|
|
15
|
+
if (includeContentType) {
|
|
16
|
+
headers["Content-Type"] = "application/json";
|
|
17
|
+
}
|
|
18
|
+
return headers;
|
|
16
19
|
}
|
|
17
20
|
async request(method, path, body) {
|
|
18
21
|
const url = `${this.baseUrl}${path}`;
|
|
22
|
+
const bodyString = body === void 0 ? void 0 : JSON.stringify(body);
|
|
23
|
+
const hasBody = bodyString !== void 0;
|
|
19
24
|
try {
|
|
20
25
|
const response = await fetch(url, {
|
|
21
26
|
method,
|
|
22
|
-
headers: this.getHeaders(),
|
|
23
|
-
body:
|
|
27
|
+
headers: this.getHeaders(hasBody),
|
|
28
|
+
body: hasBody ? bodyString : void 0
|
|
24
29
|
});
|
|
25
30
|
if (!response.ok) {
|
|
26
31
|
await this.handleErrorResponse(response);
|
|
@@ -64,6 +69,9 @@ var HttpClient = class {
|
|
|
64
69
|
async delete(path) {
|
|
65
70
|
return this.request("DELETE", path);
|
|
66
71
|
}
|
|
72
|
+
async deleteWithBody(path, body) {
|
|
73
|
+
return this.request("DELETE", path, body);
|
|
74
|
+
}
|
|
67
75
|
async patch(path, body) {
|
|
68
76
|
return this.request("PATCH", path, body);
|
|
69
77
|
}
|
package/dist/mail/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":";;;AAUO,IAAM,aAAN,MAAiB;AAAA,EACd,MAAA;AAAA,EACA,OAAA;AAAA,EAER,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,2BAAA;AAAA,EACnC;AAAA,EAEQ,UAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 Mail Client\n * API compatible with Resend for easy migration\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type { SendEmailRequest, SendEmailResponse, GetEmailResponse } from \"./types\";\n\nexport class Mail {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n /**\n * Send an email\n *\n * @example\n * ```typescript\n * const result = await mail.send({\n * from: 'noreply@example.com',\n * to: 'user@example.com',\n * subject: 'Hello World',\n * html: '<p>Welcome!</p>',\n * });\n * ```\n */\n async send(request: SendEmailRequest): Promise<SendEmailResponse> {\n const response = await this.http.post<SendEmailResponse>(\"/mail/send\", request);\n\n // Convert date strings to Date objects if needed\n if (typeof response.createdAt === \"string\") {\n response.createdAt = new Date(response.createdAt);\n }\n\n return response;\n }\n\n /**\n * Get email details by ID\n *\n * @example\n * ```typescript\n * const email = await mail.get('email-id');\n * console.log(email.status); // 'delivered'\n * ```\n */\n async get(id: string): Promise<GetEmailResponse> {\n const response = await this.http.get<GetEmailResponse>(`/mail/${id}`);\n\n // Convert date strings to Date objects\n const dateFields = [\"createdAt\", \"sentAt\", \"deliveredAt\", \"openedAt\", \"clickedAt\", \"bouncedAt\"] as const;\n\n for (const field of dateFields) {\n if (response[field] && typeof response[field] === \"string\") {\n (response[field] as unknown as Date) = new Date(response[field] as string);\n }\n }\n\n return response;\n }\n}\n"]}
|
package/dist/mail/index.mjs
CHANGED
|
@@ -6,19 +6,24 @@ var HttpClient = class {
|
|
|
6
6
|
this.apiKey = config.apiKey;
|
|
7
7
|
this.baseUrl = config.baseUrl || "https://api.stack0.dev/v1";
|
|
8
8
|
}
|
|
9
|
-
getHeaders() {
|
|
10
|
-
|
|
11
|
-
"Content-Type": "application/json",
|
|
9
|
+
getHeaders(includeContentType = true) {
|
|
10
|
+
const headers = {
|
|
12
11
|
Authorization: `Bearer ${this.apiKey}`
|
|
13
12
|
};
|
|
13
|
+
if (includeContentType) {
|
|
14
|
+
headers["Content-Type"] = "application/json";
|
|
15
|
+
}
|
|
16
|
+
return headers;
|
|
14
17
|
}
|
|
15
18
|
async request(method, path, body) {
|
|
16
19
|
const url = `${this.baseUrl}${path}`;
|
|
20
|
+
const bodyString = body === void 0 ? void 0 : JSON.stringify(body);
|
|
21
|
+
const hasBody = bodyString !== void 0;
|
|
17
22
|
try {
|
|
18
23
|
const response = await fetch(url, {
|
|
19
24
|
method,
|
|
20
|
-
headers: this.getHeaders(),
|
|
21
|
-
body:
|
|
25
|
+
headers: this.getHeaders(hasBody),
|
|
26
|
+
body: hasBody ? bodyString : void 0
|
|
22
27
|
});
|
|
23
28
|
if (!response.ok) {
|
|
24
29
|
await this.handleErrorResponse(response);
|
|
@@ -62,6 +67,9 @@ var HttpClient = class {
|
|
|
62
67
|
async delete(path) {
|
|
63
68
|
return this.request("DELETE", path);
|
|
64
69
|
}
|
|
70
|
+
async deleteWithBody(path, body) {
|
|
71
|
+
return this.request("DELETE", path, body);
|
|
72
|
+
}
|
|
65
73
|
async patch(path, body) {
|
|
66
74
|
return this.request("PATCH", path, body);
|
|
67
75
|
}
|
package/dist/mail/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":";AAUO,IAAM,aAAN,MAAiB;AAAA,EACd,MAAA;AAAA,EACA,OAAA;AAAA,EAER,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,2BAAA;AAAA,EACnC;AAAA,EAEQ,UAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 Mail Client\n * API compatible with Resend for easy migration\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type { SendEmailRequest, SendEmailResponse, GetEmailResponse } from \"./types\";\n\nexport class Mail {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n /**\n * Send an email\n *\n * @example\n * ```typescript\n * const result = await mail.send({\n * from: 'noreply@example.com',\n * to: 'user@example.com',\n * subject: 'Hello World',\n * html: '<p>Welcome!</p>',\n * });\n * ```\n */\n async send(request: SendEmailRequest): Promise<SendEmailResponse> {\n const response = await this.http.post<SendEmailResponse>(\"/mail/send\", request);\n\n // Convert date strings to Date objects if needed\n if (typeof response.createdAt === \"string\") {\n response.createdAt = new Date(response.createdAt);\n }\n\n return response;\n }\n\n /**\n * Get email details by ID\n *\n * @example\n * ```typescript\n * const email = await mail.get('email-id');\n * console.log(email.status); // 'delivered'\n * ```\n */\n async get(id: string): Promise<GetEmailResponse> {\n const response = await this.http.get<GetEmailResponse>(`/mail/${id}`);\n\n // Convert date strings to Date objects\n const dateFields = [\"createdAt\", \"sentAt\", \"deliveredAt\", \"openedAt\", \"clickedAt\", \"bouncedAt\"] as const;\n\n for (const field of dateFields) {\n if (response[field] && typeof response[field] === \"string\") {\n (response[field] as unknown as Date) = new Date(response[field] as string);\n }\n }\n\n return response;\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as HttpClientConfig } from '../http-client-
|
|
1
|
+
import { a as HttpClientConfig } from '../http-client-Cgie_Rv6.mjs';
|
|
2
2
|
import { E as Environment, B as BatchJobStatus, S as ScheduleFrequency, C as CreateBatchResponse, G as GetBatchJobRequest, L as ListBatchJobsRequest, c as CreateScheduleResponse, a as GetScheduleRequest, b as ListSchedulesRequest } from '../shared-types-B0PyC7cF.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as HttpClientConfig } from '../http-client-
|
|
1
|
+
import { a as HttpClientConfig } from '../http-client-Cgie_Rv6.js';
|
|
2
2
|
import { E as Environment, B as BatchJobStatus, S as ScheduleFrequency, C as CreateBatchResponse, G as GetBatchJobRequest, L as ListBatchJobsRequest, c as CreateScheduleResponse, a as GetScheduleRequest, b as ListSchedulesRequest } from '../shared-types-B0PyC7cF.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -8,19 +8,24 @@ var HttpClient = class {
|
|
|
8
8
|
this.apiKey = config.apiKey;
|
|
9
9
|
this.baseUrl = config.baseUrl || "https://api.stack0.dev/v1";
|
|
10
10
|
}
|
|
11
|
-
getHeaders() {
|
|
12
|
-
|
|
13
|
-
"Content-Type": "application/json",
|
|
11
|
+
getHeaders(includeContentType = true) {
|
|
12
|
+
const headers = {
|
|
14
13
|
Authorization: `Bearer ${this.apiKey}`
|
|
15
14
|
};
|
|
15
|
+
if (includeContentType) {
|
|
16
|
+
headers["Content-Type"] = "application/json";
|
|
17
|
+
}
|
|
18
|
+
return headers;
|
|
16
19
|
}
|
|
17
20
|
async request(method, path, body) {
|
|
18
21
|
const url = `${this.baseUrl}${path}`;
|
|
22
|
+
const bodyString = body === void 0 ? void 0 : JSON.stringify(body);
|
|
23
|
+
const hasBody = bodyString !== void 0;
|
|
19
24
|
try {
|
|
20
25
|
const response = await fetch(url, {
|
|
21
26
|
method,
|
|
22
|
-
headers: this.getHeaders(),
|
|
23
|
-
body:
|
|
27
|
+
headers: this.getHeaders(hasBody),
|
|
28
|
+
body: hasBody ? bodyString : void 0
|
|
24
29
|
});
|
|
25
30
|
if (!response.ok) {
|
|
26
31
|
await this.handleErrorResponse(response);
|
|
@@ -64,6 +69,9 @@ var HttpClient = class {
|
|
|
64
69
|
async delete(path) {
|
|
65
70
|
return this.request("DELETE", path);
|
|
66
71
|
}
|
|
72
|
+
async deleteWithBody(path, body) {
|
|
73
|
+
return this.request("DELETE", path, body);
|
|
74
|
+
}
|
|
67
75
|
async patch(path, body) {
|
|
68
76
|
return this.request("PATCH", path, body);
|
|
69
77
|
}
|
|
@@ -138,9 +146,7 @@ var Screenshots = class {
|
|
|
138
146
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
139
147
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
140
148
|
const query = params.toString();
|
|
141
|
-
const response = await this.http.get(
|
|
142
|
-
`/webdata/screenshots${query ? `?${query}` : ""}`
|
|
143
|
-
);
|
|
149
|
+
const response = await this.http.get(`/webdata/screenshots${query ? `?${query}` : ""}`);
|
|
144
150
|
return {
|
|
145
151
|
...response,
|
|
146
152
|
items: response.items.map((item) => this.convertDates(item))
|
|
@@ -159,8 +165,13 @@ var Screenshots = class {
|
|
|
159
165
|
if (request.environment) params.set("environment", request.environment);
|
|
160
166
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
161
167
|
const query = params.toString();
|
|
162
|
-
return this.http.
|
|
163
|
-
`/webdata/screenshots/${request.id}${query ? `?${query}` : ""}
|
|
168
|
+
return this.http.deleteWithBody(
|
|
169
|
+
`/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`,
|
|
170
|
+
{
|
|
171
|
+
id: request.id,
|
|
172
|
+
environment: request.environment,
|
|
173
|
+
projectId: request.projectId
|
|
174
|
+
}
|
|
164
175
|
);
|
|
165
176
|
}
|
|
166
177
|
/**
|
|
@@ -243,9 +254,7 @@ var Screenshots = class {
|
|
|
243
254
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
244
255
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
245
256
|
const query = params.toString();
|
|
246
|
-
const response = await this.http.get(
|
|
247
|
-
`/webdata/batch${query ? `?${query}` : ""}`
|
|
248
|
-
);
|
|
257
|
+
const response = await this.http.get(`/webdata/batch${query ? `?${query}` : ""}`);
|
|
249
258
|
return {
|
|
250
259
|
...response,
|
|
251
260
|
items: response.items.map((item) => this.convertBatchJobDates(item))
|
|
@@ -259,10 +268,7 @@ var Screenshots = class {
|
|
|
259
268
|
if (request.environment) params.set("environment", request.environment);
|
|
260
269
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
261
270
|
const query = params.toString();
|
|
262
|
-
return this.http.post(
|
|
263
|
-
`/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`,
|
|
264
|
-
{}
|
|
265
|
-
);
|
|
271
|
+
return this.http.post(`/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`, {});
|
|
266
272
|
}
|
|
267
273
|
/**
|
|
268
274
|
* Create a batch screenshot job and wait for completion
|
|
@@ -315,10 +321,7 @@ var Screenshots = class {
|
|
|
315
321
|
if (environment) params.set("environment", environment);
|
|
316
322
|
if (projectId) params.set("projectId", projectId);
|
|
317
323
|
const query = params.toString();
|
|
318
|
-
return this.http.post(
|
|
319
|
-
`/webdata/schedules/${id}${query ? `?${query}` : ""}`,
|
|
320
|
-
data
|
|
321
|
-
);
|
|
324
|
+
return this.http.post(`/webdata/schedules/${id}${query ? `?${query}` : ""}`, data);
|
|
322
325
|
}
|
|
323
326
|
/**
|
|
324
327
|
* Get a schedule by ID
|
|
@@ -344,9 +347,7 @@ var Screenshots = class {
|
|
|
344
347
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
345
348
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
346
349
|
const query = params.toString();
|
|
347
|
-
const response = await this.http.get(
|
|
348
|
-
`/webdata/schedules${query ? `?${query}` : ""}`
|
|
349
|
-
);
|
|
350
|
+
const response = await this.http.get(`/webdata/schedules${query ? `?${query}` : ""}`);
|
|
350
351
|
return {
|
|
351
352
|
...response,
|
|
352
353
|
items: response.items.map((item) => this.convertScheduleDates(item))
|
|
@@ -360,8 +361,13 @@ var Screenshots = class {
|
|
|
360
361
|
if (request.environment) params.set("environment", request.environment);
|
|
361
362
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
362
363
|
const query = params.toString();
|
|
363
|
-
return this.http.
|
|
364
|
-
`/webdata/schedules/${request.id}${query ? `?${query}` : ""}
|
|
364
|
+
return this.http.deleteWithBody(
|
|
365
|
+
`/webdata/schedules/${request.id}${query ? `?${query}` : ""}`,
|
|
366
|
+
{
|
|
367
|
+
id: request.id,
|
|
368
|
+
environment: request.environment,
|
|
369
|
+
projectId: request.projectId
|
|
370
|
+
}
|
|
365
371
|
);
|
|
366
372
|
}
|
|
367
373
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/screenshots/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 Screenshots Client\n * Capture high-quality screenshots of any webpage\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n CreateBatchResponse,\n GetBatchJobRequest,\n ListBatchJobsRequest,\n CreateScheduleResponse,\n GetScheduleRequest,\n ListSchedulesRequest,\n} from \"../lib/shared-types\";\nimport type {\n Screenshot,\n CreateScreenshotRequest,\n CreateScreenshotResponse,\n GetScreenshotRequest,\n ListScreenshotsRequest,\n ListScreenshotsResponse,\n BatchScreenshotJob,\n CreateBatchScreenshotsRequest,\n ScreenshotBatchJobsResponse,\n ScreenshotSchedule,\n CreateScreenshotScheduleRequest,\n UpdateScreenshotScheduleRequest,\n ScreenshotSchedulesResponse,\n} from \"./types\";\n\nexport class Screenshots {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n // ==========================================================================\n // SCREENSHOTS\n // ==========================================================================\n\n /**\n * Capture a screenshot of a URL\n *\n * @example\n * ```typescript\n * const { id, status } = await screenshots.capture({\n * url: 'https://example.com',\n * format: 'png',\n * fullPage: true,\n * deviceType: 'desktop',\n * });\n *\n * // Poll for completion\n * const screenshot = await screenshots.get({ id });\n * console.log(screenshot.imageUrl);\n * ```\n */\n async capture(request: CreateScreenshotRequest): Promise<CreateScreenshotResponse> {\n return this.http.post<CreateScreenshotResponse>(\"/webdata/screenshots\", request);\n }\n\n /**\n * Get a screenshot by ID\n *\n * @example\n * ```typescript\n * const screenshot = await screenshots.get({ id: 'screenshot-id' });\n * if (screenshot.status === 'completed') {\n * console.log(screenshot.imageUrl);\n * }\n * ```\n */\n async get(request: GetScreenshotRequest): Promise<Screenshot> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/screenshots/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<Screenshot>(path);\n return this.convertDates(response);\n }\n\n /**\n * List screenshots with pagination and filters\n *\n * @example\n * ```typescript\n * const { items, nextCursor } = await screenshots.list({\n * status: 'completed',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListScreenshotsRequest = {}): Promise<ListScreenshotsResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n if (request.status) params.set(\"status\", request.status);\n if (request.url) params.set(\"url\", request.url);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ListScreenshotsResponse>(\n `/webdata/screenshots${query ? `?${query}` : \"\"}`\n );\n\n return {\n ...response,\n items: response.items.map((item) => this.convertDates(item)),\n };\n }\n\n /**\n * Delete a screenshot\n *\n * @example\n * ```typescript\n * await screenshots.delete({ id: 'screenshot-id' });\n * ```\n */\n async delete(request: GetScreenshotRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.delete<{ success: boolean }>(\n `/webdata/screenshots/${request.id}${query ? `?${query}` : \"\"}`\n );\n }\n\n /**\n * Capture a screenshot and wait for completion\n *\n * @example\n * ```typescript\n * const screenshot = await screenshots.captureAndWait({\n * url: 'https://example.com',\n * format: 'png',\n * });\n * console.log(screenshot.imageUrl);\n * ```\n */\n async captureAndWait(\n request: CreateScreenshotRequest,\n options: { pollInterval?: number; timeout?: number } = {}\n ): Promise<Screenshot> {\n const { pollInterval = 1000, timeout = 60000 } = options;\n const startTime = Date.now();\n\n const { id } = await this.capture(request);\n\n while (Date.now() - startTime < timeout) {\n const screenshot = await this.get({\n id,\n environment: request.environment,\n projectId: request.projectId,\n });\n\n if (screenshot.status === \"completed\" || screenshot.status === \"failed\") {\n if (screenshot.status === \"failed\") {\n throw new Error(screenshot.error || \"Screenshot failed\");\n }\n return screenshot;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(\"Screenshot timed out\");\n }\n\n // ==========================================================================\n // BATCH JOBS\n // ==========================================================================\n\n /**\n * Create a batch screenshot job for multiple URLs\n *\n * @example\n * ```typescript\n * const { id, totalUrls } = await screenshots.batch({\n * urls: [\n * 'https://example.com',\n * 'https://example.org',\n * ],\n * config: { format: 'png', fullPage: true },\n * });\n *\n * // Poll for completion\n * const job = await screenshots.getBatchJob({ id });\n * console.log(`Progress: ${job.processedUrls}/${job.totalUrls}`);\n * ```\n */\n async batch(request: CreateBatchScreenshotsRequest): Promise<CreateBatchResponse> {\n return this.http.post<CreateBatchResponse>(\"/webdata/batch/screenshots\", request);\n }\n\n /**\n * Get a batch job by ID\n */\n async getBatchJob(request: GetBatchJobRequest): Promise<BatchScreenshotJob> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/batch/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<BatchScreenshotJob>(path);\n return this.convertBatchJobDates(response);\n }\n\n /**\n * List batch jobs with pagination and filters\n */\n async listBatchJobs(request: ListBatchJobsRequest = {}): Promise<ScreenshotBatchJobsResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n if (request.status) params.set(\"status\", request.status);\n params.set(\"type\", \"screenshot\");\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ScreenshotBatchJobsResponse>(\n `/webdata/batch${query ? `?${query}` : \"\"}`\n );\n\n return {\n ...response,\n items: response.items.map((item) => this.convertBatchJobDates(item)),\n };\n }\n\n /**\n * Cancel a batch job\n */\n async cancelBatchJob(request: GetBatchJobRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.post<{ success: boolean }>(\n `/webdata/batch/${request.id}/cancel${query ? `?${query}` : \"\"}`,\n {}\n );\n }\n\n /**\n * Create a batch screenshot job and wait for completion\n */\n async batchAndWait(\n request: CreateBatchScreenshotsRequest,\n options: { pollInterval?: number; timeout?: number } = {}\n ): Promise<BatchScreenshotJob> {\n const { pollInterval = 2000, timeout = 300000 } = options;\n const startTime = Date.now();\n\n const { id } = await this.batch(request);\n\n while (Date.now() - startTime < timeout) {\n const job = await this.getBatchJob({\n id,\n environment: request.environment,\n projectId: request.projectId,\n });\n\n if (job.status === \"completed\" || job.status === \"failed\" || job.status === \"cancelled\") {\n return job;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(\"Batch job timed out\");\n }\n\n // ==========================================================================\n // SCHEDULES\n // ==========================================================================\n\n /**\n * Create a scheduled screenshot job\n *\n * @example\n * ```typescript\n * const { id } = await screenshots.createSchedule({\n * name: 'Daily homepage screenshot',\n * url: 'https://example.com',\n * frequency: 'daily',\n * config: { format: 'png', fullPage: true },\n * });\n * ```\n */\n async createSchedule(request: CreateScreenshotScheduleRequest): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>(\"/webdata/schedules\", {\n ...request,\n type: \"screenshot\",\n });\n }\n\n /**\n * Update a schedule\n */\n async updateSchedule(request: UpdateScreenshotScheduleRequest): Promise<{ success: boolean }> {\n const { id, environment, projectId, ...data } = request;\n\n const params = new URLSearchParams();\n if (environment) params.set(\"environment\", environment);\n if (projectId) params.set(\"projectId\", projectId);\n\n const query = params.toString();\n return this.http.post<{ success: boolean }>(\n `/webdata/schedules/${id}${query ? `?${query}` : \"\"}`,\n data\n );\n }\n\n /**\n * Get a schedule by ID\n */\n async getSchedule(request: GetScheduleRequest): Promise<ScreenshotSchedule> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/schedules/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<ScreenshotSchedule>(path);\n return this.convertScheduleDates(response);\n }\n\n /**\n * List schedules with pagination and filters\n */\n async listSchedules(request: ListSchedulesRequest = {}): Promise<ScreenshotSchedulesResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n params.set(\"type\", \"screenshot\");\n if (request.isActive !== undefined) params.set(\"isActive\", request.isActive.toString());\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ScreenshotSchedulesResponse>(\n `/webdata/schedules${query ? `?${query}` : \"\"}`\n );\n\n return {\n ...response,\n items: response.items.map((item) => this.convertScheduleDates(item)),\n };\n }\n\n /**\n * Delete a schedule\n */\n async deleteSchedule(request: GetScheduleRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.delete<{ success: boolean }>(\n `/webdata/schedules/${request.id}${query ? `?${query}` : \"\"}`\n );\n }\n\n /**\n * Toggle a schedule on or off\n */\n async toggleSchedule(request: GetScheduleRequest): Promise<{ isActive: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.post<{ isActive: boolean }>(\n `/webdata/schedules/${request.id}/toggle${query ? `?${query}` : \"\"}`,\n {}\n );\n }\n\n // ==========================================================================\n // HELPERS\n // ==========================================================================\n\n private convertDates(screenshot: Screenshot): Screenshot {\n if (typeof screenshot.createdAt === \"string\") {\n screenshot.createdAt = new Date(screenshot.createdAt);\n }\n if (screenshot.completedAt && typeof screenshot.completedAt === \"string\") {\n screenshot.completedAt = new Date(screenshot.completedAt);\n }\n return screenshot;\n }\n\n private convertBatchJobDates(job: BatchScreenshotJob): BatchScreenshotJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n\n private convertScheduleDates(schedule: ScreenshotSchedule): ScreenshotSchedule {\n if (typeof schedule.createdAt === \"string\") {\n schedule.createdAt = new Date(schedule.createdAt);\n }\n if (typeof schedule.updatedAt === \"string\") {\n schedule.updatedAt = new Date(schedule.updatedAt);\n }\n if (schedule.lastRunAt && typeof schedule.lastRunAt === \"string\") {\n schedule.lastRunAt = new Date(schedule.lastRunAt);\n }\n if (schedule.nextRunAt && typeof schedule.nextRunAt === \"string\") {\n schedule.nextRunAt = new Date(schedule.nextRunAt);\n }\n return schedule;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/screenshots/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.dev/v1\";\n }\n\n private getHeaders(includeContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (includeContentType) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n return headers;\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const bodyString = body === undefined ? undefined : JSON.stringify(body);\n const hasBody = bodyString !== undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(hasBody),\n body: hasBody ? bodyString : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n\n async deleteWithBody<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"DELETE\", path, body);\n }\n\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PATCH\", path, body);\n }\n}\n","/**\n * Stack0 Screenshots Client\n * Capture high-quality screenshots of any webpage\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type {\n CreateBatchResponse,\n GetBatchJobRequest,\n ListBatchJobsRequest,\n CreateScheduleResponse,\n GetScheduleRequest,\n ListSchedulesRequest,\n} from \"../lib/shared-types\";\nimport type {\n Screenshot,\n CreateScreenshotRequest,\n CreateScreenshotResponse,\n GetScreenshotRequest,\n ListScreenshotsRequest,\n ListScreenshotsResponse,\n BatchScreenshotJob,\n CreateBatchScreenshotsRequest,\n ScreenshotBatchJobsResponse,\n ScreenshotSchedule,\n CreateScreenshotScheduleRequest,\n UpdateScreenshotScheduleRequest,\n ScreenshotSchedulesResponse,\n} from \"./types\";\n\nexport class Screenshots {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n // ==========================================================================\n // SCREENSHOTS\n // ==========================================================================\n\n /**\n * Capture a screenshot of a URL\n *\n * @example\n * ```typescript\n * const { id, status } = await screenshots.capture({\n * url: 'https://example.com',\n * format: 'png',\n * fullPage: true,\n * deviceType: 'desktop',\n * });\n *\n * // Poll for completion\n * const screenshot = await screenshots.get({ id });\n * console.log(screenshot.imageUrl);\n * ```\n */\n async capture(request: CreateScreenshotRequest): Promise<CreateScreenshotResponse> {\n return this.http.post<CreateScreenshotResponse>(\"/webdata/screenshots\", request);\n }\n\n /**\n * Get a screenshot by ID\n *\n * @example\n * ```typescript\n * const screenshot = await screenshots.get({ id: 'screenshot-id' });\n * if (screenshot.status === 'completed') {\n * console.log(screenshot.imageUrl);\n * }\n * ```\n */\n async get(request: GetScreenshotRequest): Promise<Screenshot> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/screenshots/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<Screenshot>(path);\n return this.convertDates(response);\n }\n\n /**\n * List screenshots with pagination and filters\n *\n * @example\n * ```typescript\n * const { items, nextCursor } = await screenshots.list({\n * status: 'completed',\n * limit: 20,\n * });\n * ```\n */\n async list(request: ListScreenshotsRequest = {}): Promise<ListScreenshotsResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n if (request.status) params.set(\"status\", request.status);\n if (request.url) params.set(\"url\", request.url);\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ListScreenshotsResponse>(`/webdata/screenshots${query ? `?${query}` : \"\"}`);\n\n return {\n ...response,\n items: response.items.map((item) => this.convertDates(item)),\n };\n }\n\n /**\n * Delete a screenshot\n *\n * @example\n * ```typescript\n * await screenshots.delete({ id: 'screenshot-id' });\n * ```\n */\n async delete(request: GetScreenshotRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.deleteWithBody<{ success: boolean }>(\n `/webdata/screenshots/${request.id}${query ? `?${query}` : \"\"}`,\n {\n id: request.id,\n environment: request.environment,\n projectId: request.projectId,\n },\n );\n }\n\n /**\n * Capture a screenshot and wait for completion\n *\n * @example\n * ```typescript\n * const screenshot = await screenshots.captureAndWait({\n * url: 'https://example.com',\n * format: 'png',\n * });\n * console.log(screenshot.imageUrl);\n * ```\n */\n async captureAndWait(\n request: CreateScreenshotRequest,\n options: { pollInterval?: number; timeout?: number } = {},\n ): Promise<Screenshot> {\n const { pollInterval = 1000, timeout = 60000 } = options;\n const startTime = Date.now();\n\n const { id } = await this.capture(request);\n\n while (Date.now() - startTime < timeout) {\n const screenshot = await this.get({\n id,\n environment: request.environment,\n projectId: request.projectId,\n });\n\n if (screenshot.status === \"completed\" || screenshot.status === \"failed\") {\n if (screenshot.status === \"failed\") {\n throw new Error(screenshot.error || \"Screenshot failed\");\n }\n return screenshot;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(\"Screenshot timed out\");\n }\n\n // ==========================================================================\n // BATCH JOBS\n // ==========================================================================\n\n /**\n * Create a batch screenshot job for multiple URLs\n *\n * @example\n * ```typescript\n * const { id, totalUrls } = await screenshots.batch({\n * urls: [\n * 'https://example.com',\n * 'https://example.org',\n * ],\n * config: { format: 'png', fullPage: true },\n * });\n *\n * // Poll for completion\n * const job = await screenshots.getBatchJob({ id });\n * console.log(`Progress: ${job.processedUrls}/${job.totalUrls}`);\n * ```\n */\n async batch(request: CreateBatchScreenshotsRequest): Promise<CreateBatchResponse> {\n return this.http.post<CreateBatchResponse>(\"/webdata/batch/screenshots\", request);\n }\n\n /**\n * Get a batch job by ID\n */\n async getBatchJob(request: GetBatchJobRequest): Promise<BatchScreenshotJob> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/batch/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<BatchScreenshotJob>(path);\n return this.convertBatchJobDates(response);\n }\n\n /**\n * List batch jobs with pagination and filters\n */\n async listBatchJobs(request: ListBatchJobsRequest = {}): Promise<ScreenshotBatchJobsResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n if (request.status) params.set(\"status\", request.status);\n params.set(\"type\", \"screenshot\");\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ScreenshotBatchJobsResponse>(`/webdata/batch${query ? `?${query}` : \"\"}`);\n\n return {\n ...response,\n items: response.items.map((item) => this.convertBatchJobDates(item)),\n };\n }\n\n /**\n * Cancel a batch job\n */\n async cancelBatchJob(request: GetBatchJobRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.post<{ success: boolean }>(`/webdata/batch/${request.id}/cancel${query ? `?${query}` : \"\"}`, {});\n }\n\n /**\n * Create a batch screenshot job and wait for completion\n */\n async batchAndWait(\n request: CreateBatchScreenshotsRequest,\n options: { pollInterval?: number; timeout?: number } = {},\n ): Promise<BatchScreenshotJob> {\n const { pollInterval = 2000, timeout = 300000 } = options;\n const startTime = Date.now();\n\n const { id } = await this.batch(request);\n\n while (Date.now() - startTime < timeout) {\n const job = await this.getBatchJob({\n id,\n environment: request.environment,\n projectId: request.projectId,\n });\n\n if (job.status === \"completed\" || job.status === \"failed\" || job.status === \"cancelled\") {\n return job;\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(\"Batch job timed out\");\n }\n\n // ==========================================================================\n // SCHEDULES\n // ==========================================================================\n\n /**\n * Create a scheduled screenshot job\n *\n * @example\n * ```typescript\n * const { id } = await screenshots.createSchedule({\n * name: 'Daily homepage screenshot',\n * url: 'https://example.com',\n * frequency: 'daily',\n * config: { format: 'png', fullPage: true },\n * });\n * ```\n */\n async createSchedule(request: CreateScreenshotScheduleRequest): Promise<CreateScheduleResponse> {\n return this.http.post<CreateScheduleResponse>(\"/webdata/schedules\", {\n ...request,\n type: \"screenshot\",\n });\n }\n\n /**\n * Update a schedule\n */\n async updateSchedule(request: UpdateScreenshotScheduleRequest): Promise<{ success: boolean }> {\n const { id, environment, projectId, ...data } = request;\n\n const params = new URLSearchParams();\n if (environment) params.set(\"environment\", environment);\n if (projectId) params.set(\"projectId\", projectId);\n\n const query = params.toString();\n return this.http.post<{ success: boolean }>(`/webdata/schedules/${id}${query ? `?${query}` : \"\"}`, data);\n }\n\n /**\n * Get a schedule by ID\n */\n async getSchedule(request: GetScheduleRequest): Promise<ScreenshotSchedule> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n const path = `/webdata/schedules/${request.id}${query ? `?${query}` : \"\"}`;\n\n const response = await this.http.get<ScreenshotSchedule>(path);\n return this.convertScheduleDates(response);\n }\n\n /**\n * List schedules with pagination and filters\n */\n async listSchedules(request: ListSchedulesRequest = {}): Promise<ScreenshotSchedulesResponse> {\n const params = new URLSearchParams();\n\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n params.set(\"type\", \"screenshot\");\n if (request.isActive !== undefined) params.set(\"isActive\", request.isActive.toString());\n if (request.limit) params.set(\"limit\", request.limit.toString());\n if (request.cursor) params.set(\"cursor\", request.cursor);\n\n const query = params.toString();\n const response = await this.http.get<ScreenshotSchedulesResponse>(`/webdata/schedules${query ? `?${query}` : \"\"}`);\n\n return {\n ...response,\n items: response.items.map((item) => this.convertScheduleDates(item)),\n };\n }\n\n /**\n * Delete a schedule\n */\n async deleteSchedule(request: GetScheduleRequest): Promise<{ success: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.deleteWithBody<{ success: boolean }>(\n `/webdata/schedules/${request.id}${query ? `?${query}` : \"\"}`,\n {\n id: request.id,\n environment: request.environment,\n projectId: request.projectId,\n },\n );\n }\n\n /**\n * Toggle a schedule on or off\n */\n async toggleSchedule(request: GetScheduleRequest): Promise<{ isActive: boolean }> {\n const params = new URLSearchParams();\n if (request.environment) params.set(\"environment\", request.environment);\n if (request.projectId) params.set(\"projectId\", request.projectId);\n\n const query = params.toString();\n return this.http.post<{ isActive: boolean }>(\n `/webdata/schedules/${request.id}/toggle${query ? `?${query}` : \"\"}`,\n {},\n );\n }\n\n // ==========================================================================\n // HELPERS\n // ==========================================================================\n\n private convertDates(screenshot: Screenshot): Screenshot {\n if (typeof screenshot.createdAt === \"string\") {\n screenshot.createdAt = new Date(screenshot.createdAt);\n }\n if (screenshot.completedAt && typeof screenshot.completedAt === \"string\") {\n screenshot.completedAt = new Date(screenshot.completedAt);\n }\n return screenshot;\n }\n\n private convertBatchJobDates(job: BatchScreenshotJob): BatchScreenshotJob {\n if (typeof job.createdAt === \"string\") {\n job.createdAt = new Date(job.createdAt);\n }\n if (job.startedAt && typeof job.startedAt === \"string\") {\n job.startedAt = new Date(job.startedAt);\n }\n if (job.completedAt && typeof job.completedAt === \"string\") {\n job.completedAt = new Date(job.completedAt);\n }\n return job;\n }\n\n private convertScheduleDates(schedule: ScreenshotSchedule): ScreenshotSchedule {\n if (typeof schedule.createdAt === \"string\") {\n schedule.createdAt = new Date(schedule.createdAt);\n }\n if (typeof schedule.updatedAt === \"string\") {\n schedule.updatedAt = new Date(schedule.updatedAt);\n }\n if (schedule.lastRunAt && typeof schedule.lastRunAt === \"string\") {\n schedule.lastRunAt = new Date(schedule.lastRunAt);\n }\n if (schedule.nextRunAt && typeof schedule.nextRunAt === \"string\") {\n schedule.nextRunAt = new Date(schedule.nextRunAt);\n }\n return schedule;\n }\n}\n"]}
|
|
@@ -6,19 +6,24 @@ var HttpClient = class {
|
|
|
6
6
|
this.apiKey = config.apiKey;
|
|
7
7
|
this.baseUrl = config.baseUrl || "https://api.stack0.dev/v1";
|
|
8
8
|
}
|
|
9
|
-
getHeaders() {
|
|
10
|
-
|
|
11
|
-
"Content-Type": "application/json",
|
|
9
|
+
getHeaders(includeContentType = true) {
|
|
10
|
+
const headers = {
|
|
12
11
|
Authorization: `Bearer ${this.apiKey}`
|
|
13
12
|
};
|
|
13
|
+
if (includeContentType) {
|
|
14
|
+
headers["Content-Type"] = "application/json";
|
|
15
|
+
}
|
|
16
|
+
return headers;
|
|
14
17
|
}
|
|
15
18
|
async request(method, path, body) {
|
|
16
19
|
const url = `${this.baseUrl}${path}`;
|
|
20
|
+
const bodyString = body === void 0 ? void 0 : JSON.stringify(body);
|
|
21
|
+
const hasBody = bodyString !== void 0;
|
|
17
22
|
try {
|
|
18
23
|
const response = await fetch(url, {
|
|
19
24
|
method,
|
|
20
|
-
headers: this.getHeaders(),
|
|
21
|
-
body:
|
|
25
|
+
headers: this.getHeaders(hasBody),
|
|
26
|
+
body: hasBody ? bodyString : void 0
|
|
22
27
|
});
|
|
23
28
|
if (!response.ok) {
|
|
24
29
|
await this.handleErrorResponse(response);
|
|
@@ -62,6 +67,9 @@ var HttpClient = class {
|
|
|
62
67
|
async delete(path) {
|
|
63
68
|
return this.request("DELETE", path);
|
|
64
69
|
}
|
|
70
|
+
async deleteWithBody(path, body) {
|
|
71
|
+
return this.request("DELETE", path, body);
|
|
72
|
+
}
|
|
65
73
|
async patch(path, body) {
|
|
66
74
|
return this.request("PATCH", path, body);
|
|
67
75
|
}
|
|
@@ -136,9 +144,7 @@ var Screenshots = class {
|
|
|
136
144
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
137
145
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
138
146
|
const query = params.toString();
|
|
139
|
-
const response = await this.http.get(
|
|
140
|
-
`/webdata/screenshots${query ? `?${query}` : ""}`
|
|
141
|
-
);
|
|
147
|
+
const response = await this.http.get(`/webdata/screenshots${query ? `?${query}` : ""}`);
|
|
142
148
|
return {
|
|
143
149
|
...response,
|
|
144
150
|
items: response.items.map((item) => this.convertDates(item))
|
|
@@ -157,8 +163,13 @@ var Screenshots = class {
|
|
|
157
163
|
if (request.environment) params.set("environment", request.environment);
|
|
158
164
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
159
165
|
const query = params.toString();
|
|
160
|
-
return this.http.
|
|
161
|
-
`/webdata/screenshots/${request.id}${query ? `?${query}` : ""}
|
|
166
|
+
return this.http.deleteWithBody(
|
|
167
|
+
`/webdata/screenshots/${request.id}${query ? `?${query}` : ""}`,
|
|
168
|
+
{
|
|
169
|
+
id: request.id,
|
|
170
|
+
environment: request.environment,
|
|
171
|
+
projectId: request.projectId
|
|
172
|
+
}
|
|
162
173
|
);
|
|
163
174
|
}
|
|
164
175
|
/**
|
|
@@ -241,9 +252,7 @@ var Screenshots = class {
|
|
|
241
252
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
242
253
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
243
254
|
const query = params.toString();
|
|
244
|
-
const response = await this.http.get(
|
|
245
|
-
`/webdata/batch${query ? `?${query}` : ""}`
|
|
246
|
-
);
|
|
255
|
+
const response = await this.http.get(`/webdata/batch${query ? `?${query}` : ""}`);
|
|
247
256
|
return {
|
|
248
257
|
...response,
|
|
249
258
|
items: response.items.map((item) => this.convertBatchJobDates(item))
|
|
@@ -257,10 +266,7 @@ var Screenshots = class {
|
|
|
257
266
|
if (request.environment) params.set("environment", request.environment);
|
|
258
267
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
259
268
|
const query = params.toString();
|
|
260
|
-
return this.http.post(
|
|
261
|
-
`/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`,
|
|
262
|
-
{}
|
|
263
|
-
);
|
|
269
|
+
return this.http.post(`/webdata/batch/${request.id}/cancel${query ? `?${query}` : ""}`, {});
|
|
264
270
|
}
|
|
265
271
|
/**
|
|
266
272
|
* Create a batch screenshot job and wait for completion
|
|
@@ -313,10 +319,7 @@ var Screenshots = class {
|
|
|
313
319
|
if (environment) params.set("environment", environment);
|
|
314
320
|
if (projectId) params.set("projectId", projectId);
|
|
315
321
|
const query = params.toString();
|
|
316
|
-
return this.http.post(
|
|
317
|
-
`/webdata/schedules/${id}${query ? `?${query}` : ""}`,
|
|
318
|
-
data
|
|
319
|
-
);
|
|
322
|
+
return this.http.post(`/webdata/schedules/${id}${query ? `?${query}` : ""}`, data);
|
|
320
323
|
}
|
|
321
324
|
/**
|
|
322
325
|
* Get a schedule by ID
|
|
@@ -342,9 +345,7 @@ var Screenshots = class {
|
|
|
342
345
|
if (request.limit) params.set("limit", request.limit.toString());
|
|
343
346
|
if (request.cursor) params.set("cursor", request.cursor);
|
|
344
347
|
const query = params.toString();
|
|
345
|
-
const response = await this.http.get(
|
|
346
|
-
`/webdata/schedules${query ? `?${query}` : ""}`
|
|
347
|
-
);
|
|
348
|
+
const response = await this.http.get(`/webdata/schedules${query ? `?${query}` : ""}`);
|
|
348
349
|
return {
|
|
349
350
|
...response,
|
|
350
351
|
items: response.items.map((item) => this.convertScheduleDates(item))
|
|
@@ -358,8 +359,13 @@ var Screenshots = class {
|
|
|
358
359
|
if (request.environment) params.set("environment", request.environment);
|
|
359
360
|
if (request.projectId) params.set("projectId", request.projectId);
|
|
360
361
|
const query = params.toString();
|
|
361
|
-
return this.http.
|
|
362
|
-
`/webdata/schedules/${request.id}${query ? `?${query}` : ""}
|
|
362
|
+
return this.http.deleteWithBody(
|
|
363
|
+
`/webdata/schedules/${request.id}${query ? `?${query}` : ""}`,
|
|
364
|
+
{
|
|
365
|
+
id: request.id,
|
|
366
|
+
environment: request.environment,
|
|
367
|
+
projectId: request.projectId
|
|
368
|
+
}
|
|
363
369
|
);
|
|
364
370
|
}
|
|
365
371
|
/**
|