@clawnify/services 0.1.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/dist/index.d.ts +119 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/package.json +30 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
interface ServicesEnv {
|
|
2
|
+
CLAWNIFY_TOKEN?: string;
|
|
3
|
+
/** Base URL override, for a local fake in tests. Default https://services.clawnify.com. */
|
|
4
|
+
CLAWNIFY_SERVICES_URL?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A failed call. `code` is the service's own error code: `invalid_token`,
|
|
8
|
+
* `quota_exceeded`, `render_failed`, … and `body` the whole answer, which for
|
|
9
|
+
* `quota_exceeded` carries `limit`, `used` and `resets_at`.
|
|
10
|
+
*/
|
|
11
|
+
declare class ClawnifyServicesError extends Error {
|
|
12
|
+
readonly status?: number;
|
|
13
|
+
readonly code?: string;
|
|
14
|
+
readonly body?: Record<string, unknown>;
|
|
15
|
+
constructor(message: string, opts?: {
|
|
16
|
+
status?: number;
|
|
17
|
+
code?: string;
|
|
18
|
+
body?: Record<string, unknown>;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** A render the service stored for you, served from a presigned link (`output: "url"`). */
|
|
22
|
+
interface StoredFile {
|
|
23
|
+
url: string;
|
|
24
|
+
key: string;
|
|
25
|
+
expires_at: string;
|
|
26
|
+
size: number;
|
|
27
|
+
content_type: string;
|
|
28
|
+
}
|
|
29
|
+
interface Viewport {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
deviceScaleFactor?: number;
|
|
33
|
+
}
|
|
34
|
+
type WaitUntil = "load" | "domcontentloaded" | "networkidle0" | "networkidle2";
|
|
35
|
+
interface CallOptions {
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
/** Ask for a link instead of the bytes: for callers that can't hold or pass the file on themselves. */
|
|
39
|
+
interface AsLink {
|
|
40
|
+
output: "url";
|
|
41
|
+
/** Download name. */
|
|
42
|
+
filename?: string;
|
|
43
|
+
/** Link lifetime in seconds, at most 7 days. */
|
|
44
|
+
expiresIn?: number;
|
|
45
|
+
}
|
|
46
|
+
type PaperFormat = "Letter" | "Legal" | "Tabloid" | "Ledger" | "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6";
|
|
47
|
+
interface RenderPDFOptions extends CallOptions {
|
|
48
|
+
html: string;
|
|
49
|
+
format?: PaperFormat;
|
|
50
|
+
margin?: {
|
|
51
|
+
top?: string;
|
|
52
|
+
right?: string;
|
|
53
|
+
bottom?: string;
|
|
54
|
+
left?: string;
|
|
55
|
+
};
|
|
56
|
+
landscape?: boolean;
|
|
57
|
+
printBackground?: boolean;
|
|
58
|
+
scale?: number;
|
|
59
|
+
/** Exact page size, e.g. "1280px"; wins over `format`. For fixed-canvas documents like slides. */
|
|
60
|
+
width?: string;
|
|
61
|
+
height?: string;
|
|
62
|
+
/** Use the document's own CSS `@page { size }`. */
|
|
63
|
+
preferCSSPageSize?: boolean;
|
|
64
|
+
/** Browser viewport, for layouts that scale to it (pin it to the canvas size). */
|
|
65
|
+
viewport?: Viewport;
|
|
66
|
+
}
|
|
67
|
+
/** HTML to a PDF: the bytes, or with `output: "url"` a link to it. */
|
|
68
|
+
declare function renderPDF(env: ServicesEnv, opts: RenderPDFOptions & {
|
|
69
|
+
output?: "bytes";
|
|
70
|
+
}): Promise<Uint8Array>;
|
|
71
|
+
declare function renderPDF(env: ServicesEnv, opts: RenderPDFOptions & AsLink): Promise<StoredFile>;
|
|
72
|
+
type ImageType = "png" | "jpeg" | "webp";
|
|
73
|
+
interface ScreenshotBase extends CallOptions {
|
|
74
|
+
/** Capture size; or pass a full `viewport`. */
|
|
75
|
+
width?: number;
|
|
76
|
+
height?: number;
|
|
77
|
+
viewport?: Viewport;
|
|
78
|
+
/** Default png. */
|
|
79
|
+
type?: ImageType;
|
|
80
|
+
/** The whole scrollable page, not just the viewport. */
|
|
81
|
+
fullPage?: boolean;
|
|
82
|
+
/** Transparent background (png, webp). */
|
|
83
|
+
omitBackground?: boolean;
|
|
84
|
+
/** 0 to 100, jpeg and webp only. */
|
|
85
|
+
quality?: number;
|
|
86
|
+
/** Capture once this CSS selector exists, for pages that finish rendering in script. */
|
|
87
|
+
waitForSelector?: string;
|
|
88
|
+
gotoWaitUntil?: WaitUntil;
|
|
89
|
+
}
|
|
90
|
+
/** Markup you supply, or a live public https page, never both. */
|
|
91
|
+
type RenderScreenshotOptions = ScreenshotBase & ({
|
|
92
|
+
html: string;
|
|
93
|
+
url?: never;
|
|
94
|
+
} | {
|
|
95
|
+
url: string;
|
|
96
|
+
html?: never;
|
|
97
|
+
});
|
|
98
|
+
/** Markup or a live page to an image: the bytes, or with `output: "url"` a link to it. */
|
|
99
|
+
declare function renderScreenshot(env: ServicesEnv, opts: RenderScreenshotOptions & {
|
|
100
|
+
output?: "bytes";
|
|
101
|
+
}): Promise<Uint8Array>;
|
|
102
|
+
declare function renderScreenshot(env: ServicesEnv, opts: RenderScreenshotOptions & AsLink): Promise<StoredFile>;
|
|
103
|
+
interface RenderMarkdownOptions extends CallOptions {
|
|
104
|
+
/** A public https page. It is rendered first, so a page built by script reads like a static one. */
|
|
105
|
+
url: string;
|
|
106
|
+
/** Cut the markdown to this many characters (the service caps it at 50,000). */
|
|
107
|
+
maxChars?: number;
|
|
108
|
+
gotoWaitUntil?: WaitUntil;
|
|
109
|
+
}
|
|
110
|
+
interface MarkdownPage {
|
|
111
|
+
url: string;
|
|
112
|
+
markdown: string;
|
|
113
|
+
chars: number;
|
|
114
|
+
truncated: boolean;
|
|
115
|
+
}
|
|
116
|
+
/** A live page's content as markdown, for example as a model's context. */
|
|
117
|
+
declare function renderMarkdown(env: ServicesEnv, opts: RenderMarkdownOptions): Promise<MarkdownPage>;
|
|
118
|
+
|
|
119
|
+
export { ClawnifyServicesError, type ImageType, type MarkdownPage, type PaperFormat, type RenderMarkdownOptions, type RenderPDFOptions, type RenderScreenshotOptions, type ServicesEnv, type StoredFile, type Viewport, type WaitUntil, renderMarkdown, renderPDF, renderScreenshot };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var ClawnifyServicesError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
code;
|
|
5
|
+
body;
|
|
6
|
+
constructor(message, opts = {}) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "ClawnifyServicesError";
|
|
9
|
+
this.status = opts.status;
|
|
10
|
+
this.code = opts.code;
|
|
11
|
+
this.body = opts.body;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var DEFAULT_URL = "https://services.clawnify.com";
|
|
15
|
+
async function post(env, path, body, signal) {
|
|
16
|
+
if (!env.CLAWNIFY_TOKEN) {
|
|
17
|
+
throw new ClawnifyServicesError("CLAWNIFY_TOKEN is not set, so Clawnify services are unavailable.");
|
|
18
|
+
}
|
|
19
|
+
const base = (env.CLAWNIFY_SERVICES_URL || DEFAULT_URL).replace(/\/+$/, "");
|
|
20
|
+
const res = await fetch(`${base}${path}`, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: { Authorization: `Bearer ${env.CLAWNIFY_TOKEN}`, "Content-Type": "application/json" },
|
|
23
|
+
body: JSON.stringify(body),
|
|
24
|
+
signal
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
const parsed = await res.json().catch(() => null);
|
|
28
|
+
const answer = parsed && typeof parsed === "object" ? parsed : void 0;
|
|
29
|
+
const code = typeof answer?.error === "string" ? answer.error : void 0;
|
|
30
|
+
const detail = typeof answer?.detail === "string" ? answer.detail : void 0;
|
|
31
|
+
throw new ClawnifyServicesError(detail || code || `${path} answered ${res.status}`, { status: res.status, code, body: answer });
|
|
32
|
+
}
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
async function deliver(res, output) {
|
|
36
|
+
return output === "url" ? await res.json() : new Uint8Array(await res.arrayBuffer());
|
|
37
|
+
}
|
|
38
|
+
async function renderPDF(env, opts) {
|
|
39
|
+
const link = opts.output === "url" ? opts : void 0;
|
|
40
|
+
const res = await post(env, "/pdf/render", {
|
|
41
|
+
html: opts.html,
|
|
42
|
+
format: opts.format,
|
|
43
|
+
margin: opts.margin,
|
|
44
|
+
landscape: opts.landscape,
|
|
45
|
+
print_background: opts.printBackground,
|
|
46
|
+
scale: opts.scale,
|
|
47
|
+
width: opts.width,
|
|
48
|
+
height: opts.height,
|
|
49
|
+
prefer_css_page_size: opts.preferCSSPageSize,
|
|
50
|
+
viewport: opts.viewport,
|
|
51
|
+
output: opts.output,
|
|
52
|
+
filename: link?.filename,
|
|
53
|
+
expires_in: link?.expiresIn
|
|
54
|
+
}, opts.signal);
|
|
55
|
+
return deliver(res, opts.output);
|
|
56
|
+
}
|
|
57
|
+
async function renderScreenshot(env, opts) {
|
|
58
|
+
const link = opts.output === "url" ? opts : void 0;
|
|
59
|
+
const res = await post(env, "/screenshot/render", {
|
|
60
|
+
html: opts.html,
|
|
61
|
+
url: opts.url,
|
|
62
|
+
width: opts.width,
|
|
63
|
+
height: opts.height,
|
|
64
|
+
viewport: opts.viewport,
|
|
65
|
+
type: opts.type,
|
|
66
|
+
full_page: opts.fullPage,
|
|
67
|
+
omit_background: opts.omitBackground,
|
|
68
|
+
quality: opts.quality,
|
|
69
|
+
wait_for_selector: opts.waitForSelector,
|
|
70
|
+
goto_wait_until: opts.gotoWaitUntil,
|
|
71
|
+
output: opts.output,
|
|
72
|
+
filename: link?.filename,
|
|
73
|
+
expires_in: link?.expiresIn
|
|
74
|
+
}, opts.signal);
|
|
75
|
+
return deliver(res, opts.output);
|
|
76
|
+
}
|
|
77
|
+
async function renderMarkdown(env, opts) {
|
|
78
|
+
const res = await post(env, "/markdown/render", {
|
|
79
|
+
url: opts.url,
|
|
80
|
+
max_chars: opts.maxChars,
|
|
81
|
+
goto_wait_until: opts.gotoWaitUntil
|
|
82
|
+
}, opts.signal);
|
|
83
|
+
return await res.json();
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
ClawnifyServicesError,
|
|
87
|
+
renderMarkdown,
|
|
88
|
+
renderPDF,
|
|
89
|
+
renderScreenshot
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @clawnify/services — call Clawnify's managed services (services.clawnify.com)\n// from a deployed app.\n//\n// One client for every service: the org's CLAWNIFY_TOKEN, injected into every\n// app at build, authorizes each call, and each call counts against the org's\n// monthly quota for that service. A function exists here for each route an app\n// calls; add one next to its siblings when a new service gets its first caller.\n// The queue has its own package, @clawnify/queue.\n\nexport interface ServicesEnv {\n CLAWNIFY_TOKEN?: string;\n /** Base URL override, for a local fake in tests. Default https://services.clawnify.com. */\n CLAWNIFY_SERVICES_URL?: string;\n}\n\n/**\n * A failed call. `code` is the service's own error code: `invalid_token`,\n * `quota_exceeded`, `render_failed`, … and `body` the whole answer, which for\n * `quota_exceeded` carries `limit`, `used` and `resets_at`.\n */\nexport class ClawnifyServicesError extends Error {\n readonly status?: number;\n readonly code?: string;\n readonly body?: Record<string, unknown>;\n constructor(message: string, opts: { status?: number; code?: string; body?: Record<string, unknown> } = {}) {\n super(message);\n this.name = \"ClawnifyServicesError\";\n this.status = opts.status;\n this.code = opts.code;\n this.body = opts.body;\n }\n}\n\n/** A render the service stored for you, served from a presigned link (`output: \"url\"`). */\nexport interface StoredFile {\n url: string;\n key: string;\n expires_at: string;\n size: number;\n content_type: string;\n}\n\nexport interface Viewport {\n width: number;\n height: number;\n deviceScaleFactor?: number;\n}\n\nexport type WaitUntil = \"load\" | \"domcontentloaded\" | \"networkidle0\" | \"networkidle2\";\n\ninterface CallOptions {\n signal?: AbortSignal;\n}\n\n/** Ask for a link instead of the bytes: for callers that can't hold or pass the file on themselves. */\ninterface AsLink {\n output: \"url\";\n /** Download name. */\n filename?: string;\n /** Link lifetime in seconds, at most 7 days. */\n expiresIn?: number;\n}\n\nconst DEFAULT_URL = \"https://services.clawnify.com\";\n\nasync function post(env: ServicesEnv, path: string, body: Record<string, unknown>, signal?: AbortSignal): Promise<Response> {\n if (!env.CLAWNIFY_TOKEN) {\n throw new ClawnifyServicesError(\"CLAWNIFY_TOKEN is not set, so Clawnify services are unavailable.\");\n }\n const base = (env.CLAWNIFY_SERVICES_URL || DEFAULT_URL).replace(/\\/+$/, \"\");\n const res = await fetch(`${base}${path}`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${env.CLAWNIFY_TOKEN}`, \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n if (!res.ok) {\n const parsed = (await res.json().catch(() => null)) as Record<string, unknown> | null;\n const answer = parsed && typeof parsed === \"object\" ? parsed : undefined;\n const code = typeof answer?.error === \"string\" ? answer.error : undefined;\n const detail = typeof answer?.detail === \"string\" ? answer.detail : undefined;\n throw new ClawnifyServicesError(detail || code || `${path} answered ${res.status}`, { status: res.status, code, body: answer });\n }\n return res;\n}\n\nasync function deliver(res: Response, output: \"bytes\" | \"url\" | undefined): Promise<Uint8Array | StoredFile> {\n return output === \"url\" ? ((await res.json()) as StoredFile) : new Uint8Array(await res.arrayBuffer());\n}\n\n// ── PDF ──────────────────────────────────────────────────────────────────────\n\nexport type PaperFormat = \"Letter\" | \"Legal\" | \"Tabloid\" | \"Ledger\" | \"A0\" | \"A1\" | \"A2\" | \"A3\" | \"A4\" | \"A5\" | \"A6\";\n\nexport interface RenderPDFOptions extends CallOptions {\n html: string;\n format?: PaperFormat;\n margin?: { top?: string; right?: string; bottom?: string; left?: string };\n landscape?: boolean;\n printBackground?: boolean;\n scale?: number;\n /** Exact page size, e.g. \"1280px\"; wins over `format`. For fixed-canvas documents like slides. */\n width?: string;\n height?: string;\n /** Use the document's own CSS `@page { size }`. */\n preferCSSPageSize?: boolean;\n /** Browser viewport, for layouts that scale to it (pin it to the canvas size). */\n viewport?: Viewport;\n}\n\n/** HTML to a PDF: the bytes, or with `output: \"url\"` a link to it. */\nexport function renderPDF(env: ServicesEnv, opts: RenderPDFOptions & { output?: \"bytes\" }): Promise<Uint8Array>;\nexport function renderPDF(env: ServicesEnv, opts: RenderPDFOptions & AsLink): Promise<StoredFile>;\nexport async function renderPDF(\n env: ServicesEnv,\n opts: RenderPDFOptions & ({ output?: \"bytes\" } | AsLink),\n): Promise<Uint8Array | StoredFile> {\n const link = opts.output === \"url\" ? (opts as AsLink) : undefined;\n const res = await post(env, \"/pdf/render\", {\n html: opts.html,\n format: opts.format,\n margin: opts.margin,\n landscape: opts.landscape,\n print_background: opts.printBackground,\n scale: opts.scale,\n width: opts.width,\n height: opts.height,\n prefer_css_page_size: opts.preferCSSPageSize,\n viewport: opts.viewport,\n output: opts.output,\n filename: link?.filename,\n expires_in: link?.expiresIn,\n }, opts.signal);\n return deliver(res, opts.output);\n}\n\n// ── Screenshot ───────────────────────────────────────────────────────────────\n\nexport type ImageType = \"png\" | \"jpeg\" | \"webp\";\n\ninterface ScreenshotBase extends CallOptions {\n /** Capture size; or pass a full `viewport`. */\n width?: number;\n height?: number;\n viewport?: Viewport;\n /** Default png. */\n type?: ImageType;\n /** The whole scrollable page, not just the viewport. */\n fullPage?: boolean;\n /** Transparent background (png, webp). */\n omitBackground?: boolean;\n /** 0 to 100, jpeg and webp only. */\n quality?: number;\n /** Capture once this CSS selector exists, for pages that finish rendering in script. */\n waitForSelector?: string;\n gotoWaitUntil?: WaitUntil;\n}\n\n/** Markup you supply, or a live public https page, never both. */\nexport type RenderScreenshotOptions = ScreenshotBase & ({ html: string; url?: never } | { url: string; html?: never });\n\n/** Markup or a live page to an image: the bytes, or with `output: \"url\"` a link to it. */\nexport function renderScreenshot(env: ServicesEnv, opts: RenderScreenshotOptions & { output?: \"bytes\" }): Promise<Uint8Array>;\nexport function renderScreenshot(env: ServicesEnv, opts: RenderScreenshotOptions & AsLink): Promise<StoredFile>;\nexport async function renderScreenshot(\n env: ServicesEnv,\n opts: RenderScreenshotOptions & ({ output?: \"bytes\" } | AsLink),\n): Promise<Uint8Array | StoredFile> {\n const link = opts.output === \"url\" ? (opts as AsLink) : undefined;\n const res = await post(env, \"/screenshot/render\", {\n html: opts.html,\n url: opts.url,\n width: opts.width,\n height: opts.height,\n viewport: opts.viewport,\n type: opts.type,\n full_page: opts.fullPage,\n omit_background: opts.omitBackground,\n quality: opts.quality,\n wait_for_selector: opts.waitForSelector,\n goto_wait_until: opts.gotoWaitUntil,\n output: opts.output,\n filename: link?.filename,\n expires_in: link?.expiresIn,\n }, opts.signal);\n return deliver(res, opts.output);\n}\n\n// ── Markdown ─────────────────────────────────────────────────────────────────\n\nexport interface RenderMarkdownOptions extends CallOptions {\n /** A public https page. It is rendered first, so a page built by script reads like a static one. */\n url: string;\n /** Cut the markdown to this many characters (the service caps it at 50,000). */\n maxChars?: number;\n gotoWaitUntil?: WaitUntil;\n}\n\nexport interface MarkdownPage {\n url: string;\n markdown: string;\n chars: number;\n truncated: boolean;\n}\n\n/** A live page's content as markdown, for example as a model's context. */\nexport async function renderMarkdown(env: ServicesEnv, opts: RenderMarkdownOptions): Promise<MarkdownPage> {\n const res = await post(env, \"/markdown/render\", {\n url: opts.url,\n max_chars: opts.maxChars,\n goto_wait_until: opts.gotoWaitUntil,\n }, opts.signal);\n return (await res.json()) as MarkdownPage;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@clawnify/services",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Call Clawnify's managed services (PDF, screenshots, page markdown) from a deployed app.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.0.0",
|
|
22
|
+
"typescript": "^5.7.0",
|
|
23
|
+
"vitest": "^4.1.10"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"test": "vitest run"
|
|
29
|
+
}
|
|
30
|
+
}
|