chartsplat 1.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 ADDED
@@ -0,0 +1,311 @@
1
+ # chartsplat
2
+
3
+ Official TypeScript/JavaScript client for [Chart Splat](https://chartsplat.com) - Generate beautiful charts via API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install chartsplat
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { ChartSplat } from 'chartsplat';
15
+
16
+ const client = new ChartSplat('YOUR_API_KEY');
17
+
18
+ // Generate a bar chart
19
+ const chart = await client.generateChart({
20
+ type: 'bar',
21
+ data: {
22
+ labels: ['Jan', 'Feb', 'Mar', 'Apr'],
23
+ datasets: [{
24
+ label: 'Revenue',
25
+ data: [12, 19, 3, 5],
26
+ backgroundColor: '#8b5cf6'
27
+ }]
28
+ }
29
+ });
30
+
31
+ // Use the base64 image
32
+ console.log(chart.image); // data:image/png;base64,...
33
+
34
+ // Use in HTML
35
+ const img = document.createElement('img');
36
+ img.src = chart.image;
37
+ ```
38
+
39
+ ## Features
40
+
41
+ - Full TypeScript support
42
+ - Works in Node.js (18+) and browsers
43
+ - Convenience methods for all chart types
44
+ - Rate limit tracking
45
+ - Timeout handling
46
+ - Custom fetch support for older Node.js versions
47
+
48
+ ## Usage
49
+
50
+ ### Basic Example
51
+
52
+ ```typescript
53
+ import { ChartSplat } from 'chartsplat';
54
+
55
+ const client = new ChartSplat('cs_your_api_key');
56
+
57
+ const chart = await client.generateChart({
58
+ type: 'line',
59
+ data: {
60
+ labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
61
+ datasets: [{
62
+ label: 'Visitors',
63
+ data: [100, 200, 150, 300, 250],
64
+ borderColor: '#3b82f6',
65
+ fill: false
66
+ }]
67
+ },
68
+ options: {
69
+ width: 1200,
70
+ height: 800
71
+ }
72
+ });
73
+ ```
74
+
75
+ ### Convenience Methods
76
+
77
+ ```typescript
78
+ // Line chart
79
+ const lineChart = await client.lineChart({
80
+ labels: ['A', 'B', 'C'],
81
+ datasets: [{ data: [1, 2, 3], borderColor: '#3b82f6' }]
82
+ });
83
+
84
+ // Bar chart
85
+ const barChart = await client.barChart({
86
+ labels: ['A', 'B', 'C'],
87
+ datasets: [{ data: [1, 2, 3], backgroundColor: '#8b5cf6' }]
88
+ });
89
+
90
+ // Pie chart
91
+ const pieChart = await client.pieChart({
92
+ labels: ['Red', 'Blue', 'Yellow'],
93
+ datasets: [{ data: [30, 50, 20], backgroundColor: ['#ef4444', '#3b82f6', '#eab308'] }]
94
+ });
95
+
96
+ // Doughnut chart
97
+ const doughnutChart = await client.doughnutChart({
98
+ labels: ['Desktop', 'Mobile'],
99
+ datasets: [{ data: [60, 40], backgroundColor: ['#8b5cf6', '#ec4899'] }]
100
+ });
101
+
102
+ // Radar chart
103
+ const radarChart = await client.radarChart({
104
+ labels: ['Speed', 'Power', 'Range'],
105
+ datasets: [{ label: 'Player', data: [65, 59, 90], borderColor: '#f59e0b' }]
106
+ });
107
+
108
+ // Polar area chart
109
+ const polarChart = await client.polarAreaChart({
110
+ labels: ['Red', 'Green', 'Blue'],
111
+ datasets: [{ data: [11, 16, 7], backgroundColor: ['#ef4444', '#10b981', '#3b82f6'] }]
112
+ });
113
+ ```
114
+
115
+ ### Save to File (Node.js)
116
+
117
+ ```typescript
118
+ import fs from 'fs';
119
+ import { ChartSplat } from 'chartsplat';
120
+
121
+ const client = new ChartSplat('cs_your_api_key');
122
+
123
+ const chart = await client.generateChart({
124
+ type: 'bar',
125
+ data: {
126
+ labels: ['A', 'B', 'C'],
127
+ datasets: [{ data: [1, 2, 3] }]
128
+ }
129
+ });
130
+
131
+ // Remove the data URI prefix and decode
132
+ const base64Data = chart.image.replace(/^data:image\/png;base64,/, '');
133
+ fs.writeFileSync('chart.png', Buffer.from(base64Data, 'base64'));
134
+ ```
135
+
136
+ ### React Example
137
+
138
+ ```tsx
139
+ import { ChartSplat } from 'chartsplat';
140
+ import { useState, useEffect } from 'react';
141
+
142
+ const client = new ChartSplat('cs_your_api_key');
143
+
144
+ function MyChart() {
145
+ const [chartUrl, setChartUrl] = useState<string | null>(null);
146
+ const [error, setError] = useState<string | null>(null);
147
+
148
+ useEffect(() => {
149
+ async function loadChart() {
150
+ try {
151
+ const chart = await client.generateChart({
152
+ type: 'line',
153
+ data: {
154
+ labels: ['Jan', 'Feb', 'Mar'],
155
+ datasets: [{
156
+ label: 'Sales',
157
+ data: [100, 200, 150],
158
+ borderColor: '#ec4899'
159
+ }]
160
+ }
161
+ });
162
+ setChartUrl(chart.image);
163
+ } catch (err) {
164
+ setError(err.message);
165
+ }
166
+ }
167
+ loadChart();
168
+ }, []);
169
+
170
+ if (error) return <div>Error: {error}</div>;
171
+ if (!chartUrl) return <div>Loading...</div>;
172
+ return <img src={chartUrl} alt="Chart" />;
173
+ }
174
+ ```
175
+
176
+ ### Rate Limit Handling
177
+
178
+ ```typescript
179
+ import { ChartSplat, ChartSplatAPIError } from 'chartsplat';
180
+
181
+ const client = new ChartSplat('cs_your_api_key');
182
+
183
+ try {
184
+ const chart = await client.generateChart({ /* ... */ });
185
+
186
+ // Check rate limit after request
187
+ const rateLimit = client.getRateLimit();
188
+ console.log(`${rateLimit.remaining}/${rateLimit.limit} requests remaining`);
189
+ console.log(`Resets at: ${rateLimit.reset}`);
190
+ } catch (error) {
191
+ if (error instanceof ChartSplatAPIError && error.status === 429) {
192
+ console.log('Rate limited!');
193
+ console.log(`Limit: ${error.rateLimit?.limit}`);
194
+ console.log(`Resets at: ${error.rateLimit?.reset}`);
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### Custom Configuration
200
+
201
+ ```typescript
202
+ import { ChartSplat } from 'chartsplat';
203
+
204
+ const client = new ChartSplat('cs_your_api_key', {
205
+ // Custom base URL (for local development)
206
+ baseUrl: 'http://localhost:3001',
207
+
208
+ // Request timeout in milliseconds
209
+ timeout: 60000,
210
+
211
+ // Custom fetch (for Node.js < 18)
212
+ fetch: require('node-fetch'),
213
+ });
214
+ ```
215
+
216
+ ## API Reference
217
+
218
+ ### `ChartSplat` Class
219
+
220
+ #### Constructor
221
+
222
+ ```typescript
223
+ new ChartSplat(apiKey: string, options?: ChartSplatOptions)
224
+ ```
225
+
226
+ - `apiKey` - Your Chart Splat API key (starts with `cs_`)
227
+ - `options.baseUrl` - Base URL for the API (default: `https://api.chartsplat.com`)
228
+ - `options.timeout` - Request timeout in ms (default: `30000`)
229
+ - `options.fetch` - Custom fetch implementation
230
+
231
+ #### Methods
232
+
233
+ - `generateChart(request: ChartRequest): Promise<ChartResponse>` - Generate any chart type
234
+ - `lineChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a line chart
235
+ - `barChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a bar chart
236
+ - `pieChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a pie chart
237
+ - `doughnutChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a doughnut chart
238
+ - `radarChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a radar chart
239
+ - `polarAreaChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>` - Generate a polar area chart
240
+ - `getRateLimit(): RateLimitInfo | undefined` - Get rate limit info from last request
241
+
242
+ ### Types
243
+
244
+ ```typescript
245
+ interface ChartRequest {
246
+ type?: 'line' | 'bar' | 'pie' | 'doughnut' | 'radar' | 'polarArea';
247
+ data: ChartData;
248
+ options?: ChartOptions;
249
+ }
250
+
251
+ interface ChartData {
252
+ labels: string[];
253
+ datasets: Dataset[];
254
+ }
255
+
256
+ interface Dataset {
257
+ label?: string;
258
+ data: number[];
259
+ backgroundColor?: string | string[];
260
+ borderColor?: string | string[];
261
+ borderWidth?: number;
262
+ fill?: boolean;
263
+ }
264
+
265
+ interface ChartOptions {
266
+ width?: number; // Default: 800
267
+ height?: number; // Default: 600
268
+ plugins?: Record<string, unknown>;
269
+ scales?: Record<string, unknown>;
270
+ }
271
+
272
+ interface ChartResponse {
273
+ image: string; // Base64 PNG with data URI prefix
274
+ format: 'png';
275
+ width: number;
276
+ height: number;
277
+ }
278
+ ```
279
+
280
+ ## Error Handling
281
+
282
+ The client throws typed errors for different failure scenarios:
283
+
284
+ ```typescript
285
+ import { ChartSplat, ChartSplatAPIError, ChartSplatTimeoutError } from 'chartsplat';
286
+
287
+ try {
288
+ const chart = await client.generateChart({ /* ... */ });
289
+ } catch (error) {
290
+ if (error instanceof ChartSplatAPIError) {
291
+ console.log('API Error:', error.message);
292
+ console.log('Status:', error.status);
293
+ console.log('Code:', error.code);
294
+ } else if (error instanceof ChartSplatTimeoutError) {
295
+ console.log('Request timed out');
296
+ } else {
297
+ console.log('Unknown error:', error);
298
+ }
299
+ }
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT - see [LICENSE](./LICENSE) for details.
305
+
306
+ ## Links
307
+
308
+ - [Website](https://chartsplat.com)
309
+ - [Documentation](https://chartsplat.com/docs)
310
+ - [Pricing](https://chartsplat.com/pricing)
311
+ - [OpenAPI Spec](https://chartsplat.com/openapi.yaml)
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Chart Splat - Official TypeScript/JavaScript Client
3
+ *
4
+ * Generate beautiful charts via API using Chart.js configuration.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { ChartSplat } from 'chartsplat';
9
+ *
10
+ * const client = new ChartSplat('YOUR_API_KEY');
11
+ *
12
+ * const chart = await client.generateChart({
13
+ * type: 'bar',
14
+ * data: {
15
+ * labels: ['Jan', 'Feb', 'Mar'],
16
+ * datasets: [{
17
+ * label: 'Revenue',
18
+ * data: [12, 19, 3],
19
+ * backgroundColor: '#8b5cf6'
20
+ * }]
21
+ * }
22
+ * });
23
+ *
24
+ * console.log(chart.image); // data:image/png;base64,...
25
+ * ```
26
+ */
27
+ /** Chart types supported by Chart Splat */
28
+ type ChartType = 'line' | 'bar' | 'pie' | 'doughnut' | 'radar' | 'polarArea';
29
+ /** Dataset configuration for a chart */
30
+ interface Dataset {
31
+ /** Label for the dataset (shown in legend) */
32
+ label?: string;
33
+ /** Data points for the dataset */
34
+ data: number[];
35
+ /** Background color(s) for the dataset */
36
+ backgroundColor?: string | string[];
37
+ /** Border color(s) for the dataset */
38
+ borderColor?: string | string[];
39
+ /** Border width in pixels */
40
+ borderWidth?: number;
41
+ /** Whether to fill the area under line charts */
42
+ fill?: boolean;
43
+ /** Additional Chart.js dataset options */
44
+ [key: string]: unknown;
45
+ }
46
+ /** Chart data configuration */
47
+ interface ChartData {
48
+ /** Labels for the X-axis or segments */
49
+ labels: string[];
50
+ /** Array of datasets to display */
51
+ datasets: Dataset[];
52
+ }
53
+ /** Chart options configuration */
54
+ interface ChartOptions {
55
+ /** Image width in pixels (default: 800) */
56
+ width?: number;
57
+ /** Image height in pixels (default: 600) */
58
+ height?: number;
59
+ /** Chart.js plugin options */
60
+ plugins?: Record<string, unknown>;
61
+ /** Chart.js scale options */
62
+ scales?: Record<string, unknown>;
63
+ /** Additional Chart.js options */
64
+ [key: string]: unknown;
65
+ }
66
+ /** Request payload for chart generation */
67
+ interface ChartRequest {
68
+ /** The type of chart to generate (default: 'line') */
69
+ type?: ChartType;
70
+ /** Chart data configuration */
71
+ data: ChartData;
72
+ /** Chart options */
73
+ options?: ChartOptions;
74
+ }
75
+ /** Response from chart generation */
76
+ interface ChartResponse {
77
+ /** Base64-encoded PNG image with data URI prefix */
78
+ image: string;
79
+ /** Image format (always 'png') */
80
+ format: 'png';
81
+ /** Image width in pixels */
82
+ width: number;
83
+ /** Image height in pixels */
84
+ height: number;
85
+ }
86
+ /** Error response from the API */
87
+ interface ChartSplatError {
88
+ /** Error type or message */
89
+ error: string;
90
+ /** Detailed error message */
91
+ message?: string;
92
+ /** Rate limit (if applicable) */
93
+ limit?: number;
94
+ /** Requests used (if applicable) */
95
+ used?: number;
96
+ /** Current plan (if applicable) */
97
+ plan?: string;
98
+ }
99
+ /** Rate limit information from response headers */
100
+ interface RateLimitInfo {
101
+ /** Monthly request limit */
102
+ limit: number;
103
+ /** Requests remaining this month */
104
+ remaining: number;
105
+ /** When the limit resets (ISO 8601 date) */
106
+ reset: string;
107
+ }
108
+ /** Options for the ChartSplat client */
109
+ interface ChartSplatOptions {
110
+ /** Base URL for the API (default: https://api.chartsplat.com) */
111
+ baseUrl?: string;
112
+ /** Request timeout in milliseconds (default: 30000) */
113
+ timeout?: number;
114
+ /** Custom fetch implementation (for Node.js < 18 or testing) */
115
+ fetch?: typeof fetch;
116
+ }
117
+ /** Error thrown when the API returns an error response */
118
+ declare class ChartSplatAPIError extends Error {
119
+ /** HTTP status code */
120
+ readonly status: number;
121
+ /** Error code from the API */
122
+ readonly code: string;
123
+ /** Rate limit info (if rate limited) */
124
+ readonly rateLimit?: RateLimitInfo;
125
+ constructor(message: string, status: number, code: string, rateLimit?: RateLimitInfo);
126
+ }
127
+ /** Error thrown when a request times out */
128
+ declare class ChartSplatTimeoutError extends Error {
129
+ constructor(timeout: number);
130
+ }
131
+ /**
132
+ * Chart Splat API Client
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const client = new ChartSplat('YOUR_API_KEY');
137
+ *
138
+ * // Generate a simple bar chart
139
+ * const chart = await client.generateChart({
140
+ * type: 'bar',
141
+ * data: {
142
+ * labels: ['A', 'B', 'C'],
143
+ * datasets: [{ data: [1, 2, 3] }]
144
+ * }
145
+ * });
146
+ * ```
147
+ */
148
+ declare class ChartSplat {
149
+ private readonly apiKey;
150
+ private readonly baseUrl;
151
+ private readonly timeout;
152
+ private readonly fetchFn;
153
+ /** Rate limit info from the last request */
154
+ lastRateLimit?: RateLimitInfo;
155
+ /**
156
+ * Create a new Chart Splat client
157
+ *
158
+ * @param apiKey - Your Chart Splat API key (starts with 'cs_')
159
+ * @param options - Client configuration options
160
+ */
161
+ constructor(apiKey: string, options?: ChartSplatOptions);
162
+ /**
163
+ * Generate a chart image
164
+ *
165
+ * @param request - Chart configuration
166
+ * @returns Chart response with base64 image
167
+ * @throws {ChartSplatAPIError} If the API returns an error
168
+ * @throws {ChartSplatTimeoutError} If the request times out
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const chart = await client.generateChart({
173
+ * type: 'line',
174
+ * data: {
175
+ * labels: ['Jan', 'Feb', 'Mar'],
176
+ * datasets: [{
177
+ * label: 'Sales',
178
+ * data: [100, 200, 150],
179
+ * borderColor: '#3b82f6'
180
+ * }]
181
+ * },
182
+ * options: {
183
+ * width: 1200,
184
+ * height: 800
185
+ * }
186
+ * });
187
+ * ```
188
+ */
189
+ generateChart(request: ChartRequest): Promise<ChartResponse>;
190
+ /**
191
+ * Generate a line chart
192
+ *
193
+ * @param data - Chart data
194
+ * @param options - Chart options
195
+ * @returns Chart response with base64 image
196
+ */
197
+ lineChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
198
+ /**
199
+ * Generate a bar chart
200
+ *
201
+ * @param data - Chart data
202
+ * @param options - Chart options
203
+ * @returns Chart response with base64 image
204
+ */
205
+ barChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
206
+ /**
207
+ * Generate a pie chart
208
+ *
209
+ * @param data - Chart data
210
+ * @param options - Chart options
211
+ * @returns Chart response with base64 image
212
+ */
213
+ pieChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
214
+ /**
215
+ * Generate a doughnut chart
216
+ *
217
+ * @param data - Chart data
218
+ * @param options - Chart options
219
+ * @returns Chart response with base64 image
220
+ */
221
+ doughnutChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
222
+ /**
223
+ * Generate a radar chart
224
+ *
225
+ * @param data - Chart data
226
+ * @param options - Chart options
227
+ * @returns Chart response with base64 image
228
+ */
229
+ radarChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
230
+ /**
231
+ * Generate a polar area chart
232
+ *
233
+ * @param data - Chart data
234
+ * @param options - Chart options
235
+ * @returns Chart response with base64 image
236
+ */
237
+ polarAreaChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
238
+ /**
239
+ * Get rate limit information from the last request
240
+ *
241
+ * @returns Rate limit info or undefined if no request has been made
242
+ */
243
+ getRateLimit(): RateLimitInfo | undefined;
244
+ }
245
+
246
+ export { type ChartData, type ChartOptions, type ChartRequest, type ChartResponse, ChartSplat, ChartSplatAPIError, type ChartSplatError, type ChartSplatOptions, ChartSplatTimeoutError, type ChartType, type Dataset, type RateLimitInfo, ChartSplat as default };
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Chart Splat - Official TypeScript/JavaScript Client
3
+ *
4
+ * Generate beautiful charts via API using Chart.js configuration.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { ChartSplat } from 'chartsplat';
9
+ *
10
+ * const client = new ChartSplat('YOUR_API_KEY');
11
+ *
12
+ * const chart = await client.generateChart({
13
+ * type: 'bar',
14
+ * data: {
15
+ * labels: ['Jan', 'Feb', 'Mar'],
16
+ * datasets: [{
17
+ * label: 'Revenue',
18
+ * data: [12, 19, 3],
19
+ * backgroundColor: '#8b5cf6'
20
+ * }]
21
+ * }
22
+ * });
23
+ *
24
+ * console.log(chart.image); // data:image/png;base64,...
25
+ * ```
26
+ */
27
+ /** Chart types supported by Chart Splat */
28
+ type ChartType = 'line' | 'bar' | 'pie' | 'doughnut' | 'radar' | 'polarArea';
29
+ /** Dataset configuration for a chart */
30
+ interface Dataset {
31
+ /** Label for the dataset (shown in legend) */
32
+ label?: string;
33
+ /** Data points for the dataset */
34
+ data: number[];
35
+ /** Background color(s) for the dataset */
36
+ backgroundColor?: string | string[];
37
+ /** Border color(s) for the dataset */
38
+ borderColor?: string | string[];
39
+ /** Border width in pixels */
40
+ borderWidth?: number;
41
+ /** Whether to fill the area under line charts */
42
+ fill?: boolean;
43
+ /** Additional Chart.js dataset options */
44
+ [key: string]: unknown;
45
+ }
46
+ /** Chart data configuration */
47
+ interface ChartData {
48
+ /** Labels for the X-axis or segments */
49
+ labels: string[];
50
+ /** Array of datasets to display */
51
+ datasets: Dataset[];
52
+ }
53
+ /** Chart options configuration */
54
+ interface ChartOptions {
55
+ /** Image width in pixels (default: 800) */
56
+ width?: number;
57
+ /** Image height in pixels (default: 600) */
58
+ height?: number;
59
+ /** Chart.js plugin options */
60
+ plugins?: Record<string, unknown>;
61
+ /** Chart.js scale options */
62
+ scales?: Record<string, unknown>;
63
+ /** Additional Chart.js options */
64
+ [key: string]: unknown;
65
+ }
66
+ /** Request payload for chart generation */
67
+ interface ChartRequest {
68
+ /** The type of chart to generate (default: 'line') */
69
+ type?: ChartType;
70
+ /** Chart data configuration */
71
+ data: ChartData;
72
+ /** Chart options */
73
+ options?: ChartOptions;
74
+ }
75
+ /** Response from chart generation */
76
+ interface ChartResponse {
77
+ /** Base64-encoded PNG image with data URI prefix */
78
+ image: string;
79
+ /** Image format (always 'png') */
80
+ format: 'png';
81
+ /** Image width in pixels */
82
+ width: number;
83
+ /** Image height in pixels */
84
+ height: number;
85
+ }
86
+ /** Error response from the API */
87
+ interface ChartSplatError {
88
+ /** Error type or message */
89
+ error: string;
90
+ /** Detailed error message */
91
+ message?: string;
92
+ /** Rate limit (if applicable) */
93
+ limit?: number;
94
+ /** Requests used (if applicable) */
95
+ used?: number;
96
+ /** Current plan (if applicable) */
97
+ plan?: string;
98
+ }
99
+ /** Rate limit information from response headers */
100
+ interface RateLimitInfo {
101
+ /** Monthly request limit */
102
+ limit: number;
103
+ /** Requests remaining this month */
104
+ remaining: number;
105
+ /** When the limit resets (ISO 8601 date) */
106
+ reset: string;
107
+ }
108
+ /** Options for the ChartSplat client */
109
+ interface ChartSplatOptions {
110
+ /** Base URL for the API (default: https://api.chartsplat.com) */
111
+ baseUrl?: string;
112
+ /** Request timeout in milliseconds (default: 30000) */
113
+ timeout?: number;
114
+ /** Custom fetch implementation (for Node.js < 18 or testing) */
115
+ fetch?: typeof fetch;
116
+ }
117
+ /** Error thrown when the API returns an error response */
118
+ declare class ChartSplatAPIError extends Error {
119
+ /** HTTP status code */
120
+ readonly status: number;
121
+ /** Error code from the API */
122
+ readonly code: string;
123
+ /** Rate limit info (if rate limited) */
124
+ readonly rateLimit?: RateLimitInfo;
125
+ constructor(message: string, status: number, code: string, rateLimit?: RateLimitInfo);
126
+ }
127
+ /** Error thrown when a request times out */
128
+ declare class ChartSplatTimeoutError extends Error {
129
+ constructor(timeout: number);
130
+ }
131
+ /**
132
+ * Chart Splat API Client
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const client = new ChartSplat('YOUR_API_KEY');
137
+ *
138
+ * // Generate a simple bar chart
139
+ * const chart = await client.generateChart({
140
+ * type: 'bar',
141
+ * data: {
142
+ * labels: ['A', 'B', 'C'],
143
+ * datasets: [{ data: [1, 2, 3] }]
144
+ * }
145
+ * });
146
+ * ```
147
+ */
148
+ declare class ChartSplat {
149
+ private readonly apiKey;
150
+ private readonly baseUrl;
151
+ private readonly timeout;
152
+ private readonly fetchFn;
153
+ /** Rate limit info from the last request */
154
+ lastRateLimit?: RateLimitInfo;
155
+ /**
156
+ * Create a new Chart Splat client
157
+ *
158
+ * @param apiKey - Your Chart Splat API key (starts with 'cs_')
159
+ * @param options - Client configuration options
160
+ */
161
+ constructor(apiKey: string, options?: ChartSplatOptions);
162
+ /**
163
+ * Generate a chart image
164
+ *
165
+ * @param request - Chart configuration
166
+ * @returns Chart response with base64 image
167
+ * @throws {ChartSplatAPIError} If the API returns an error
168
+ * @throws {ChartSplatTimeoutError} If the request times out
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const chart = await client.generateChart({
173
+ * type: 'line',
174
+ * data: {
175
+ * labels: ['Jan', 'Feb', 'Mar'],
176
+ * datasets: [{
177
+ * label: 'Sales',
178
+ * data: [100, 200, 150],
179
+ * borderColor: '#3b82f6'
180
+ * }]
181
+ * },
182
+ * options: {
183
+ * width: 1200,
184
+ * height: 800
185
+ * }
186
+ * });
187
+ * ```
188
+ */
189
+ generateChart(request: ChartRequest): Promise<ChartResponse>;
190
+ /**
191
+ * Generate a line chart
192
+ *
193
+ * @param data - Chart data
194
+ * @param options - Chart options
195
+ * @returns Chart response with base64 image
196
+ */
197
+ lineChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
198
+ /**
199
+ * Generate a bar chart
200
+ *
201
+ * @param data - Chart data
202
+ * @param options - Chart options
203
+ * @returns Chart response with base64 image
204
+ */
205
+ barChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
206
+ /**
207
+ * Generate a pie chart
208
+ *
209
+ * @param data - Chart data
210
+ * @param options - Chart options
211
+ * @returns Chart response with base64 image
212
+ */
213
+ pieChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
214
+ /**
215
+ * Generate a doughnut chart
216
+ *
217
+ * @param data - Chart data
218
+ * @param options - Chart options
219
+ * @returns Chart response with base64 image
220
+ */
221
+ doughnutChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
222
+ /**
223
+ * Generate a radar chart
224
+ *
225
+ * @param data - Chart data
226
+ * @param options - Chart options
227
+ * @returns Chart response with base64 image
228
+ */
229
+ radarChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
230
+ /**
231
+ * Generate a polar area chart
232
+ *
233
+ * @param data - Chart data
234
+ * @param options - Chart options
235
+ * @returns Chart response with base64 image
236
+ */
237
+ polarAreaChart(data: ChartData, options?: ChartOptions): Promise<ChartResponse>;
238
+ /**
239
+ * Get rate limit information from the last request
240
+ *
241
+ * @returns Rate limit info or undefined if no request has been made
242
+ */
243
+ getRateLimit(): RateLimitInfo | undefined;
244
+ }
245
+
246
+ export { type ChartData, type ChartOptions, type ChartRequest, type ChartResponse, ChartSplat, ChartSplatAPIError, type ChartSplatError, type ChartSplatOptions, ChartSplatTimeoutError, type ChartType, type Dataset, type RateLimitInfo, ChartSplat as default };
package/dist/index.js ADDED
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ChartSplat: () => ChartSplat,
24
+ ChartSplatAPIError: () => ChartSplatAPIError,
25
+ ChartSplatTimeoutError: () => ChartSplatTimeoutError,
26
+ default: () => index_default
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var ChartSplatAPIError = class extends Error {
30
+ constructor(message, status, code, rateLimit) {
31
+ super(message);
32
+ this.name = "ChartSplatAPIError";
33
+ this.status = status;
34
+ this.code = code;
35
+ this.rateLimit = rateLimit;
36
+ }
37
+ };
38
+ var ChartSplatTimeoutError = class extends Error {
39
+ constructor(timeout) {
40
+ super(`Request timed out after ${timeout}ms`);
41
+ this.name = "ChartSplatTimeoutError";
42
+ }
43
+ };
44
+ var ChartSplat = class {
45
+ /**
46
+ * Create a new Chart Splat client
47
+ *
48
+ * @param apiKey - Your Chart Splat API key (starts with 'cs_')
49
+ * @param options - Client configuration options
50
+ */
51
+ constructor(apiKey, options = {}) {
52
+ if (!apiKey) {
53
+ throw new Error("API key is required");
54
+ }
55
+ if (!apiKey.startsWith("cs_")) {
56
+ throw new Error('Invalid API key format. API keys start with "cs_"');
57
+ }
58
+ this.apiKey = apiKey;
59
+ this.baseUrl = options.baseUrl || "https://api.chartsplat.com";
60
+ this.timeout = options.timeout || 3e4;
61
+ this.fetchFn = options.fetch || globalThis.fetch;
62
+ if (!this.fetchFn) {
63
+ throw new Error(
64
+ "fetch is not available. Please provide a fetch implementation or upgrade to Node.js 18+"
65
+ );
66
+ }
67
+ }
68
+ /**
69
+ * Generate a chart image
70
+ *
71
+ * @param request - Chart configuration
72
+ * @returns Chart response with base64 image
73
+ * @throws {ChartSplatAPIError} If the API returns an error
74
+ * @throws {ChartSplatTimeoutError} If the request times out
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const chart = await client.generateChart({
79
+ * type: 'line',
80
+ * data: {
81
+ * labels: ['Jan', 'Feb', 'Mar'],
82
+ * datasets: [{
83
+ * label: 'Sales',
84
+ * data: [100, 200, 150],
85
+ * borderColor: '#3b82f6'
86
+ * }]
87
+ * },
88
+ * options: {
89
+ * width: 1200,
90
+ * height: 800
91
+ * }
92
+ * });
93
+ * ```
94
+ */
95
+ async generateChart(request) {
96
+ if (!request.data) {
97
+ throw new Error("data is required");
98
+ }
99
+ if (!request.data.labels || !Array.isArray(request.data.labels)) {
100
+ throw new Error("data.labels is required and must be an array");
101
+ }
102
+ if (!request.data.datasets || !Array.isArray(request.data.datasets)) {
103
+ throw new Error("data.datasets is required and must be an array");
104
+ }
105
+ const controller = new AbortController();
106
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
107
+ try {
108
+ const response = await this.fetchFn(`${this.baseUrl}/chart`, {
109
+ method: "POST",
110
+ headers: {
111
+ "X-Api-Key": this.apiKey,
112
+ "Content-Type": "application/json"
113
+ },
114
+ body: JSON.stringify(request),
115
+ signal: controller.signal
116
+ });
117
+ this.lastRateLimit = {
118
+ limit: parseInt(response.headers.get("X-RateLimit-Limit") || "0", 10),
119
+ remaining: parseInt(response.headers.get("X-RateLimit-Remaining") || "0", 10),
120
+ reset: response.headers.get("X-RateLimit-Reset") || ""
121
+ };
122
+ if (!response.ok) {
123
+ const errorData = await response.json();
124
+ throw new ChartSplatAPIError(
125
+ errorData.message || errorData.error,
126
+ response.status,
127
+ errorData.error,
128
+ response.status === 429 ? this.lastRateLimit : void 0
129
+ );
130
+ }
131
+ return await response.json();
132
+ } catch (error) {
133
+ if (error instanceof ChartSplatAPIError) {
134
+ throw error;
135
+ }
136
+ if (error instanceof Error && error.name === "AbortError") {
137
+ throw new ChartSplatTimeoutError(this.timeout);
138
+ }
139
+ throw error;
140
+ } finally {
141
+ clearTimeout(timeoutId);
142
+ }
143
+ }
144
+ /**
145
+ * Generate a line chart
146
+ *
147
+ * @param data - Chart data
148
+ * @param options - Chart options
149
+ * @returns Chart response with base64 image
150
+ */
151
+ async lineChart(data, options) {
152
+ return this.generateChart({ type: "line", data, options });
153
+ }
154
+ /**
155
+ * Generate a bar chart
156
+ *
157
+ * @param data - Chart data
158
+ * @param options - Chart options
159
+ * @returns Chart response with base64 image
160
+ */
161
+ async barChart(data, options) {
162
+ return this.generateChart({ type: "bar", data, options });
163
+ }
164
+ /**
165
+ * Generate a pie chart
166
+ *
167
+ * @param data - Chart data
168
+ * @param options - Chart options
169
+ * @returns Chart response with base64 image
170
+ */
171
+ async pieChart(data, options) {
172
+ return this.generateChart({ type: "pie", data, options });
173
+ }
174
+ /**
175
+ * Generate a doughnut chart
176
+ *
177
+ * @param data - Chart data
178
+ * @param options - Chart options
179
+ * @returns Chart response with base64 image
180
+ */
181
+ async doughnutChart(data, options) {
182
+ return this.generateChart({ type: "doughnut", data, options });
183
+ }
184
+ /**
185
+ * Generate a radar chart
186
+ *
187
+ * @param data - Chart data
188
+ * @param options - Chart options
189
+ * @returns Chart response with base64 image
190
+ */
191
+ async radarChart(data, options) {
192
+ return this.generateChart({ type: "radar", data, options });
193
+ }
194
+ /**
195
+ * Generate a polar area chart
196
+ *
197
+ * @param data - Chart data
198
+ * @param options - Chart options
199
+ * @returns Chart response with base64 image
200
+ */
201
+ async polarAreaChart(data, options) {
202
+ return this.generateChart({ type: "polarArea", data, options });
203
+ }
204
+ /**
205
+ * Get rate limit information from the last request
206
+ *
207
+ * @returns Rate limit info or undefined if no request has been made
208
+ */
209
+ getRateLimit() {
210
+ return this.lastRateLimit;
211
+ }
212
+ };
213
+ var index_default = ChartSplat;
214
+ // Annotate the CommonJS export names for ESM import in node:
215
+ 0 && (module.exports = {
216
+ ChartSplat,
217
+ ChartSplatAPIError,
218
+ ChartSplatTimeoutError
219
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,192 @@
1
+ // src/index.ts
2
+ var ChartSplatAPIError = class extends Error {
3
+ constructor(message, status, code, rateLimit) {
4
+ super(message);
5
+ this.name = "ChartSplatAPIError";
6
+ this.status = status;
7
+ this.code = code;
8
+ this.rateLimit = rateLimit;
9
+ }
10
+ };
11
+ var ChartSplatTimeoutError = class extends Error {
12
+ constructor(timeout) {
13
+ super(`Request timed out after ${timeout}ms`);
14
+ this.name = "ChartSplatTimeoutError";
15
+ }
16
+ };
17
+ var ChartSplat = class {
18
+ /**
19
+ * Create a new Chart Splat client
20
+ *
21
+ * @param apiKey - Your Chart Splat API key (starts with 'cs_')
22
+ * @param options - Client configuration options
23
+ */
24
+ constructor(apiKey, options = {}) {
25
+ if (!apiKey) {
26
+ throw new Error("API key is required");
27
+ }
28
+ if (!apiKey.startsWith("cs_")) {
29
+ throw new Error('Invalid API key format. API keys start with "cs_"');
30
+ }
31
+ this.apiKey = apiKey;
32
+ this.baseUrl = options.baseUrl || "https://api.chartsplat.com";
33
+ this.timeout = options.timeout || 3e4;
34
+ this.fetchFn = options.fetch || globalThis.fetch;
35
+ if (!this.fetchFn) {
36
+ throw new Error(
37
+ "fetch is not available. Please provide a fetch implementation or upgrade to Node.js 18+"
38
+ );
39
+ }
40
+ }
41
+ /**
42
+ * Generate a chart image
43
+ *
44
+ * @param request - Chart configuration
45
+ * @returns Chart response with base64 image
46
+ * @throws {ChartSplatAPIError} If the API returns an error
47
+ * @throws {ChartSplatTimeoutError} If the request times out
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const chart = await client.generateChart({
52
+ * type: 'line',
53
+ * data: {
54
+ * labels: ['Jan', 'Feb', 'Mar'],
55
+ * datasets: [{
56
+ * label: 'Sales',
57
+ * data: [100, 200, 150],
58
+ * borderColor: '#3b82f6'
59
+ * }]
60
+ * },
61
+ * options: {
62
+ * width: 1200,
63
+ * height: 800
64
+ * }
65
+ * });
66
+ * ```
67
+ */
68
+ async generateChart(request) {
69
+ if (!request.data) {
70
+ throw new Error("data is required");
71
+ }
72
+ if (!request.data.labels || !Array.isArray(request.data.labels)) {
73
+ throw new Error("data.labels is required and must be an array");
74
+ }
75
+ if (!request.data.datasets || !Array.isArray(request.data.datasets)) {
76
+ throw new Error("data.datasets is required and must be an array");
77
+ }
78
+ const controller = new AbortController();
79
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
80
+ try {
81
+ const response = await this.fetchFn(`${this.baseUrl}/chart`, {
82
+ method: "POST",
83
+ headers: {
84
+ "X-Api-Key": this.apiKey,
85
+ "Content-Type": "application/json"
86
+ },
87
+ body: JSON.stringify(request),
88
+ signal: controller.signal
89
+ });
90
+ this.lastRateLimit = {
91
+ limit: parseInt(response.headers.get("X-RateLimit-Limit") || "0", 10),
92
+ remaining: parseInt(response.headers.get("X-RateLimit-Remaining") || "0", 10),
93
+ reset: response.headers.get("X-RateLimit-Reset") || ""
94
+ };
95
+ if (!response.ok) {
96
+ const errorData = await response.json();
97
+ throw new ChartSplatAPIError(
98
+ errorData.message || errorData.error,
99
+ response.status,
100
+ errorData.error,
101
+ response.status === 429 ? this.lastRateLimit : void 0
102
+ );
103
+ }
104
+ return await response.json();
105
+ } catch (error) {
106
+ if (error instanceof ChartSplatAPIError) {
107
+ throw error;
108
+ }
109
+ if (error instanceof Error && error.name === "AbortError") {
110
+ throw new ChartSplatTimeoutError(this.timeout);
111
+ }
112
+ throw error;
113
+ } finally {
114
+ clearTimeout(timeoutId);
115
+ }
116
+ }
117
+ /**
118
+ * Generate a line chart
119
+ *
120
+ * @param data - Chart data
121
+ * @param options - Chart options
122
+ * @returns Chart response with base64 image
123
+ */
124
+ async lineChart(data, options) {
125
+ return this.generateChart({ type: "line", data, options });
126
+ }
127
+ /**
128
+ * Generate a bar chart
129
+ *
130
+ * @param data - Chart data
131
+ * @param options - Chart options
132
+ * @returns Chart response with base64 image
133
+ */
134
+ async barChart(data, options) {
135
+ return this.generateChart({ type: "bar", data, options });
136
+ }
137
+ /**
138
+ * Generate a pie chart
139
+ *
140
+ * @param data - Chart data
141
+ * @param options - Chart options
142
+ * @returns Chart response with base64 image
143
+ */
144
+ async pieChart(data, options) {
145
+ return this.generateChart({ type: "pie", data, options });
146
+ }
147
+ /**
148
+ * Generate a doughnut chart
149
+ *
150
+ * @param data - Chart data
151
+ * @param options - Chart options
152
+ * @returns Chart response with base64 image
153
+ */
154
+ async doughnutChart(data, options) {
155
+ return this.generateChart({ type: "doughnut", data, options });
156
+ }
157
+ /**
158
+ * Generate a radar chart
159
+ *
160
+ * @param data - Chart data
161
+ * @param options - Chart options
162
+ * @returns Chart response with base64 image
163
+ */
164
+ async radarChart(data, options) {
165
+ return this.generateChart({ type: "radar", data, options });
166
+ }
167
+ /**
168
+ * Generate a polar area chart
169
+ *
170
+ * @param data - Chart data
171
+ * @param options - Chart options
172
+ * @returns Chart response with base64 image
173
+ */
174
+ async polarAreaChart(data, options) {
175
+ return this.generateChart({ type: "polarArea", data, options });
176
+ }
177
+ /**
178
+ * Get rate limit information from the last request
179
+ *
180
+ * @returns Rate limit info or undefined if no request has been made
181
+ */
182
+ getRateLimit() {
183
+ return this.lastRateLimit;
184
+ }
185
+ };
186
+ var index_default = ChartSplat;
187
+ export {
188
+ ChartSplat,
189
+ ChartSplatAPIError,
190
+ ChartSplatTimeoutError,
191
+ index_default as default
192
+ };
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "chartsplat",
3
+ "version": "1.0.0",
4
+ "description": "Official TypeScript/JavaScript client for Chart Splat API - Generate beautiful charts via API",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
21
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
+ "prepublishOnly": "npm run build",
23
+ "test": "vitest",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "keywords": [
27
+ "chart",
28
+ "charts",
29
+ "chartjs",
30
+ "chart.js",
31
+ "api",
32
+ "image",
33
+ "png",
34
+ "visualization",
35
+ "data-visualization",
36
+ "chartsplat"
37
+ ],
38
+ "author": "Chart Splat",
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/chartsplat/chartsplat.git",
43
+ "directory": "packages/chartsplat"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/chartsplat/chartsplat/issues"
47
+ },
48
+ "homepage": "https://chartsplat.com",
49
+ "devDependencies": {
50
+ "tsup": "^8.0.0",
51
+ "typescript": "^5.3.0",
52
+ "vitest": "^1.0.0"
53
+ },
54
+ "engines": {
55
+ "node": ">=16.0.0"
56
+ }
57
+ }