@ever-works/urlbox-plugin 1.0.0 → 1.0.3
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/dist/index.cjs +394 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +385 -0
- package/package.json +94 -81
- package/LICENSE +0 -661
- package/src/__tests__/urlbox.plugin.spec.ts +0 -353
- package/src/index.ts +0 -2
- package/src/urlbox.plugin.ts +0 -406
- package/tsconfig.json +0 -23
- package/tsup.config.ts +0 -12
- package/vitest.config.ts +0 -13
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var Urlbox = require('urlbox');
|
|
6
|
+
var net = require('net');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var Urlbox__default = /*#__PURE__*/_interopDefault(Urlbox);
|
|
11
|
+
|
|
12
|
+
// src/urlbox.plugin.ts
|
|
13
|
+
function isSafeWebhookUrl(rawUrl) {
|
|
14
|
+
let url;
|
|
15
|
+
try {
|
|
16
|
+
url = new URL(rawUrl);
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
let host = url.hostname.toLowerCase();
|
|
24
|
+
if (host.startsWith("[") && host.endsWith("]")) {
|
|
25
|
+
host = host.slice(1, -1);
|
|
26
|
+
}
|
|
27
|
+
if (CLOUD_METADATA_HOSTNAMES.has(host)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
const ipKind = net.isIP(host);
|
|
31
|
+
if (ipKind === 4 && isPrivateIPv4(host)) return false;
|
|
32
|
+
if (ipKind === 6 && isPrivateIPv6(host)) return false;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
var CLOUD_METADATA_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
36
|
+
// GCP
|
|
37
|
+
"metadata.google.internal",
|
|
38
|
+
"metadata.goog",
|
|
39
|
+
// AWS
|
|
40
|
+
"instance-data",
|
|
41
|
+
"instance-data.ec2.internal",
|
|
42
|
+
// Azure
|
|
43
|
+
"metadata.azure.internal"
|
|
44
|
+
]);
|
|
45
|
+
function isPrivateIPv4(ip) {
|
|
46
|
+
const parts = ip.split(".").map((p) => Number(p));
|
|
47
|
+
if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return false;
|
|
48
|
+
const [a, b] = parts;
|
|
49
|
+
if (a === 10) return true;
|
|
50
|
+
if (a === 127) return true;
|
|
51
|
+
if (a === 0) return true;
|
|
52
|
+
if (a === 169 && b === 254) return true;
|
|
53
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
54
|
+
if (a === 192 && b === 168) return true;
|
|
55
|
+
if (a === 192 && b === 0 && parts[2] === 0) return true;
|
|
56
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
57
|
+
if (a >= 224) return true;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
function isPrivateIPv6(ip) {
|
|
61
|
+
const lower = ip.toLowerCase();
|
|
62
|
+
if (lower === "::1" || lower === "::") return true;
|
|
63
|
+
if (lower.startsWith("fc") || lower.startsWith("fd")) return true;
|
|
64
|
+
const firstHextet = lower.split(":", 1)[0];
|
|
65
|
+
if (/^[0-9a-f]{1,4}$/.test(firstHextet)) {
|
|
66
|
+
const group0 = parseInt(firstHextet, 16);
|
|
67
|
+
if ((group0 & 65472) === 65152) return true;
|
|
68
|
+
}
|
|
69
|
+
if (lower.startsWith("::ffff:")) {
|
|
70
|
+
const v4 = lower.slice("::ffff:".length);
|
|
71
|
+
if (net.isIP(v4) === 4) return isPrivateIPv4(v4);
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/urlbox.plugin.ts
|
|
77
|
+
var UrlboxPlugin = class {
|
|
78
|
+
constructor() {
|
|
79
|
+
this.id = "urlbox";
|
|
80
|
+
this.name = "Urlbox";
|
|
81
|
+
this.version = "1.0.0";
|
|
82
|
+
this.category = "screenshot";
|
|
83
|
+
this.capabilities = ["screenshot"];
|
|
84
|
+
this.providerName = "Urlbox";
|
|
85
|
+
this.settingsSchema = {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
apiKey: {
|
|
89
|
+
type: "string",
|
|
90
|
+
title: "API Key",
|
|
91
|
+
description: "Your Urlbox API key. Get one at https://urlbox.com",
|
|
92
|
+
"x-secret": true,
|
|
93
|
+
"x-envVar": "PLUGIN_URLBOX_API_KEY",
|
|
94
|
+
"x-scope": "user"
|
|
95
|
+
},
|
|
96
|
+
apiSecret: {
|
|
97
|
+
type: "string",
|
|
98
|
+
title: "API Secret",
|
|
99
|
+
description: "Your Urlbox API secret for signed render links (recommended for security)",
|
|
100
|
+
"x-secret": true,
|
|
101
|
+
"x-envVar": "PLUGIN_URLBOX_API_SECRET",
|
|
102
|
+
"x-scope": "user"
|
|
103
|
+
},
|
|
104
|
+
viewportWidth: {
|
|
105
|
+
type: "number",
|
|
106
|
+
title: "Viewport Width",
|
|
107
|
+
description: "Default viewport width in pixels",
|
|
108
|
+
default: 1280,
|
|
109
|
+
minimum: 320,
|
|
110
|
+
maximum: 3840,
|
|
111
|
+
"x-envVar": "PLUGIN_URLBOX_VIEWPORT_WIDTH"
|
|
112
|
+
},
|
|
113
|
+
viewportHeight: {
|
|
114
|
+
type: "number",
|
|
115
|
+
title: "Viewport Height",
|
|
116
|
+
description: "Default viewport height in pixels",
|
|
117
|
+
default: 1024,
|
|
118
|
+
minimum: 200,
|
|
119
|
+
maximum: 2160,
|
|
120
|
+
"x-envVar": "PLUGIN_URLBOX_VIEWPORT_HEIGHT"
|
|
121
|
+
},
|
|
122
|
+
format: {
|
|
123
|
+
type: "string",
|
|
124
|
+
title: "Image Format",
|
|
125
|
+
description: "Default output image format",
|
|
126
|
+
enum: ["png", "jpg", "jpeg", "webp"],
|
|
127
|
+
default: "png",
|
|
128
|
+
"x-envVar": "PLUGIN_URLBOX_FORMAT"
|
|
129
|
+
},
|
|
130
|
+
fullPage: {
|
|
131
|
+
type: "boolean",
|
|
132
|
+
title: "Full Page",
|
|
133
|
+
description: "Capture full page by default",
|
|
134
|
+
default: false
|
|
135
|
+
},
|
|
136
|
+
quality: {
|
|
137
|
+
type: "number",
|
|
138
|
+
title: "Image Quality",
|
|
139
|
+
description: "Image quality for lossy formats (1-100)",
|
|
140
|
+
default: 80,
|
|
141
|
+
minimum: 1,
|
|
142
|
+
maximum: 100
|
|
143
|
+
},
|
|
144
|
+
retina: {
|
|
145
|
+
type: "boolean",
|
|
146
|
+
title: "Retina",
|
|
147
|
+
description: "Enable retina/HiDPI rendering (2x device scale factor)",
|
|
148
|
+
default: false
|
|
149
|
+
},
|
|
150
|
+
blockAds: {
|
|
151
|
+
type: "boolean",
|
|
152
|
+
title: "Block Ads",
|
|
153
|
+
description: "Block ads when capturing screenshots",
|
|
154
|
+
default: true
|
|
155
|
+
},
|
|
156
|
+
hideCookieBanners: {
|
|
157
|
+
type: "boolean",
|
|
158
|
+
title: "Hide Cookie Banners",
|
|
159
|
+
description: "Hide cookie consent banners when capturing screenshots",
|
|
160
|
+
default: true
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
required: ["apiKey"]
|
|
164
|
+
};
|
|
165
|
+
this.configurationMode = "hybrid";
|
|
166
|
+
}
|
|
167
|
+
async capture(options) {
|
|
168
|
+
const settings = this.mergeSettings(options.settings);
|
|
169
|
+
if (!isSafeWebhookUrl(options.url)) {
|
|
170
|
+
return {
|
|
171
|
+
success: false,
|
|
172
|
+
error: `URL host is not safe to capture (SSRF guard blocked: ${options.url})`
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const client = this.createClient(settings);
|
|
177
|
+
const renderOptions = this.buildOptions(options, settings);
|
|
178
|
+
const renderUrl = client.generateRenderLink(renderOptions);
|
|
179
|
+
const response = await fetch(renderUrl);
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
throw new Error(`Urlbox render failed with status ${response.status}`);
|
|
182
|
+
}
|
|
183
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
184
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
185
|
+
return {
|
|
186
|
+
success: true,
|
|
187
|
+
imageBuffer: buffer,
|
|
188
|
+
imageBase64: buffer.toString("base64"),
|
|
189
|
+
imageUrl: renderUrl,
|
|
190
|
+
width: options.viewportWidth ?? settings.viewportWidth ?? 1280,
|
|
191
|
+
height: options.viewportHeight ?? settings.viewportHeight ?? 1024,
|
|
192
|
+
fileSize: buffer.length
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
196
|
+
this.context?.logger.error(`Urlbox capture failed: ${errorMessage}`);
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
error: errorMessage
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async getScreenshotUrl(options) {
|
|
204
|
+
const settings = this.mergeSettings(options.settings);
|
|
205
|
+
if (!isSafeWebhookUrl(options.url)) {
|
|
206
|
+
this.context?.logger.error(`Urlbox URL generation blocked by SSRF guard for unsafe URL: ${options.url}`);
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const client = this.createClient(settings);
|
|
211
|
+
const renderOptions = this.buildOptions(options, settings);
|
|
212
|
+
return client.generateRenderLink(renderOptions);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
this.context?.logger.error(
|
|
215
|
+
`Urlbox URL generation failed: ${error instanceof Error ? error.message : String(error)}`
|
|
216
|
+
);
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async isAvailable() {
|
|
221
|
+
if (!this.context) return false;
|
|
222
|
+
const settings = await this.context.getSettings();
|
|
223
|
+
return Boolean(settings?.apiKey);
|
|
224
|
+
}
|
|
225
|
+
async validateConnection(settings) {
|
|
226
|
+
const apiKey = settings.apiKey;
|
|
227
|
+
if (!apiKey) {
|
|
228
|
+
return { success: false, message: "Urlbox API key is not configured." };
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
const resolvedSettings = this.mergeSettings(settings);
|
|
232
|
+
const client = this.createClient(resolvedSettings);
|
|
233
|
+
const url = client.generateRenderLink({ url: "https://example.com" });
|
|
234
|
+
if (url && url.includes("api.urlbox.com")) {
|
|
235
|
+
return { success: true, message: "Urlbox connection verified." };
|
|
236
|
+
}
|
|
237
|
+
return { success: false, message: "Urlbox credentials appear invalid." };
|
|
238
|
+
} catch (error) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
message: `Urlbox connection failed: ${error instanceof Error ? error.message : String(error)}`
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async validateCredentials() {
|
|
246
|
+
if (!this.context) {
|
|
247
|
+
return {
|
|
248
|
+
valid: false,
|
|
249
|
+
message: "Plugin not initialized"
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const settings = await this.context.getSettings();
|
|
254
|
+
const resolvedSettings = this.mergeSettings(settings);
|
|
255
|
+
if (!resolvedSettings.apiKey) {
|
|
256
|
+
return {
|
|
257
|
+
valid: false,
|
|
258
|
+
message: "API key is not configured"
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const client = this.createClient(resolvedSettings);
|
|
262
|
+
const url = client.generateRenderLink({ url: "https://example.com" });
|
|
263
|
+
if (url && url.includes("api.urlbox.com")) {
|
|
264
|
+
return {
|
|
265
|
+
valid: true,
|
|
266
|
+
message: "Credentials are valid"
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
valid: false,
|
|
271
|
+
message: "Invalid credentials format"
|
|
272
|
+
};
|
|
273
|
+
} catch (error) {
|
|
274
|
+
return {
|
|
275
|
+
valid: false,
|
|
276
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
getSupportedFormats() {
|
|
281
|
+
return ["png", "jpg", "jpeg", "webp"];
|
|
282
|
+
}
|
|
283
|
+
getMaxDimensions() {
|
|
284
|
+
return { width: 3840, height: 2160 };
|
|
285
|
+
}
|
|
286
|
+
createClient(settings) {
|
|
287
|
+
const apiKey = settings.apiKey;
|
|
288
|
+
const apiSecret = settings.apiSecret ?? "";
|
|
289
|
+
if (!apiKey) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
"Urlbox API key not configured. Set it in plugin settings or via PLUGIN_URLBOX_API_KEY environment variable."
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
return Urlbox__default.default(apiKey, apiSecret);
|
|
295
|
+
}
|
|
296
|
+
buildOptions(options, settings) {
|
|
297
|
+
const format = options.format ?? settings.format ?? "png";
|
|
298
|
+
const renderOptions = {
|
|
299
|
+
url: options.url,
|
|
300
|
+
width: options.viewportWidth ?? settings.viewportWidth ?? 1280,
|
|
301
|
+
height: options.viewportHeight ?? settings.viewportHeight ?? 1024,
|
|
302
|
+
format,
|
|
303
|
+
full_page: options.fullPage ?? settings.fullPage ?? false,
|
|
304
|
+
quality: settings.quality ?? 80,
|
|
305
|
+
retina: settings.retina ?? false,
|
|
306
|
+
block_ads: options.blockAds ?? settings.blockAds ?? true,
|
|
307
|
+
hide_cookie_banners: options.blockCookieBanners ?? settings.hideCookieBanners ?? true
|
|
308
|
+
};
|
|
309
|
+
if (options.delay !== void 0) {
|
|
310
|
+
renderOptions.delay = options.delay;
|
|
311
|
+
}
|
|
312
|
+
if (options.waitForSelector) {
|
|
313
|
+
renderOptions.selector = options.waitForSelector;
|
|
314
|
+
}
|
|
315
|
+
if (options.userAgent) {
|
|
316
|
+
renderOptions.user_agent = options.userAgent;
|
|
317
|
+
}
|
|
318
|
+
return renderOptions;
|
|
319
|
+
}
|
|
320
|
+
mergeSettings(settings) {
|
|
321
|
+
return {
|
|
322
|
+
apiKey: settings?.apiKey,
|
|
323
|
+
apiSecret: settings?.apiSecret,
|
|
324
|
+
viewportWidth: settings?.viewportWidth ?? 1280,
|
|
325
|
+
viewportHeight: settings?.viewportHeight ?? 1024,
|
|
326
|
+
format: settings?.format ?? "png",
|
|
327
|
+
fullPage: settings?.fullPage ?? false,
|
|
328
|
+
quality: settings?.quality ?? 80,
|
|
329
|
+
retina: settings?.retina ?? false,
|
|
330
|
+
blockAds: settings?.blockAds ?? true,
|
|
331
|
+
hideCookieBanners: settings?.hideCookieBanners ?? true
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
async onLoad(context) {
|
|
335
|
+
this.context = context;
|
|
336
|
+
context.logger.log("Urlbox Plugin loaded");
|
|
337
|
+
}
|
|
338
|
+
async onUnload() {
|
|
339
|
+
this.context = void 0;
|
|
340
|
+
}
|
|
341
|
+
async healthCheck() {
|
|
342
|
+
return {
|
|
343
|
+
status: "healthy",
|
|
344
|
+
message: "Urlbox plugin is ready (API key required for operations)",
|
|
345
|
+
checkedAt: Date.now()
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
getManifest() {
|
|
349
|
+
return {
|
|
350
|
+
id: this.id,
|
|
351
|
+
name: this.name,
|
|
352
|
+
version: this.version,
|
|
353
|
+
description: "Automatically capture website screenshots for your work items",
|
|
354
|
+
category: this.category,
|
|
355
|
+
capabilities: [...this.capabilities],
|
|
356
|
+
author: { name: "Ever Works Team" },
|
|
357
|
+
license: "AGPL-3.0",
|
|
358
|
+
builtIn: false,
|
|
359
|
+
systemPlugin: false,
|
|
360
|
+
readme: [
|
|
361
|
+
"## What does Urlbox do?",
|
|
362
|
+
"",
|
|
363
|
+
"Urlbox is a screenshot capture API. When work items include source URLs, this plugin automatically generates preview images by capturing a screenshot of each page.",
|
|
364
|
+
"",
|
|
365
|
+
"## Why use it?",
|
|
366
|
+
"",
|
|
367
|
+
"- **Automated capture** \u2014 preview images are generated for each work item without manual effort",
|
|
368
|
+
"- **Consistent output** \u2014 every screenshot uses the same viewport size, format, and rendering settings",
|
|
369
|
+
"- **Ad and cookie banner blocking** \u2014 captures clean screenshots free of ads and cookie banners",
|
|
370
|
+
"- **Retina rendering** \u2014 supports HiDPI output for crisp images on high-resolution displays",
|
|
371
|
+
"- **Multiple formats** \u2014 supports PNG, JPG, and WebP output with configurable quality",
|
|
372
|
+
"",
|
|
373
|
+
"## How it works in Ever Works",
|
|
374
|
+
"",
|
|
375
|
+
"During work generation, the screenshot facade sends capture requests to Urlbox for items that have a source URL. The resulting images are used as item preview thumbnails. You can configure viewport dimensions, image format, quality, retina rendering, and ad/cookie blocking behavior.",
|
|
376
|
+
"",
|
|
377
|
+
"## Getting started",
|
|
378
|
+
"",
|
|
379
|
+
"1. Sign up at [urlbox.com](https://urlbox.com)",
|
|
380
|
+
"2. Copy your API key and API secret",
|
|
381
|
+
"3. Enable the Urlbox plugin on this page",
|
|
382
|
+
"4. Enter your credentials in the settings below"
|
|
383
|
+
].join("\n"),
|
|
384
|
+
homepage: "https://urlbox.com",
|
|
385
|
+
icon: {
|
|
386
|
+
type: "url",
|
|
387
|
+
value: "https://urlbox.com/apple-touch-icon.png"
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
exports.UrlboxPlugin = UrlboxPlugin;
|
|
394
|
+
exports.default = UrlboxPlugin;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IPlugin, IScreenshotPlugin, PluginCategory, JsonSchema, ScreenshotOptions, ScreenshotResult, ConnectionValidationResult, ScreenshotValidationResult, ScreenshotFormat, PluginContext, PluginHealthCheck, PluginManifest } from '@ever-works/plugin';
|
|
2
|
+
|
|
3
|
+
declare class UrlboxPlugin implements IPlugin, IScreenshotPlugin {
|
|
4
|
+
readonly id = "urlbox";
|
|
5
|
+
readonly name = "Urlbox";
|
|
6
|
+
readonly version = "1.0.0";
|
|
7
|
+
readonly category: PluginCategory;
|
|
8
|
+
readonly capabilities: readonly string[];
|
|
9
|
+
readonly providerName = "Urlbox";
|
|
10
|
+
readonly settingsSchema: JsonSchema;
|
|
11
|
+
readonly configurationMode: 'admin-only' | 'user-required' | 'hybrid';
|
|
12
|
+
private context?;
|
|
13
|
+
capture(options: ScreenshotOptions): Promise<ScreenshotResult>;
|
|
14
|
+
getScreenshotUrl(options: ScreenshotOptions): Promise<string | null>;
|
|
15
|
+
isAvailable(): Promise<boolean>;
|
|
16
|
+
validateConnection(settings: Record<string, unknown>): Promise<ConnectionValidationResult>;
|
|
17
|
+
validateCredentials(): Promise<ScreenshotValidationResult>;
|
|
18
|
+
getSupportedFormats(): readonly ScreenshotFormat[];
|
|
19
|
+
getMaxDimensions(): {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
private createClient;
|
|
24
|
+
private buildOptions;
|
|
25
|
+
private mergeSettings;
|
|
26
|
+
onLoad(context: PluginContext): Promise<void>;
|
|
27
|
+
onUnload(): Promise<void>;
|
|
28
|
+
healthCheck(): Promise<PluginHealthCheck>;
|
|
29
|
+
getManifest(): PluginManifest;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { UrlboxPlugin, UrlboxPlugin as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IPlugin, IScreenshotPlugin, PluginCategory, JsonSchema, ScreenshotOptions, ScreenshotResult, ConnectionValidationResult, ScreenshotValidationResult, ScreenshotFormat, PluginContext, PluginHealthCheck, PluginManifest } from '@ever-works/plugin';
|
|
2
|
+
|
|
3
|
+
declare class UrlboxPlugin implements IPlugin, IScreenshotPlugin {
|
|
4
|
+
readonly id = "urlbox";
|
|
5
|
+
readonly name = "Urlbox";
|
|
6
|
+
readonly version = "1.0.0";
|
|
7
|
+
readonly category: PluginCategory;
|
|
8
|
+
readonly capabilities: readonly string[];
|
|
9
|
+
readonly providerName = "Urlbox";
|
|
10
|
+
readonly settingsSchema: JsonSchema;
|
|
11
|
+
readonly configurationMode: 'admin-only' | 'user-required' | 'hybrid';
|
|
12
|
+
private context?;
|
|
13
|
+
capture(options: ScreenshotOptions): Promise<ScreenshotResult>;
|
|
14
|
+
getScreenshotUrl(options: ScreenshotOptions): Promise<string | null>;
|
|
15
|
+
isAvailable(): Promise<boolean>;
|
|
16
|
+
validateConnection(settings: Record<string, unknown>): Promise<ConnectionValidationResult>;
|
|
17
|
+
validateCredentials(): Promise<ScreenshotValidationResult>;
|
|
18
|
+
getSupportedFormats(): readonly ScreenshotFormat[];
|
|
19
|
+
getMaxDimensions(): {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
private createClient;
|
|
24
|
+
private buildOptions;
|
|
25
|
+
private mergeSettings;
|
|
26
|
+
onLoad(context: PluginContext): Promise<void>;
|
|
27
|
+
onUnload(): Promise<void>;
|
|
28
|
+
healthCheck(): Promise<PluginHealthCheck>;
|
|
29
|
+
getManifest(): PluginManifest;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { UrlboxPlugin, UrlboxPlugin as default };
|