@xyo-network/image-thumbnail-plugin 6.0.2 → 6.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/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![logo][]](https://xyo.network)
2
+
1
3
  # @xyo-network/image-thumbnail-plugin
2
4
 
3
5
  [![npm][npm-badge]][npm-link]
@@ -36,9 +38,12 @@ bun add {{name}}
36
38
 
37
39
  See the [LICENSE](LICENSE) file for license rights and limitations (LGPL-3.0-only).
38
40
 
41
+ ## Credits
39
42
 
43
+ [Made with 🔥 and ❄️ by XYO Foundation](https://xyo.network)
40
44
 
41
45
  [npm-badge]: https://img.shields.io/npm/v/@xyo-network/image-thumbnail-plugin.svg
42
46
  [npm-link]: https://www.npmjs.com/package/@xyo-network/image-thumbnail-plugin
43
47
  [license-badge]: https://img.shields.io/npm/l/@xyo-network/image-thumbnail-plugin.svg
44
48
  [license-link]: https://github.com/xylabs/sdk-js/blob/main/LICENSE
49
+ [logo]: https://cdn.xy.company/img/brand/XYO_full_colored.png
@@ -179,7 +179,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness
179
179
  }
180
180
  static bufferFromDataUrl(url) {
181
181
  if (url.startsWith("data:image")) {
182
- const data = url.split(",")[1];
182
+ const data = url.split(",", 2)[1];
183
183
  if (data) {
184
184
  return Uint8Array.from(atob(data), (c) => c.codePointAt(0) ?? 0).buffer;
185
185
  } else {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/Plugin.ts", "../../src/Witness/Config.ts", "../../src/Witness/Witness.ts", "../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts", "../../src/Witness/lib/checkIpfsUrl.ts", "../../src/Witness/lib/createDataUrl.ts", "../../src/Witness/lib/resolveDynamicSvg.ts", "../../src/index.ts"],
4
- "sourcesContent": ["import { ImageThumbnailDiviner } from '@xyo-network/diviner-image-thumbnail'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { createPayloadSetDualPlugin, PayloadSetSchema } from '@xyo-network/sdk-js'\n\nimport { ImageThumbnailWitness } from './Witness/index.ts'\n\nexport const ImageThumbnailPlugin = () =>\n createPayloadSetDualPlugin<ImageThumbnailWitness, ImageThumbnailDiviner>(\n { required: { [ImageThumbnailSchema]: 1 }, schema: PayloadSetSchema },\n {\n diviner: async (params) => {\n const result = await ImageThumbnailDiviner.create(params)\n return result\n },\n witness: async (params) => {\n const result = await ImageThumbnailWitness.create(params)\n return result\n },\n },\n )\n", "import { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport type { WitnessConfig } from '@xyo-network/sdk-js'\nimport { asSchema } from '@xyo-network/sdk-js'\n\nexport const ImageThumbnailWitnessConfigSchema = asSchema(`${ImageThumbnailSchema}.witness.config`, true)\nexport type ImageThumbnailWitnessConfigSchema = typeof ImageThumbnailWitnessConfigSchema\n\nexport type ImageThumbnailEncoding = 'PNG' | 'JPG' | 'GIF'\n\nexport type ImageThumbnailWitnessConfig = WitnessConfig<{\n dataUrlPassthrough?: boolean\n encoding?: ImageThumbnailEncoding\n height?: number\n ipfsGateway?: string\n maxAsyncProcesses?: number\n maxCacheBytes?: number\n maxCacheEntries?: number\n quality?: number\n runExclusive?: boolean\n schema: ImageThumbnailWitnessConfigSchema\n width?: number\n}>\n", "/* eslint-disable max-statements */\nimport { Buffer } from 'node:buffer'\nimport { promises as dnsPromises } from 'node:dns'\n\nimport { exists } from '@xylabs/sdk-js'\nimport type { ImageThumbnail } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport type { Schema } from '@xyo-network/sdk-js'\nimport { AbstractWitness, ObjectHasher } from '@xyo-network/sdk-js'\nimport type { UrlPayload } from '@xyo-network/url-payload-plugin'\nimport { UrlSchema } from '@xyo-network/url-payload-plugin'\nimport { Semaphore } from 'async-mutex'\nimport { fileTypeFromBuffer } from 'file-type'\nimport graphicsMagick from 'gm'\nimport hasbin from 'hasbin'\nimport { sha256 } from 'hash-wasm'\nimport shajs from 'sha.js'\n\nimport type { ImageThumbnailEncoding } from './Config.ts'\nimport { ImageThumbnailWitnessConfigSchema } from './Config.ts'\nimport { getVideoFrameAsImageFluent } from './ffmpeg/index.ts'\nimport {\n checkIpfsUrl, createDataUrl, resolveDynamicSvg,\n} from './lib/index.ts'\nimport type { ImageThumbnailWitnessParams } from './Params.ts'\n\n// TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\nconst gm = graphicsMagick.subClass({ imageMagick: '7+' })\n\nexport interface ImageThumbnailWitnessError extends Error {\n name: 'ImageThumbnailWitnessError'\n url: string\n}\n\nexport interface DnsError extends Error {\n code: string\n}\n\nexport class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams = ImageThumbnailWitnessParams> extends AbstractWitness<TParams> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, ImageThumbnailWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = ImageThumbnailWitnessConfigSchema\n\n private _semaphore = new Semaphore(this.maxAsyncProcesses)\n\n get encoding() {\n return this.config.encoding ?? 'PNG'\n }\n\n get height() {\n return this.config.height ?? 128\n }\n\n get ipfsGateway() {\n return this.config.ipfsGateway ?? '5d7b6582.beta.decentralnetworkservices.com'\n }\n\n get maxAsyncProcesses() {\n return this.config.maxAsyncProcesses ?? 4\n }\n\n get quality() {\n return this.config.quality ?? 50\n }\n\n get width() {\n return this.config.width ?? 128\n }\n\n private static async binaryToSha256(data: ArrayBufferLike) {\n const viewData = new Uint8Array(data)\n await ObjectHasher.wasmInitialized\n if (ObjectHasher.wasmSupport.canUseWasm) {\n try {\n return await sha256(viewData)\n } catch {\n ObjectHasher.wasmSupport.allowWasm = false\n }\n }\n\n return shajs('sha256').update(viewData).digest().toString()\n }\n\n private static bufferFromDataUrl(url: string): ArrayBufferLike | undefined {\n if (url.startsWith('data:image')) {\n const data = url.split(',')[1]\n if (data) {\n return Uint8Array.from(atob(data), c => c.codePointAt(0) ?? 0).buffer\n } else {\n const error: ImageThumbnailWitnessError = {\n message: 'Invalid data Url',\n name: 'ImageThumbnailWitnessError',\n url,\n }\n throw error\n }\n }\n }\n\n protected override async observeHandler(payloads: UrlPayload[] = []): Promise<ImageThumbnail[]> {\n if (!hasbin.sync('magick')) {\n throw new Error('ImageMagick is required for this witness')\n }\n const urlPayloads = payloads.filter(payload => payload.schema === UrlSchema)\n const process = async () => {\n return (await Promise.all(\n urlPayloads.map<Promise<ImageThumbnail>>(async ({ url }) => {\n let result: ImageThumbnail\n\n // if it is a data URL, return a Buffer\n const dataBuffer = ImageThumbnailWitness.bufferFromDataUrl(url)\n\n if (dataBuffer) {\n if (this.config.dataUrlPassthrough) {\n result = {\n schema: ImageThumbnailSchema,\n sourceHash: await ImageThumbnailWitness.binaryToSha256(dataBuffer),\n sourceUrl: url,\n url,\n }\n } else {\n let cookedDataBuffer = dataBuffer\n const urlParts = url.split(';')\n const [, contentType] = urlParts[0].split(':')\n if (contentType.startsWith('image/svg')) {\n const [encoding, byteString] = urlParts[1].split(',')\n if (encoding === 'base64') {\n const newSvg = await resolveDynamicSvg(byteString)\n const newSvgDataUrl = createDataUrl(Buffer.from(newSvg).buffer, contentType)\n cookedDataBuffer = ImageThumbnailWitness.bufferFromDataUrl(newSvgDataUrl) ?? dataBuffer\n }\n }\n result = await this.processMedia(\n cookedDataBuffer,\n {\n schema: ImageThumbnailSchema,\n sourceUrl: url,\n },\n contentType,\n )\n }\n } else {\n // if it is ipfs, go through cloud flair\n const mutatedUrl = checkIpfsUrl(url, this.ipfsGateway)\n result = await this.fromHttp(mutatedUrl, url)\n }\n return result\n }),\n )).filter(exists)\n }\n return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process()\n }\n\n private async createThumbnailDataUrl(sourceBuffer: ArrayBufferLike, encoding?: ImageThumbnailEncoding) {\n const thumb = await new Promise<Buffer>((resolve, reject) => {\n gm(Buffer.from(sourceBuffer))\n .quality(this.quality)\n .resize(this.width, this.height)\n .flatten()\n .toBuffer(encoding ?? this.encoding, (error, buffer) => {\n if (error) {\n reject(error)\n } else {\n resolve(buffer)\n }\n })\n })\n return createDataUrl(thumb.buffer, 'image/png')\n }\n\n /**\n * Creates an image thumbnail from a video.\n * @param videoBuffer The input video buffer.\n * @returns An buffer containing an image thumbnail for the video.\n */\n private async createThumbnailFromVideo(videoBuffer: ArrayBufferLike) {\n const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer)\n return this.createThumbnailDataUrl(imageBuffer.buffer)\n }\n\n private async fromHttp(url: string, sourceUrl?: string): Promise<ImageThumbnail> {\n let response: Response\n let dnsResult: string[]\n try {\n const urlObj = new URL(url)\n dnsResult = await dnsPromises.resolve(urlObj.host)\n } catch (ex) {\n const error = ex as DnsError\n const result: ImageThumbnail = {\n http: { code: error.code },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n return result\n }\n try {\n response = await fetch(url)\n } catch (ex) {\n const result: ImageThumbnail = {\n http: { ipAddress: dnsResult[0] },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n if (ex instanceof Error) {\n result.http = result.http ?? {}\n result.http.code = ex.name\n }\n return result\n }\n\n const result: ImageThumbnail = {\n http: { status: response.status },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n\n if (response.status >= 200 && response.status < 300) {\n const contentType: string | undefined = response.headers.get('content-type') ?? undefined\n const sourceBuffer = await response.arrayBuffer()\n\n return this.processMedia(sourceBuffer, result, contentType)\n }\n return result\n }\n\n private async processMedia(sourceBuffer: ArrayBufferLike, imageThumbnail: ImageThumbnail, contentType?: string): Promise<ImageThumbnail> {\n const [mediaType, fileType] = contentType?.split('/') ?? ['', '']\n imageThumbnail.mime = imageThumbnail.mime ?? {}\n imageThumbnail.mime.returned = mediaType\n\n try {\n imageThumbnail.mime.detected = await fileTypeFromBuffer(sourceBuffer as ArrayBuffer)\n } catch (ex) {\n const error = ex as Error\n this.logger?.error(`FileType error: ${error.message}`)\n }\n\n const processImage = async (encoding?: ImageThumbnailEncoding) => {\n imageThumbnail.sourceHash = await ImageThumbnailWitness.binaryToSha256(sourceBuffer)\n imageThumbnail.url = await this.createThumbnailDataUrl(sourceBuffer, encoding)\n }\n\n const processVideo = async () => {\n // Gracefully handle the case where ffmpeg is not installed.\n\n if (hasbin.sync('ffmpeg')) {\n imageThumbnail.sourceHash = await ImageThumbnailWitness.binaryToSha256(sourceBuffer)\n imageThumbnail.url = await this.createThumbnailFromVideo(sourceBuffer)\n } else {\n imageThumbnail.mime = imageThumbnail.mime ?? {}\n imageThumbnail.mime.invalid = true\n }\n }\n\n let encoding: ImageThumbnailEncoding = 'PNG'\n\n switch (fileType.toUpperCase()) {\n case 'GIF': {\n encoding = 'GIF'\n break\n }\n case 'JPG':\n case 'JPEG': {\n encoding = 'JPG'\n break\n }\n }\n\n switch (mediaType) {\n case 'image': {\n await processImage(encoding)\n imageThumbnail.mime.type = mediaType\n break\n }\n case 'video': {\n await processVideo()\n imageThumbnail.mime.type = mediaType\n break\n }\n default: {\n const [detectedMediaType] = imageThumbnail.mime.detected?.mime?.split('/') ?? ['', '']\n switch (detectedMediaType) {\n case 'image': {\n await processImage()\n imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime\n break\n }\n case 'video': {\n await processVideo()\n imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime\n break\n }\n default: {\n imageThumbnail.mime.invalid = true\n break\n }\n }\n break\n }\n }\n return imageThumbnail\n }\n}\n", "import { unlink, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport type { WritableOptions } from 'node:stream'\nimport { Writable } from 'node:stream'\n\nimport ffmpeg from 'fluent-ffmpeg'\nimport { v4 as uuid } from 'uuid'\n\n/**\n * A Writable stream that collects output from ffmpeg.\n */\nclass FfmpegOutputStream extends Writable {\n private readonly chunks: Uint8Array[] = []\n\n constructor(options?: WritableOptions) {\n super(options)\n }\n\n override _write(chunk: never, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n this.chunks.push(chunk)\n callback()\n }\n\n /**\n * Collects the output from ffmpeg into a buffer.\n * @returns A buffer containing the concatenated\n * output from ffmpeg.\n */\n toBuffer = () => Buffer.concat(this.chunks)\n}\n\n/**\n * Execute FFmpeg using fluent API with provided input buffer and video thumbnail image.\n * @param videoBuffer Input video buffer.\n * @returns Output buffer containing the video thumbnail image.\n */\nexport const getVideoFrameAsImageFluent = async (videoBuffer: ArrayBufferLike) => {\n // Get a temp file name\n const tmpFile = `/${tmpdir()}/${uuid()}`\n try {\n // Write videoBuffer to temp file for use as input to ffmpeg to\n // avoid issues with ffmpeg inferring premature EOF from buffer\n // passed via stdin (happens when ffmpeg is trying to infer\n // input video format)\n await writeFile(tmpFile, new Uint8Array(videoBuffer), { encoding: 'binary' })\n const imageBuffer = await new Promise<Buffer>((resolve, reject) => {\n // Create a Writable stream to collect PNG output from ffmpeg\n const ffmpegOutput = new FfmpegOutputStream()\n // Execute ffmpeg using fluent API\n ffmpeg()\n // Uncomment to debug CLI args to ffmpeg\n // .on('start', (commandLine) => console.log('Spawned Ffmpeg with command: ' + commandLine))\n .on('error', err => reject(new Error(err.message, { cause: err })))\n // Listen for the 'end' event to combine the output into a buffer holding the PNG image\n .on('end', () => resolve(ffmpegOutput.toBuffer()))\n .input(tmpFile) // Use temp file as input\n .takeFrames(1) // Only take 1st video frame\n .withNoAudio() // Don't include audio\n .outputOptions('-f image2pipe') // Write output to stdout\n .videoCodec('png') // Force PNG output\n // Start processing and direct ffmpeg stdout to writable stream\n .pipe(ffmpegOutput)\n })\n return imageBuffer\n } finally {\n // Cleanup temp file\n try {\n await unlink(tmpFile)\n } catch {\n // No error here since file doesn't exist\n }\n }\n}\n", "import { assertEx } from '@xylabs/sdk-js'\n\nconst allowIpfsIoRepair = true\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string): string => {\n try {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, () => 'No ipfsGateway provided')\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else if (allowIpfsIoRepair && protocol === 'https' && host === 'ipfs.io') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, () => 'No ipfsGateway provided')\n const pathParts = path.split('/')\n if (pathParts[0] === 'ipfs') {\n pathParts.shift()\n }\n path = pathParts.join('/')\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n } catch {\n // const error = ex as Error\n // console.error(`${error.name}:${error.message} [${urlToCheck}]`)\n // console.log(error.stack)\n return urlToCheck\n }\n}\n", "import { fromByteArray } from 'base64-js'\n\nexport const createDataUrl = (data: ArrayBufferLike, contextType: string, encoding: 'base64' = 'base64') => {\n return `data:${contextType};${encoding},${fromByteArray(new Uint8Array(data))}`\n}\n", "import { toByteArray } from 'base64-js'\nimport { Builder, parseStringPromise } from 'xml2js'\n\ninterface FetchedImage {\n buffer: ArrayBuffer\n contentType: string | null\n href: string\n ok: boolean\n}\n\nexport const resolveDynamicSvg = async (base64Bytes: string) => {\n const decoder = new TextDecoder()\n const bytes = toByteArray(base64Bytes)\n const svg = decoder.decode(bytes)\n const svgObj = await parseStringPromise(svg)\n const svgNode = svgObj.svg\n const imageResults: FetchedImage[] = await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgNode.image.map(async (img: any): Promise<FetchedImage> => {\n const href: string = img.$.href\n const response = await fetch(href)\n return {\n buffer: await response.arrayBuffer(),\n contentType: response.headers.get('content-type'),\n href,\n ok: response.ok,\n }\n }),\n )\n const image = imageResults.map(({\n buffer, contentType, href, ok,\n }) => {\n if (ok && buffer.byteLength > 0) {\n const sourceBuffer = Buffer.from(buffer)\n return { $: { href: `data:${contentType ?? 'application/octet-stream'};base64,${sourceBuffer.toString('base64')}` } }\n } else {\n return { $: { href } }\n }\n })\n const updatedSVG = { ...svgObj, svg: { ...svgNode, image } }\n const builder = new Builder()\n return builder.buildObject(updatedSVG)\n}\n", "export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin.ts'\nexport * from './Witness/index.ts'\nexport * from '@xyo-network/diviner-image-thumbnail'\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { ImageThumbnailDiviner } from '@xyo-network/diviner-image-thumbnail'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { createPayloadSetDualPlugin, PayloadSetSchema } from '@xyo-network/sdk-js'\n\nimport { ImageThumbnailWitness } from './Witness/index.ts'\n\nexport const ImageThumbnailPlugin = () =>\n createPayloadSetDualPlugin<ImageThumbnailWitness, ImageThumbnailDiviner>(\n { required: { [ImageThumbnailSchema]: 1 }, schema: PayloadSetSchema },\n {\n diviner: async (params) => {\n const result = await ImageThumbnailDiviner.create(params)\n return result\n },\n witness: async (params) => {\n const result = await ImageThumbnailWitness.create(params)\n return result\n },\n },\n )\n", "import { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport type { WitnessConfig } from '@xyo-network/sdk-js'\nimport { asSchema } from '@xyo-network/sdk-js'\n\nexport const ImageThumbnailWitnessConfigSchema = asSchema(`${ImageThumbnailSchema}.witness.config`, true)\nexport type ImageThumbnailWitnessConfigSchema = typeof ImageThumbnailWitnessConfigSchema\n\nexport type ImageThumbnailEncoding = 'PNG' | 'JPG' | 'GIF'\n\nexport type ImageThumbnailWitnessConfig = WitnessConfig<{\n dataUrlPassthrough?: boolean\n encoding?: ImageThumbnailEncoding\n height?: number\n ipfsGateway?: string\n maxAsyncProcesses?: number\n maxCacheBytes?: number\n maxCacheEntries?: number\n quality?: number\n runExclusive?: boolean\n schema: ImageThumbnailWitnessConfigSchema\n width?: number\n}>\n", "/* eslint-disable max-statements */\nimport { Buffer } from 'node:buffer'\nimport { promises as dnsPromises } from 'node:dns'\n\nimport { exists } from '@xylabs/sdk-js'\nimport type { ImageThumbnail } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport type { Schema } from '@xyo-network/sdk-js'\nimport { AbstractWitness, ObjectHasher } from '@xyo-network/sdk-js'\nimport type { UrlPayload } from '@xyo-network/url-payload-plugin'\nimport { UrlSchema } from '@xyo-network/url-payload-plugin'\nimport { Semaphore } from 'async-mutex'\nimport { fileTypeFromBuffer } from 'file-type'\nimport graphicsMagick from 'gm'\nimport hasbin from 'hasbin'\nimport { sha256 } from 'hash-wasm'\nimport shajs from 'sha.js'\n\nimport type { ImageThumbnailEncoding } from './Config.ts'\nimport { ImageThumbnailWitnessConfigSchema } from './Config.ts'\nimport { getVideoFrameAsImageFluent } from './ffmpeg/index.ts'\nimport {\n checkIpfsUrl, createDataUrl, resolveDynamicSvg,\n} from './lib/index.ts'\nimport type { ImageThumbnailWitnessParams } from './Params.ts'\n\n// TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\nconst gm = graphicsMagick.subClass({ imageMagick: '7+' })\n\nexport interface ImageThumbnailWitnessError extends Error {\n name: 'ImageThumbnailWitnessError'\n url: string\n}\n\nexport interface DnsError extends Error {\n code: string\n}\n\nexport class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams = ImageThumbnailWitnessParams> extends AbstractWitness<TParams> {\n static override readonly configSchemas: Schema[] = [...super.configSchemas, ImageThumbnailWitnessConfigSchema]\n static override readonly defaultConfigSchema: Schema = ImageThumbnailWitnessConfigSchema\n\n private _semaphore = new Semaphore(this.maxAsyncProcesses)\n\n get encoding() {\n return this.config.encoding ?? 'PNG'\n }\n\n get height() {\n return this.config.height ?? 128\n }\n\n get ipfsGateway() {\n return this.config.ipfsGateway ?? '5d7b6582.beta.decentralnetworkservices.com'\n }\n\n get maxAsyncProcesses() {\n return this.config.maxAsyncProcesses ?? 4\n }\n\n get quality() {\n return this.config.quality ?? 50\n }\n\n get width() {\n return this.config.width ?? 128\n }\n\n private static async binaryToSha256(data: ArrayBufferLike) {\n const viewData = new Uint8Array(data)\n await ObjectHasher.wasmInitialized\n if (ObjectHasher.wasmSupport.canUseWasm) {\n try {\n return await sha256(viewData)\n } catch {\n ObjectHasher.wasmSupport.allowWasm = false\n }\n }\n\n return shajs('sha256').update(viewData).digest().toString()\n }\n\n private static bufferFromDataUrl(url: string): ArrayBufferLike | undefined {\n if (url.startsWith('data:image')) {\n const data = url.split(',', 2)[1]\n if (data) {\n return Uint8Array.from(atob(data), c => c.codePointAt(0) ?? 0).buffer\n } else {\n const error: ImageThumbnailWitnessError = {\n message: 'Invalid data Url',\n name: 'ImageThumbnailWitnessError',\n url,\n }\n throw error\n }\n }\n }\n\n protected override async observeHandler(payloads: UrlPayload[] = []): Promise<ImageThumbnail[]> {\n if (!hasbin.sync('magick')) {\n throw new Error('ImageMagick is required for this witness')\n }\n const urlPayloads = payloads.filter(payload => payload.schema === UrlSchema)\n const process = async () => {\n return (await Promise.all(\n urlPayloads.map<Promise<ImageThumbnail>>(async ({ url }) => {\n let result: ImageThumbnail\n\n // if it is a data URL, return a Buffer\n const dataBuffer = ImageThumbnailWitness.bufferFromDataUrl(url)\n\n if (dataBuffer) {\n if (this.config.dataUrlPassthrough) {\n result = {\n schema: ImageThumbnailSchema,\n sourceHash: await ImageThumbnailWitness.binaryToSha256(dataBuffer),\n sourceUrl: url,\n url,\n }\n } else {\n let cookedDataBuffer = dataBuffer\n const urlParts = url.split(';')\n const [, contentType] = urlParts[0].split(':')\n if (contentType.startsWith('image/svg')) {\n const [encoding, byteString] = urlParts[1].split(',')\n if (encoding === 'base64') {\n const newSvg = await resolveDynamicSvg(byteString)\n const newSvgDataUrl = createDataUrl(Buffer.from(newSvg).buffer, contentType)\n cookedDataBuffer = ImageThumbnailWitness.bufferFromDataUrl(newSvgDataUrl) ?? dataBuffer\n }\n }\n result = await this.processMedia(\n cookedDataBuffer,\n {\n schema: ImageThumbnailSchema,\n sourceUrl: url,\n },\n contentType,\n )\n }\n } else {\n // if it is ipfs, go through cloud flair\n const mutatedUrl = checkIpfsUrl(url, this.ipfsGateway)\n result = await this.fromHttp(mutatedUrl, url)\n }\n return result\n }),\n )).filter(exists)\n }\n return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process()\n }\n\n private async createThumbnailDataUrl(sourceBuffer: ArrayBufferLike, encoding?: ImageThumbnailEncoding) {\n const thumb = await new Promise<Buffer>((resolve, reject) => {\n gm(Buffer.from(sourceBuffer))\n .quality(this.quality)\n .resize(this.width, this.height)\n .flatten()\n .toBuffer(encoding ?? this.encoding, (error, buffer) => {\n if (error) {\n reject(error)\n } else {\n resolve(buffer)\n }\n })\n })\n return createDataUrl(thumb.buffer, 'image/png')\n }\n\n /**\n * Creates an image thumbnail from a video.\n * @param videoBuffer The input video buffer.\n * @returns An buffer containing an image thumbnail for the video.\n */\n private async createThumbnailFromVideo(videoBuffer: ArrayBufferLike) {\n const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer)\n return this.createThumbnailDataUrl(imageBuffer.buffer)\n }\n\n private async fromHttp(url: string, sourceUrl?: string): Promise<ImageThumbnail> {\n let response: Response\n let dnsResult: string[]\n try {\n const urlObj = new URL(url)\n dnsResult = await dnsPromises.resolve(urlObj.host)\n } catch (ex) {\n const error = ex as DnsError\n const result: ImageThumbnail = {\n http: { code: error.code },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n return result\n }\n try {\n response = await fetch(url)\n } catch (ex) {\n const result: ImageThumbnail = {\n http: { ipAddress: dnsResult[0] },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n if (ex instanceof Error) {\n result.http = result.http ?? {}\n result.http.code = ex.name\n }\n return result\n }\n\n const result: ImageThumbnail = {\n http: { status: response.status },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n\n if (response.status >= 200 && response.status < 300) {\n const contentType: string | undefined = response.headers.get('content-type') ?? undefined\n const sourceBuffer = await response.arrayBuffer()\n\n return this.processMedia(sourceBuffer, result, contentType)\n }\n return result\n }\n\n private async processMedia(sourceBuffer: ArrayBufferLike, imageThumbnail: ImageThumbnail, contentType?: string): Promise<ImageThumbnail> {\n const [mediaType, fileType] = contentType?.split('/') ?? ['', '']\n imageThumbnail.mime = imageThumbnail.mime ?? {}\n imageThumbnail.mime.returned = mediaType\n\n try {\n imageThumbnail.mime.detected = await fileTypeFromBuffer(sourceBuffer as ArrayBuffer)\n } catch (ex) {\n const error = ex as Error\n this.logger?.error(`FileType error: ${error.message}`)\n }\n\n const processImage = async (encoding?: ImageThumbnailEncoding) => {\n imageThumbnail.sourceHash = await ImageThumbnailWitness.binaryToSha256(sourceBuffer)\n imageThumbnail.url = await this.createThumbnailDataUrl(sourceBuffer, encoding)\n }\n\n const processVideo = async () => {\n // Gracefully handle the case where ffmpeg is not installed.\n\n if (hasbin.sync('ffmpeg')) {\n imageThumbnail.sourceHash = await ImageThumbnailWitness.binaryToSha256(sourceBuffer)\n imageThumbnail.url = await this.createThumbnailFromVideo(sourceBuffer)\n } else {\n imageThumbnail.mime = imageThumbnail.mime ?? {}\n imageThumbnail.mime.invalid = true\n }\n }\n\n let encoding: ImageThumbnailEncoding = 'PNG'\n\n switch (fileType.toUpperCase()) {\n case 'GIF': {\n encoding = 'GIF'\n break\n }\n case 'JPG':\n case 'JPEG': {\n encoding = 'JPG'\n break\n }\n }\n\n switch (mediaType) {\n case 'image': {\n await processImage(encoding)\n imageThumbnail.mime.type = mediaType\n break\n }\n case 'video': {\n await processVideo()\n imageThumbnail.mime.type = mediaType\n break\n }\n default: {\n const [detectedMediaType] = imageThumbnail.mime.detected?.mime?.split('/') ?? ['', '']\n switch (detectedMediaType) {\n case 'image': {\n await processImage()\n imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime\n break\n }\n case 'video': {\n await processVideo()\n imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime\n break\n }\n default: {\n imageThumbnail.mime.invalid = true\n break\n }\n }\n break\n }\n }\n return imageThumbnail\n }\n}\n", "import { unlink, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport type { WritableOptions } from 'node:stream'\nimport { Writable } from 'node:stream'\n\nimport ffmpeg from 'fluent-ffmpeg'\nimport { v4 as uuid } from 'uuid'\n\n/**\n * A Writable stream that collects output from ffmpeg.\n */\nclass FfmpegOutputStream extends Writable {\n private readonly chunks: Uint8Array[] = []\n\n constructor(options?: WritableOptions) {\n super(options)\n }\n\n override _write(chunk: never, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n this.chunks.push(chunk)\n callback()\n }\n\n /**\n * Collects the output from ffmpeg into a buffer.\n * @returns A buffer containing the concatenated\n * output from ffmpeg.\n */\n toBuffer = () => Buffer.concat(this.chunks)\n}\n\n/**\n * Execute FFmpeg using fluent API with provided input buffer and video thumbnail image.\n * @param videoBuffer Input video buffer.\n * @returns Output buffer containing the video thumbnail image.\n */\nexport const getVideoFrameAsImageFluent = async (videoBuffer: ArrayBufferLike) => {\n // Get a temp file name\n const tmpFile = `/${tmpdir()}/${uuid()}`\n try {\n // Write videoBuffer to temp file for use as input to ffmpeg to\n // avoid issues with ffmpeg inferring premature EOF from buffer\n // passed via stdin (happens when ffmpeg is trying to infer\n // input video format)\n await writeFile(tmpFile, new Uint8Array(videoBuffer), { encoding: 'binary' })\n const imageBuffer = await new Promise<Buffer>((resolve, reject) => {\n // Create a Writable stream to collect PNG output from ffmpeg\n const ffmpegOutput = new FfmpegOutputStream()\n // Execute ffmpeg using fluent API\n ffmpeg()\n // Uncomment to debug CLI args to ffmpeg\n // .on('start', (commandLine) => console.log('Spawned Ffmpeg with command: ' + commandLine))\n .on('error', err => reject(new Error(err.message, { cause: err })))\n // Listen for the 'end' event to combine the output into a buffer holding the PNG image\n .on('end', () => resolve(ffmpegOutput.toBuffer()))\n .input(tmpFile) // Use temp file as input\n .takeFrames(1) // Only take 1st video frame\n .withNoAudio() // Don't include audio\n .outputOptions('-f image2pipe') // Write output to stdout\n .videoCodec('png') // Force PNG output\n // Start processing and direct ffmpeg stdout to writable stream\n .pipe(ffmpegOutput)\n })\n return imageBuffer\n } finally {\n // Cleanup temp file\n try {\n await unlink(tmpFile)\n } catch {\n // No error here since file doesn't exist\n }\n }\n}\n", "import { assertEx } from '@xylabs/sdk-js'\n\nconst allowIpfsIoRepair = true\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string): string => {\n try {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, () => 'No ipfsGateway provided')\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else if (allowIpfsIoRepair && protocol === 'https' && host === 'ipfs.io') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, () => 'No ipfsGateway provided')\n const pathParts = path.split('/')\n if (pathParts[0] === 'ipfs') {\n pathParts.shift()\n }\n path = pathParts.join('/')\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n } catch {\n // const error = ex as Error\n // console.error(`${error.name}:${error.message} [${urlToCheck}]`)\n // console.log(error.stack)\n return urlToCheck\n }\n}\n", "import { fromByteArray } from 'base64-js'\n\nexport const createDataUrl = (data: ArrayBufferLike, contextType: string, encoding: 'base64' = 'base64') => {\n return `data:${contextType};${encoding},${fromByteArray(new Uint8Array(data))}`\n}\n", "import { toByteArray } from 'base64-js'\nimport { Builder, parseStringPromise } from 'xml2js'\n\ninterface FetchedImage {\n buffer: ArrayBuffer\n contentType: string | null\n href: string\n ok: boolean\n}\n\nexport const resolveDynamicSvg = async (base64Bytes: string) => {\n const decoder = new TextDecoder()\n const bytes = toByteArray(base64Bytes)\n const svg = decoder.decode(bytes)\n const svgObj = await parseStringPromise(svg)\n const svgNode = svgObj.svg\n const imageResults: FetchedImage[] = await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgNode.image.map(async (img: any): Promise<FetchedImage> => {\n const href: string = img.$.href\n const response = await fetch(href)\n return {\n buffer: await response.arrayBuffer(),\n contentType: response.headers.get('content-type'),\n href,\n ok: response.ok,\n }\n }),\n )\n const image = imageResults.map(({\n buffer, contentType, href, ok,\n }) => {\n if (ok && buffer.byteLength > 0) {\n const sourceBuffer = Buffer.from(buffer)\n return { $: { href: `data:${contentType ?? 'application/octet-stream'};base64,${sourceBuffer.toString('base64')}` } }\n } else {\n return { $: { href } }\n }\n })\n const updatedSVG = { ...svgObj, svg: { ...svgNode, image } }\n const builder = new Builder()\n return builder.buildObject(updatedSVG)\n}\n", "export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin.ts'\nexport * from './Witness/index.ts'\nexport * from '@xyo-network/diviner-image-thumbnail'\n"],
5
+ "mappings": "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",
6
6
  "names": ["ImageThumbnailSchema", "Buffer", "ImageThumbnailSchema", "ImageThumbnailSchema", "Buffer", "result", "encoding", "ImageThumbnailSchema"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/image-thumbnail-plugin",
3
- "version": "6.0.2",
3
+ "version": "6.1.0",
4
4
  "description": "Typescript/Javascript Plugins for XYO Platform",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -33,9 +33,9 @@
33
33
  "README.md"
34
34
  ],
35
35
  "dependencies": {
36
- "@xyo-network/image-thumbnail-payload-plugin": "~6.0.2",
37
- "@xyo-network/diviner-image-thumbnail": "~6.0.2",
38
- "@xyo-network/url-payload-plugin": "~6.0.2"
36
+ "@xyo-network/diviner-image-thumbnail": "~6.1.0",
37
+ "@xyo-network/image-thumbnail-payload-plugin": "~6.1.0",
38
+ "@xyo-network/url-payload-plugin": "~6.1.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@bitauth/libauth": "~3.0.0",
@@ -51,34 +51,32 @@
51
51
  "@types/sha.js": "~2.4.4",
52
52
  "@types/uuid": "~11.0.0",
53
53
  "@types/xml2js": "~0.4.14",
54
- "@xylabs/geo": "^6.0.6",
55
- "@xylabs/sdk-js": "^6.0.6",
56
- "@xylabs/threads": "^6.0.6",
57
- "@xylabs/toolchain": "~8.1.11",
58
- "@xylabs/tsconfig": "~8.1.11",
59
- "@xylabs/vitest-extended": "~6.0.6",
60
- "@xyo-network/archivist-model": "^6.0.2",
61
- "@xyo-network/boundwitness-builder": "~6.0.7",
62
- "@xyo-network/boundwitness-model": "^6.0.7",
63
- "@xyo-network/diviner-boundwitness": "^6.0.2",
64
- "@xyo-network/diviner-indexing": "~6.0.2",
65
- "@xyo-network/diviner-model": "^6.0.2",
66
- "@xyo-network/diviner-payload-generic": "~6.0.2",
67
- "@xyo-network/diviner-payload-model": "^6.0.2",
68
- "@xyo-network/module-model": "^6.0.2",
69
- "@xyo-network/node-memory": "~6.0.2",
70
- "@xyo-network/payload-model": "^6.0.7",
71
- "@xyo-network/payload-utils": "~6.0.7",
72
- "@xyo-network/sdk-js": "^6.0.2",
73
- "@xyo-network/sdk-protocol-js": "~6.0.7",
74
- "@xyo-network/sentinel-memory": "~6.0.2",
75
- "@xyo-network/sentinel-wrapper": "~6.0.2",
76
- "@xyo-network/witness-timestamp": "^6.0.2",
54
+ "@xylabs/geo": "^6.1.0",
55
+ "@xylabs/sdk-js": "^6.1.0",
56
+ "@xylabs/threads": "^6.1.0",
57
+ "@xylabs/toolchain": "~8.1.20",
58
+ "@xylabs/tsconfig": "~8.1.20",
59
+ "@xylabs/vitest-extended": "~6.1.0",
60
+ "@xyo-network/archivist-model": "~6.1.0",
61
+ "@xyo-network/boundwitness-builder": "~6.1.0",
62
+ "@xyo-network/boundwitness-model": "~6.1.0",
63
+ "@xyo-network/diviner-boundwitness": "~6.1.0",
64
+ "@xyo-network/diviner-indexing": "^6.1.0",
65
+ "@xyo-network/diviner-model": "~6.1.0",
66
+ "@xyo-network/diviner-payload-generic": "~6.1.0",
67
+ "@xyo-network/diviner-payload-model": "^6.1.0",
68
+ "@xyo-network/module-model": "~6.1.0",
69
+ "@xyo-network/node-memory": "~6.1.0",
70
+ "@xyo-network/payload-model": "~6.1.0",
71
+ "@xyo-network/payload-utils": "~6.1",
72
+ "@xyo-network/sdk-js": "^6.1.0",
73
+ "@xyo-network/sdk-protocol-js": "~6.1",
74
+ "@xyo-network/sentinel-memory": "~6.1.0",
75
+ "@xyo-network/sentinel-wrapper": "~6.1.0",
76
+ "@xyo-network/witness-timestamp": "^6.1.0",
77
77
  "ajv": "^8.20.0",
78
78
  "async-mutex": "^0.5.0",
79
79
  "base64-js": "^1.5.1",
80
- "bn.js": "^5.2.3",
81
- "buffer": "^6.0.3",
82
80
  "debug": "~4.4.3",
83
81
  "eslint": "^10.4.1",
84
82
  "ethers": "^6.16.0",
@@ -91,12 +89,11 @@
91
89
  "jsonpath-plus": "^10.4.0",
92
90
  "lru-cache": "^11.5.1",
93
91
  "observable-fns": "~0.6.1",
94
- "pako": "~2.1.0",
95
92
  "sha.js": "^2.4.12",
96
93
  "typescript": "~6.0.3",
97
94
  "uuid": "^14.0.0",
98
95
  "vite": "^8.0.16",
99
- "vitest": "^4.1.8",
96
+ "vitest": "~4.1.8",
100
97
  "webextension-polyfill": "^0.12.0",
101
98
  "xml2js": "^0.6.2",
102
99
  "zod": "^4.4.3"
@@ -114,15 +111,13 @@
114
111
  "@xylabs/threads": "^6.0",
115
112
  "@xyo-network/diviner-indexing": "^6.0",
116
113
  "@xyo-network/diviner-payload-model": "^6.0",
117
- "@xyo-network/payload-utils": "~6.0",
114
+ "@xyo-network/payload-utils": "^6.1",
118
115
  "@xyo-network/sdk-js": "^6.0",
119
- "@xyo-network/sdk-protocol-js": "~6.0",
116
+ "@xyo-network/sdk-protocol-js": "^6.1",
120
117
  "@xyo-network/witness-timestamp": "^6.0",
121
118
  "ajv": "^8.20",
122
119
  "async-mutex": "^0.5",
123
120
  "base64-js": "^1.5",
124
- "bn.js": "^5.2",
125
- "buffer": "^6.0",
126
121
  "debug": "~4.4",
127
122
  "ethers": "^6.16",
128
123
  "file-type": "~22.0",
@@ -134,7 +129,6 @@
134
129
  "jsonpath-plus": "^10.3",
135
130
  "lru-cache": "^11.3",
136
131
  "observable-fns": "~0.6",
137
- "pako": "~2.1",
138
132
  "sha.js": "^2.4",
139
133
  "uuid": "^14.0",
140
134
  "webextension-polyfill": "^0.12",