@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.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Templates resource for managing design templates
3
+ */
4
+ export class TemplatesResource {
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ /**
9
+ * List available templates
10
+ */
11
+ async list(options = {}) {
12
+ const params = {
13
+ page: String(options.page || 1),
14
+ limit: String(options.limit || 20),
15
+ };
16
+ if (options.myOnly)
17
+ params.myOnly = 'true';
18
+ if (options.search)
19
+ params.search = options.search;
20
+ if (options.category)
21
+ params.category = options.category;
22
+ return await this.client.request('GET', '/api/automation/templates', { params });
23
+ }
24
+ /**
25
+ * Iterate through all templates with automatic pagination
26
+ */
27
+ async *iterateAll(options = {}) {
28
+ let page = 1;
29
+ const limit = options.limit || 50;
30
+ while (true) {
31
+ const response = await this.list({ ...options, page, limit });
32
+ const templates = response.data || [];
33
+ if (templates.length === 0)
34
+ break;
35
+ for (const template of templates) {
36
+ yield template;
37
+ }
38
+ if (page >= (response.pagination?.totalPages || 1))
39
+ break;
40
+ page++;
41
+ }
42
+ }
43
+ /**
44
+ * Get a specific template by ID
45
+ */
46
+ async get(id) {
47
+ return await this.client.request('GET', `/api/automation/designs/${id}`);
48
+ }
49
+ /**
50
+ * Apply a template to a design
51
+ */
52
+ async apply(options) {
53
+ const payload = {
54
+ templateId: options.templateId,
55
+ };
56
+ if (options.dynamicData) {
57
+ payload.dynamicData = options.dynamicData;
58
+ }
59
+ return await this.client.request('POST', `/api/automation/designs/${options.designId}/apply-template`, { json: payload });
60
+ }
61
+ /**
62
+ * Create a template from an existing design
63
+ */
64
+ async create(options) {
65
+ const payload = {
66
+ name: options.name,
67
+ };
68
+ if (options.description) {
69
+ payload.description = options.description;
70
+ }
71
+ if (options.category) {
72
+ payload.category = options.category;
73
+ }
74
+ return await this.client.request('POST', `/api/automation/designs/${options.designId}/save-as-template`, { json: payload });
75
+ }
76
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Usage tracking resource for monitoring API usage and credits
3
+ */
4
+ import type { CanveleteClient } from '../client';
5
+ import type { PaginatedResponse } from '../types';
6
+ export interface UsageStats {
7
+ creditsUsed: number;
8
+ creditLimit: number;
9
+ creditsRemaining: number;
10
+ apiCalls: number;
11
+ apiCallLimit: number;
12
+ renders: number;
13
+ storageUsed: number;
14
+ }
15
+ export interface UsageEvent {
16
+ type: string;
17
+ creditsUsed: number;
18
+ timestamp: string;
19
+ details?: Record<string, any>;
20
+ }
21
+ export interface ApiStats {
22
+ endpoints: Record<string, number>;
23
+ totalCalls: number;
24
+ period: string;
25
+ }
26
+ export interface Activity {
27
+ action: string;
28
+ timestamp: string;
29
+ details?: Record<string, any>;
30
+ }
31
+ export interface Analytics {
32
+ totalRenders: number;
33
+ averagePerDay: number;
34
+ peakDay: string;
35
+ trend: 'increasing' | 'decreasing' | 'stable';
36
+ breakdown?: Record<string, number>;
37
+ }
38
+ export interface UsageHistoryOptions {
39
+ page?: number;
40
+ limit?: number;
41
+ startDate?: Date;
42
+ endDate?: Date;
43
+ }
44
+ export declare class UsageResource {
45
+ private client;
46
+ constructor(client: CanveleteClient);
47
+ /**
48
+ * Get current usage statistics
49
+ */
50
+ getStats(): Promise<{
51
+ data: UsageStats;
52
+ }>;
53
+ /**
54
+ * Get usage history
55
+ */
56
+ getHistory(options?: UsageHistoryOptions): Promise<PaginatedResponse<UsageEvent>>;
57
+ /**
58
+ * Get API usage statistics by endpoint
59
+ */
60
+ getApiStats(): Promise<{
61
+ data: ApiStats;
62
+ }>;
63
+ /**
64
+ * Get recent activities
65
+ */
66
+ getActivities(options?: {
67
+ page?: number;
68
+ limit?: number;
69
+ }): Promise<PaginatedResponse<Activity>>;
70
+ /**
71
+ * Get usage analytics
72
+ */
73
+ getAnalytics(period?: 'day' | 'week' | 'month' | 'year'): Promise<{
74
+ data: Analytics;
75
+ }>;
76
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Usage tracking resource for monitoring API usage and credits
3
+ */
4
+ export class UsageResource {
5
+ constructor(client) {
6
+ this.client = client;
7
+ }
8
+ /**
9
+ * Get current usage statistics
10
+ */
11
+ async getStats() {
12
+ return await this.client.request('GET', '/api/v1/usage/stats');
13
+ }
14
+ /**
15
+ * Get usage history
16
+ */
17
+ async getHistory(options = {}) {
18
+ const params = {
19
+ page: String(options.page || 1),
20
+ limit: String(options.limit || 20),
21
+ };
22
+ if (options.startDate) {
23
+ params.startDate = options.startDate.toISOString();
24
+ }
25
+ if (options.endDate) {
26
+ params.endDate = options.endDate.toISOString();
27
+ }
28
+ return await this.client.request('GET', '/api/v1/usage/history', { params });
29
+ }
30
+ /**
31
+ * Get API usage statistics by endpoint
32
+ */
33
+ async getApiStats() {
34
+ return await this.client.request('GET', '/api/v1/usage/api-stats');
35
+ }
36
+ /**
37
+ * Get recent activities
38
+ */
39
+ async getActivities(options = {}) {
40
+ const params = {
41
+ page: String(options.page || 1),
42
+ limit: String(options.limit || 20),
43
+ };
44
+ return await this.client.request('GET', '/api/usage/activities', { params });
45
+ }
46
+ /**
47
+ * Get usage analytics
48
+ */
49
+ async getAnalytics(period = 'month') {
50
+ return await this.client.request('GET', '/api/usage/analytics', { params: { period } });
51
+ }
52
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Type definitions for Canvelete API
3
+ */
4
+ export interface ElementBase {
5
+ id?: string;
6
+ type: string;
7
+ x: number;
8
+ y: number;
9
+ width?: number;
10
+ height?: number;
11
+ rotation?: number;
12
+ opacity?: number;
13
+ visible?: boolean;
14
+ locked?: boolean;
15
+ name?: string;
16
+ groupId?: string;
17
+ }
18
+ export interface RectangleElement extends ElementBase {
19
+ type: 'rectangle';
20
+ fill?: string;
21
+ stroke?: string;
22
+ strokeWidth?: number;
23
+ borderRadius?: number;
24
+ borderRadiusTopLeft?: number;
25
+ borderRadiusTopRight?: number;
26
+ borderRadiusBottomLeft?: number;
27
+ borderRadiusBottomRight?: number;
28
+ boxShadow?: string;
29
+ }
30
+ export interface CircleElement extends ElementBase {
31
+ type: 'circle';
32
+ fill?: string;
33
+ stroke?: string;
34
+ strokeWidth?: number;
35
+ }
36
+ export interface TextElement extends ElementBase {
37
+ type: 'text';
38
+ text: string;
39
+ fontSize?: number;
40
+ fontFamily?: string;
41
+ fontWeight?: string;
42
+ fontStyle?: 'normal' | 'italic' | 'oblique';
43
+ fill?: string;
44
+ color?: string;
45
+ textAlign?: 'left' | 'center' | 'right' | 'justify';
46
+ textDecoration?: 'none' | 'underline' | 'line-through' | 'overline';
47
+ textTransform?: 'none' | 'uppercase' | 'lowercase' | 'capitalize';
48
+ lineHeight?: number;
49
+ letterSpacing?: number;
50
+ textStrokeColor?: string;
51
+ textStrokeWidth?: number;
52
+ textShadowColor?: string;
53
+ textShadowX?: number;
54
+ textShadowY?: number;
55
+ textShadowBlur?: number;
56
+ isDynamic?: boolean;
57
+ }
58
+ export interface ImageElement extends ElementBase {
59
+ type: 'image';
60
+ src: string;
61
+ objectFit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
62
+ objectPosition?: string;
63
+ brightness?: number;
64
+ contrast?: number;
65
+ saturate?: number;
66
+ hueRotate?: number;
67
+ blur?: number;
68
+ }
69
+ export interface LineElement extends ElementBase {
70
+ type: 'line';
71
+ linePoints?: Array<{
72
+ x: number;
73
+ y: number;
74
+ }>;
75
+ stroke?: string;
76
+ strokeWidth?: number;
77
+ lineCap?: 'butt' | 'round' | 'square';
78
+ lineDash?: string;
79
+ }
80
+ export interface PolygonElement extends ElementBase {
81
+ type: 'polygon';
82
+ polygonPoints?: Array<{
83
+ x: number;
84
+ y: number;
85
+ }>;
86
+ polygonSides?: number;
87
+ fill?: string;
88
+ stroke?: string;
89
+ strokeWidth?: number;
90
+ svgPath?: string;
91
+ svgViewBox?: string;
92
+ }
93
+ export interface StarElement extends ElementBase {
94
+ type: 'star';
95
+ starPoints?: number;
96
+ starInnerRadius?: number;
97
+ fill?: string;
98
+ stroke?: string;
99
+ strokeWidth?: number;
100
+ }
101
+ export interface SvgElement extends ElementBase {
102
+ type: 'svg';
103
+ src?: string;
104
+ svgPath?: string;
105
+ svgViewBox?: string;
106
+ fill?: string;
107
+ stroke?: string;
108
+ }
109
+ export interface QrElement extends ElementBase {
110
+ type: 'qr';
111
+ qrValue: string;
112
+ qrColor?: string;
113
+ qrBgColor?: string;
114
+ qrErrorLevel?: 'L' | 'M' | 'Q' | 'H';
115
+ qrMargin?: number;
116
+ }
117
+ export interface BarcodeElement extends ElementBase {
118
+ type: 'barcode';
119
+ barcodeValue: string;
120
+ barcodeFormat?: 'CODE128' | 'CODE39' | 'EAN13' | 'EAN8' | 'UPC' | 'UPCE' | 'ITF14' | 'MSI' | 'pharmacode' | 'codabar';
121
+ barcodeLineColor?: string;
122
+ barcodeBackground?: string;
123
+ barcodeShowText?: boolean;
124
+ barcodeFontSize?: number;
125
+ barcodeTextAlign?: 'left' | 'center' | 'right';
126
+ barcodeTextMargin?: number;
127
+ }
128
+ export interface TableElement extends ElementBase {
129
+ type: 'table';
130
+ tableRows?: number;
131
+ tableColumns?: number;
132
+ tableCellData?: Array<Record<string, any>>;
133
+ tableHeaderData?: Array<Record<string, any>>;
134
+ tableHasHeader?: boolean;
135
+ tableHasVerticalHeader?: boolean;
136
+ tableBorderWidth?: number;
137
+ tableBorderColor?: string;
138
+ tableCellPadding?: number;
139
+ tableHeaderBackground?: string;
140
+ tableHeaderTextColor?: string;
141
+ tableAlternateRowColor?: string;
142
+ tableCellTextColor?: string;
143
+ tableCellFontSize?: number;
144
+ tableCellAlignment?: 'left' | 'center' | 'right';
145
+ tableHeaderAlignment?: 'left' | 'center' | 'right';
146
+ tableColumnWidths?: number[];
147
+ tableRowHeights?: number[];
148
+ }
149
+ export type CanvasElement = RectangleElement | CircleElement | TextElement | ImageElement | LineElement | PolygonElement | StarElement | SvgElement | QrElement | BarcodeElement | TableElement | ElementBase;
150
+ export interface CanvasData {
151
+ elements: CanvasElement[];
152
+ background?: string;
153
+ [key: string]: any;
154
+ }
155
+ export interface Design {
156
+ id: string;
157
+ name: string;
158
+ description?: string;
159
+ canvasData: CanvasData;
160
+ width: number;
161
+ height: number;
162
+ status: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';
163
+ visibility: 'PRIVATE' | 'PUBLIC' | 'TEAM';
164
+ isTemplate: boolean;
165
+ thumbnailUrl?: string;
166
+ createdAt: string;
167
+ updatedAt: string;
168
+ }
169
+ export interface Template extends Design {
170
+ isTemplate: true;
171
+ dynamicFields?: string[];
172
+ category?: string;
173
+ }
174
+ export interface PaginatedResponse<T> {
175
+ data: T[];
176
+ pagination: {
177
+ page: number;
178
+ limit: number;
179
+ total: number;
180
+ totalPages: number;
181
+ };
182
+ }
183
+ export interface APIKey {
184
+ id: string;
185
+ name: string;
186
+ keyPrefix: string;
187
+ status: 'ACTIVE' | 'REVOKED';
188
+ scopes: string[];
189
+ createdAt: string;
190
+ lastUsedAt?: string;
191
+ expiresAt?: string;
192
+ }
193
+ export interface ClientOptions {
194
+ apiKey?: string;
195
+ baseUrl?: string;
196
+ timeout?: number;
197
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Type definitions for Canvelete API
3
+ */
4
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utility exports
3
+ */
4
+ export { withRetry, retryOnRateLimit, createRetryWrapper } from './retry';
5
+ export type { RetryConfig } from './retry';
6
+ export { verifyWebhookSignature, parseWebhookPayload, constructWebhookEvent, generateWebhookSignature, } from './webhooks';
7
+ export type { WebhookEvent, WebhookVerifyOptions } from './webhooks';
8
+ export { validateElement, validateCanvasDimensions, validateRenderOptions, validateColor, } from './validation';
9
+ export type { ElementBase, RectangleElement, CircleElement, TextElement, ImageElement, LineElement, CanvasElement, } from './validation';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utility exports
3
+ */
4
+ export { withRetry, retryOnRateLimit, createRetryWrapper } from './retry';
5
+ export { verifyWebhookSignature, parseWebhookPayload, constructWebhookEvent, generateWebhookSignature, } from './webhooks';
6
+ export { validateElement, validateCanvasDimensions, validateRenderOptions, validateColor, } from './validation';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Retry logic with exponential backoff
3
+ */
4
+ export interface RetryConfig {
5
+ maxAttempts: number;
6
+ backoffFactor: number;
7
+ initialDelay: number;
8
+ maxDelay: number;
9
+ retryOn: Array<new (...args: any[]) => Error>;
10
+ }
11
+ /**
12
+ * Execute a function with retry logic and exponential backoff
13
+ */
14
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: Partial<RetryConfig>): Promise<T>;
15
+ /**
16
+ * Create a retry wrapper for rate limit errors
17
+ */
18
+ export declare function retryOnRateLimit<T>(fn: () => Promise<T>): Promise<T>;
19
+ /**
20
+ * Decorator-style retry wrapper
21
+ */
22
+ export declare function createRetryWrapper(config?: Partial<RetryConfig>): <T>(fn: () => Promise<T>) => Promise<T>;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Retry logic with exponential backoff
3
+ */
4
+ import { RateLimitError, ServerError, CanveleteError } from '../errors';
5
+ const defaultConfig = {
6
+ maxAttempts: 3,
7
+ backoffFactor: 2.0,
8
+ initialDelay: 1000,
9
+ maxDelay: 60000,
10
+ retryOn: [RateLimitError, ServerError],
11
+ };
12
+ /**
13
+ * Sleep for a specified duration
14
+ */
15
+ function sleep(ms) {
16
+ return new Promise(resolve => setTimeout(resolve, ms));
17
+ }
18
+ /**
19
+ * Execute a function with retry logic and exponential backoff
20
+ */
21
+ export async function withRetry(fn, config = {}) {
22
+ const cfg = { ...defaultConfig, ...config };
23
+ let attempt = 0;
24
+ let delay = cfg.initialDelay;
25
+ while (attempt < cfg.maxAttempts) {
26
+ try {
27
+ return await fn();
28
+ }
29
+ catch (error) {
30
+ attempt++;
31
+ // Check if we should retry this error
32
+ const shouldRetry = cfg.retryOn.some(ErrorClass => error instanceof ErrorClass);
33
+ if (!shouldRetry || attempt >= cfg.maxAttempts) {
34
+ throw error;
35
+ }
36
+ // Check for rate limit with retry-after header
37
+ if (error instanceof RateLimitError && error.retryAfter) {
38
+ delay = error.retryAfter * 1000;
39
+ console.warn(`Rate limited. Retrying after ${delay}ms (attempt ${attempt}/${cfg.maxAttempts})`);
40
+ }
41
+ else {
42
+ console.warn(`Attempt ${attempt}/${cfg.maxAttempts} failed: ${error.message}. ` +
43
+ `Retrying in ${delay}ms...`);
44
+ }
45
+ await sleep(delay);
46
+ // Exponential backoff
47
+ delay = Math.min(delay * cfg.backoffFactor, cfg.maxDelay);
48
+ }
49
+ }
50
+ // This should never be reached, but TypeScript needs it
51
+ throw new CanveleteError('Max retry attempts reached');
52
+ }
53
+ /**
54
+ * Create a retry wrapper for rate limit errors
55
+ */
56
+ export function retryOnRateLimit(fn) {
57
+ return withRetry(fn, {
58
+ maxAttempts: 5,
59
+ backoffFactor: 2,
60
+ retryOn: [RateLimitError, ServerError],
61
+ });
62
+ }
63
+ /**
64
+ * Decorator-style retry wrapper
65
+ */
66
+ export function createRetryWrapper(config = {}) {
67
+ return function (fn) {
68
+ return withRetry(fn, config);
69
+ };
70
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Element validation utilities
3
+ */
4
+ export interface ElementBase {
5
+ type: string;
6
+ x: number;
7
+ y: number;
8
+ width?: number;
9
+ height?: number;
10
+ }
11
+ export interface RectangleElement extends ElementBase {
12
+ type: 'rectangle';
13
+ fill?: string;
14
+ stroke?: string;
15
+ strokeWidth?: number;
16
+ borderRadius?: number;
17
+ opacity?: number;
18
+ }
19
+ export interface CircleElement extends ElementBase {
20
+ type: 'circle';
21
+ fill?: string;
22
+ stroke?: string;
23
+ strokeWidth?: number;
24
+ opacity?: number;
25
+ }
26
+ export interface TextElement extends ElementBase {
27
+ type: 'text';
28
+ text: string;
29
+ fontSize?: number;
30
+ fontFamily?: string;
31
+ fontWeight?: string;
32
+ fontStyle?: string;
33
+ fill?: string;
34
+ textAlign?: 'left' | 'center' | 'right' | 'justify';
35
+ lineHeight?: number;
36
+ }
37
+ export interface ImageElement extends ElementBase {
38
+ type: 'image';
39
+ src: string;
40
+ objectFit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down';
41
+ opacity?: number;
42
+ }
43
+ export interface LineElement extends ElementBase {
44
+ type: 'line';
45
+ linePoints?: Array<{
46
+ x: number;
47
+ y: number;
48
+ }>;
49
+ stroke?: string;
50
+ strokeWidth?: number;
51
+ lineCap?: 'butt' | 'round' | 'square';
52
+ }
53
+ export type CanvasElement = RectangleElement | CircleElement | TextElement | ImageElement | LineElement | ElementBase;
54
+ /**
55
+ * Validate an element's basic properties
56
+ */
57
+ export declare function validateElement(element: Record<string, any>): void;
58
+ /**
59
+ * Validate canvas dimensions
60
+ */
61
+ export declare function validateCanvasDimensions(width: number, height: number): void;
62
+ /**
63
+ * Validate render options
64
+ */
65
+ export declare function validateRenderOptions(options: Record<string, any>): void;
66
+ /**
67
+ * Validate color format
68
+ */
69
+ export declare function validateColor(color: string): boolean;