renderscreenshot 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/LICENSE +21 -0
- package/README.md +366 -0
- package/dist/cjs/cache.js +125 -0
- package/dist/cjs/cache.js.map +1 -0
- package/dist/cjs/client.js +304 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/errors.js +85 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +44 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/options.js +659 -0
- package/dist/cjs/options.js.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/webhooks.js +152 -0
- package/dist/cjs/webhooks.js.map +1 -0
- package/dist/esm/cache.js +121 -0
- package/dist/esm/cache.js.map +1 -0
- package/dist/esm/client.js +300 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/errors.js +81 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/options.js +655 -0
- package/dist/esm/options.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/webhooks.js +147 -0
- package/dist/esm/webhooks.js.map +1 -0
- package/dist/types/cache.d.ts +96 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/client.d.ts +147 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/errors.d.ts +51 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/options.d.ts +265 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/types.d.ts +249 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/webhooks.d.ts +60 -0
- package/dist/types/webhooks.d.ts.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Verify a webhook signature
|
|
4
|
+
*
|
|
5
|
+
* Webhooks are signed using HMAC-SHA256 with the format:
|
|
6
|
+
* `sha256=hmac(secret, "${timestamp}.${payload}")`
|
|
7
|
+
*
|
|
8
|
+
* @param payload - The raw request body as a string
|
|
9
|
+
* @param signature - The X-Webhook-Signature header value
|
|
10
|
+
* @param timestamp - The X-Webhook-Timestamp header value
|
|
11
|
+
* @param secret - Your webhook signing secret from the dashboard
|
|
12
|
+
* @returns true if the signature is valid
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { verifyWebhook } from 'renderscreenshot';
|
|
17
|
+
*
|
|
18
|
+
* // In your webhook handler
|
|
19
|
+
* const signature = req.headers['x-webhook-signature'];
|
|
20
|
+
* const timestamp = req.headers['x-webhook-timestamp'];
|
|
21
|
+
* const payload = JSON.stringify(req.body);
|
|
22
|
+
*
|
|
23
|
+
* if (verifyWebhook(payload, signature, timestamp, process.env.WEBHOOK_SECRET)) {
|
|
24
|
+
* // Process webhook
|
|
25
|
+
* } else {
|
|
26
|
+
* res.status(401).send('Invalid signature');
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function verifyWebhook(payload, signature, timestamp, secret) {
|
|
31
|
+
// Validate inputs
|
|
32
|
+
if (payload === '' || signature === '' || timestamp === '' || secret === '') {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
// Check timestamp to prevent replay attacks (5 minute tolerance)
|
|
36
|
+
const timestampNum = parseInt(timestamp, 10);
|
|
37
|
+
if (isNaN(timestampNum)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const now = Math.floor(Date.now() / 1000);
|
|
41
|
+
const tolerance = 5 * 60; // 5 minutes
|
|
42
|
+
if (Math.abs(now - timestampNum) > tolerance) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
// Compute expected signature
|
|
46
|
+
const message = `${timestamp}.${payload}`;
|
|
47
|
+
const expected = `sha256=${createHmac('sha256', secret).update(message).digest('hex')}`;
|
|
48
|
+
// Use timing-safe comparison to prevent timing attacks
|
|
49
|
+
try {
|
|
50
|
+
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Buffers have different lengths
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse a webhook payload into a typed event object
|
|
59
|
+
*
|
|
60
|
+
* @param payload - The raw request body (string or parsed object)
|
|
61
|
+
* @returns Typed webhook event
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* import { parseWebhook, verifyWebhook } from 'renderscreenshot';
|
|
66
|
+
*
|
|
67
|
+
* // After verifying signature
|
|
68
|
+
* const event = parseWebhook(req.body);
|
|
69
|
+
*
|
|
70
|
+
* if (event.type === 'screenshot.completed') {
|
|
71
|
+
* console.log(`Screenshot ready: ${event.data.response?.url}`);
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export function parseWebhook(payload) {
|
|
76
|
+
const raw = typeof payload === 'string' ? JSON.parse(payload) : payload;
|
|
77
|
+
const data = raw;
|
|
78
|
+
const event = {
|
|
79
|
+
id: data.id,
|
|
80
|
+
type: data.event,
|
|
81
|
+
timestamp: new Date(data.timestamp),
|
|
82
|
+
data: {},
|
|
83
|
+
};
|
|
84
|
+
// Parse based on event type
|
|
85
|
+
switch (data.event) {
|
|
86
|
+
case 'screenshot.completed': {
|
|
87
|
+
const eventData = {
|
|
88
|
+
response: {
|
|
89
|
+
url: data.data.screenshot_url ?? '',
|
|
90
|
+
width: data.data.width ?? 0,
|
|
91
|
+
height: data.data.height ?? 0,
|
|
92
|
+
format: (data.data.format ?? 'png'),
|
|
93
|
+
size: data.data.size ?? 0,
|
|
94
|
+
cached: data.data.cached ?? false,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
if (data.data.url !== undefined) {
|
|
98
|
+
eventData.url = data.data.url;
|
|
99
|
+
}
|
|
100
|
+
event.data = eventData;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case 'screenshot.failed': {
|
|
104
|
+
const eventData = {
|
|
105
|
+
error: {
|
|
106
|
+
code: 'render_failed',
|
|
107
|
+
message: data.data.error ?? 'Unknown error',
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
if (data.data.url !== undefined) {
|
|
111
|
+
eventData.url = data.data.url;
|
|
112
|
+
}
|
|
113
|
+
event.data = eventData;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case 'batch.completed':
|
|
117
|
+
case 'batch.failed':
|
|
118
|
+
event.data = {
|
|
119
|
+
batchId: data.id,
|
|
120
|
+
};
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
return event;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extract webhook headers from a request-like object
|
|
127
|
+
*
|
|
128
|
+
* @param headers - Headers object (works with Express, Node http, etc.)
|
|
129
|
+
* @returns Object with signature and timestamp
|
|
130
|
+
*/
|
|
131
|
+
export function extractWebhookHeaders(headers) {
|
|
132
|
+
const getHeader = (name) => {
|
|
133
|
+
if (headers instanceof Headers) {
|
|
134
|
+
return headers.get(name) ?? '';
|
|
135
|
+
}
|
|
136
|
+
const value = headers[name] ?? headers[name.toLowerCase()];
|
|
137
|
+
if (Array.isArray(value)) {
|
|
138
|
+
return value[0] ?? '';
|
|
139
|
+
}
|
|
140
|
+
return value ?? '';
|
|
141
|
+
};
|
|
142
|
+
return {
|
|
143
|
+
signature: getHeader('X-Webhook-Signature'),
|
|
144
|
+
timestamp: getHeader('X-Webhook-Timestamp'),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/webhooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { PurgeResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for the Client to avoid circular dependency
|
|
4
|
+
*/
|
|
5
|
+
interface ClientInterface {
|
|
6
|
+
request<T>(method: string, path: string, options?: {
|
|
7
|
+
body?: unknown;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
responseType?: 'json' | 'buffer';
|
|
10
|
+
}): Promise<T>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Cache management methods for RenderScreenshot
|
|
14
|
+
*/
|
|
15
|
+
export declare class CacheManager {
|
|
16
|
+
private readonly client;
|
|
17
|
+
constructor(client: ClientInterface);
|
|
18
|
+
/**
|
|
19
|
+
* Get a cached screenshot by its cache key
|
|
20
|
+
*
|
|
21
|
+
* @param key - The cache key returned in X-Cache-Key header
|
|
22
|
+
* @returns Buffer containing the screenshot, or null if not found
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const image = await client.cache.get('cache_xyz789');
|
|
27
|
+
* if (image) {
|
|
28
|
+
* await fs.writeFile('cached.png', image);
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
get(key: string): Promise<Buffer | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Delete a single cache entry
|
|
35
|
+
*
|
|
36
|
+
* @param key - The cache key to delete
|
|
37
|
+
* @returns true if deleted, false if not found
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const deleted = await client.cache.delete('cache_xyz789');
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
delete(key: string): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Bulk purge cache entries by keys
|
|
47
|
+
*
|
|
48
|
+
* @param keys - Array of cache keys to purge
|
|
49
|
+
* @returns Purge result with count and keys
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const result = await client.cache.purge(['cache_abc', 'cache_def']);
|
|
54
|
+
* console.log(`Purged ${result.purged} entries`);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
purge(keys: string[]): Promise<PurgeResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Purge cache entries matching a URL pattern
|
|
60
|
+
*
|
|
61
|
+
* @param pattern - Glob pattern to match source URLs (e.g., "https://mysite.com/*")
|
|
62
|
+
* @returns Purge result with count
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const result = await client.cache.purgeUrl('https://mysite.com/blog/*');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
purgeUrl(pattern: string): Promise<PurgeResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Purge cache entries created before a specific date
|
|
72
|
+
*
|
|
73
|
+
* @param date - Purge entries created before this date
|
|
74
|
+
* @returns Purge result with count
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const result = await client.cache.purgeBefore(new Date('2024-01-01'));
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
purgeBefore(date: Date): Promise<PurgeResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Purge cache entries matching a storage path pattern
|
|
84
|
+
*
|
|
85
|
+
* @param pattern - Glob pattern for storage paths (e.g., "screenshots/2024/01/*")
|
|
86
|
+
* @returns Purge result with count
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const result = await client.cache.purgePattern('screenshots/2024/*');
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
purgePattern(pattern: string): Promise<PurgeResult>;
|
|
94
|
+
}
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,CAAC,CAAC,EACP,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;KAClC,GACA,OAAO,CAAC,CAAC,CAAC,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;gBAE7B,MAAM,EAAE,eAAe;IAInC;;;;;;;;;;;;;OAaG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmB9C;;;;;;;;;;OAUG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ3C;;;;;;;;;;;OAWG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAMjD;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAMrD;;;;;;;;;;OAUG;IACG,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC;IAMnD;;;;;;;;;;OAUG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAK1D"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ClientOptions, ScreenshotResponse, BatchResponse, BatchRequestItem, PresetInfo, DeviceInfo, TakeOptionsConfig } from './types.js';
|
|
2
|
+
import { TakeOptions } from './options.js';
|
|
3
|
+
import { CacheManager } from './cache.js';
|
|
4
|
+
/**
|
|
5
|
+
* RenderScreenshot API client
|
|
6
|
+
*/
|
|
7
|
+
export declare class Client {
|
|
8
|
+
private readonly apiKey;
|
|
9
|
+
private readonly baseUrl;
|
|
10
|
+
private readonly timeout;
|
|
11
|
+
/** Cache management methods */
|
|
12
|
+
readonly cache: CacheManager;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new RenderScreenshot client
|
|
15
|
+
* @param apiKey - Your API key (rs_live_* or rs_test_*)
|
|
16
|
+
* @param options - Optional client configuration
|
|
17
|
+
*/
|
|
18
|
+
constructor(apiKey: string, options?: ClientOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Get the API key for internal use
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
getApiKey(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get the base URL for internal use
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
getBaseUrl(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Get the timeout for internal use
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
getTimeout(): number;
|
|
34
|
+
/**
|
|
35
|
+
* Make an authenticated request to the API
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
request<T>(method: string, path: string, options?: {
|
|
39
|
+
body?: unknown;
|
|
40
|
+
headers?: Record<string, string>;
|
|
41
|
+
responseType?: 'json' | 'buffer';
|
|
42
|
+
}): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Generate a signed URL for embedding screenshots
|
|
45
|
+
*
|
|
46
|
+
* @param options - Screenshot options (TakeOptions instance or config object)
|
|
47
|
+
* @param expiresAt - Expiration time for the signed URL
|
|
48
|
+
* @returns Signed URL string
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const url = client.generateUrl(
|
|
53
|
+
* TakeOptions.url('https://example.com').preset('og_card'),
|
|
54
|
+
* new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours
|
|
55
|
+
* );
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
generateUrl(options: TakeOptions | TakeOptionsConfig, expiresAt: Date): string;
|
|
59
|
+
/**
|
|
60
|
+
* Take a screenshot and return the binary data
|
|
61
|
+
*
|
|
62
|
+
* @param options - Screenshot options (TakeOptions instance or config object)
|
|
63
|
+
* @returns Buffer containing the screenshot binary data
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const image = await client.take(
|
|
68
|
+
* TakeOptions.url('https://example.com').preset('og_card')
|
|
69
|
+
* );
|
|
70
|
+
* await fs.writeFile('screenshot.png', image);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
take(options: TakeOptions | TakeOptionsConfig): Promise<Buffer>;
|
|
74
|
+
/**
|
|
75
|
+
* Take a screenshot and return JSON metadata with URLs
|
|
76
|
+
*
|
|
77
|
+
* @param options - Screenshot options (TakeOptions instance or config object)
|
|
78
|
+
* @returns Screenshot response with metadata and URLs
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const response = await client.takeJson(
|
|
83
|
+
* TakeOptions.url('https://example.com').preset('og_card')
|
|
84
|
+
* );
|
|
85
|
+
* console.log(response.url); // CDN URL to the screenshot
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
takeJson(options: TakeOptions | TakeOptionsConfig): Promise<ScreenshotResponse>;
|
|
89
|
+
/**
|
|
90
|
+
* Process multiple screenshots in a batch
|
|
91
|
+
*
|
|
92
|
+
* @param urls - Array of URLs to screenshot
|
|
93
|
+
* @param options - Options to apply to all screenshots
|
|
94
|
+
* @returns Batch response with results for each URL
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const results = await client.batch(
|
|
99
|
+
* ['https://example1.com', 'https://example2.com'],
|
|
100
|
+
* TakeOptions.url('').preset('og_card')
|
|
101
|
+
* );
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
batch(urls: string[], options?: TakeOptions | TakeOptionsConfig): Promise<BatchResponse>;
|
|
105
|
+
/**
|
|
106
|
+
* Process multiple screenshots with per-URL options
|
|
107
|
+
*
|
|
108
|
+
* @param requests - Array of batch request items with individual options
|
|
109
|
+
* @returns Batch response with results for each URL
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const results = await client.batch([
|
|
114
|
+
* { url: 'https://example1.com', options: { width: 1200 } },
|
|
115
|
+
* { url: 'https://example2.com', options: { preset: 'full_page' } }
|
|
116
|
+
* ]);
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
batch(requests: BatchRequestItem[]): Promise<BatchResponse>;
|
|
120
|
+
/**
|
|
121
|
+
* Get the status of a batch job
|
|
122
|
+
*
|
|
123
|
+
* @param batchId - The batch job ID
|
|
124
|
+
* @returns Batch status and results
|
|
125
|
+
*/
|
|
126
|
+
getBatch(batchId: string): Promise<BatchResponse>;
|
|
127
|
+
/**
|
|
128
|
+
* List all available presets
|
|
129
|
+
*
|
|
130
|
+
* @returns Array of preset configurations
|
|
131
|
+
*/
|
|
132
|
+
presets(): Promise<PresetInfo[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Get a single preset by ID
|
|
135
|
+
*
|
|
136
|
+
* @param id - Preset identifier
|
|
137
|
+
* @returns Preset configuration
|
|
138
|
+
*/
|
|
139
|
+
preset(id: string): Promise<PresetInfo>;
|
|
140
|
+
/**
|
|
141
|
+
* List all available device presets
|
|
142
|
+
*
|
|
143
|
+
* @returns Array of device configurations
|
|
144
|
+
*/
|
|
145
|
+
devices(): Promise<DeviceInfo[]>;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoC1C;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAE7B;;;;OAIG;gBACS,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAWvD;;;OAGG;IACH,SAAS,IAAI,MAAM;IAInB;;;OAGG;IACH,UAAU,IAAI,MAAM;IAIpB;;;OAGG;IACH,UAAU,IAAI,MAAM;IAIpB;;;OAGG;IACG,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;KAC7B,GACL,OAAO,CAAC,CAAC,CAAC;IAuDb;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM;IA8C9E;;;;;;;;;;;;;OAaG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IASrE;;;;;;;;;;;;;OAaG;IACG,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQrF;;;;;;;;;;;;;;OAcG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAE9F;;;;;;;;;;;;;OAaG;IACG,KAAK,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAmCjE;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAIvD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAItC;;;;;OAKG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7C;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;CAGvC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes returned by the RenderScreenshot API
|
|
3
|
+
*/
|
|
4
|
+
export type ErrorCode = 'invalid_request' | 'invalid_url' | 'unauthorized' | 'forbidden' | 'not_found' | 'rate_limited' | 'timeout' | 'render_failed' | 'internal_error';
|
|
5
|
+
/**
|
|
6
|
+
* Custom error class for RenderScreenshot API errors
|
|
7
|
+
*/
|
|
8
|
+
export declare class RenderScreenshotError extends Error {
|
|
9
|
+
/** HTTP status code */
|
|
10
|
+
readonly httpStatus: number;
|
|
11
|
+
/** Error code from the API */
|
|
12
|
+
readonly code: ErrorCode;
|
|
13
|
+
/** Whether this error can be retried */
|
|
14
|
+
readonly retryable: boolean;
|
|
15
|
+
/** Seconds to wait before retrying (for rate limits) */
|
|
16
|
+
readonly retryAfter?: number;
|
|
17
|
+
constructor(httpStatus: number, code: ErrorCode, message: string, retryAfter?: number);
|
|
18
|
+
/**
|
|
19
|
+
* Create an error from an API response
|
|
20
|
+
*/
|
|
21
|
+
static fromResponse(httpStatus: number, body: {
|
|
22
|
+
code?: string;
|
|
23
|
+
message?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}, retryAfter?: number): RenderScreenshotError;
|
|
26
|
+
/**
|
|
27
|
+
* Create an invalid URL error
|
|
28
|
+
*/
|
|
29
|
+
static invalidUrl(url: string): RenderScreenshotError;
|
|
30
|
+
/**
|
|
31
|
+
* Create an invalid request error
|
|
32
|
+
*/
|
|
33
|
+
static invalidRequest(message: string): RenderScreenshotError;
|
|
34
|
+
/**
|
|
35
|
+
* Create an unauthorized error
|
|
36
|
+
*/
|
|
37
|
+
static unauthorized(): RenderScreenshotError;
|
|
38
|
+
/**
|
|
39
|
+
* Create a rate limited error
|
|
40
|
+
*/
|
|
41
|
+
static rateLimited(retryAfter?: number): RenderScreenshotError;
|
|
42
|
+
/**
|
|
43
|
+
* Create a timeout error
|
|
44
|
+
*/
|
|
45
|
+
static timeout(): RenderScreenshotError;
|
|
46
|
+
/**
|
|
47
|
+
* Create an internal error
|
|
48
|
+
*/
|
|
49
|
+
static internal(message?: string): RenderScreenshotError;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,aAAa,GACb,cAAc,GACd,WAAW,GACX,WAAW,GACX,cAAc,GACd,SAAS,GACT,eAAe,GACf,gBAAgB,CAAC;AAYrB;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,uBAAuB;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAEzB,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAgBrF;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EACzD,UAAU,CAAC,EAAE,MAAM,GAClB,qBAAqB;IAMxB;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB;IAIrD;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAI7D;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,qBAAqB;IAI5C;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,qBAAqB;IAS9D;;OAEG;IACH,MAAM,CAAC,OAAO,IAAI,qBAAqB;IAIvC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,qBAAqB;CAOzD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RenderScreenshot Node.js SDK
|
|
3
|
+
*
|
|
4
|
+
* Official Node.js/TypeScript SDK for the RenderScreenshot API.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module renderscreenshot
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* Basic usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { Client, TakeOptions } from 'renderscreenshot';
|
|
13
|
+
*
|
|
14
|
+
* const client = new Client('rs_live_xxxxx');
|
|
15
|
+
*
|
|
16
|
+
* // Take a screenshot
|
|
17
|
+
* const image = await client.take(
|
|
18
|
+
* TakeOptions.url('https://example.com').preset('og_card')
|
|
19
|
+
* );
|
|
20
|
+
*
|
|
21
|
+
* // Generate a signed URL for embedding
|
|
22
|
+
* const url = client.generateUrl(
|
|
23
|
+
* TakeOptions.url('https://example.com').preset('og_card'),
|
|
24
|
+
* new Date(Date.now() + 24 * 60 * 60 * 1000)
|
|
25
|
+
* );
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export { Client } from './client.js';
|
|
29
|
+
export { TakeOptions } from './options.js';
|
|
30
|
+
export { RenderScreenshotError } from './errors.js';
|
|
31
|
+
export type { ErrorCode } from './errors.js';
|
|
32
|
+
export { CacheManager } from './cache.js';
|
|
33
|
+
export { verifyWebhook, parseWebhook, extractWebhookHeaders } from './webhooks.js';
|
|
34
|
+
export type { ClientOptions, TakeOptionsConfig, ImageFormat, WaitCondition, BlockableResource, MediaType, StorageAcl, Preset, Device, PdfPaperSize, Cookie, Geolocation, ScreenshotResponse, BatchRequestItem, BatchResponseItem, BatchResponse, CacheEntry, PurgeResult, WebhookEventType, WebhookEvent, PresetInfo, DeviceInfo, } from './types.js';
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGnF,YAAY,EAEV,aAAa,EAGb,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,EACN,YAAY,EACZ,MAAM,EACN,WAAW,EAGX,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EAGb,UAAU,EACV,WAAW,EAGX,gBAAgB,EAChB,YAAY,EAGZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
|