@zhin.js/html-renderer 3.0.15 → 3.0.16

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @zhin.js/html-renderer
2
2
 
3
- HTML → PNG/SVG,供 Zhin.js 出站富媒体段(`segment.html` / `segment.markdown`)与可选 `aiTextAsImage` 使用。
3
+ HTML → 图片,供 Zhin.js 出站富媒体段(`segment.html` / `segment.markdown`)与可选 `aiTextAsImage` 使用。
4
4
 
5
- 基于 `@zhin.js/satori` + `@resvg/resvg-js`,**不**再作为插件加载。
5
+ 现在只使用 **Shotium(裁剪版 Chromium)** 渲染,不再依赖 `satori + resvg`。
6
6
 
7
7
  ## 安装
8
8
 
@@ -16,30 +16,28 @@ pnpm add @zhin.js/html-renderer
16
16
 
17
17
  ```yaml
18
18
  htmlRenderer:
19
- defaultWidth: 1080
20
- defaultBackgroundColor: "#ffffff"
21
- aiTextAsImage: false # true 时纯文本出站转 PNG(before.sendMessage)
19
+ width: 1080
20
+ viewport:
21
+ height: 600
22
+ backgroundColor: "#ffffff"
23
+ scale: 1
24
+ aiTextAsImage: false
22
25
  ```
23
26
 
27
+ 兼容旧字段 `defaultWidth` / `defaultBackgroundColor` / `defaultFonts`;新后端还支持 `viewport`、`scale`、`timeout`、`waitUntil`、`fontFamily`、`allowFileAccess`、`cacheDir`、`cacheMaxBytes`、`userAgent`、`idleTimeoutMs`、`logStats`。
28
+
24
29
  ## API
25
30
 
26
31
  ```typescript
27
32
  import { createHtmlRenderer } from '@zhin.js/html-renderer';
28
33
 
29
- const renderer = createHtmlRenderer({ defaultWidth: 540 });
34
+ const renderer = createHtmlRenderer({ width: 540 });
30
35
  const png = await renderer.render('<div>Hello</div>', { format: 'png' });
36
+ const stillPng = await renderer.render('<div>Hello</div>', { format: 'svg' });
31
37
  ```
32
38
 
33
- Core 出站链通过动态 import 自动调用,业务代码通常只需 `segment.html({ html: '...' })`。
34
-
35
- ## IM 组件与 Context(安装包后 zhin 启动自动注册)
39
+ - `format: 'png'`:优先走 Shotium。
40
+ - `format: 'svg'`:为兼容旧调用方,仍可传入,但会返回 `png` 并警告一次。
41
+ - `renderJsx()` / `renderComponent()`:继续保留,可直接把 JSX/函数组件转成图片。
36
42
 
37
- 无需再写 plugins 列表,安装 `@zhin.js/html-renderer` 后启动时自动:
38
-
39
- | 能力 | 说明 |
40
- |------|------|
41
- | **`RenderImage` 组件** | 模板/命令中 `<RenderImage html="..." width="540"/>`,异步渲染为 `image` 段 |
42
- | **`html-renderer` Context** | `useContext('html-renderer', (r) => …)` 或 `inject('html-renderer')` |
43
- | **Agent 工具** | `html_render`、`html_card`(需已装 `@zhin.js/agent` 且 tool 服务可用) |
44
-
45
- 自定义组件仍用 `defineComponent` + `addComponent`;需要转图时在组件内 `inject('html-renderer')` 或返回 `segment.html({ html })` 走出站 policy。
43
+ Core 出站链通过动态 import 自动调用,业务代码通常只需 `segment.html({ html: '...' })`。
@@ -0,0 +1,33 @@
1
+ import type { FontConfig, HtmlRendererAiTextAsImageConfig, RasterFormat, WaitUntil } from './types.js';
2
+ export interface ShotiumConfig {
3
+ viewport: {
4
+ width: number;
5
+ height: number;
6
+ };
7
+ scale: number;
8
+ type: RasterFormat;
9
+ quality: number;
10
+ timeout: number;
11
+ waitUntil: WaitUntil;
12
+ backgroundColor: string;
13
+ fontFamily: string;
14
+ maxImageHeight: number;
15
+ sliceCompression: number;
16
+ allowFileAccess: boolean;
17
+ takeOverHtmlSegments: boolean;
18
+ cacheDir: string;
19
+ cacheMaxBytes: number;
20
+ userAgent: string;
21
+ idleTimeoutMs: number;
22
+ logStats: boolean;
23
+ mode: 'inprocess' | 'daemon';
24
+ }
25
+ export interface ResolvedHtmlRendererConfig {
26
+ defaultWidth: number;
27
+ defaultFonts: FontConfig[];
28
+ defaultBackgroundColor: string;
29
+ aiTextAsImage?: boolean | HtmlRendererAiTextAsImageConfig;
30
+ shotium: ShotiumConfig;
31
+ }
32
+ export declare function resolveHtmlRendererConfig(raw: unknown): ResolvedHtmlRendererConfig;
33
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,+BAA+B,EAE/B,YAAY,EACZ,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,WAAW,GAAG,QAAQ,CAAC;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,GAAG,+BAA+B,CAAC;IAC1D,OAAO,EAAE,aAAa,CAAC;CACxB;AAiED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,0BAA0B,CAwElF"}
package/lib/config.js ADDED
@@ -0,0 +1,90 @@
1
+ const DEFAULT_CONFIG = {
2
+ defaultWidth: 800,
3
+ defaultFonts: [],
4
+ defaultBackgroundColor: '#ffffff',
5
+ aiTextAsImage: undefined,
6
+ shotium: {
7
+ mode: 'inprocess',
8
+ viewport: { width: 800, height: 600 },
9
+ scale: 1,
10
+ type: 'png',
11
+ quality: 90,
12
+ timeout: 30_000,
13
+ waitUntil: 'load',
14
+ backgroundColor: '#ffffff',
15
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif',
16
+ maxImageHeight: 0,
17
+ sliceCompression: 3,
18
+ allowFileAccess: true,
19
+ takeOverHtmlSegments: true,
20
+ cacheDir: '',
21
+ cacheMaxBytes: 256 * 1024 * 1024,
22
+ userAgent: '',
23
+ idleTimeoutMs: 300_000,
24
+ logStats: false,
25
+ },
26
+ };
27
+ function clamp(value, min, max) {
28
+ return Math.min(max, Math.max(min, value));
29
+ }
30
+ function pickNumber(value, fallback, min, max) {
31
+ return typeof value === 'number' && Number.isFinite(value)
32
+ ? clamp(value, min, max)
33
+ : fallback;
34
+ }
35
+ function pickString(value, fallback, allowed) {
36
+ if (typeof value !== 'string')
37
+ return fallback;
38
+ if (allowed && !allowed.includes(value))
39
+ return fallback;
40
+ return value;
41
+ }
42
+ function pickBoolean(value, fallback) {
43
+ return typeof value === 'boolean' ? value : fallback;
44
+ }
45
+ function pickConfigRoot(raw) {
46
+ if (raw && typeof raw === 'object') {
47
+ const input = raw;
48
+ if (input.htmlRenderer && typeof input.htmlRenderer === 'object') {
49
+ return input.htmlRenderer;
50
+ }
51
+ return input;
52
+ }
53
+ return {};
54
+ }
55
+ export function resolveHtmlRendererConfig(raw) {
56
+ const input = pickConfigRoot(raw);
57
+ const viewport = (input.viewport ?? {});
58
+ const defaultWidth = pickNumber(input.defaultWidth ?? input.width ?? viewport.width, DEFAULT_CONFIG.defaultWidth, 1, 30_000);
59
+ const defaultBackgroundColor = pickString(input.defaultBackgroundColor ?? input.backgroundColor, DEFAULT_CONFIG.defaultBackgroundColor);
60
+ return {
61
+ defaultWidth,
62
+ defaultFonts: Array.isArray(input.defaultFonts) ? input.defaultFonts.filter(Boolean) : [],
63
+ defaultBackgroundColor,
64
+ aiTextAsImage: input.aiTextAsImage,
65
+ shotium: {
66
+ mode: pickString(input.mode, DEFAULT_CONFIG.shotium.mode, ['inprocess', 'daemon']),
67
+ viewport: {
68
+ width: pickNumber(viewport.width ?? input.width ?? input.defaultWidth, defaultWidth, 1, 30_000),
69
+ height: pickNumber(viewport.height, DEFAULT_CONFIG.shotium.viewport.height, 1, 30_000),
70
+ },
71
+ scale: pickNumber(input.scale, DEFAULT_CONFIG.shotium.scale, 0.01, 8),
72
+ type: pickString(input.type, DEFAULT_CONFIG.shotium.type, ['png', 'jpeg', 'webp']),
73
+ quality: pickNumber(input.quality, DEFAULT_CONFIG.shotium.quality, 1, 100),
74
+ timeout: pickNumber(input.timeout, DEFAULT_CONFIG.shotium.timeout, 1, 600_000),
75
+ waitUntil: pickString(input.waitUntil, DEFAULT_CONFIG.shotium.waitUntil, ['load', 'networkidle']),
76
+ backgroundColor: pickString(input.backgroundColor ?? input.defaultBackgroundColor, defaultBackgroundColor),
77
+ fontFamily: pickString(input.fontFamily, DEFAULT_CONFIG.shotium.fontFamily),
78
+ maxImageHeight: pickNumber(input.maxImageHeight, DEFAULT_CONFIG.shotium.maxImageHeight, 0, 100_000),
79
+ sliceCompression: pickNumber(input.sliceCompression, DEFAULT_CONFIG.shotium.sliceCompression, 0, 9),
80
+ allowFileAccess: pickBoolean(input.allowFileAccess, DEFAULT_CONFIG.shotium.allowFileAccess),
81
+ takeOverHtmlSegments: pickBoolean(input.takeOverHtmlSegments, DEFAULT_CONFIG.shotium.takeOverHtmlSegments),
82
+ cacheDir: pickString(input.cacheDir, DEFAULT_CONFIG.shotium.cacheDir),
83
+ cacheMaxBytes: pickNumber(input.cacheMaxBytes, DEFAULT_CONFIG.shotium.cacheMaxBytes, 0, Number.MAX_SAFE_INTEGER),
84
+ userAgent: pickString(input.userAgent, DEFAULT_CONFIG.shotium.userAgent),
85
+ idleTimeoutMs: pickNumber(input.idleTimeoutMs, DEFAULT_CONFIG.shotium.idleTimeoutMs, 0, 86_400_000),
86
+ logStats: pickBoolean(input.logStats, DEFAULT_CONFIG.shotium.logStats),
87
+ },
88
+ };
89
+ }
90
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ScreenshotOptions, ScreenshotResult } from '@shotkit/shotium';
2
+ import type { ShotiumConfig } from './config.js';
3
+ import type { HtmlRendererLogger } from './types.js';
4
+ interface Engine {
5
+ screenshot(options: ScreenshotOptions): Promise<ScreenshotResult>;
6
+ release(): void;
7
+ describe(): string;
8
+ close(): Promise<void>;
9
+ }
10
+ export declare function createEngine(config: ShotiumConfig, logger?: HtmlRendererLogger): Engine;
11
+ export {};
12
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,UAAU,MAAM;IACd,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,IAAI,MAAM,CAAC;IACnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA8FD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAIvF"}
package/lib/engine.js ADDED
@@ -0,0 +1,97 @@
1
+ import { daemon, releaseMemory, screenshot, start, status, } from '@shotkit/shotium';
2
+ function toStartOptions(config) {
3
+ const options = { cacheMaxBytes: config.cacheMaxBytes };
4
+ const cacheDir = config.cacheDir.trim();
5
+ if (cacheDir === 'off')
6
+ options.cacheDir = null;
7
+ else if (cacheDir)
8
+ options.cacheDir = cacheDir;
9
+ if (config.userAgent)
10
+ options.userAgent = config.userAgent;
11
+ return options;
12
+ }
13
+ function createInprocessEngine(config, logger) {
14
+ const options = toStartOptions(config);
15
+ let started = false;
16
+ let mismatchWarned = false;
17
+ const ensureStarted = () => {
18
+ if (started && status().running)
19
+ return;
20
+ try {
21
+ const result = start(options);
22
+ logger?.debug?.(`[shotium] in-process engine ready cache=${result.cacheActive ? result.cacheDir : 'off'}`);
23
+ }
24
+ catch (error) {
25
+ if (!status().running)
26
+ throw error;
27
+ if (!mismatchWarned) {
28
+ mismatchWarned = true;
29
+ logger?.warn?.('[shotium] engine already started with different cacheDir/userAgent; reusing current process engine', error);
30
+ }
31
+ }
32
+ started = true;
33
+ };
34
+ return {
35
+ async screenshot(shot) {
36
+ ensureStarted();
37
+ return screenshot(shot);
38
+ },
39
+ release() {
40
+ if (status().running)
41
+ releaseMemory();
42
+ },
43
+ describe: () => 'inprocess',
44
+ async close() {
45
+ if (status().running)
46
+ releaseMemory({ releaseWorkingSet: true });
47
+ },
48
+ };
49
+ }
50
+ function createDaemonEngine(config, logger) {
51
+ const options = { ...toStartOptions(config), idleTimeoutMs: config.idleTimeoutMs };
52
+ let client = null;
53
+ let pending = null;
54
+ const connect = async () => {
55
+ if (client)
56
+ return client;
57
+ if (!pending) {
58
+ pending = daemon.connect(options)
59
+ .then((connected) => {
60
+ client = connected;
61
+ connected.once('close', () => {
62
+ client = null;
63
+ logger?.warn?.('[shotium] daemon connection closed; reconnecting on next render');
64
+ });
65
+ logger?.debug?.('[shotium] daemon engine connected');
66
+ return connected;
67
+ })
68
+ .finally(() => {
69
+ pending = null;
70
+ });
71
+ }
72
+ return pending;
73
+ };
74
+ return {
75
+ async screenshot(shot) {
76
+ try {
77
+ return await (await connect()).screenshot(shot);
78
+ }
79
+ catch {
80
+ client = null;
81
+ return (await connect()).screenshot(shot);
82
+ }
83
+ },
84
+ release() { },
85
+ describe: () => 'daemon',
86
+ async close() {
87
+ client?.close();
88
+ client = null;
89
+ },
90
+ };
91
+ }
92
+ export function createEngine(config, logger) {
93
+ return config.mode === 'daemon'
94
+ ? createDaemonEngine(config, logger)
95
+ : createInprocessEngine(config, logger);
96
+ }
97
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/lib/html.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { FontConfig } from './types.js';
2
+ interface WrapOptions {
3
+ width: number;
4
+ height?: number;
5
+ backgroundColor: string;
6
+ fontFamily: string;
7
+ fontFaces?: string;
8
+ }
9
+ export declare function isFullDocument(html: string): boolean;
10
+ export declare function wrapDocument(html: string, options: WrapOptions): string;
11
+ export declare function buildFontFaces(fonts: readonly FontConfig[]): string;
12
+ export declare function withDocumentFile<T>(document: string, run: (file: string) => Promise<T>): Promise<T>;
13
+ export {};
14
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CA8BvE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAyBnE;AAED,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,CAAC,CAAC,CAUZ"}
package/lib/html.js ADDED
@@ -0,0 +1,94 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { pathToFileURL } from 'node:url';
6
+ const TEMP_ROOT = path.join(os.tmpdir(), 'zhin-shotium');
7
+ const FONT_DIR = path.join(TEMP_ROOT, 'fonts');
8
+ function escapeCssValue(value) {
9
+ return value.replace(/[<>{};]/g, '');
10
+ }
11
+ function fontExtension(data) {
12
+ const tag = data.subarray(0, 4).toString('ascii');
13
+ if (tag === 'wOFF')
14
+ return 'woff';
15
+ if (tag === 'wOF2')
16
+ return 'woff2';
17
+ if (tag === 'OTTO')
18
+ return 'otf';
19
+ if (tag === 'ttcf')
20
+ return 'ttc';
21
+ return 'ttf';
22
+ }
23
+ function toBuffer(data) {
24
+ return Buffer.isBuffer(data) ? data : Buffer.from(new Uint8Array(data));
25
+ }
26
+ export function isFullDocument(html) {
27
+ return /<!doctype\s+html|<html[\s>]/i.test(html);
28
+ }
29
+ export function wrapDocument(html, options) {
30
+ const fontFaces = options.fontFaces ?? '';
31
+ if (isFullDocument(html)) {
32
+ if (!fontFaces)
33
+ return html;
34
+ const style = `<style>${fontFaces}</style>`;
35
+ if (/<\/head>/i.test(html))
36
+ return html.replace(/<\/head>/i, `${style}</head>`);
37
+ if (/<body[^>]*>/i.test(html)) {
38
+ return html.replace(/<body[^>]*>/i, (match) => `${match}${style}`);
39
+ }
40
+ return `${style}${html}`;
41
+ }
42
+ const height = options.height ? `min-height:${Math.round(options.height)}px;` : '';
43
+ return [
44
+ '<!DOCTYPE html>',
45
+ '<html><head><meta charset="utf-8">',
46
+ '<style>',
47
+ fontFaces,
48
+ '*,*::before,*::after{box-sizing:border-box}',
49
+ 'html,body{margin:0;padding:0}',
50
+ `body{width:${Math.round(options.width)}px;${height}`,
51
+ `background:${escapeCssValue(options.backgroundColor)};`,
52
+ `font-family:${escapeCssValue(options.fontFamily)};`,
53
+ '-webkit-font-smoothing:antialiased}',
54
+ '</style></head><body>',
55
+ html,
56
+ '</body></html>',
57
+ ].join('');
58
+ }
59
+ export function buildFontFaces(fonts) {
60
+ if (fonts.length === 0)
61
+ return '';
62
+ const rules = [];
63
+ for (const font of fonts) {
64
+ const data = toBuffer(font.data);
65
+ if (data.length === 0)
66
+ continue;
67
+ const hash = crypto.createHash('sha1').update(data).digest('hex').slice(0, 16);
68
+ const file = path.join(FONT_DIR, `${hash}.${fontExtension(data)}`);
69
+ if (!fs.existsSync(file)) {
70
+ fs.mkdirSync(FONT_DIR, { recursive: true });
71
+ fs.writeFileSync(file, data);
72
+ }
73
+ rules.push('@font-face{'
74
+ + `font-family:"${escapeCssValue(font.name).replace(/"/g, '')}";`
75
+ + `font-weight:${font.weight ?? 400};`
76
+ + `font-style:${font.style === 'italic' ? 'italic' : 'normal'};`
77
+ + 'font-display:block;'
78
+ + `src:url("${pathToFileURL(file).href}")}`);
79
+ }
80
+ return rules.join('');
81
+ }
82
+ export async function withDocumentFile(document, run) {
83
+ fs.mkdirSync(TEMP_ROOT, { recursive: true });
84
+ const name = `${process.pid}-${crypto.randomBytes(8).toString('hex')}.html`;
85
+ const file = path.join(TEMP_ROOT, name);
86
+ fs.writeFileSync(file, document, 'utf8');
87
+ try {
88
+ return await run(file);
89
+ }
90
+ finally {
91
+ fs.rm(file, { force: true }, () => { });
92
+ }
93
+ }
94
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"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"}
package/lib/image.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export declare function readImageSize(buf: Buffer): {
2
+ width: number;
3
+ height: number;
4
+ } | null;
5
+ export interface PngInfo {
6
+ width: number;
7
+ height: number;
8
+ bitDepth: number;
9
+ colorType: number;
10
+ interlace: number;
11
+ }
12
+ export declare function readPngInfo(buf: Buffer): PngInfo | null;
13
+ export declare function splitPng(buf: Buffer, sliceHeight: number, level?: number): Buffer[] | null;
14
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AA+DA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAInF;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAWvD;AAuGD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,GAAG,IAAI,CA2DrF"}