@nhtio/adk 1.20260609.0 → 1.20260610.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/CHANGELOG.md +132 -9
- package/batteries/llm/ollama/helpers.cjs +9 -0
- package/batteries/llm/ollama/helpers.cjs.map +1 -1
- package/batteries/llm/ollama/helpers.mjs +9 -0
- package/batteries/llm/ollama/helpers.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +19 -0
- package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.mjs +19 -0
- package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
- package/batteries/media/builder.d.ts +245 -0
- package/batteries/media/contracts.cjs +119 -0
- package/batteries/media/contracts.cjs.map +1 -0
- package/batteries/media/contracts.d.ts +321 -0
- package/batteries/media/contracts.mjs +110 -0
- package/batteries/media/contracts.mjs.map +1 -0
- package/batteries/media/engines/audio_decode.cjs +92 -0
- package/batteries/media/engines/audio_decode.cjs.map +1 -0
- package/batteries/media/engines/audio_decode.d.ts +46 -0
- package/batteries/media/engines/audio_decode.mjs +90 -0
- package/batteries/media/engines/audio_decode.mjs.map +1 -0
- package/batteries/media/engines/execa_executor.cjs +64 -0
- package/batteries/media/engines/execa_executor.cjs.map +1 -0
- package/batteries/media/engines/execa_executor.d.ts +54 -0
- package/batteries/media/engines/execa_executor.mjs +62 -0
- package/batteries/media/engines/execa_executor.mjs.map +1 -0
- package/batteries/media/engines/fs_workspace.cjs +84 -0
- package/batteries/media/engines/fs_workspace.cjs.map +1 -0
- package/batteries/media/engines/fs_workspace.d.ts +51 -0
- package/batteries/media/engines/fs_workspace.mjs +82 -0
- package/batteries/media/engines/fs_workspace.mjs.map +1 -0
- package/batteries/media/engines/jimp.cjs +116 -0
- package/batteries/media/engines/jimp.cjs.map +1 -0
- package/batteries/media/engines/jimp.d.ts +32 -0
- package/batteries/media/engines/jimp.mjs +114 -0
- package/batteries/media/engines/jimp.mjs.map +1 -0
- package/batteries/media/engines/sharp.cjs +120 -0
- package/batteries/media/engines/sharp.cjs.map +1 -0
- package/batteries/media/engines/sharp.d.ts +42 -0
- package/batteries/media/engines/sharp.mjs +117 -0
- package/batteries/media/engines/sharp.mjs.map +1 -0
- package/batteries/media/engines/soffice.cjs +246 -0
- package/batteries/media/engines/soffice.cjs.map +1 -0
- package/batteries/media/engines/soffice.d.ts +39 -0
- package/batteries/media/engines/soffice.mjs +244 -0
- package/batteries/media/engines/soffice.mjs.map +1 -0
- package/batteries/media/engines/tesseract_js.cjs +87 -0
- package/batteries/media/engines/tesseract_js.cjs.map +1 -0
- package/batteries/media/engines/tesseract_js.d.ts +41 -0
- package/batteries/media/engines/tesseract_js.mjs +85 -0
- package/batteries/media/engines/tesseract_js.mjs.map +1 -0
- package/batteries/media/engines/transformers_asr.cjs +111 -0
- package/batteries/media/engines/transformers_asr.cjs.map +1 -0
- package/batteries/media/engines/transformers_asr.d.ts +41 -0
- package/batteries/media/engines/transformers_asr.mjs +109 -0
- package/batteries/media/engines/transformers_asr.mjs.map +1 -0
- package/batteries/media/exceptions.d.ts +103 -0
- package/batteries/media/forge.cjs +403 -0
- package/batteries/media/forge.cjs.map +1 -0
- package/batteries/media/forge.d.ts +90 -0
- package/batteries/media/forge.mjs +399 -0
- package/batteries/media/forge.mjs.map +1 -0
- package/batteries/media/formats.d.ts +72 -0
- package/batteries/media/index.d.ts +136 -0
- package/batteries/media/lint.cjs +339 -0
- package/batteries/media/lint.cjs.map +1 -0
- package/batteries/media/lint.d.ts +117 -0
- package/batteries/media/lint.mjs +331 -0
- package/batteries/media/lint.mjs.map +1 -0
- package/batteries/media/pipe.d.ts +66 -0
- package/batteries/media/plan.d.ts +133 -0
- package/batteries/media/registry.d.ts +92 -0
- package/batteries/media/runtime.d.ts +105 -0
- package/batteries/media/steps/doc.d.ts +33 -0
- package/batteries/media/steps/image_audio.d.ts +24 -0
- package/batteries/media/steps/ingest.d.ts +25 -0
- package/batteries/media/steps/pages.d.ts +18 -0
- package/batteries/media/steps/sheet.d.ts +36 -0
- package/batteries/media/steps/slides.d.ts +35 -0
- package/batteries/media/steps/text.d.ts +43 -0
- package/batteries/media/validate.d.ts +49 -0
- package/batteries/media/verbs.d.ts +126 -0
- package/batteries/media.cjs +3049 -0
- package/batteries/media.cjs.map +1 -0
- package/batteries/media.mjs +3009 -0
- package/batteries/media.mjs.map +1 -0
- package/batteries/tools/_shared/index.d.ts +142 -0
- package/batteries/tools/_shared.cjs +173 -0
- package/batteries/tools/_shared.cjs.map +1 -0
- package/batteries/tools/_shared.mjs +164 -0
- package/batteries/tools/_shared.mjs.map +1 -0
- package/batteries/tools/index.d.ts +2 -0
- package/batteries/tools/scrapper/exceptions.d.ts +21 -0
- package/batteries/tools/scrapper/index.d.ts +172 -0
- package/batteries/tools/scrapper/shared.d.ts +146 -0
- package/batteries/tools/scrapper.cjs +8 -0
- package/batteries/tools/scrapper.mjs +2 -0
- package/batteries/tools/searxng/index.d.ts +54 -20
- package/batteries/tools/searxng.cjs +2 -1
- package/batteries/tools/searxng.mjs +2 -2
- package/batteries/tools/web_retrieval/index.d.ts +186 -0
- package/batteries/tools/web_retrieval.cjs +206 -0
- package/batteries/tools/web_retrieval.cjs.map +1 -0
- package/batteries/tools/web_retrieval.mjs +201 -0
- package/batteries/tools/web_retrieval.mjs.map +1 -0
- package/batteries/tools.cjs +13 -1
- package/batteries/tools.mjs +4 -2
- package/batteries.cjs +13 -1
- package/batteries.mjs +4 -2
- package/common.d.ts +1 -1
- package/eslint.cjs +1 -1
- package/eslint.mjs +1 -1
- package/exceptions-C7FSHEnV.mjs +87 -0
- package/exceptions-C7FSHEnV.mjs.map +1 -0
- package/exceptions-CQi_lNs1.js +152 -0
- package/exceptions-CQi_lNs1.js.map +1 -0
- package/index.cjs +2 -2
- package/index.mjs +2 -2
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +301 -178
- package/scrapper-BOLWYGbD.js +463 -0
- package/scrapper-BOLWYGbD.js.map +1 -0
- package/scrapper-hDKlNuCT.mjs +433 -0
- package/scrapper-hDKlNuCT.mjs.map +1 -0
- package/{searxng-Bkrwhwhw.js → searxng-CJtEpa8p.js} +82 -85
- package/searxng-CJtEpa8p.js.map +1 -0
- package/{searxng-CyA-nEu5.mjs → searxng-riarj_0u.mjs} +76 -85
- package/searxng-riarj_0u.mjs.map +1 -0
- package/skills/adk-assembly/SKILL.md +2 -2
- package/validate-BFaUYHDN.js +1298 -0
- package/validate-BFaUYHDN.js.map +1 -0
- package/validate-DSZ3wicB.mjs +1215 -0
- package/validate-DSZ3wicB.mjs.map +1 -0
- package/searxng-Bkrwhwhw.js.map +0 -1
- package/searxng-CyA-nEu5.mjs.map +0 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_tool_registry = require("../../../tool_registry-CKJPze3j.js");
|
|
4
|
+
require("../../../guards.cjs");
|
|
5
|
+
const require_exceptions = require("../../../exceptions-CQi_lNs1.js");
|
|
6
|
+
//#region src/batteries/media/engines/jimp.ts
|
|
7
|
+
/**
|
|
8
|
+
* A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
9
|
+
* backed by Jimp (pure JavaScript — no native bindings, no binaries).
|
|
10
|
+
*
|
|
11
|
+
* @module @nhtio/adk/batteries/media/engines/jimp
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
|
|
15
|
+
* capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
|
|
16
|
+
* flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
|
|
17
|
+
* `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
|
|
18
|
+
* compose a sharp-backed engine instead — the capability declaration is the seam.
|
|
19
|
+
*
|
|
20
|
+
* `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
|
|
21
|
+
* the engine — and therefore the pipeline — never loads it).
|
|
22
|
+
*/
|
|
23
|
+
var SUPPORTED_OUTPUT = [
|
|
24
|
+
"png",
|
|
25
|
+
"jpg",
|
|
26
|
+
"jpeg",
|
|
27
|
+
"bmp",
|
|
28
|
+
"gif",
|
|
29
|
+
"tiff"
|
|
30
|
+
];
|
|
31
|
+
var MIME_BY_FORMAT = {
|
|
32
|
+
png: "image/png",
|
|
33
|
+
jpg: "image/jpeg",
|
|
34
|
+
jpeg: "image/jpeg",
|
|
35
|
+
bmp: "image/bmp",
|
|
36
|
+
gif: "image/gif",
|
|
37
|
+
tiff: "image/tiff"
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Construct the Jimp-backed image engine.
|
|
41
|
+
*
|
|
42
|
+
* @param options - Optional module resolver override.
|
|
43
|
+
* @returns The engine.
|
|
44
|
+
*/
|
|
45
|
+
var jimpEngine = (options = {}) => {
|
|
46
|
+
let modPromise;
|
|
47
|
+
const getJimp = () => {
|
|
48
|
+
modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import("jimp")).catch((err) => {
|
|
49
|
+
throw new require_exceptions.E_INVALID_MEDIA_PIPELINE_CONFIG([`the jimp engine could not load its peer dependency "jimp": ${require_tool_registry.isError(err) ? err.message : String(err)} — install it (pnpm add jimp)`]);
|
|
50
|
+
});
|
|
51
|
+
return modPromise;
|
|
52
|
+
};
|
|
53
|
+
const mutate = async (request) => {
|
|
54
|
+
const { Jimp } = await getJimp();
|
|
55
|
+
const image = await Jimp.read(request.bytes.buffer.slice(request.bytes.byteOffset, request.bytes.byteOffset + request.bytes.byteLength));
|
|
56
|
+
if (request.resize) {
|
|
57
|
+
const { width, height, fit } = request.resize;
|
|
58
|
+
if (width !== void 0 && height !== void 0) if (fit === "cover") image.cover({
|
|
59
|
+
w: width,
|
|
60
|
+
h: height
|
|
61
|
+
});
|
|
62
|
+
else if (fit === "contain") image.contain({
|
|
63
|
+
w: width,
|
|
64
|
+
h: height
|
|
65
|
+
});
|
|
66
|
+
else image.resize({
|
|
67
|
+
w: width,
|
|
68
|
+
h: height
|
|
69
|
+
});
|
|
70
|
+
else if (width !== void 0) image.resize({ w: width });
|
|
71
|
+
else if (height !== void 0) image.resize({ h: height });
|
|
72
|
+
}
|
|
73
|
+
if (request.rotate) image.rotate(request.rotate);
|
|
74
|
+
if (request.flip) image.flip({
|
|
75
|
+
horizontal: request.flip.horizontal === true,
|
|
76
|
+
vertical: request.flip.vertical === true
|
|
77
|
+
});
|
|
78
|
+
const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType);
|
|
79
|
+
const mimeType = MIME_BY_FORMAT[targetFormat];
|
|
80
|
+
if (!mimeType) throw new Error(`jimp cannot encode "${targetFormat}"; supported: ${SUPPORTED_OUTPUT.join(", ")} (compose a sharp engine for webp/avif)`);
|
|
81
|
+
const quality = request.format?.quality;
|
|
82
|
+
const buffer = mimeType === "image/jpeg" && quality !== void 0 ? await image.getBuffer("image/jpeg", { quality }) : await image.getBuffer(mimeType);
|
|
83
|
+
return {
|
|
84
|
+
bytes: new Uint8Array(buffer),
|
|
85
|
+
mimeType
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
id: "jimp",
|
|
90
|
+
mutates: [{
|
|
91
|
+
over: [
|
|
92
|
+
"image/png",
|
|
93
|
+
"image/jpeg",
|
|
94
|
+
"image/bmp",
|
|
95
|
+
"image/gif",
|
|
96
|
+
"image/tiff"
|
|
97
|
+
],
|
|
98
|
+
ops: [
|
|
99
|
+
"resize",
|
|
100
|
+
"rotate",
|
|
101
|
+
"flip",
|
|
102
|
+
"strip_metadata"
|
|
103
|
+
],
|
|
104
|
+
encodes: SUPPORTED_OUTPUT,
|
|
105
|
+
mutate
|
|
106
|
+
}]
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
var mimeToFormat = (mimeType) => {
|
|
110
|
+
const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
|
|
111
|
+
return sub === "jpeg" ? "jpg" : sub;
|
|
112
|
+
};
|
|
113
|
+
//#endregion
|
|
114
|
+
exports.jimpEngine = jimpEngine;
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=jimp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jimp.cjs","names":[],"sources":["../../../../src/batteries/media/engines/jimp.ts"],"sourcesContent":["/**\n * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by Jimp (pure JavaScript — no native bindings, no binaries).\n *\n * @module @nhtio/adk/batteries/media/engines/jimp\n *\n * @remarks\n * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate\n * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,\n * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —\n * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,\n * compose a sharp-backed engine instead — the capability declaration is the seam.\n *\n * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing\n * the engine — and therefore the pipeline — never loads it).\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type * as JimpNS from 'jimp'\nimport type { MediaEngine, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype JimpModule = typeof JimpNS\n\n/** Options for {@link jimpEngine}. */\nexport interface JimpEngineOptions {\n /** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */\n jimp?: () => JimpModule | Promise<JimpModule>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n bmp: 'image/bmp',\n gif: 'image/gif',\n tiff: 'image/tiff',\n}\n\n/**\n * Construct the Jimp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const jimpEngine = (options: JimpEngineOptions = {}): MediaEngine => {\n let modPromise: Promise<JimpModule> | undefined\n const getJimp = (): Promise<JimpModule> => {\n modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import('jimp')).catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the jimp engine could not load its peer dependency \"jimp\": ${detail} — install it (pnpm add jimp)`,\n ])\n })\n return modPromise\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const { Jimp } = await getJimp()\n const image = await Jimp.read(\n request.bytes.buffer.slice(\n request.bytes.byteOffset,\n request.bytes.byteOffset + request.bytes.byteLength\n ) as ArrayBuffer\n )\n\n if (request.resize) {\n const { width, height, fit } = request.resize\n if (width !== undefined && height !== undefined) {\n if (fit === 'cover') image.cover({ w: width, h: height })\n else if (fit === 'contain') image.contain({ w: width, h: height })\n else image.resize({ w: width, h: height })\n } else if (width !== undefined) {\n image.resize({ w: width })\n } else if (height !== undefined) {\n image.resize({ h: height })\n }\n }\n if (request.rotate) {\n image.rotate(request.rotate)\n }\n if (request.flip) {\n image.flip({\n horizontal: request.flip.horizontal === true,\n vertical: request.flip.vertical === true,\n })\n }\n\n const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[targetFormat]\n if (!mimeType) {\n throw new Error(\n `jimp cannot encode \"${targetFormat}\"; supported: ${SUPPORTED_OUTPUT.join(', ')} (compose a sharp engine for webp/avif)`\n )\n }\n const quality = request.format?.quality\n const buffer =\n mimeType === 'image/jpeg' && quality !== undefined\n ? await image.getBuffer('image/jpeg', { quality })\n : await image.getBuffer(mimeType as 'image/png')\n return { bytes: new Uint8Array(buffer), mimeType }\n }\n\n return {\n id: 'jimp',\n mutates: [\n {\n over: ['image/png', 'image/jpeg', 'image/bmp', 'image/gif', 'image/tiff'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate,\n },\n ],\n }\n}\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAO;CAAO;AAAM;AAEpE,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;AACR;;;;;;;AAQA,IAAa,cAAc,UAA6B,CAAC,MAAmB;CAC1E,IAAI;CACJ,MAAM,gBAAqC;EACzC,eAAe,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,EAAE,OAAO,QAAQ;GAE5F,MAAM,IAAI,mBAAA,gCAAgC,CACxC,8DAFa,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEiB,8BACvE,CAAC;EACH,CAAC;EACD,OAAO;CACT;CAEA,MAAM,SAAS,OAAO,YAAuD;EAC3E,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,KAAK,KACvB,QAAQ,MAAM,OAAO,MACnB,QAAQ,MAAM,YACd,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAC3C,CACF;EAEA,IAAI,QAAQ,QAAQ;GAClB,MAAM,EAAE,OAAO,QAAQ,QAAQ,QAAQ;GACvC,IAAI,UAAU,KAAA,KAAa,WAAW,KAAA,GACpC,IAAI,QAAQ,SAAS,MAAM,MAAM;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACnD,IAAI,QAAQ,WAAW,MAAM,QAAQ;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QAC5D,MAAM,OAAO;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACpC,IAAI,UAAU,KAAA,GACnB,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC;QACpB,IAAI,WAAW,KAAA,GACpB,MAAM,OAAO,EAAE,GAAG,OAAO,CAAC;EAE9B;EACA,IAAI,QAAQ,QACV,MAAM,OAAO,QAAQ,MAAM;EAE7B,IAAI,QAAQ,MACV,MAAM,KAAK;GACT,YAAY,QAAQ,KAAK,eAAe;GACxC,UAAU,QAAQ,KAAK,aAAa;EACtC,CAAC;EAGH,MAAM,eAAe,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;EACxE,MAAM,WAAW,eAAe;EAChC,IAAI,CAAC,UACH,MAAM,IAAI,MACR,uBAAuB,aAAa,gBAAgB,iBAAiB,KAAK,IAAI,EAAE,wCAClF;EAEF,MAAM,UAAU,QAAQ,QAAQ;EAChC,MAAM,SACJ,aAAa,gBAAgB,YAAY,KAAA,IACrC,MAAM,MAAM,UAAU,cAAc,EAAE,QAAQ,CAAC,IAC/C,MAAM,MAAM,UAAU,QAAuB;EACnD,OAAO;GAAE,OAAO,IAAI,WAAW,MAAM;GAAG;EAAS;CACnD;CAEA,OAAO;EACL,IAAI;EACJ,SAAS,CACP;GACE,MAAM;IAAC;IAAa;IAAc;IAAa;IAAa;GAAY;GACxE,KAAK;IAAC;IAAU;IAAU;IAAQ;GAAgB;GAClD,SAAS;GACT;EACF,CACF;CACF;AACF;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
3
|
+
* backed by Jimp (pure JavaScript — no native bindings, no binaries).
|
|
4
|
+
*
|
|
5
|
+
* @module @nhtio/adk/batteries/media/engines/jimp
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
|
|
9
|
+
* capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
|
|
10
|
+
* flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
|
|
11
|
+
* `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
|
|
12
|
+
* compose a sharp-backed engine instead — the capability declaration is the seam.
|
|
13
|
+
*
|
|
14
|
+
* `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
|
|
15
|
+
* the engine — and therefore the pipeline — never loads it).
|
|
16
|
+
*/
|
|
17
|
+
import type * as JimpNS from 'jimp';
|
|
18
|
+
import type { MediaEngine } from "../contracts";
|
|
19
|
+
type JimpModule = typeof JimpNS;
|
|
20
|
+
/** Options for {@link jimpEngine}. */
|
|
21
|
+
export interface JimpEngineOptions {
|
|
22
|
+
/** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */
|
|
23
|
+
jimp?: () => JimpModule | Promise<JimpModule>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Construct the Jimp-backed image engine.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Optional module resolver override.
|
|
29
|
+
* @returns The engine.
|
|
30
|
+
*/
|
|
31
|
+
export declare const jimpEngine: (options?: JimpEngineOptions) => MediaEngine;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { o as isError } from "../../../tool_registry-791Vrjtf.mjs";
|
|
2
|
+
import "../../../guards.mjs";
|
|
3
|
+
import { t as E_INVALID_MEDIA_PIPELINE_CONFIG } from "../../../exceptions-C7FSHEnV.mjs";
|
|
4
|
+
//#region src/batteries/media/engines/jimp.ts
|
|
5
|
+
/**
|
|
6
|
+
* A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
7
|
+
* backed by Jimp (pure JavaScript — no native bindings, no binaries).
|
|
8
|
+
*
|
|
9
|
+
* @module @nhtio/adk/batteries/media/engines/jimp
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
|
|
13
|
+
* capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
|
|
14
|
+
* flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
|
|
15
|
+
* `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
|
|
16
|
+
* compose a sharp-backed engine instead — the capability declaration is the seam.
|
|
17
|
+
*
|
|
18
|
+
* `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
|
|
19
|
+
* the engine — and therefore the pipeline — never loads it).
|
|
20
|
+
*/
|
|
21
|
+
var SUPPORTED_OUTPUT = [
|
|
22
|
+
"png",
|
|
23
|
+
"jpg",
|
|
24
|
+
"jpeg",
|
|
25
|
+
"bmp",
|
|
26
|
+
"gif",
|
|
27
|
+
"tiff"
|
|
28
|
+
];
|
|
29
|
+
var MIME_BY_FORMAT = {
|
|
30
|
+
png: "image/png",
|
|
31
|
+
jpg: "image/jpeg",
|
|
32
|
+
jpeg: "image/jpeg",
|
|
33
|
+
bmp: "image/bmp",
|
|
34
|
+
gif: "image/gif",
|
|
35
|
+
tiff: "image/tiff"
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Construct the Jimp-backed image engine.
|
|
39
|
+
*
|
|
40
|
+
* @param options - Optional module resolver override.
|
|
41
|
+
* @returns The engine.
|
|
42
|
+
*/
|
|
43
|
+
var jimpEngine = (options = {}) => {
|
|
44
|
+
let modPromise;
|
|
45
|
+
const getJimp = () => {
|
|
46
|
+
modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import("jimp")).catch((err) => {
|
|
47
|
+
throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`the jimp engine could not load its peer dependency "jimp": ${isError(err) ? err.message : String(err)} — install it (pnpm add jimp)`]);
|
|
48
|
+
});
|
|
49
|
+
return modPromise;
|
|
50
|
+
};
|
|
51
|
+
const mutate = async (request) => {
|
|
52
|
+
const { Jimp } = await getJimp();
|
|
53
|
+
const image = await Jimp.read(request.bytes.buffer.slice(request.bytes.byteOffset, request.bytes.byteOffset + request.bytes.byteLength));
|
|
54
|
+
if (request.resize) {
|
|
55
|
+
const { width, height, fit } = request.resize;
|
|
56
|
+
if (width !== void 0 && height !== void 0) if (fit === "cover") image.cover({
|
|
57
|
+
w: width,
|
|
58
|
+
h: height
|
|
59
|
+
});
|
|
60
|
+
else if (fit === "contain") image.contain({
|
|
61
|
+
w: width,
|
|
62
|
+
h: height
|
|
63
|
+
});
|
|
64
|
+
else image.resize({
|
|
65
|
+
w: width,
|
|
66
|
+
h: height
|
|
67
|
+
});
|
|
68
|
+
else if (width !== void 0) image.resize({ w: width });
|
|
69
|
+
else if (height !== void 0) image.resize({ h: height });
|
|
70
|
+
}
|
|
71
|
+
if (request.rotate) image.rotate(request.rotate);
|
|
72
|
+
if (request.flip) image.flip({
|
|
73
|
+
horizontal: request.flip.horizontal === true,
|
|
74
|
+
vertical: request.flip.vertical === true
|
|
75
|
+
});
|
|
76
|
+
const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType);
|
|
77
|
+
const mimeType = MIME_BY_FORMAT[targetFormat];
|
|
78
|
+
if (!mimeType) throw new Error(`jimp cannot encode "${targetFormat}"; supported: ${SUPPORTED_OUTPUT.join(", ")} (compose a sharp engine for webp/avif)`);
|
|
79
|
+
const quality = request.format?.quality;
|
|
80
|
+
const buffer = mimeType === "image/jpeg" && quality !== void 0 ? await image.getBuffer("image/jpeg", { quality }) : await image.getBuffer(mimeType);
|
|
81
|
+
return {
|
|
82
|
+
bytes: new Uint8Array(buffer),
|
|
83
|
+
mimeType
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
id: "jimp",
|
|
88
|
+
mutates: [{
|
|
89
|
+
over: [
|
|
90
|
+
"image/png",
|
|
91
|
+
"image/jpeg",
|
|
92
|
+
"image/bmp",
|
|
93
|
+
"image/gif",
|
|
94
|
+
"image/tiff"
|
|
95
|
+
],
|
|
96
|
+
ops: [
|
|
97
|
+
"resize",
|
|
98
|
+
"rotate",
|
|
99
|
+
"flip",
|
|
100
|
+
"strip_metadata"
|
|
101
|
+
],
|
|
102
|
+
encodes: SUPPORTED_OUTPUT,
|
|
103
|
+
mutate
|
|
104
|
+
}]
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
var mimeToFormat = (mimeType) => {
|
|
108
|
+
const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
|
|
109
|
+
return sub === "jpeg" ? "jpg" : sub;
|
|
110
|
+
};
|
|
111
|
+
//#endregion
|
|
112
|
+
export { jimpEngine };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=jimp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jimp.mjs","names":[],"sources":["../../../../src/batteries/media/engines/jimp.ts"],"sourcesContent":["/**\n * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by Jimp (pure JavaScript — no native bindings, no binaries).\n *\n * @module @nhtio/adk/batteries/media/engines/jimp\n *\n * @remarks\n * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate\n * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,\n * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —\n * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,\n * compose a sharp-backed engine instead — the capability declaration is the seam.\n *\n * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing\n * the engine — and therefore the pipeline — never loads it).\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type * as JimpNS from 'jimp'\nimport type { MediaEngine, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype JimpModule = typeof JimpNS\n\n/** Options for {@link jimpEngine}. */\nexport interface JimpEngineOptions {\n /** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */\n jimp?: () => JimpModule | Promise<JimpModule>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n bmp: 'image/bmp',\n gif: 'image/gif',\n tiff: 'image/tiff',\n}\n\n/**\n * Construct the Jimp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const jimpEngine = (options: JimpEngineOptions = {}): MediaEngine => {\n let modPromise: Promise<JimpModule> | undefined\n const getJimp = (): Promise<JimpModule> => {\n modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import('jimp')).catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the jimp engine could not load its peer dependency \"jimp\": ${detail} — install it (pnpm add jimp)`,\n ])\n })\n return modPromise\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const { Jimp } = await getJimp()\n const image = await Jimp.read(\n request.bytes.buffer.slice(\n request.bytes.byteOffset,\n request.bytes.byteOffset + request.bytes.byteLength\n ) as ArrayBuffer\n )\n\n if (request.resize) {\n const { width, height, fit } = request.resize\n if (width !== undefined && height !== undefined) {\n if (fit === 'cover') image.cover({ w: width, h: height })\n else if (fit === 'contain') image.contain({ w: width, h: height })\n else image.resize({ w: width, h: height })\n } else if (width !== undefined) {\n image.resize({ w: width })\n } else if (height !== undefined) {\n image.resize({ h: height })\n }\n }\n if (request.rotate) {\n image.rotate(request.rotate)\n }\n if (request.flip) {\n image.flip({\n horizontal: request.flip.horizontal === true,\n vertical: request.flip.vertical === true,\n })\n }\n\n const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[targetFormat]\n if (!mimeType) {\n throw new Error(\n `jimp cannot encode \"${targetFormat}\"; supported: ${SUPPORTED_OUTPUT.join(', ')} (compose a sharp engine for webp/avif)`\n )\n }\n const quality = request.format?.quality\n const buffer =\n mimeType === 'image/jpeg' && quality !== undefined\n ? await image.getBuffer('image/jpeg', { quality })\n : await image.getBuffer(mimeType as 'image/png')\n return { bytes: new Uint8Array(buffer), mimeType }\n }\n\n return {\n id: 'jimp',\n mutates: [\n {\n over: ['image/png', 'image/jpeg', 'image/bmp', 'image/gif', 'image/tiff'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate,\n },\n ],\n }\n}\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAO;CAAO;AAAM;AAEpE,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;AACR;;;;;;;AAQA,IAAa,cAAc,UAA6B,CAAC,MAAmB;CAC1E,IAAI;CACJ,MAAM,gBAAqC;EACzC,eAAe,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,EAAE,OAAO,QAAQ;GAE5F,MAAM,IAAI,gCAAgC,CACxC,8DAFa,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEiB,8BACvE,CAAC;EACH,CAAC;EACD,OAAO;CACT;CAEA,MAAM,SAAS,OAAO,YAAuD;EAC3E,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,KAAK,KACvB,QAAQ,MAAM,OAAO,MACnB,QAAQ,MAAM,YACd,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAC3C,CACF;EAEA,IAAI,QAAQ,QAAQ;GAClB,MAAM,EAAE,OAAO,QAAQ,QAAQ,QAAQ;GACvC,IAAI,UAAU,KAAA,KAAa,WAAW,KAAA,GACpC,IAAI,QAAQ,SAAS,MAAM,MAAM;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACnD,IAAI,QAAQ,WAAW,MAAM,QAAQ;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QAC5D,MAAM,OAAO;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACpC,IAAI,UAAU,KAAA,GACnB,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC;QACpB,IAAI,WAAW,KAAA,GACpB,MAAM,OAAO,EAAE,GAAG,OAAO,CAAC;EAE9B;EACA,IAAI,QAAQ,QACV,MAAM,OAAO,QAAQ,MAAM;EAE7B,IAAI,QAAQ,MACV,MAAM,KAAK;GACT,YAAY,QAAQ,KAAK,eAAe;GACxC,UAAU,QAAQ,KAAK,aAAa;EACtC,CAAC;EAGH,MAAM,eAAe,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;EACxE,MAAM,WAAW,eAAe;EAChC,IAAI,CAAC,UACH,MAAM,IAAI,MACR,uBAAuB,aAAa,gBAAgB,iBAAiB,KAAK,IAAI,EAAE,wCAClF;EAEF,MAAM,UAAU,QAAQ,QAAQ;EAChC,MAAM,SACJ,aAAa,gBAAgB,YAAY,KAAA,IACrC,MAAM,MAAM,UAAU,cAAc,EAAE,QAAQ,CAAC,IAC/C,MAAM,MAAM,UAAU,QAAuB;EACnD,OAAO;GAAE,OAAO,IAAI,WAAW,MAAM;GAAG;EAAS;CACnD;CAEA,OAAO;EACL,IAAI;EACJ,SAAS,CACP;GACE,MAAM;IAAC;IAAa;IAAc;IAAa;IAAa;GAAY;GACxE,KAAK;IAAC;IAAU;IAAU;IAAQ;GAAgB;GAClD,SAAS;GACT;EACF,CACF;CACF;AACF;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_tool_registry = require("../../../tool_registry-CKJPze3j.js");
|
|
4
|
+
require("../../../guards.cjs");
|
|
5
|
+
const require_exceptions = require("../../../exceptions-CQi_lNs1.js");
|
|
6
|
+
//#region src/batteries/media/engines/sharp.ts
|
|
7
|
+
/**
|
|
8
|
+
* A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
9
|
+
* backed by sharp (libvips bindings — fast, full-format).
|
|
10
|
+
*
|
|
11
|
+
* @module @nhtio/adk/batteries/media/engines/sharp
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The performance/fidelity engine for Node deployments: native speed plus webp/avif output
|
|
15
|
+
* and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
|
|
16
|
+
* cross-environment engine compose the jimp implementation instead — the capability
|
|
17
|
+
* declaration is the seam, and BYO instances adapt via {@link fromSharp}.
|
|
18
|
+
*
|
|
19
|
+
* `sharp` is an optional peer dependency, lazily imported on first actual use.
|
|
20
|
+
*/
|
|
21
|
+
var SUPPORTED_OUTPUT = [
|
|
22
|
+
"png",
|
|
23
|
+
"jpg",
|
|
24
|
+
"jpeg",
|
|
25
|
+
"webp",
|
|
26
|
+
"tiff",
|
|
27
|
+
"avif",
|
|
28
|
+
"gif"
|
|
29
|
+
];
|
|
30
|
+
var MIME_BY_FORMAT = {
|
|
31
|
+
png: "image/png",
|
|
32
|
+
jpg: "image/jpeg",
|
|
33
|
+
jpeg: "image/jpeg",
|
|
34
|
+
webp: "image/webp",
|
|
35
|
+
tiff: "image/tiff",
|
|
36
|
+
avif: "image/avif",
|
|
37
|
+
gif: "image/gif"
|
|
38
|
+
};
|
|
39
|
+
var resolveSharp = async (supplied) => {
|
|
40
|
+
try {
|
|
41
|
+
const mod = await (supplied ? supplied() : import("sharp"));
|
|
42
|
+
const fn = typeof mod === "function" ? mod : mod.default;
|
|
43
|
+
if (typeof fn !== "function") throw new Error("sharp did not resolve to a function");
|
|
44
|
+
return fn;
|
|
45
|
+
} catch (err) {
|
|
46
|
+
throw new require_exceptions.E_INVALID_MEDIA_PIPELINE_CONFIG([`the sharp engine could not load its peer dependency "sharp": ${require_tool_registry.isError(err) ? err.message : String(err)} — install it (pnpm add sharp); note sharp is Node-only`]);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/** Run a fused mutate request through a sharp instance function. */
|
|
50
|
+
var runTransform = async (sharp, request) => {
|
|
51
|
+
let img = sharp(request.bytes);
|
|
52
|
+
if (request.rotate) img = img.rotate(request.rotate);
|
|
53
|
+
if (request.flip?.vertical) img = img.flip();
|
|
54
|
+
if (request.flip?.horizontal) img = img.flop();
|
|
55
|
+
if (request.resize && (request.resize.width !== void 0 || request.resize.height !== void 0)) img = img.resize({
|
|
56
|
+
width: request.resize.width,
|
|
57
|
+
height: request.resize.height,
|
|
58
|
+
fit: request.resize.fit ?? "cover"
|
|
59
|
+
});
|
|
60
|
+
const target = request.format?.to ?? mimeToFormat(request.mimeType);
|
|
61
|
+
const mimeType = MIME_BY_FORMAT[target];
|
|
62
|
+
if (!mimeType) throw new Error(`sharp cannot encode "${target}"; supported: ${SUPPORTED_OUTPUT.join(", ")}`);
|
|
63
|
+
const formatKey = target === "jpg" ? "jpeg" : target;
|
|
64
|
+
img = img.toFormat(formatKey, request.format?.quality !== void 0 ? { quality: request.format.quality } : {});
|
|
65
|
+
if (request.stripMetadata !== true) img = img.keepMetadata();
|
|
66
|
+
const buffer = await img.toBuffer();
|
|
67
|
+
return {
|
|
68
|
+
bytes: new Uint8Array(buffer),
|
|
69
|
+
mimeType
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/** Build the single mutate capability over a sharp source. */
|
|
73
|
+
var capabilityOf = (run) => ({
|
|
74
|
+
over: ["image/*"],
|
|
75
|
+
ops: [
|
|
76
|
+
"resize",
|
|
77
|
+
"rotate",
|
|
78
|
+
"flip",
|
|
79
|
+
"strip_metadata"
|
|
80
|
+
],
|
|
81
|
+
encodes: SUPPORTED_OUTPUT,
|
|
82
|
+
mutate: run
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Construct the sharp-backed image engine.
|
|
86
|
+
*
|
|
87
|
+
* @param options - Optional module resolver override.
|
|
88
|
+
* @returns The engine.
|
|
89
|
+
*/
|
|
90
|
+
var sharpEngine = (options = {}) => {
|
|
91
|
+
let sharpPromise;
|
|
92
|
+
const getSharp = () => {
|
|
93
|
+
sharpPromise ??= resolveSharp(options.sharp);
|
|
94
|
+
return sharpPromise;
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
id: "sharp",
|
|
98
|
+
mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))]
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Adapt an already-configured sharp module (your import, your build flags) to the engine
|
|
103
|
+
* contract — the BYO transformer.
|
|
104
|
+
*
|
|
105
|
+
* @param sharp - The sharp function you imported.
|
|
106
|
+
* @returns The engine.
|
|
107
|
+
*/
|
|
108
|
+
var fromSharp = (sharp) => ({
|
|
109
|
+
id: "sharp",
|
|
110
|
+
mutates: [capabilityOf(async (request) => runTransform(sharp, request))]
|
|
111
|
+
});
|
|
112
|
+
var mimeToFormat = (mimeType) => {
|
|
113
|
+
const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
|
|
114
|
+
return sub === "jpeg" ? "jpg" : sub;
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
117
|
+
exports.fromSharp = fromSharp;
|
|
118
|
+
exports.sharpEngine = sharpEngine;
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=sharp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharp.cjs","names":[],"sources":["../../../../src/batteries/media/engines/sharp.ts"],"sourcesContent":["/**\n * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by sharp (libvips bindings — fast, full-format).\n *\n * @module @nhtio/adk/batteries/media/engines/sharp\n *\n * @remarks\n * The performance/fidelity engine for Node deployments: native speed plus webp/avif output\n * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a\n * cross-environment engine compose the jimp implementation instead — the capability\n * declaration is the seam, and BYO instances adapt via {@link fromSharp}.\n *\n * `sharp` is an optional peer dependency, lazily imported on first actual use.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { default as SharpDefault } from 'sharp'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type { MediaEngine, MutateCapability, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype SharpFn = typeof SharpDefault\n\n/** Options for {@link sharpEngine}. */\nexport interface SharpEngineOptions {\n /** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */\n sharp?: () => SharpFn | { default: SharpFn } | Promise<SharpFn | { default: SharpFn }>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif', 'gif'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n tiff: 'image/tiff',\n avif: 'image/avif',\n gif: 'image/gif',\n}\n\nconst resolveSharp = async (supplied: SharpEngineOptions['sharp']): Promise<SharpFn> => {\n try {\n const mod = await (supplied ? supplied() : import('sharp'))\n const fn = typeof mod === 'function' ? mod : (mod as { default: SharpFn }).default\n if (typeof fn !== 'function') throw new Error('sharp did not resolve to a function')\n return fn\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the sharp engine could not load its peer dependency \"sharp\": ${detail} — install it (pnpm add sharp); note sharp is Node-only`,\n ])\n }\n}\n\n/** Run a fused mutate request through a sharp instance function. */\nconst runTransform = async (sharp: SharpFn, request: MutateRequest): Promise<EngineBytesResult> => {\n let img = sharp(request.bytes)\n if (request.rotate) img = img.rotate(request.rotate)\n if (request.flip?.vertical) img = img.flip()\n if (request.flip?.horizontal) img = img.flop()\n if (\n request.resize &&\n (request.resize.width !== undefined || request.resize.height !== undefined)\n ) {\n img = img.resize({\n width: request.resize.width,\n height: request.resize.height,\n fit: request.resize.fit ?? 'cover',\n })\n }\n const target = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[target]\n if (!mimeType) {\n throw new Error(`sharp cannot encode \"${target}\"; supported: ${SUPPORTED_OUTPUT.join(', ')}`)\n }\n const formatKey = (target === 'jpg' ? 'jpeg' : target) as\n | 'png'\n | 'jpeg'\n | 'webp'\n | 'tiff'\n | 'avif'\n | 'gif'\n img = img.toFormat(\n formatKey,\n request.format?.quality !== undefined ? { quality: request.format.quality } : {}\n )\n if (request.stripMetadata !== true) {\n // sharp strips metadata by default; keep it when NOT asked to strip.\n img = img.keepMetadata()\n }\n const buffer = await img.toBuffer()\n return { bytes: new Uint8Array(buffer), mimeType }\n}\n\n/** Build the single mutate capability over a sharp source. */\nconst capabilityOf = (\n run: (request: MutateRequest) => Promise<EngineBytesResult>\n): MutateCapability => ({\n over: ['image/*'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate: run,\n})\n\n/**\n * Construct the sharp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const sharpEngine = (options: SharpEngineOptions = {}): MediaEngine => {\n let sharpPromise: Promise<SharpFn> | undefined\n const getSharp = (): Promise<SharpFn> => {\n sharpPromise ??= resolveSharp(options.sharp)\n return sharpPromise\n }\n return {\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))],\n }\n}\n\n/**\n * Adapt an already-configured sharp module (your import, your build flags) to the engine\n * contract — the BYO transformer.\n *\n * @param sharp - The sharp function you imported.\n * @returns The engine.\n */\nexport const fromSharp = (sharp: SharpFn): MediaEngine => ({\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(sharp, request))],\n})\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;AAE7E,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;AACP;AAEA,IAAM,eAAe,OAAO,aAA4D;CACtF,IAAI;EACF,MAAM,MAAM,OAAO,WAAW,SAAS,IAAI,OAAO;EAClD,MAAM,KAAK,OAAO,QAAQ,aAAa,MAAO,IAA6B;EAC3E,IAAI,OAAO,OAAO,YAAY,MAAM,IAAI,MAAM,qCAAqC;EACnF,OAAO;CACT,SAAS,KAAK;EAEZ,MAAM,IAAI,mBAAA,gCAAgC,CACxC,gEAFa,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEmB,wDACzE,CAAC;CACH;AACF;;AAGA,IAAM,eAAe,OAAO,OAAgB,YAAuD;CACjG,IAAI,MAAM,MAAM,QAAQ,KAAK;CAC7B,IAAI,QAAQ,QAAQ,MAAM,IAAI,OAAO,QAAQ,MAAM;CACnD,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI,KAAK;CAC3C,IAAI,QAAQ,MAAM,YAAY,MAAM,IAAI,KAAK;CAC7C,IACE,QAAQ,WACP,QAAQ,OAAO,UAAU,KAAA,KAAa,QAAQ,OAAO,WAAW,KAAA,IAEjE,MAAM,IAAI,OAAO;EACf,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,OAAO;EACvB,KAAK,QAAQ,OAAO,OAAO;CAC7B,CAAC;CAEH,MAAM,SAAS,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;CAClE,MAAM,WAAW,eAAe;CAChC,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,wBAAwB,OAAO,gBAAgB,iBAAiB,KAAK,IAAI,GAAG;CAE9F,MAAM,YAAa,WAAW,QAAQ,SAAS;CAO/C,MAAM,IAAI,SACR,WACA,QAAQ,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,OAAO,QAAQ,IAAI,CAAC,CACjF;CACA,IAAI,QAAQ,kBAAkB,MAE5B,MAAM,IAAI,aAAa;CAEzB,MAAM,SAAS,MAAM,IAAI,SAAS;CAClC,OAAO;EAAE,OAAO,IAAI,WAAW,MAAM;EAAG;CAAS;AACnD;;AAGA,IAAM,gBACJ,SACsB;CACtB,MAAM,CAAC,SAAS;CAChB,KAAK;EAAC;EAAU;EAAU;EAAQ;CAAgB;CAClD,SAAS;CACT,QAAQ;AACV;;;;;;;AAQA,IAAa,eAAe,UAA8B,CAAC,MAAmB;CAC5E,IAAI;CACJ,MAAM,iBAAmC;EACvC,iBAAiB,aAAa,QAAQ,KAAK;EAC3C,OAAO;CACT;CACA,OAAO;EACL,IAAI;EACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC;CACpF;AACF;;;;;;;;AASA,IAAa,aAAa,WAAiC;CACzD,IAAI;CACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,OAAO,OAAO,CAAC,CAAC;AACzE;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
3
|
+
* backed by sharp (libvips bindings — fast, full-format).
|
|
4
|
+
*
|
|
5
|
+
* @module @nhtio/adk/batteries/media/engines/sharp
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The performance/fidelity engine for Node deployments: native speed plus webp/avif output
|
|
9
|
+
* and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
|
|
10
|
+
* cross-environment engine compose the jimp implementation instead — the capability
|
|
11
|
+
* declaration is the seam, and BYO instances adapt via {@link fromSharp}.
|
|
12
|
+
*
|
|
13
|
+
* `sharp` is an optional peer dependency, lazily imported on first actual use.
|
|
14
|
+
*/
|
|
15
|
+
import { default as SharpDefault } from 'sharp';
|
|
16
|
+
import type { MediaEngine } from "../contracts";
|
|
17
|
+
type SharpFn = typeof SharpDefault;
|
|
18
|
+
/** Options for {@link sharpEngine}. */
|
|
19
|
+
export interface SharpEngineOptions {
|
|
20
|
+
/** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */
|
|
21
|
+
sharp?: () => SharpFn | {
|
|
22
|
+
default: SharpFn;
|
|
23
|
+
} | Promise<SharpFn | {
|
|
24
|
+
default: SharpFn;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Construct the sharp-backed image engine.
|
|
29
|
+
*
|
|
30
|
+
* @param options - Optional module resolver override.
|
|
31
|
+
* @returns The engine.
|
|
32
|
+
*/
|
|
33
|
+
export declare const sharpEngine: (options?: SharpEngineOptions) => MediaEngine;
|
|
34
|
+
/**
|
|
35
|
+
* Adapt an already-configured sharp module (your import, your build flags) to the engine
|
|
36
|
+
* contract — the BYO transformer.
|
|
37
|
+
*
|
|
38
|
+
* @param sharp - The sharp function you imported.
|
|
39
|
+
* @returns The engine.
|
|
40
|
+
*/
|
|
41
|
+
export declare const fromSharp: (sharp: SharpFn) => MediaEngine;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { o as isError } from "../../../tool_registry-791Vrjtf.mjs";
|
|
2
|
+
import "../../../guards.mjs";
|
|
3
|
+
import { t as E_INVALID_MEDIA_PIPELINE_CONFIG } from "../../../exceptions-C7FSHEnV.mjs";
|
|
4
|
+
//#region src/batteries/media/engines/sharp.ts
|
|
5
|
+
/**
|
|
6
|
+
* A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
|
|
7
|
+
* backed by sharp (libvips bindings — fast, full-format).
|
|
8
|
+
*
|
|
9
|
+
* @module @nhtio/adk/batteries/media/engines/sharp
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* The performance/fidelity engine for Node deployments: native speed plus webp/avif output
|
|
13
|
+
* and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
|
|
14
|
+
* cross-environment engine compose the jimp implementation instead — the capability
|
|
15
|
+
* declaration is the seam, and BYO instances adapt via {@link fromSharp}.
|
|
16
|
+
*
|
|
17
|
+
* `sharp` is an optional peer dependency, lazily imported on first actual use.
|
|
18
|
+
*/
|
|
19
|
+
var SUPPORTED_OUTPUT = [
|
|
20
|
+
"png",
|
|
21
|
+
"jpg",
|
|
22
|
+
"jpeg",
|
|
23
|
+
"webp",
|
|
24
|
+
"tiff",
|
|
25
|
+
"avif",
|
|
26
|
+
"gif"
|
|
27
|
+
];
|
|
28
|
+
var MIME_BY_FORMAT = {
|
|
29
|
+
png: "image/png",
|
|
30
|
+
jpg: "image/jpeg",
|
|
31
|
+
jpeg: "image/jpeg",
|
|
32
|
+
webp: "image/webp",
|
|
33
|
+
tiff: "image/tiff",
|
|
34
|
+
avif: "image/avif",
|
|
35
|
+
gif: "image/gif"
|
|
36
|
+
};
|
|
37
|
+
var resolveSharp = async (supplied) => {
|
|
38
|
+
try {
|
|
39
|
+
const mod = await (supplied ? supplied() : import("sharp"));
|
|
40
|
+
const fn = typeof mod === "function" ? mod : mod.default;
|
|
41
|
+
if (typeof fn !== "function") throw new Error("sharp did not resolve to a function");
|
|
42
|
+
return fn;
|
|
43
|
+
} catch (err) {
|
|
44
|
+
throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`the sharp engine could not load its peer dependency "sharp": ${isError(err) ? err.message : String(err)} — install it (pnpm add sharp); note sharp is Node-only`]);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/** Run a fused mutate request through a sharp instance function. */
|
|
48
|
+
var runTransform = async (sharp, request) => {
|
|
49
|
+
let img = sharp(request.bytes);
|
|
50
|
+
if (request.rotate) img = img.rotate(request.rotate);
|
|
51
|
+
if (request.flip?.vertical) img = img.flip();
|
|
52
|
+
if (request.flip?.horizontal) img = img.flop();
|
|
53
|
+
if (request.resize && (request.resize.width !== void 0 || request.resize.height !== void 0)) img = img.resize({
|
|
54
|
+
width: request.resize.width,
|
|
55
|
+
height: request.resize.height,
|
|
56
|
+
fit: request.resize.fit ?? "cover"
|
|
57
|
+
});
|
|
58
|
+
const target = request.format?.to ?? mimeToFormat(request.mimeType);
|
|
59
|
+
const mimeType = MIME_BY_FORMAT[target];
|
|
60
|
+
if (!mimeType) throw new Error(`sharp cannot encode "${target}"; supported: ${SUPPORTED_OUTPUT.join(", ")}`);
|
|
61
|
+
const formatKey = target === "jpg" ? "jpeg" : target;
|
|
62
|
+
img = img.toFormat(formatKey, request.format?.quality !== void 0 ? { quality: request.format.quality } : {});
|
|
63
|
+
if (request.stripMetadata !== true) img = img.keepMetadata();
|
|
64
|
+
const buffer = await img.toBuffer();
|
|
65
|
+
return {
|
|
66
|
+
bytes: new Uint8Array(buffer),
|
|
67
|
+
mimeType
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/** Build the single mutate capability over a sharp source. */
|
|
71
|
+
var capabilityOf = (run) => ({
|
|
72
|
+
over: ["image/*"],
|
|
73
|
+
ops: [
|
|
74
|
+
"resize",
|
|
75
|
+
"rotate",
|
|
76
|
+
"flip",
|
|
77
|
+
"strip_metadata"
|
|
78
|
+
],
|
|
79
|
+
encodes: SUPPORTED_OUTPUT,
|
|
80
|
+
mutate: run
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Construct the sharp-backed image engine.
|
|
84
|
+
*
|
|
85
|
+
* @param options - Optional module resolver override.
|
|
86
|
+
* @returns The engine.
|
|
87
|
+
*/
|
|
88
|
+
var sharpEngine = (options = {}) => {
|
|
89
|
+
let sharpPromise;
|
|
90
|
+
const getSharp = () => {
|
|
91
|
+
sharpPromise ??= resolveSharp(options.sharp);
|
|
92
|
+
return sharpPromise;
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
id: "sharp",
|
|
96
|
+
mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))]
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Adapt an already-configured sharp module (your import, your build flags) to the engine
|
|
101
|
+
* contract — the BYO transformer.
|
|
102
|
+
*
|
|
103
|
+
* @param sharp - The sharp function you imported.
|
|
104
|
+
* @returns The engine.
|
|
105
|
+
*/
|
|
106
|
+
var fromSharp = (sharp) => ({
|
|
107
|
+
id: "sharp",
|
|
108
|
+
mutates: [capabilityOf(async (request) => runTransform(sharp, request))]
|
|
109
|
+
});
|
|
110
|
+
var mimeToFormat = (mimeType) => {
|
|
111
|
+
const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
|
|
112
|
+
return sub === "jpeg" ? "jpg" : sub;
|
|
113
|
+
};
|
|
114
|
+
//#endregion
|
|
115
|
+
export { fromSharp, sharpEngine };
|
|
116
|
+
|
|
117
|
+
//# sourceMappingURL=sharp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharp.mjs","names":[],"sources":["../../../../src/batteries/media/engines/sharp.ts"],"sourcesContent":["/**\n * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by sharp (libvips bindings — fast, full-format).\n *\n * @module @nhtio/adk/batteries/media/engines/sharp\n *\n * @remarks\n * The performance/fidelity engine for Node deployments: native speed plus webp/avif output\n * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a\n * cross-environment engine compose the jimp implementation instead — the capability\n * declaration is the seam, and BYO instances adapt via {@link fromSharp}.\n *\n * `sharp` is an optional peer dependency, lazily imported on first actual use.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { default as SharpDefault } from 'sharp'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type { MediaEngine, MutateCapability, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype SharpFn = typeof SharpDefault\n\n/** Options for {@link sharpEngine}. */\nexport interface SharpEngineOptions {\n /** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */\n sharp?: () => SharpFn | { default: SharpFn } | Promise<SharpFn | { default: SharpFn }>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif', 'gif'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n tiff: 'image/tiff',\n avif: 'image/avif',\n gif: 'image/gif',\n}\n\nconst resolveSharp = async (supplied: SharpEngineOptions['sharp']): Promise<SharpFn> => {\n try {\n const mod = await (supplied ? supplied() : import('sharp'))\n const fn = typeof mod === 'function' ? mod : (mod as { default: SharpFn }).default\n if (typeof fn !== 'function') throw new Error('sharp did not resolve to a function')\n return fn\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the sharp engine could not load its peer dependency \"sharp\": ${detail} — install it (pnpm add sharp); note sharp is Node-only`,\n ])\n }\n}\n\n/** Run a fused mutate request through a sharp instance function. */\nconst runTransform = async (sharp: SharpFn, request: MutateRequest): Promise<EngineBytesResult> => {\n let img = sharp(request.bytes)\n if (request.rotate) img = img.rotate(request.rotate)\n if (request.flip?.vertical) img = img.flip()\n if (request.flip?.horizontal) img = img.flop()\n if (\n request.resize &&\n (request.resize.width !== undefined || request.resize.height !== undefined)\n ) {\n img = img.resize({\n width: request.resize.width,\n height: request.resize.height,\n fit: request.resize.fit ?? 'cover',\n })\n }\n const target = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[target]\n if (!mimeType) {\n throw new Error(`sharp cannot encode \"${target}\"; supported: ${SUPPORTED_OUTPUT.join(', ')}`)\n }\n const formatKey = (target === 'jpg' ? 'jpeg' : target) as\n | 'png'\n | 'jpeg'\n | 'webp'\n | 'tiff'\n | 'avif'\n | 'gif'\n img = img.toFormat(\n formatKey,\n request.format?.quality !== undefined ? { quality: request.format.quality } : {}\n )\n if (request.stripMetadata !== true) {\n // sharp strips metadata by default; keep it when NOT asked to strip.\n img = img.keepMetadata()\n }\n const buffer = await img.toBuffer()\n return { bytes: new Uint8Array(buffer), mimeType }\n}\n\n/** Build the single mutate capability over a sharp source. */\nconst capabilityOf = (\n run: (request: MutateRequest) => Promise<EngineBytesResult>\n): MutateCapability => ({\n over: ['image/*'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate: run,\n})\n\n/**\n * Construct the sharp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const sharpEngine = (options: SharpEngineOptions = {}): MediaEngine => {\n let sharpPromise: Promise<SharpFn> | undefined\n const getSharp = (): Promise<SharpFn> => {\n sharpPromise ??= resolveSharp(options.sharp)\n return sharpPromise\n }\n return {\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))],\n }\n}\n\n/**\n * Adapt an already-configured sharp module (your import, your build flags) to the engine\n * contract — the BYO transformer.\n *\n * @param sharp - The sharp function you imported.\n * @returns The engine.\n */\nexport const fromSharp = (sharp: SharpFn): MediaEngine => ({\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(sharp, request))],\n})\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;AAE7E,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;AACP;AAEA,IAAM,eAAe,OAAO,aAA4D;CACtF,IAAI;EACF,MAAM,MAAM,OAAO,WAAW,SAAS,IAAI,OAAO;EAClD,MAAM,KAAK,OAAO,QAAQ,aAAa,MAAO,IAA6B;EAC3E,IAAI,OAAO,OAAO,YAAY,MAAM,IAAI,MAAM,qCAAqC;EACnF,OAAO;CACT,SAAS,KAAK;EAEZ,MAAM,IAAI,gCAAgC,CACxC,gEAFa,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEmB,wDACzE,CAAC;CACH;AACF;;AAGA,IAAM,eAAe,OAAO,OAAgB,YAAuD;CACjG,IAAI,MAAM,MAAM,QAAQ,KAAK;CAC7B,IAAI,QAAQ,QAAQ,MAAM,IAAI,OAAO,QAAQ,MAAM;CACnD,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI,KAAK;CAC3C,IAAI,QAAQ,MAAM,YAAY,MAAM,IAAI,KAAK;CAC7C,IACE,QAAQ,WACP,QAAQ,OAAO,UAAU,KAAA,KAAa,QAAQ,OAAO,WAAW,KAAA,IAEjE,MAAM,IAAI,OAAO;EACf,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,OAAO;EACvB,KAAK,QAAQ,OAAO,OAAO;CAC7B,CAAC;CAEH,MAAM,SAAS,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;CAClE,MAAM,WAAW,eAAe;CAChC,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,wBAAwB,OAAO,gBAAgB,iBAAiB,KAAK,IAAI,GAAG;CAE9F,MAAM,YAAa,WAAW,QAAQ,SAAS;CAO/C,MAAM,IAAI,SACR,WACA,QAAQ,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,OAAO,QAAQ,IAAI,CAAC,CACjF;CACA,IAAI,QAAQ,kBAAkB,MAE5B,MAAM,IAAI,aAAa;CAEzB,MAAM,SAAS,MAAM,IAAI,SAAS;CAClC,OAAO;EAAE,OAAO,IAAI,WAAW,MAAM;EAAG;CAAS;AACnD;;AAGA,IAAM,gBACJ,SACsB;CACtB,MAAM,CAAC,SAAS;CAChB,KAAK;EAAC;EAAU;EAAU;EAAQ;CAAgB;CAClD,SAAS;CACT,QAAQ;AACV;;;;;;;AAQA,IAAa,eAAe,UAA8B,CAAC,MAAmB;CAC5E,IAAI;CACJ,MAAM,iBAAmC;EACvC,iBAAiB,aAAa,QAAQ,KAAK;EAC3C,OAAO;CACT;CACA,OAAO;EACL,IAAI;EACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC;CACpF;AACF;;;;;;;;AASA,IAAa,aAAa,WAAiC;CACzD,IAAI;CACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,OAAO,OAAO,CAAC,CAAC;AACzE;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
|