@canveletedotcom/sdk 2.0.0
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 +143 -0
- package/dist/client.d.ts +46 -0
- package/dist/client.js +132 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.js +48 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -0
- package/dist/resources/apiKeys.d.ts +22 -0
- package/dist/resources/apiKeys.js +15 -0
- package/dist/resources/assets.d.ts +101 -0
- package/dist/resources/assets.js +93 -0
- package/dist/resources/billing.d.ts +96 -0
- package/dist/resources/billing.js +64 -0
- package/dist/resources/canvas.d.ts +36 -0
- package/dist/resources/canvas.js +26 -0
- package/dist/resources/designs.d.ts +42 -0
- package/dist/resources/designs.js +46 -0
- package/dist/resources/index.d.ts +15 -0
- package/dist/resources/index.js +9 -0
- package/dist/resources/render.d.ts +90 -0
- package/dist/resources/render.js +171 -0
- package/dist/resources/templates.d.ts +53 -0
- package/dist/resources/templates.js +76 -0
- package/dist/resources/usage.d.ts +76 -0
- package/dist/resources/usage.js +52 -0
- package/dist/types/index.d.ts +197 -0
- package/dist/types/index.js +4 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/retry.d.ts +22 -0
- package/dist/utils/retry.js +70 -0
- package/dist/utils/validation.d.ts +69 -0
- package/dist/utils/validation.js +126 -0
- package/dist/utils/webhooks.d.ts +31 -0
- package/dist/utils/webhooks.js +70 -0
- package/package.json +57 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing resource for managing subscriptions, credits, and invoices
|
|
3
|
+
*/
|
|
4
|
+
import type { CanveleteClient } from '../client';
|
|
5
|
+
import type { PaginatedResponse } from '../types';
|
|
6
|
+
export interface BillingInfo {
|
|
7
|
+
plan: string;
|
|
8
|
+
status: 'active' | 'cancelled' | 'past_due' | 'trialing';
|
|
9
|
+
creditBalance: number;
|
|
10
|
+
creditLimit: number;
|
|
11
|
+
nextBillingDate: string;
|
|
12
|
+
currentPeriodStart: string;
|
|
13
|
+
currentPeriodEnd: string;
|
|
14
|
+
cancelAtPeriodEnd: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface Invoice {
|
|
17
|
+
id: string;
|
|
18
|
+
date: string;
|
|
19
|
+
amount: number;
|
|
20
|
+
currency: string;
|
|
21
|
+
status: 'paid' | 'pending' | 'failed';
|
|
22
|
+
description: string;
|
|
23
|
+
pdfUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface BillingSummary {
|
|
26
|
+
totalSpent: number;
|
|
27
|
+
currentMonth: number;
|
|
28
|
+
previousMonth: number;
|
|
29
|
+
averageMonthly: number;
|
|
30
|
+
currency: string;
|
|
31
|
+
}
|
|
32
|
+
export interface Seats {
|
|
33
|
+
used: number;
|
|
34
|
+
total: number;
|
|
35
|
+
available: number;
|
|
36
|
+
}
|
|
37
|
+
export interface CreditPurchase {
|
|
38
|
+
id: string;
|
|
39
|
+
amount: number;
|
|
40
|
+
credits: number;
|
|
41
|
+
newBalance: number;
|
|
42
|
+
status: string;
|
|
43
|
+
}
|
|
44
|
+
export declare class BillingResource {
|
|
45
|
+
private client;
|
|
46
|
+
constructor(client: CanveleteClient);
|
|
47
|
+
/**
|
|
48
|
+
* Get billing information and subscription details
|
|
49
|
+
*/
|
|
50
|
+
getInfo(): Promise<{
|
|
51
|
+
data: BillingInfo;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* Get invoice history
|
|
55
|
+
*/
|
|
56
|
+
getInvoices(options?: {
|
|
57
|
+
page?: number;
|
|
58
|
+
limit?: number;
|
|
59
|
+
}): Promise<PaginatedResponse<Invoice>>;
|
|
60
|
+
/**
|
|
61
|
+
* Get billing summary
|
|
62
|
+
*/
|
|
63
|
+
getSummary(): Promise<{
|
|
64
|
+
data: BillingSummary;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Purchase additional credits
|
|
68
|
+
*/
|
|
69
|
+
purchaseCredits(amount: number, paymentMethodId?: string): Promise<{
|
|
70
|
+
data: CreditPurchase;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Get team seats information
|
|
74
|
+
*/
|
|
75
|
+
getSeats(): Promise<{
|
|
76
|
+
data: Seats;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* Add team seats
|
|
80
|
+
*/
|
|
81
|
+
addSeats(count: number): Promise<{
|
|
82
|
+
data: Seats;
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Remove team seats
|
|
86
|
+
*/
|
|
87
|
+
removeSeats(count: number): Promise<{
|
|
88
|
+
data: Seats;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* Get billing portal URL
|
|
92
|
+
*/
|
|
93
|
+
getPortalUrl(): Promise<{
|
|
94
|
+
url: string;
|
|
95
|
+
}>;
|
|
96
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing resource for managing subscriptions, credits, and invoices
|
|
3
|
+
*/
|
|
4
|
+
export class BillingResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Get billing information and subscription details
|
|
10
|
+
*/
|
|
11
|
+
async getInfo() {
|
|
12
|
+
return await this.client.request('GET', '/api/v1/billing/info');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get invoice history
|
|
16
|
+
*/
|
|
17
|
+
async getInvoices(options = {}) {
|
|
18
|
+
const params = {
|
|
19
|
+
page: String(options.page || 1),
|
|
20
|
+
limit: String(options.limit || 20),
|
|
21
|
+
};
|
|
22
|
+
return await this.client.request('GET', '/api/v1/billing/invoices', { params });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get billing summary
|
|
26
|
+
*/
|
|
27
|
+
async getSummary() {
|
|
28
|
+
return await this.client.request('GET', '/api/v1/billing/summary');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Purchase additional credits
|
|
32
|
+
*/
|
|
33
|
+
async purchaseCredits(amount, paymentMethodId) {
|
|
34
|
+
const payload = { creditAmount: amount };
|
|
35
|
+
if (paymentMethodId) {
|
|
36
|
+
payload.paymentMethodId = paymentMethodId;
|
|
37
|
+
}
|
|
38
|
+
return await this.client.request('POST', '/api/v1/billing/credits/purchase', { json: payload });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get team seats information
|
|
42
|
+
*/
|
|
43
|
+
async getSeats() {
|
|
44
|
+
return await this.client.request('GET', '/api/v1/billing/seats');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Add team seats
|
|
48
|
+
*/
|
|
49
|
+
async addSeats(count) {
|
|
50
|
+
return await this.client.request('POST', '/api/v1/billing/seats/add', { json: { count } });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Remove team seats
|
|
54
|
+
*/
|
|
55
|
+
async removeSeats(count) {
|
|
56
|
+
return await this.client.request('DELETE', '/api/v1/billing/seats/remove', { json: { count } });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get billing portal URL
|
|
60
|
+
*/
|
|
61
|
+
async getPortalUrl() {
|
|
62
|
+
return await this.client.request('GET', '/api/billing/portal');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CanveleteClient } from '../client';
|
|
2
|
+
export interface CanvasElement {
|
|
3
|
+
type: string;
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width?: number;
|
|
7
|
+
height?: number;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}
|
|
10
|
+
export declare class CanvasResource {
|
|
11
|
+
private client;
|
|
12
|
+
constructor(client: CanveleteClient);
|
|
13
|
+
addElement(designId: string, element: CanvasElement): Promise<{
|
|
14
|
+
data: CanvasElement;
|
|
15
|
+
}>;
|
|
16
|
+
updateElement(designId: string, elementId: string, updates: Partial<CanvasElement>): Promise<{
|
|
17
|
+
data: CanvasElement;
|
|
18
|
+
}>;
|
|
19
|
+
deleteElement(designId: string, elementId: string): Promise<{
|
|
20
|
+
success: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
getElements(designId: string): Promise<{
|
|
23
|
+
data: {
|
|
24
|
+
elements: CanvasElement[];
|
|
25
|
+
};
|
|
26
|
+
}>;
|
|
27
|
+
resize(designId: string, width: number, height: number): Promise<{
|
|
28
|
+
data: any;
|
|
29
|
+
}>;
|
|
30
|
+
clear(designId: string): Promise<{
|
|
31
|
+
success: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
updateBackground(designId: string, background: string): Promise<{
|
|
34
|
+
data: any;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class CanvasResource {
|
|
2
|
+
constructor(client) {
|
|
3
|
+
this.client = client;
|
|
4
|
+
}
|
|
5
|
+
async addElement(designId, element) {
|
|
6
|
+
return await this.client.request('POST', `/api/designs/${designId}/elements`, { json: { element } });
|
|
7
|
+
}
|
|
8
|
+
async updateElement(designId, elementId, updates) {
|
|
9
|
+
return await this.client.request('PATCH', `/api/designs/${designId}/elements/${elementId}`, { json: updates });
|
|
10
|
+
}
|
|
11
|
+
async deleteElement(designId, elementId) {
|
|
12
|
+
return await this.client.request('DELETE', `/api/designs/${designId}/elements/${elementId}`);
|
|
13
|
+
}
|
|
14
|
+
async getElements(designId) {
|
|
15
|
+
return await this.client.request('GET', `/api/designs/${designId}/canvas`);
|
|
16
|
+
}
|
|
17
|
+
async resize(designId, width, height) {
|
|
18
|
+
return await this.client.request('PATCH', `/api/designs/${designId}/canvas/resize`, { json: { width, height } });
|
|
19
|
+
}
|
|
20
|
+
async clear(designId) {
|
|
21
|
+
return await this.client.request('DELETE', `/api/designs/${designId}/canvas/elements`);
|
|
22
|
+
}
|
|
23
|
+
async updateBackground(designId, background) {
|
|
24
|
+
return await this.client.request('PATCH', `/api/designs/${designId}/canvas/background`, { json: { background } });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CanveleteClient } from '../client';
|
|
2
|
+
import type { Design, PaginatedResponse } from '../types';
|
|
3
|
+
export interface ListDesignsOptions {
|
|
4
|
+
page?: number;
|
|
5
|
+
limit?: number;
|
|
6
|
+
isTemplate?: boolean;
|
|
7
|
+
status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';
|
|
8
|
+
}
|
|
9
|
+
export interface CreateDesignData {
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
canvasData: Record<string, any>;
|
|
13
|
+
width?: number;
|
|
14
|
+
height?: number;
|
|
15
|
+
isTemplate?: boolean;
|
|
16
|
+
visibility?: 'PRIVATE' | 'PUBLIC' | 'TEAM';
|
|
17
|
+
}
|
|
18
|
+
export interface UpdateDesignData {
|
|
19
|
+
name?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
canvasData?: Record<string, any>;
|
|
22
|
+
width?: number;
|
|
23
|
+
height?: number;
|
|
24
|
+
status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';
|
|
25
|
+
visibility?: 'PRIVATE' | 'PUBLIC' | 'TEAM';
|
|
26
|
+
}
|
|
27
|
+
export declare class DesignsResource {
|
|
28
|
+
private client;
|
|
29
|
+
constructor(client: CanveleteClient);
|
|
30
|
+
list(options?: ListDesignsOptions): Promise<PaginatedResponse<Design>>;
|
|
31
|
+
iterateAll(options?: ListDesignsOptions): AsyncGenerator<Design>;
|
|
32
|
+
create(data: CreateDesignData): Promise<{
|
|
33
|
+
data: Design;
|
|
34
|
+
}>;
|
|
35
|
+
get(id: string): Promise<{
|
|
36
|
+
data: Design;
|
|
37
|
+
}>;
|
|
38
|
+
update(id: string, data: UpdateDesignData): Promise<{
|
|
39
|
+
data: Design;
|
|
40
|
+
}>;
|
|
41
|
+
delete(id: string): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export class DesignsResource {
|
|
2
|
+
constructor(client) {
|
|
3
|
+
this.client = client;
|
|
4
|
+
}
|
|
5
|
+
async list(options = {}) {
|
|
6
|
+
const params = {
|
|
7
|
+
page: String(options.page || 1),
|
|
8
|
+
limit: String(options.limit || 20),
|
|
9
|
+
};
|
|
10
|
+
if (options.isTemplate !== undefined) {
|
|
11
|
+
params.isTemplate = options.isTemplate ? 'true' : 'false';
|
|
12
|
+
}
|
|
13
|
+
if (options.status) {
|
|
14
|
+
params.status = options.status;
|
|
15
|
+
}
|
|
16
|
+
return await this.client.request('GET', '/api/automation/designs', { params });
|
|
17
|
+
}
|
|
18
|
+
async *iterateAll(options = {}) {
|
|
19
|
+
let page = 1;
|
|
20
|
+
const limit = options.limit || 50;
|
|
21
|
+
while (true) {
|
|
22
|
+
const response = await this.list({ ...options, page, limit });
|
|
23
|
+
const designs = response.data || [];
|
|
24
|
+
if (designs.length === 0)
|
|
25
|
+
break;
|
|
26
|
+
for (const design of designs) {
|
|
27
|
+
yield design;
|
|
28
|
+
}
|
|
29
|
+
if (page >= (response.pagination?.totalPages || 1))
|
|
30
|
+
break;
|
|
31
|
+
page++;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async create(data) {
|
|
35
|
+
return await this.client.request('POST', '/api/automation/designs', { json: data });
|
|
36
|
+
}
|
|
37
|
+
async get(id) {
|
|
38
|
+
return await this.client.request('GET', `/api/automation/designs/${id}`);
|
|
39
|
+
}
|
|
40
|
+
async update(id, data) {
|
|
41
|
+
return await this.client.request('PATCH', `/api/automation/designs/${id}`, { json: data });
|
|
42
|
+
}
|
|
43
|
+
async delete(id) {
|
|
44
|
+
await this.client.request('DELETE', `/api/automation/designs/${id}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { DesignsResource } from './designs';
|
|
2
|
+
export type { ListDesignsOptions, CreateDesignData, UpdateDesignData } from './designs';
|
|
3
|
+
export { TemplatesResource } from './templates';
|
|
4
|
+
export type { ListTemplatesOptions, ApplyTemplateOptions, CreateTemplateOptions } from './templates';
|
|
5
|
+
export { RenderResource } from './render';
|
|
6
|
+
export type { RenderOptions, RenderRecord, ListRenderOptions, AsyncRenderResponse, BatchRenderOptions, BatchRenderResponse } from './render';
|
|
7
|
+
export { APIKeysResource } from './apiKeys';
|
|
8
|
+
export type { ListAPIKeysOptions, CreateAPIKeyData, CreateAPIKeyResponse } from './apiKeys';
|
|
9
|
+
export { CanvasResource } from './canvas';
|
|
10
|
+
export { AssetsResource } from './assets';
|
|
11
|
+
export type { Asset, StockImage, Icon, Font, ListAssetsOptions, SearchOptions } from './assets';
|
|
12
|
+
export { UsageResource } from './usage';
|
|
13
|
+
export type { UsageStats, UsageEvent, ApiStats, Activity, Analytics, UsageHistoryOptions } from './usage';
|
|
14
|
+
export { BillingResource } from './billing';
|
|
15
|
+
export type { BillingInfo, Invoice, BillingSummary, Seats, CreditPurchase } from './billing';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { DesignsResource } from './designs';
|
|
2
|
+
export { TemplatesResource } from './templates';
|
|
3
|
+
export { RenderResource } from './render';
|
|
4
|
+
export { APIKeysResource } from './apiKeys';
|
|
5
|
+
export { CanvasResource } from './canvas';
|
|
6
|
+
// CanvasElement type is exported from types/index.ts
|
|
7
|
+
export { AssetsResource } from './assets';
|
|
8
|
+
export { UsageResource } from './usage';
|
|
9
|
+
export { BillingResource } from './billing';
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render resource for creating and managing render jobs
|
|
3
|
+
*/
|
|
4
|
+
import type { CanveleteClient } from '../client';
|
|
5
|
+
import type { PaginatedResponse } from '../types';
|
|
6
|
+
export interface RenderOptions {
|
|
7
|
+
designId?: string;
|
|
8
|
+
templateId?: string;
|
|
9
|
+
dynamicData?: Record<string, any>;
|
|
10
|
+
format?: 'png' | 'jpg' | 'jpeg' | 'pdf' | 'svg';
|
|
11
|
+
width?: number;
|
|
12
|
+
height?: number;
|
|
13
|
+
quality?: number;
|
|
14
|
+
outputFile?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface RenderRecord {
|
|
17
|
+
id: string;
|
|
18
|
+
designId: string;
|
|
19
|
+
format: string;
|
|
20
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
21
|
+
outputUrl?: string;
|
|
22
|
+
fileSize: number;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
completedAt?: string;
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AsyncRenderResponse {
|
|
28
|
+
jobId: string;
|
|
29
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
30
|
+
estimatedTime?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface BatchRenderOptions {
|
|
33
|
+
renders: RenderOptions[];
|
|
34
|
+
webhook?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface BatchRenderResponse {
|
|
37
|
+
batchId: string;
|
|
38
|
+
jobs: AsyncRenderResponse[];
|
|
39
|
+
totalJobs: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ListRenderOptions {
|
|
42
|
+
page?: number;
|
|
43
|
+
limit?: number;
|
|
44
|
+
}
|
|
45
|
+
export declare class RenderResource {
|
|
46
|
+
private client;
|
|
47
|
+
constructor(client: CanveleteClient);
|
|
48
|
+
/**
|
|
49
|
+
* Create a synchronous render (waits for completion)
|
|
50
|
+
*/
|
|
51
|
+
create(options: RenderOptions): Promise<ArrayBuffer>;
|
|
52
|
+
/**
|
|
53
|
+
* Create an asynchronous render job (returns immediately)
|
|
54
|
+
*/
|
|
55
|
+
createAsync(options: RenderOptions): Promise<AsyncRenderResponse>;
|
|
56
|
+
/**
|
|
57
|
+
* Get the status of a render job
|
|
58
|
+
*/
|
|
59
|
+
getStatus(jobId: string): Promise<RenderRecord>;
|
|
60
|
+
/**
|
|
61
|
+
* Wait for a render job to complete
|
|
62
|
+
*/
|
|
63
|
+
waitForCompletion(jobId: string, options?: {
|
|
64
|
+
timeout?: number;
|
|
65
|
+
pollInterval?: number;
|
|
66
|
+
}): Promise<RenderRecord>;
|
|
67
|
+
/**
|
|
68
|
+
* Get render history
|
|
69
|
+
*/
|
|
70
|
+
getHistory(options?: ListRenderOptions): Promise<PaginatedResponse<RenderRecord>>;
|
|
71
|
+
/**
|
|
72
|
+
* Create a batch of render jobs
|
|
73
|
+
*/
|
|
74
|
+
batchCreate(options: BatchRenderOptions): Promise<BatchRenderResponse>;
|
|
75
|
+
/**
|
|
76
|
+
* Wait for all jobs in a batch to complete
|
|
77
|
+
*/
|
|
78
|
+
waitForBatch(batchId: string, options?: {
|
|
79
|
+
timeout?: number;
|
|
80
|
+
pollInterval?: number;
|
|
81
|
+
}): Promise<RenderRecord[]>;
|
|
82
|
+
/**
|
|
83
|
+
* List render history (legacy method)
|
|
84
|
+
*/
|
|
85
|
+
list(options?: ListRenderOptions): Promise<PaginatedResponse<RenderRecord>>;
|
|
86
|
+
/**
|
|
87
|
+
* Iterate through all render records with automatic pagination
|
|
88
|
+
*/
|
|
89
|
+
iterateAll(options?: ListRenderOptions): AsyncGenerator<RenderRecord>;
|
|
90
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render resource for creating and managing render jobs
|
|
3
|
+
*/
|
|
4
|
+
import { writeFileSync } from 'fs';
|
|
5
|
+
import { ValidationError } from '../errors';
|
|
6
|
+
export class RenderResource {
|
|
7
|
+
constructor(client) {
|
|
8
|
+
this.client = client;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a synchronous render (waits for completion)
|
|
12
|
+
*/
|
|
13
|
+
async create(options) {
|
|
14
|
+
if (!options.designId && !options.templateId) {
|
|
15
|
+
throw new ValidationError('Either designId or templateId is required');
|
|
16
|
+
}
|
|
17
|
+
const data = {
|
|
18
|
+
format: options.format || 'png',
|
|
19
|
+
quality: options.quality || 90,
|
|
20
|
+
};
|
|
21
|
+
if (options.designId)
|
|
22
|
+
data.designId = options.designId;
|
|
23
|
+
if (options.templateId)
|
|
24
|
+
data.templateId = options.templateId;
|
|
25
|
+
if (options.dynamicData)
|
|
26
|
+
data.dynamicData = options.dynamicData;
|
|
27
|
+
if (options.width)
|
|
28
|
+
data.width = options.width;
|
|
29
|
+
if (options.height)
|
|
30
|
+
data.height = options.height;
|
|
31
|
+
const imageData = await this.client.request('POST', '/api/automation/render', {
|
|
32
|
+
json: data,
|
|
33
|
+
binary: true,
|
|
34
|
+
});
|
|
35
|
+
if (options.outputFile) {
|
|
36
|
+
writeFileSync(options.outputFile, Buffer.from(imageData));
|
|
37
|
+
}
|
|
38
|
+
return imageData;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create an asynchronous render job (returns immediately)
|
|
42
|
+
*/
|
|
43
|
+
async createAsync(options) {
|
|
44
|
+
if (!options.designId && !options.templateId) {
|
|
45
|
+
throw new ValidationError('Either designId or templateId is required');
|
|
46
|
+
}
|
|
47
|
+
const data = {
|
|
48
|
+
format: options.format || 'png',
|
|
49
|
+
quality: options.quality || 90,
|
|
50
|
+
async: true,
|
|
51
|
+
};
|
|
52
|
+
if (options.designId)
|
|
53
|
+
data.designId = options.designId;
|
|
54
|
+
if (options.templateId)
|
|
55
|
+
data.templateId = options.templateId;
|
|
56
|
+
if (options.dynamicData)
|
|
57
|
+
data.dynamicData = options.dynamicData;
|
|
58
|
+
if (options.width)
|
|
59
|
+
data.width = options.width;
|
|
60
|
+
if (options.height)
|
|
61
|
+
data.height = options.height;
|
|
62
|
+
return await this.client.request('POST', '/api/v1/render/async', {
|
|
63
|
+
json: data,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the status of a render job
|
|
68
|
+
*/
|
|
69
|
+
async getStatus(jobId) {
|
|
70
|
+
return await this.client.request('GET', `/api/v1/render/status/${jobId}`);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Wait for a render job to complete
|
|
74
|
+
*/
|
|
75
|
+
async waitForCompletion(jobId, options = {}) {
|
|
76
|
+
const timeout = options.timeout || 300000; // 5 minutes default
|
|
77
|
+
const pollInterval = options.pollInterval || 2000; // 2 seconds default
|
|
78
|
+
const startTime = Date.now();
|
|
79
|
+
while (Date.now() - startTime < timeout) {
|
|
80
|
+
const status = await this.getStatus(jobId);
|
|
81
|
+
if (status.status === 'completed') {
|
|
82
|
+
return status;
|
|
83
|
+
}
|
|
84
|
+
if (status.status === 'failed') {
|
|
85
|
+
throw new Error(`Render job failed: ${status.error || 'Unknown error'}`);
|
|
86
|
+
}
|
|
87
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
88
|
+
}
|
|
89
|
+
throw new Error(`Render job timed out after ${timeout}ms`);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get render history
|
|
93
|
+
*/
|
|
94
|
+
async getHistory(options = {}) {
|
|
95
|
+
const params = {
|
|
96
|
+
page: String(options.page || 1),
|
|
97
|
+
limit: String(options.limit || 20),
|
|
98
|
+
};
|
|
99
|
+
return await this.client.request('GET', '/api/v1/render/history', { params });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create a batch of render jobs
|
|
103
|
+
*/
|
|
104
|
+
async batchCreate(options) {
|
|
105
|
+
if (!options.renders || options.renders.length === 0) {
|
|
106
|
+
throw new ValidationError('At least one render is required');
|
|
107
|
+
}
|
|
108
|
+
const payload = {
|
|
109
|
+
renders: options.renders.map(r => ({
|
|
110
|
+
designId: r.designId,
|
|
111
|
+
templateId: r.templateId,
|
|
112
|
+
dynamicData: r.dynamicData,
|
|
113
|
+
format: r.format || 'png',
|
|
114
|
+
quality: r.quality || 90,
|
|
115
|
+
width: r.width,
|
|
116
|
+
height: r.height,
|
|
117
|
+
})),
|
|
118
|
+
};
|
|
119
|
+
if (options.webhook) {
|
|
120
|
+
payload.webhook = options.webhook;
|
|
121
|
+
}
|
|
122
|
+
return await this.client.request('POST', '/api/v1/render/batch', {
|
|
123
|
+
json: payload,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Wait for all jobs in a batch to complete
|
|
128
|
+
*/
|
|
129
|
+
async waitForBatch(batchId, options = {}) {
|
|
130
|
+
const timeout = options.timeout || 600000; // 10 minutes default
|
|
131
|
+
const pollInterval = options.pollInterval || 5000; // 5 seconds default
|
|
132
|
+
const startTime = Date.now();
|
|
133
|
+
while (Date.now() - startTime < timeout) {
|
|
134
|
+
const response = await this.client.request('GET', `/api/v1/render/batch/${batchId}/status`);
|
|
135
|
+
if (response.completed) {
|
|
136
|
+
return response.jobs;
|
|
137
|
+
}
|
|
138
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`Batch render timed out after ${timeout}ms`);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* List render history (legacy method)
|
|
144
|
+
*/
|
|
145
|
+
async list(options = {}) {
|
|
146
|
+
const params = {
|
|
147
|
+
page: String(options.page || 1),
|
|
148
|
+
limit: String(options.limit || 20),
|
|
149
|
+
};
|
|
150
|
+
return await this.client.request('GET', '/api/automation/render', { params });
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Iterate through all render records with automatic pagination
|
|
154
|
+
*/
|
|
155
|
+
async *iterateAll(options = {}) {
|
|
156
|
+
let page = 1;
|
|
157
|
+
const limit = options.limit || 50;
|
|
158
|
+
while (true) {
|
|
159
|
+
const response = await this.list({ page, limit });
|
|
160
|
+
const renders = response.data || [];
|
|
161
|
+
if (renders.length === 0)
|
|
162
|
+
break;
|
|
163
|
+
for (const render of renders) {
|
|
164
|
+
yield render;
|
|
165
|
+
}
|
|
166
|
+
if (page >= (response.pagination?.totalPages || 1))
|
|
167
|
+
break;
|
|
168
|
+
page++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Templates resource for managing design templates
|
|
3
|
+
*/
|
|
4
|
+
import type { CanveleteClient } from '../client';
|
|
5
|
+
import type { Template, PaginatedResponse, Design } from '../types';
|
|
6
|
+
export interface ListTemplatesOptions {
|
|
7
|
+
page?: number;
|
|
8
|
+
limit?: number;
|
|
9
|
+
myOnly?: boolean;
|
|
10
|
+
search?: string;
|
|
11
|
+
category?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ApplyTemplateOptions {
|
|
14
|
+
designId: string;
|
|
15
|
+
templateId: string;
|
|
16
|
+
dynamicData?: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
export interface CreateTemplateOptions {
|
|
19
|
+
designId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
category?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare class TemplatesResource {
|
|
25
|
+
private client;
|
|
26
|
+
constructor(client: CanveleteClient);
|
|
27
|
+
/**
|
|
28
|
+
* List available templates
|
|
29
|
+
*/
|
|
30
|
+
list(options?: ListTemplatesOptions): Promise<PaginatedResponse<Template>>;
|
|
31
|
+
/**
|
|
32
|
+
* Iterate through all templates with automatic pagination
|
|
33
|
+
*/
|
|
34
|
+
iterateAll(options?: ListTemplatesOptions): AsyncGenerator<Template>;
|
|
35
|
+
/**
|
|
36
|
+
* Get a specific template by ID
|
|
37
|
+
*/
|
|
38
|
+
get(id: string): Promise<{
|
|
39
|
+
data: Template;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Apply a template to a design
|
|
43
|
+
*/
|
|
44
|
+
apply(options: ApplyTemplateOptions): Promise<{
|
|
45
|
+
data: Design;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Create a template from an existing design
|
|
49
|
+
*/
|
|
50
|
+
create(options: CreateTemplateOptions): Promise<{
|
|
51
|
+
data: Template;
|
|
52
|
+
}>;
|
|
53
|
+
}
|