@xyo-network/image-thumbnail-plugin 5.3.2 → 5.3.4

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.
Files changed (51) hide show
  1. package/dist/node/Plugin.d.ts +4 -0
  2. package/dist/node/Plugin.d.ts.map +1 -0
  3. package/dist/node/Witness/Config.d.ts +20 -0
  4. package/dist/node/Witness/Config.d.ts.map +1 -0
  5. package/dist/node/Witness/Params.d.ts +7 -0
  6. package/dist/node/Witness/Params.d.ts.map +1 -0
  7. package/dist/node/Witness/Witness.d.ts +37 -0
  8. package/dist/node/Witness/Witness.d.ts.map +1 -0
  9. package/dist/node/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.d.ts +7 -0
  10. package/dist/node/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.d.ts.map +1 -0
  11. package/dist/node/Witness/ffmpeg/fluent/index.d.ts +2 -0
  12. package/dist/node/Witness/ffmpeg/fluent/index.d.ts.map +1 -0
  13. package/dist/node/Witness/ffmpeg/index.d.ts +3 -0
  14. package/dist/node/Witness/ffmpeg/index.d.ts.map +1 -0
  15. package/dist/node/Witness/ffmpeg/spawn/executeFfmpeg.d.ts +8 -0
  16. package/dist/node/Witness/ffmpeg/spawn/executeFfmpeg.d.ts.map +1 -0
  17. package/dist/node/Witness/ffmpeg/spawn/getVideoFrameAsImage.d.ts +7 -0
  18. package/dist/node/Witness/ffmpeg/spawn/getVideoFrameAsImage.d.ts.map +1 -0
  19. package/dist/node/Witness/ffmpeg/spawn/index.d.ts +3 -0
  20. package/dist/node/Witness/ffmpeg/spawn/index.d.ts.map +1 -0
  21. package/dist/node/Witness/index.d.ts +4 -0
  22. package/dist/node/Witness/index.d.ts.map +1 -0
  23. package/dist/node/Witness/lib/checkIpfsUrl.d.ts +8 -0
  24. package/dist/node/Witness/lib/checkIpfsUrl.d.ts.map +1 -0
  25. package/dist/node/Witness/lib/createDataUrl.d.ts +2 -0
  26. package/dist/node/Witness/lib/createDataUrl.d.ts.map +1 -0
  27. package/dist/node/Witness/lib/index.d.ts +4 -0
  28. package/dist/node/Witness/lib/index.d.ts.map +1 -0
  29. package/dist/node/Witness/lib/resolveDynamicSvg.d.ts +2 -0
  30. package/dist/node/Witness/lib/resolveDynamicSvg.d.ts.map +1 -0
  31. package/dist/node/index.d.ts +4 -0
  32. package/dist/node/index.d.ts.map +1 -0
  33. package/dist/node/index.mjs +404 -0
  34. package/dist/node/index.mjs.map +1 -0
  35. package/package.json +26 -8
  36. package/src/Plugin.ts +0 -21
  37. package/src/Witness/Config.ts +0 -22
  38. package/src/Witness/Params.ts +0 -10
  39. package/src/Witness/Witness.ts +0 -320
  40. package/src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts +0 -73
  41. package/src/Witness/ffmpeg/fluent/index.ts +0 -1
  42. package/src/Witness/ffmpeg/index.ts +0 -2
  43. package/src/Witness/ffmpeg/spawn/executeFfmpeg.ts +0 -27
  44. package/src/Witness/ffmpeg/spawn/getVideoFrameAsImage.ts +0 -11
  45. package/src/Witness/ffmpeg/spawn/index.ts +0 -2
  46. package/src/Witness/index.ts +0 -3
  47. package/src/Witness/lib/checkIpfsUrl.ts +0 -43
  48. package/src/Witness/lib/createDataUrl.ts +0 -5
  49. package/src/Witness/lib/index.ts +0 -3
  50. package/src/Witness/lib/resolveDynamicSvg.ts +0 -30
  51. package/src/index.ts +0 -3
@@ -0,0 +1,4 @@
1
+ import { ImageThumbnailDiviner } from '@xyo-network/diviner-image-thumbnail';
2
+ import { ImageThumbnailWitness } from './Witness/index.ts';
3
+ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset-plugin").PayloadSetDualPlugin<ImageThumbnailWitness<import("./Witness/Params.ts").ImageThumbnailWitnessParams>, ImageThumbnailDiviner>;
4
+ //# sourceMappingURL=Plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../../src/Plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAK5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,eAAO,MAAM,oBAAoB,8KAa9B,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { WitnessConfig } from '@xyo-network/witness-model';
2
+ export declare const ImageThumbnailWitnessConfigSchema: string & {
3
+ readonly __schema: true;
4
+ };
5
+ export type ImageThumbnailWitnessConfigSchema = typeof ImageThumbnailWitnessConfigSchema;
6
+ export type ImageThumbnailEncoding = 'PNG' | 'JPG' | 'GIF';
7
+ export type ImageThumbnailWitnessConfig = WitnessConfig<{
8
+ dataUrlPassthrough?: boolean;
9
+ encoding?: ImageThumbnailEncoding;
10
+ height?: number;
11
+ ipfsGateway?: string;
12
+ maxAsyncProcesses?: number;
13
+ maxCacheBytes?: number;
14
+ maxCacheEntries?: number;
15
+ quality?: number;
16
+ runExclusive?: boolean;
17
+ schema: ImageThumbnailWitnessConfigSchema;
18
+ width?: number;
19
+ }>;
20
+ //# sourceMappingURL=Config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/Witness/Config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAE/D,eAAO,MAAM,iCAAiC;;CAA2D,CAAA;AACzG,MAAM,MAAM,iCAAiC,GAAG,OAAO,iCAAiC,CAAA;AAExF,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;AAE1D,MAAM,MAAM,2BAA2B,GAAG,aAAa,CAAC;IACtD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,EAAE,sBAAsB,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,MAAM,EAAE,iCAAiC,CAAA;IACzC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { AnyConfigSchema } from '@xyo-network/module-model';
2
+ import type { WitnessParams } from '@xyo-network/witness-model';
3
+ import type { ImageThumbnailWitnessConfig } from './Config.ts';
4
+ export interface ImageThumbnailWitnessParams extends WitnessParams<AnyConfigSchema<ImageThumbnailWitnessConfig>> {
5
+ loaders?: string[];
6
+ }
7
+ //# sourceMappingURL=Params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Params.d.ts","sourceRoot":"","sources":["../../../src/Witness/Params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAE9D,MAAM,WAAW,2BAA4B,SAAQ,aAAa,CAChE,eAAe,CAAC,2BAA2B,CAAC,CAAC;IAE7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB"}
@@ -0,0 +1,37 @@
1
+ import { AbstractWitness } from '@xyo-network/abstract-witness';
2
+ import type { ImageThumbnail } from '@xyo-network/image-thumbnail-payload-plugin';
3
+ import type { Schema } from '@xyo-network/payload-model';
4
+ import type { UrlPayload } from '@xyo-network/url-payload-plugin';
5
+ import type { ImageThumbnailEncoding } from './Config.ts';
6
+ import type { ImageThumbnailWitnessParams } from './Params.ts';
7
+ export interface ImageThumbnailWitnessError extends Error {
8
+ name: 'ImageThumbnailWitnessError';
9
+ url: string;
10
+ }
11
+ export interface DnsError extends Error {
12
+ code: string;
13
+ }
14
+ export declare class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams = ImageThumbnailWitnessParams> extends AbstractWitness<TParams> {
15
+ static readonly configSchemas: Schema[];
16
+ static readonly defaultConfigSchema: Schema;
17
+ private _semaphore;
18
+ get encoding(): ImageThumbnailEncoding;
19
+ get height(): number;
20
+ get ipfsGateway(): string;
21
+ get maxAsyncProcesses(): number;
22
+ get quality(): number;
23
+ get width(): number;
24
+ private static binaryToSha256;
25
+ private static bufferFromDataUrl;
26
+ protected observeHandler(payloads?: UrlPayload[]): Promise<ImageThumbnail[]>;
27
+ private createThumbnailDataUrl;
28
+ /**
29
+ * Creates an image thumbnail from a video.
30
+ * @param videoBuffer The input video buffer.
31
+ * @returns An buffer containing an image thumbnail for the video.
32
+ */
33
+ private createThumbnailFromVideo;
34
+ private fromHttp;
35
+ private processMedia;
36
+ }
37
+ //# sourceMappingURL=Witness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAA;AAEjF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAYjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAMzD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AAQ9D,MAAM,WAAW,0BAA2B,SAAQ,KAAK;IACvD,IAAI,EAAE,4BAA4B,CAAA;IAClC,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,qBAAqB,CAAC,OAAO,SAAS,2BAA2B,GAAG,2BAA2B,CAAE,SAAQ,eAAe,CAAC,OAAO,CAAC;IAC5I,gBAAyB,aAAa,EAAE,MAAM,EAAE,CAA8D;IAC9G,gBAAyB,mBAAmB,EAAE,MAAM,CAAoC;IAExF,OAAO,CAAC,UAAU,CAAwC;IAE1D,IAAI,QAAQ,2BAEX;IAED,IAAI,MAAM,WAET;IAED,IAAI,WAAW,WAEd;IAED,IAAI,iBAAiB,WAEpB;IAED,IAAI,OAAO,WAEV;IAED,IAAI,KAAK,WAER;mBAEoB,cAAc;IAcnC,OAAO,CAAC,MAAM,CAAC,iBAAiB;cAgBP,cAAc,CAAC,QAAQ,GAAE,UAAU,EAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;YAsDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YAuDR,YAAY;CA6E3B"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Execute FFmpeg using fluent API with provided input buffer and video thumbnail image.
3
+ * @param videoBuffer Input video buffer.
4
+ * @returns Output buffer containing the video thumbnail image.
5
+ */
6
+ export declare const getVideoFrameAsImageFluent: (videoBuffer: ArrayBufferLike) => Promise<Buffer<ArrayBufferLike>>;
7
+ //# sourceMappingURL=getVideoFrameAsImageFluent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAU,aAAa,eAAe,qCAoC5E,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './getVideoFrameAsImageFluent.ts';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './fluent/index.ts';
2
+ export * from './spawn/index.ts';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Witness/ffmpeg/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Execute FFmpeg with the provided arguments.
3
+ * @param videoBuffer Input video buffer.
4
+ * @param ffmpegArgs FFmpeg arguments.
5
+ * @returns Output buffer containing the video thumbnail image.
6
+ */
7
+ export declare const executeFFmpeg: (videoBuffer: Buffer, ffmpegArgs: string[]) => Promise<Buffer>;
8
+ //# sourceMappingURL=executeFfmpeg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executeFfmpeg.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/spawn/executeFfmpeg.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,EAAE,YAAY,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAkBvF,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Execute FFmpeg with provided input buffer and return video thumbnail image.
3
+ * @param videoBuffer Input video buffer.
4
+ * @returns Output buffer containing the video thumbnail image.
5
+ */
6
+ export declare const getVideoFrameAsImage: (videoBuffer: Buffer) => Promise<Buffer<ArrayBufferLike>>;
7
+ //# sourceMappingURL=getVideoFrameAsImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVideoFrameAsImage.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/spawn/getVideoFrameAsImage.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAU,aAAa,MAAM,qCAG7D,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './executeFfmpeg.ts';
2
+ export * from './getVideoFrameAsImage.ts';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/spawn/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './Config.ts';
2
+ export * from './Params.ts';
3
+ export * from './Witness.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Witness/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns the equivalent IPFS gateway URL for the supplied URL.
3
+ * @param urlToCheck The URL to check
4
+ * @returns If the supplied URL is an IPFS URL, it converts the URL to the
5
+ * equivalent IPFS gateway URL. Otherwise, returns the original URL.
6
+ */
7
+ export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string;
8
+ //# sourceMappingURL=checkIpfsUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../../src/Witness/lib/checkIpfsUrl.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,YAAY,MAAM,EAAE,cAAc,MAAM,KAAG,MAgCvE,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const createDataUrl: (data: ArrayBufferLike, contextType: string, encoding?: "base64") => string;
2
+ //# sourceMappingURL=createDataUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createDataUrl.d.ts","sourceRoot":"","sources":["../../../../src/Witness/lib/createDataUrl.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,GAAI,MAAM,eAAe,EAAE,aAAa,MAAM,EAAE,WAAU,QAAmB,WAEtG,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './checkIpfsUrl.ts';
2
+ export * from './createDataUrl.ts';
3
+ export * from './resolveDynamicSvg.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Witness/lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const resolveDynamicSvg: (base64Bytes: string) => Promise<string>;
2
+ //# sourceMappingURL=resolveDynamicSvg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveDynamicSvg.d.ts","sourceRoot":"","sources":["../../../../src/Witness/lib/resolveDynamicSvg.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,GAAU,aAAa,MAAM,oBAwB1D,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin.ts';
2
+ export * from './Witness/index.ts';
3
+ export * from '@xyo-network/diviner-image-thumbnail';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,IAAI,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACnF,cAAc,oBAAoB,CAAA;AAClC,cAAc,sCAAsC,CAAA"}
@@ -0,0 +1,404 @@
1
+ // src/Plugin.ts
2
+ import { ImageThumbnailDiviner } from "@xyo-network/diviner-image-thumbnail";
3
+ import { ImageThumbnailSchema as ImageThumbnailSchema3 } from "@xyo-network/image-thumbnail-payload-plugin";
4
+ import { PayloadSetSchema } from "@xyo-network/payload-model";
5
+ import { createPayloadSetDualPlugin } from "@xyo-network/payloadset-plugin";
6
+
7
+ // src/Witness/Config.ts
8
+ import { ImageThumbnailSchema } from "@xyo-network/image-thumbnail-payload-plugin";
9
+ import { asSchema } from "@xyo-network/payload-model";
10
+ var ImageThumbnailWitnessConfigSchema = asSchema(`${ImageThumbnailSchema}.witness.config`, true);
11
+
12
+ // src/Witness/Witness.ts
13
+ import { Buffer as Buffer2 } from "buffer";
14
+ import { promises as dnsPromises } from "dns";
15
+ import { exists } from "@xylabs/sdk-js";
16
+ import { AbstractWitness } from "@xyo-network/abstract-witness";
17
+ import { ImageThumbnailSchema as ImageThumbnailSchema2 } from "@xyo-network/image-thumbnail-payload-plugin";
18
+ import { ObjectHasher } from "@xyo-network/sdk-js";
19
+ import { UrlSchema } from "@xyo-network/url-payload-plugin";
20
+ import { Semaphore } from "async-mutex";
21
+ import axios2 from "axios";
22
+ import { fileTypeFromBuffer } from "file-type";
23
+ import graphicsMagick from "gm";
24
+ import hasbin from "hasbin";
25
+ import { sha256 } from "hash-wasm";
26
+ import shajs from "sha.js";
27
+ import Url from "url-parse";
28
+
29
+ // src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts
30
+ import { unlink, writeFile } from "fs/promises";
31
+ import { tmpdir } from "os";
32
+ import { Writable } from "stream";
33
+ import ffmpeg from "fluent-ffmpeg";
34
+ import { v4 as uuid } from "uuid";
35
+ var FfmpegOutputStream = class extends Writable {
36
+ chunks = [];
37
+ constructor(options) {
38
+ super(options);
39
+ }
40
+ _write(chunk, _encoding, callback) {
41
+ this.chunks.push(chunk);
42
+ callback();
43
+ }
44
+ /**
45
+ * Collects the output from ffmpeg into a buffer.
46
+ * @returns A buffer containing the concatenated
47
+ * output from ffmpeg.
48
+ */
49
+ toBuffer = () => Buffer.concat(this.chunks);
50
+ };
51
+ var getVideoFrameAsImageFluent = async (videoBuffer) => {
52
+ const tmpFile = `/${tmpdir()}/${uuid()}`;
53
+ try {
54
+ await writeFile(tmpFile, new Uint8Array(videoBuffer), { encoding: "binary" });
55
+ const imageBuffer = await new Promise((resolve, reject) => {
56
+ const ffmpegOutput = new FfmpegOutputStream();
57
+ ffmpeg().on("error", (err) => reject(err.message)).on("end", () => resolve(ffmpegOutput.toBuffer())).input(tmpFile).takeFrames(1).withNoAudio().outputOptions("-f image2pipe").videoCodec("png").pipe(ffmpegOutput);
58
+ });
59
+ return imageBuffer;
60
+ } finally {
61
+ try {
62
+ await unlink(tmpFile);
63
+ } catch {
64
+ }
65
+ }
66
+ };
67
+
68
+ // src/Witness/lib/checkIpfsUrl.ts
69
+ import { assertEx } from "@xylabs/sdk-js";
70
+ var allowIpfsIoRepair = true;
71
+ var checkIpfsUrl = (urlToCheck, ipfsGateway) => {
72
+ try {
73
+ const url = new URL(urlToCheck);
74
+ let protocol = url.protocol;
75
+ let host = url.host;
76
+ let path = url.pathname;
77
+ const query = url.search;
78
+ if (protocol === "ipfs:") {
79
+ protocol = "https:";
80
+ host = assertEx(ipfsGateway, () => "No ipfsGateway provided");
81
+ path = url.host === "ipfs" ? `ipfs${path}` : `ipfs/${url.host}${path}`;
82
+ const root = `${protocol}//${host}/${path}`;
83
+ return query?.length > 0 ? `${root}?${query}` : root;
84
+ } else if (allowIpfsIoRepair && protocol === "https" && host === "ipfs.io") {
85
+ protocol = "https:";
86
+ host = assertEx(ipfsGateway, () => "No ipfsGateway provided");
87
+ const pathParts = path.split("/");
88
+ if (pathParts[0] === "ipfs") {
89
+ pathParts.shift();
90
+ }
91
+ path = pathParts.join("/");
92
+ const root = `${protocol}//${host}/${path}`;
93
+ return query?.length > 0 ? `${root}?${query}` : root;
94
+ } else {
95
+ return urlToCheck;
96
+ }
97
+ } catch {
98
+ return urlToCheck;
99
+ }
100
+ };
101
+
102
+ // src/Witness/lib/createDataUrl.ts
103
+ import { fromByteArray } from "base64-js";
104
+ var createDataUrl = (data, contextType, encoding = "base64") => {
105
+ return `data:${contextType};${encoding},${fromByteArray(new Uint8Array(data))}`;
106
+ };
107
+
108
+ // src/Witness/lib/resolveDynamicSvg.ts
109
+ import axios from "axios";
110
+ import { toByteArray } from "base64-js";
111
+ import { Builder, parseStringPromise } from "xml2js";
112
+ var resolveDynamicSvg = async (base64Bytes) => {
113
+ const decoder = new TextDecoder();
114
+ const bytes = toByteArray(base64Bytes);
115
+ const svg = decoder.decode(bytes);
116
+ const svgObj = await parseStringPromise(svg);
117
+ const svgNode = svgObj["svg"];
118
+ const imageResults = await Promise.all(
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ svgNode["image"].map(async (img) => [
121
+ img.$,
122
+ await axios.get(img.$.href, { responseType: "arraybuffer" })
123
+ ])
124
+ );
125
+ const image = imageResults.map(([href, response]) => {
126
+ if (response.data) {
127
+ const sourceBuffer = Buffer.from(response.data, "binary");
128
+ return { $: { href: `data:${response.headers["content-type"]?.toString()};base64,${sourceBuffer.toString("base64")}` } };
129
+ } else {
130
+ return { $: { href } };
131
+ }
132
+ });
133
+ const updatedSVG = { ...svgObj, svg: { ...svgNode, image } };
134
+ const builder = new Builder();
135
+ return builder.buildObject(updatedSVG);
136
+ };
137
+
138
+ // src/Witness/Witness.ts
139
+ var gm = graphicsMagick.subClass({ imageMagick: "7+" });
140
+ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness {
141
+ static configSchemas = [...super.configSchemas, ImageThumbnailWitnessConfigSchema];
142
+ static defaultConfigSchema = ImageThumbnailWitnessConfigSchema;
143
+ _semaphore = new Semaphore(this.maxAsyncProcesses);
144
+ get encoding() {
145
+ return this.config.encoding ?? "PNG";
146
+ }
147
+ get height() {
148
+ return this.config.height ?? 128;
149
+ }
150
+ get ipfsGateway() {
151
+ return this.config.ipfsGateway ?? "5d7b6582.beta.decentralnetworkservices.com";
152
+ }
153
+ get maxAsyncProcesses() {
154
+ return this.config.maxAsyncProcesses ?? 4;
155
+ }
156
+ get quality() {
157
+ return this.config.quality ?? 50;
158
+ }
159
+ get width() {
160
+ return this.config.width ?? 128;
161
+ }
162
+ static async binaryToSha256(data) {
163
+ const viewData = new Uint8Array(data);
164
+ await ObjectHasher.wasmInitialized;
165
+ if (ObjectHasher.wasmSupport.canUseWasm) {
166
+ try {
167
+ return await sha256(viewData);
168
+ } catch {
169
+ ObjectHasher.wasmSupport.allowWasm = false;
170
+ }
171
+ }
172
+ return shajs("sha256").update(viewData).digest().toString();
173
+ }
174
+ static bufferFromDataUrl(url) {
175
+ if (url.startsWith("data:image")) {
176
+ const data = url.split(",")[1];
177
+ if (data) {
178
+ return Uint8Array.from(atob(data), (c) => c.codePointAt(0) ?? 0).buffer;
179
+ } else {
180
+ const error = {
181
+ message: "Invalid data Url",
182
+ name: "ImageThumbnailWitnessError",
183
+ url
184
+ };
185
+ throw error;
186
+ }
187
+ }
188
+ }
189
+ async observeHandler(payloads = []) {
190
+ if (!hasbin.sync("magick")) {
191
+ throw new Error("ImageMagick is required for this witness");
192
+ }
193
+ const urlPayloads = payloads.filter((payload) => payload.schema === UrlSchema);
194
+ const process = async () => {
195
+ return (await Promise.all(
196
+ urlPayloads.map(async ({ url }) => {
197
+ let result;
198
+ const dataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(url);
199
+ if (dataBuffer) {
200
+ if (this.config.dataUrlPassthrough) {
201
+ result = {
202
+ schema: ImageThumbnailSchema2,
203
+ sourceHash: await _ImageThumbnailWitness.binaryToSha256(dataBuffer),
204
+ sourceUrl: url,
205
+ url
206
+ };
207
+ } else {
208
+ let cookedDataBuffer = dataBuffer;
209
+ const urlParts = url.split(";");
210
+ const [, contentType] = urlParts[0].split(":");
211
+ if (contentType.startsWith("image/svg")) {
212
+ const [encoding, byteString] = urlParts[1].split(",");
213
+ if (encoding === "base64") {
214
+ const newSvg = await resolveDynamicSvg(byteString);
215
+ const newSvgDataUrl = createDataUrl(Buffer2.from(newSvg).buffer, contentType);
216
+ cookedDataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(newSvgDataUrl) ?? dataBuffer;
217
+ }
218
+ }
219
+ result = await this.processMedia(
220
+ cookedDataBuffer,
221
+ {
222
+ schema: ImageThumbnailSchema2,
223
+ sourceUrl: url
224
+ },
225
+ contentType
226
+ );
227
+ }
228
+ } else {
229
+ const mutatedUrl = checkIpfsUrl(url, this.ipfsGateway);
230
+ result = await this.fromHttp(mutatedUrl, url);
231
+ }
232
+ return result;
233
+ })
234
+ )).filter(exists);
235
+ };
236
+ return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process();
237
+ }
238
+ async createThumbnailDataUrl(sourceBuffer, encoding) {
239
+ const thumb = await new Promise((resolve, reject) => {
240
+ gm(Buffer2.from(sourceBuffer)).quality(this.quality).resize(this.width, this.height).flatten().toBuffer(encoding ?? this.encoding, (error, buffer) => {
241
+ if (error) {
242
+ reject(error);
243
+ } else {
244
+ resolve(buffer);
245
+ }
246
+ });
247
+ });
248
+ return createDataUrl(thumb.buffer, "image/png");
249
+ }
250
+ /**
251
+ * Creates an image thumbnail from a video.
252
+ * @param videoBuffer The input video buffer.
253
+ * @returns An buffer containing an image thumbnail for the video.
254
+ */
255
+ async createThumbnailFromVideo(videoBuffer) {
256
+ const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer);
257
+ return this.createThumbnailDataUrl(imageBuffer.buffer);
258
+ }
259
+ // eslint-disable-next-line complexity
260
+ async fromHttp(url, sourceUrl) {
261
+ let response;
262
+ let dnsResult;
263
+ try {
264
+ const urlObj = new Url(url);
265
+ dnsResult = await dnsPromises.resolve(urlObj.host);
266
+ } catch (ex) {
267
+ const error = ex;
268
+ const result2 = {
269
+ http: { code: error.code },
270
+ schema: ImageThumbnailSchema2,
271
+ sourceUrl: sourceUrl ?? url
272
+ };
273
+ return result2;
274
+ }
275
+ try {
276
+ response = await axios2.get(url, { responseType: "arraybuffer" });
277
+ } catch (ex) {
278
+ const axiosError = ex;
279
+ if (axiosError.isAxiosError) {
280
+ const result2 = {
281
+ http: { ipAddress: dnsResult[0] },
282
+ schema: ImageThumbnailSchema2,
283
+ sourceUrl: sourceUrl ?? url
284
+ };
285
+ if (axiosError?.response?.status !== void 0) {
286
+ result2.http = result2.http ?? {};
287
+ result2.http.status = axiosError?.response?.status;
288
+ }
289
+ if (axiosError?.code !== void 0) {
290
+ result2.http = result2.http ?? {};
291
+ result2.http.code = axiosError?.code;
292
+ }
293
+ return result2;
294
+ } else {
295
+ throw ex;
296
+ }
297
+ }
298
+ const result = {
299
+ http: { status: response.status },
300
+ schema: ImageThumbnailSchema2,
301
+ sourceUrl: sourceUrl ?? url
302
+ };
303
+ if (response.status >= 200 && response.status < 300) {
304
+ const contentType = response.headers["content-type"]?.toString();
305
+ const sourceBuffer = Buffer2.from(response.data, "binary").buffer;
306
+ return this.processMedia(sourceBuffer, result, contentType);
307
+ }
308
+ return result;
309
+ }
310
+ async processMedia(sourceBuffer, imageThumbnail, contentType) {
311
+ const [mediaType, fileType] = contentType?.split("/") ?? ["", ""];
312
+ imageThumbnail.mime = imageThumbnail.mime ?? {};
313
+ imageThumbnail.mime.returned = mediaType;
314
+ try {
315
+ imageThumbnail.mime.detected = await fileTypeFromBuffer(sourceBuffer);
316
+ } catch (ex) {
317
+ const error = ex;
318
+ this.logger?.error(`FileType error: ${error.message}`);
319
+ }
320
+ const processImage = async (encoding2) => {
321
+ imageThumbnail.sourceHash = await _ImageThumbnailWitness.binaryToSha256(sourceBuffer);
322
+ imageThumbnail.url = await this.createThumbnailDataUrl(sourceBuffer, encoding2);
323
+ };
324
+ const processVideo = async () => {
325
+ if (hasbin.sync("ffmpeg")) {
326
+ imageThumbnail.sourceHash = await _ImageThumbnailWitness.binaryToSha256(sourceBuffer);
327
+ imageThumbnail.url = await this.createThumbnailFromVideo(sourceBuffer);
328
+ } else {
329
+ imageThumbnail.mime = imageThumbnail.mime ?? {};
330
+ imageThumbnail.mime.invalid = true;
331
+ }
332
+ };
333
+ let encoding = "PNG";
334
+ switch (fileType.toUpperCase()) {
335
+ case "GIF": {
336
+ encoding = "GIF";
337
+ break;
338
+ }
339
+ case "JPG":
340
+ case "JPEG": {
341
+ encoding = "JPG";
342
+ break;
343
+ }
344
+ }
345
+ switch (mediaType) {
346
+ case "image": {
347
+ await processImage(encoding);
348
+ imageThumbnail.mime.type = mediaType;
349
+ break;
350
+ }
351
+ case "video": {
352
+ await processVideo();
353
+ imageThumbnail.mime.type = mediaType;
354
+ break;
355
+ }
356
+ default: {
357
+ const [detectedMediaType] = imageThumbnail.mime.detected?.mime?.split("/") ?? ["", ""];
358
+ switch (detectedMediaType) {
359
+ case "image": {
360
+ await processImage();
361
+ imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime;
362
+ break;
363
+ }
364
+ case "video": {
365
+ await processVideo();
366
+ imageThumbnail.mime.type = imageThumbnail.mime.detected?.mime;
367
+ break;
368
+ }
369
+ default: {
370
+ imageThumbnail.mime.invalid = true;
371
+ break;
372
+ }
373
+ }
374
+ break;
375
+ }
376
+ }
377
+ return imageThumbnail;
378
+ }
379
+ };
380
+
381
+ // src/Plugin.ts
382
+ var ImageThumbnailPlugin = () => createPayloadSetDualPlugin(
383
+ { required: { [ImageThumbnailSchema3]: 1 }, schema: PayloadSetSchema },
384
+ {
385
+ diviner: async (params) => {
386
+ const result = await ImageThumbnailDiviner.create(params);
387
+ return result;
388
+ },
389
+ witness: async (params) => {
390
+ const result = await ImageThumbnailWitness.create(params);
391
+ return result;
392
+ }
393
+ }
394
+ );
395
+
396
+ // src/index.ts
397
+ export * from "@xyo-network/diviner-image-thumbnail";
398
+ export {
399
+ ImageThumbnailPlugin,
400
+ ImageThumbnailWitness,
401
+ ImageThumbnailWitnessConfigSchema,
402
+ ImageThumbnailPlugin as default
403
+ };
404
+ //# sourceMappingURL=index.mjs.map