@xyo-network/image-thumbnail-plugin 2.99.5 → 2.99.6

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.
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __reflectGet = Reflect.get;
9
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
11
8
  var __export = (target, all) => {
12
9
  for (var name in all)
13
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -30,8 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
27
  mod
31
28
  ));
32
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
34
- var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
35
30
 
36
31
  // src/index.ts
37
32
  var src_exports = {};
@@ -56,13 +51,13 @@ var ImageThumbnailWitnessConfigSchema = `${import_image_thumbnail_payload_plugin
56
51
  // src/Witness/Witness.ts
57
52
  var import_node_buffer = require("buffer");
58
53
  var import_node_dns = require("dns");
59
- var import_axios2 = require("@xylabs/axios");
60
54
  var import_lodash = require("@xylabs/lodash");
61
55
  var import_abstract_witness = require("@xyo-network/abstract-witness");
62
56
  var import_hash = require("@xyo-network/hash");
63
57
  var import_image_thumbnail_payload_plugin2 = require("@xyo-network/image-thumbnail-payload-plugin");
64
58
  var import_url_payload_plugin = require("@xyo-network/url-payload-plugin");
65
59
  var import_async_mutex = require("async-mutex");
60
+ var import_axios2 = __toESM(require("axios"), 1);
66
61
  var import_file_type = __toESM(require("file-type"), 1);
67
62
  var import_gm = __toESM(require("gm"), 1);
68
63
  var import_hasbin = __toESM(require("hasbin"), 1);
@@ -76,8 +71,7 @@ var import_node_os = require("os");
76
71
  var import_node_stream = require("stream");
77
72
  var import_fluent_ffmpeg = __toESM(require("fluent-ffmpeg"), 1);
78
73
  var import_uuid = require("uuid");
79
- var _a;
80
- var FfmpegOutputStream = (_a = class extends import_node_stream.Writable {
74
+ var FfmpegOutputStream = class extends import_node_stream.Writable {
81
75
  chunks = [];
82
76
  constructor(options) {
83
77
  super(options);
@@ -87,18 +81,16 @@ var FfmpegOutputStream = (_a = class extends import_node_stream.Writable {
87
81
  callback();
88
82
  }
89
83
  /**
90
- * Collects the output from ffmpeg into a buffer.
91
- * @returns A buffer containing the concatenated
92
- * output from ffmpeg.
93
- */
94
- toBuffer = /* @__PURE__ */ __name(() => Buffer.concat(this.chunks), "toBuffer");
95
- }, __name(_a, "FfmpegOutputStream"), _a);
96
- var getVideoFrameAsImageFluent = /* @__PURE__ */ __name(async (videoBuffer) => {
84
+ * Collects the output from ffmpeg into a buffer.
85
+ * @returns A buffer containing the concatenated
86
+ * output from ffmpeg.
87
+ */
88
+ toBuffer = () => Buffer.concat(this.chunks);
89
+ };
90
+ var getVideoFrameAsImageFluent = async (videoBuffer) => {
97
91
  const tmpFile = `/${(0, import_node_os.tmpdir)()}/${(0, import_uuid.v4)()}`;
98
92
  try {
99
- await (0, import_promises.writeFile)(tmpFile, new Uint8Array(videoBuffer), {
100
- encoding: "binary"
101
- });
93
+ await (0, import_promises.writeFile)(tmpFile, new Uint8Array(videoBuffer), { encoding: "binary" });
102
94
  const imageBuffer = await new Promise((resolve, reject) => {
103
95
  const ffmpegOutput = new FfmpegOutputStream();
104
96
  (0, import_fluent_ffmpeg.default)().on("error", (err) => reject(err.message)).on("end", () => resolve(ffmpegOutput.toBuffer())).input(tmpFile).takeFrames(1).withNoAudio().outputOptions("-f image2pipe").videoCodec("png").pipe(ffmpegOutput);
@@ -110,12 +102,12 @@ var getVideoFrameAsImageFluent = /* @__PURE__ */ __name(async (videoBuffer) => {
110
102
  } catch {
111
103
  }
112
104
  }
113
- }, "getVideoFrameAsImageFluent");
105
+ };
114
106
 
115
107
  // src/Witness/lib/checkIpfsUrl.ts
116
108
  var import_assert = require("@xylabs/assert");
117
109
  var allowIpfsIoRepair = true;
118
- var checkIpfsUrl = /* @__PURE__ */ __name((urlToCheck, ipfsGateway) => {
110
+ var checkIpfsUrl = (urlToCheck, ipfsGateway) => {
119
111
  try {
120
112
  const url = new URL(urlToCheck);
121
113
  let protocol = url.protocol;
@@ -144,19 +136,19 @@ var checkIpfsUrl = /* @__PURE__ */ __name((urlToCheck, ipfsGateway) => {
144
136
  } catch {
145
137
  return urlToCheck;
146
138
  }
147
- }, "checkIpfsUrl");
139
+ };
148
140
 
149
141
  // src/Witness/lib/createDataUrl.ts
150
142
  var import_base64_js = require("base64-js");
151
- var createDataUrl = /* @__PURE__ */ __name((data, contextType, encoding = "base64") => {
143
+ var createDataUrl = (data, contextType, encoding = "base64") => {
152
144
  return `data:${contextType};${encoding},${(0, import_base64_js.fromByteArray)(new Uint8Array(data))}`;
153
- }, "createDataUrl");
145
+ };
154
146
 
155
147
  // src/Witness/lib/resolveDynamicSvg.ts
156
- var import_axios = require("@xylabs/axios");
148
+ var import_axios = __toESM(require("axios"), 1);
157
149
  var import_base64_js2 = require("base64-js");
158
150
  var import_xml2js = require("xml2js");
159
- var resolveDynamicSvg = /* @__PURE__ */ __name(async (base64Bytes) => {
151
+ var resolveDynamicSvg = async (base64Bytes) => {
160
152
  const decoder = new TextDecoder();
161
153
  const bytes = (0, import_base64_js2.toByteArray)(base64Bytes);
162
154
  const svg = decoder.decode(bytes);
@@ -166,44 +158,30 @@ var resolveDynamicSvg = /* @__PURE__ */ __name(async (base64Bytes) => {
166
158
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
159
  svgNode["image"].map(async (img) => [
168
160
  img.$,
169
- await import_axios.axios.get(img.$.href, {
161
+ await import_axios.default.get(img.$.href, {
170
162
  responseType: "arraybuffer"
171
163
  })
172
164
  ])
173
165
  );
174
166
  const image = imageResults.map(([href, response]) => {
175
- var _a2;
167
+ var _a;
176
168
  if (response.data) {
177
169
  const sourceBuffer = Buffer.from(response.data, "binary");
178
- return {
179
- $: {
180
- href: `data:${(_a2 = response.headers["content-type"]) == null ? void 0 : _a2.toString()};base64,${sourceBuffer.toString("base64")}`
181
- }
182
- };
170
+ return { $: { href: `data:${(_a = response.headers["content-type"]) == null ? void 0 : _a.toString()};base64,${sourceBuffer.toString("base64")}` } };
183
171
  } else {
184
- return {
185
- $: {
186
- href
187
- }
188
- };
172
+ return { $: { href } };
189
173
  }
190
174
  });
191
- const updatedSVG = {
192
- ...svgObj,
193
- svg: {
194
- ...svgNode,
195
- image
196
- }
197
- };
175
+ const updatedSVG = { ...svgObj, svg: { ...svgNode, image } };
198
176
  const builder = new import_xml2js.Builder();
199
177
  return builder.buildObject(updatedSVG);
200
- }, "resolveDynamicSvg");
178
+ };
201
179
 
202
180
  // src/Witness/Witness.ts
203
- var gm = import_gm.default.subClass({
204
- imageMagick: "7+"
205
- });
206
- var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract_witness.AbstractWitness {
181
+ var gm = import_gm.default.subClass({ imageMagick: "7+" });
182
+ var ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract_witness.AbstractWitness {
183
+ static configSchemas = [...super.configSchemas, ImageThumbnailWitnessConfigSchema];
184
+ static defaultConfigSchema = ImageThumbnailWitnessConfigSchema;
207
185
  _semaphore = new import_async_mutex.Semaphore(this.maxAsyncProcesses);
208
186
  get encoding() {
209
187
  return this.config.encoding ?? "PNG";
@@ -255,42 +233,50 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
255
233
  throw new Error("ImageMagick is required for this witness");
256
234
  }
257
235
  const urlPayloads = payloads.filter((payload) => payload.schema === import_url_payload_plugin.UrlSchema);
258
- const process = /* @__PURE__ */ __name(async () => {
259
- return (0, import_lodash.compact)(await Promise.all(urlPayloads.map(async ({ url }) => {
260
- let result;
261
- const dataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(url);
262
- if (dataBuffer) {
263
- if (this.config.dataUrlPassthrough) {
264
- result = {
265
- schema: import_image_thumbnail_payload_plugin2.ImageThumbnailSchema,
266
- sourceHash: await _ImageThumbnailWitness.binaryToSha256(dataBuffer),
267
- sourceUrl: url,
268
- url
269
- };
270
- } else {
271
- let cookedDataBuffer = dataBuffer;
272
- const urlParts = url.split(";");
273
- const [, contentType] = urlParts[0].split(":");
274
- if (contentType.startsWith("image/svg")) {
275
- const [encoding, byteString] = urlParts[1].split(",");
276
- if (encoding === "base64") {
277
- const newSvg = await resolveDynamicSvg(byteString);
278
- const newSvgDataUrl = createDataUrl(import_node_buffer.Buffer.from(newSvg), contentType);
279
- cookedDataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(newSvgDataUrl) ?? dataBuffer;
236
+ const process = async () => {
237
+ return (0, import_lodash.compact)(
238
+ await Promise.all(
239
+ urlPayloads.map(async ({ url }) => {
240
+ let result;
241
+ const dataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(url);
242
+ if (dataBuffer) {
243
+ if (this.config.dataUrlPassthrough) {
244
+ result = {
245
+ schema: import_image_thumbnail_payload_plugin2.ImageThumbnailSchema,
246
+ sourceHash: await _ImageThumbnailWitness.binaryToSha256(dataBuffer),
247
+ sourceUrl: url,
248
+ url
249
+ };
250
+ } else {
251
+ let cookedDataBuffer = dataBuffer;
252
+ const urlParts = url.split(";");
253
+ const [, contentType] = urlParts[0].split(":");
254
+ if (contentType.startsWith("image/svg")) {
255
+ const [encoding, byteString] = urlParts[1].split(",");
256
+ if (encoding === "base64") {
257
+ const newSvg = await resolveDynamicSvg(byteString);
258
+ const newSvgDataUrl = createDataUrl(import_node_buffer.Buffer.from(newSvg), contentType);
259
+ cookedDataBuffer = _ImageThumbnailWitness.bufferFromDataUrl(newSvgDataUrl) ?? dataBuffer;
260
+ }
261
+ }
262
+ result = await this.processMedia(
263
+ cookedDataBuffer,
264
+ {
265
+ schema: import_image_thumbnail_payload_plugin2.ImageThumbnailSchema,
266
+ sourceUrl: url
267
+ },
268
+ contentType
269
+ );
280
270
  }
271
+ } else {
272
+ const mutatedUrl = checkIpfsUrl(url, this.ipfsGateway);
273
+ result = await this.fromHttp(mutatedUrl, url);
281
274
  }
282
- result = await this.processMedia(cookedDataBuffer, {
283
- schema: import_image_thumbnail_payload_plugin2.ImageThumbnailSchema,
284
- sourceUrl: url
285
- }, contentType);
286
- }
287
- } else {
288
- const mutatedUrl = checkIpfsUrl(url, this.ipfsGateway);
289
- result = await this.fromHttp(mutatedUrl, url);
290
- }
291
- return result;
292
- })));
293
- }, "process");
275
+ return result;
276
+ })
277
+ )
278
+ );
279
+ };
294
280
  return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process();
295
281
  }
296
282
  async createThumbnailDataUrl(sourceBuffer, encoding) {
@@ -306,17 +292,17 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
306
292
  return createDataUrl(thumb, "image/png");
307
293
  }
308
294
  /**
309
- * Creates an image thumbnail from a video.
310
- * @param videoBuffer The input video buffer.
311
- * @returns An buffer containing an image thumbnail for the video.
312
- */
295
+ * Creates an image thumbnail from a video.
296
+ * @param videoBuffer The input video buffer.
297
+ * @returns An buffer containing an image thumbnail for the video.
298
+ */
313
299
  async createThumbnailFromVideo(videoBuffer) {
314
300
  const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer);
315
301
  return this.createThumbnailDataUrl(imageBuffer);
316
302
  }
317
303
  // eslint-disable-next-line complexity
318
304
  async fromHttp(url, sourceUrl) {
319
- var _a2, _b, _c;
305
+ var _a, _b, _c;
320
306
  let response;
321
307
  let dnsResult;
322
308
  try {
@@ -334,7 +320,7 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
334
320
  return result2;
335
321
  }
336
322
  try {
337
- response = await import_axios2.axios.get(url, {
323
+ response = await import_axios2.default.get(url, {
338
324
  responseType: "arraybuffer"
339
325
  });
340
326
  } catch (ex) {
@@ -347,7 +333,7 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
347
333
  schema: import_image_thumbnail_payload_plugin2.ImageThumbnailSchema,
348
334
  sourceUrl: sourceUrl ?? url
349
335
  };
350
- if (((_a2 = axiosError == null ? void 0 : axiosError.response) == null ? void 0 : _a2.status) !== void 0) {
336
+ if (((_a = axiosError == null ? void 0 : axiosError.response) == null ? void 0 : _a.status) !== void 0) {
351
337
  result2.http = result2.http ?? {};
352
338
  result2.http.status = (_b = axiosError == null ? void 0 : axiosError.response) == null ? void 0 : _b.status;
353
339
  }
@@ -375,24 +361,21 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
375
361
  return result;
376
362
  }
377
363
  async processMedia(sourceBuffer, imageThumbnail, contentType) {
378
- var _a2, _b, _c, _d, _e;
379
- const [mediaType, fileType] = (contentType == null ? void 0 : contentType.split("/")) ?? [
380
- "",
381
- ""
382
- ];
364
+ var _a, _b, _c, _d, _e;
365
+ const [mediaType, fileType] = (contentType == null ? void 0 : contentType.split("/")) ?? ["", ""];
383
366
  imageThumbnail.mime = imageThumbnail.mime ?? {};
384
367
  imageThumbnail.mime.returned = mediaType;
385
368
  try {
386
369
  imageThumbnail.mime.detected = await import_file_type.default.fromBuffer(sourceBuffer);
387
370
  } catch (ex) {
388
371
  const error = ex;
389
- (_a2 = this.logger) == null ? void 0 : _a2.error(`FileType error: ${error.message}`);
372
+ (_a = this.logger) == null ? void 0 : _a.error(`FileType error: ${error.message}`);
390
373
  }
391
- const processImage = /* @__PURE__ */ __name(async (encoding2) => {
374
+ const processImage = async (encoding2) => {
392
375
  imageThumbnail.sourceHash = await _ImageThumbnailWitness.binaryToSha256(sourceBuffer);
393
376
  imageThumbnail.url = await this.createThumbnailDataUrl(sourceBuffer, encoding2);
394
- }, "processImage");
395
- const processVideo = /* @__PURE__ */ __name(async () => {
377
+ };
378
+ const processVideo = async () => {
396
379
  if (import_hasbin.default.sync("ffmpeg")) {
397
380
  imageThumbnail.sourceHash = await _ImageThumbnailWitness.binaryToSha256(sourceBuffer);
398
381
  imageThumbnail.url = await this.createThumbnailFromVideo(sourceBuffer);
@@ -400,7 +383,7 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
400
383
  imageThumbnail.mime = imageThumbnail.mime ?? {};
401
384
  imageThumbnail.mime.invalid = true;
402
385
  }
403
- }, "processVideo");
386
+ };
404
387
  let encoding = "PNG";
405
388
  switch (fileType.toUpperCase()) {
406
389
  case "GIF": {
@@ -425,10 +408,7 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
425
408
  break;
426
409
  }
427
410
  default: {
428
- const [detectedMediaType] = ((_c = (_b = imageThumbnail.mime.detected) == null ? void 0 : _b.mime) == null ? void 0 : _c.split("/")) ?? [
429
- "",
430
- ""
431
- ];
411
+ const [detectedMediaType] = ((_c = (_b = imageThumbnail.mime.detected) == null ? void 0 : _b.mime) == null ? void 0 : _c.split("/")) ?? ["", ""];
432
412
  switch (detectedMediaType) {
433
413
  case "image": {
434
414
  await processImage();
@@ -451,30 +431,21 @@ var _ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstrac
451
431
  return imageThumbnail;
452
432
  }
453
433
  };
454
- __name(_ImageThumbnailWitness, "ImageThumbnailWitness");
455
- __publicField(_ImageThumbnailWitness, "configSchemas", [
456
- ...__superGet(_ImageThumbnailWitness, _ImageThumbnailWitness, "configSchemas"),
457
- ImageThumbnailWitnessConfigSchema
458
- ]);
459
- __publicField(_ImageThumbnailWitness, "defaultConfigSchema", ImageThumbnailWitnessConfigSchema);
460
- var ImageThumbnailWitness = _ImageThumbnailWitness;
461
434
 
462
435
  // src/Plugin.ts
463
- var ImageThumbnailPlugin = /* @__PURE__ */ __name(() => (0, import_payloadset_plugin.createPayloadSetDualPlugin)({
464
- required: {
465
- [import_image_thumbnail_payload_plugin3.ImageThumbnailSchema]: 1
466
- },
467
- schema: import_payload_model.PayloadSetSchema
468
- }, {
469
- diviner: /* @__PURE__ */ __name(async (params) => {
470
- const result = await import_diviner_image_thumbnail.ImageThumbnailDiviner.create(params);
471
- return result;
472
- }, "diviner"),
473
- witness: /* @__PURE__ */ __name(async (params) => {
474
- const result = await ImageThumbnailWitness.create(params);
475
- return result;
476
- }, "witness")
477
- }), "ImageThumbnailPlugin");
436
+ var ImageThumbnailPlugin = () => (0, import_payloadset_plugin.createPayloadSetDualPlugin)(
437
+ { required: { [import_image_thumbnail_payload_plugin3.ImageThumbnailSchema]: 1 }, schema: import_payload_model.PayloadSetSchema },
438
+ {
439
+ diviner: async (params) => {
440
+ const result = await import_diviner_image_thumbnail.ImageThumbnailDiviner.create(params);
441
+ return result;
442
+ },
443
+ witness: async (params) => {
444
+ const result = await ImageThumbnailWitness.create(params);
445
+ return result;
446
+ }
447
+ }
448
+ );
478
449
 
479
450
  // src/index.ts
480
451
  __reExport(src_exports, require("@xyo-network/diviner-image-thumbnail"), module.exports);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../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"],"sourcesContent":["// eslint-disable-next-line import/no-default-export\nexport { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin.ts'\nexport * from './Witness/index.ts'\nexport * from '@xyo-network/diviner-image-thumbnail'\n","import { ImageThumbnailDiviner } from '@xyo-network/diviner-image-thumbnail'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetDualPlugin } from '@xyo-network/payloadset-plugin'\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 { WitnessConfig } from '@xyo-network/witness-model'\n\nexport const ImageThumbnailWitnessConfigSchema = `${ImageThumbnailSchema}.witness.config` as const\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 { axios, AxiosError, AxiosResponse } from '@xylabs/axios'\nimport { compact } from '@xylabs/lodash'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { ImageThumbnail, ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { Schema } from '@xyo-network/payload-model'\nimport { UrlPayload, UrlSchema } from '@xyo-network/url-payload-plugin'\nimport { Semaphore } from 'async-mutex'\nimport FileType from 'file-type'\nimport graphicsMagick from 'gm'\nimport hasbin from 'hasbin'\nimport { sha256 } from 'hash-wasm'\nimport shajs from 'sha.js'\nimport Url from 'url-parse'\n\nimport { ImageThumbnailEncoding, ImageThumbnailWitnessConfigSchema } from './Config.ts'\nimport { getVideoFrameAsImageFluent } from './ffmpeg/index.ts'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib/index.ts'\nimport { 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: ArrayBuffer) {\n const viewData = new Uint8Array(data)\n await PayloadHasher.wasmInitialized\n if (PayloadHasher.wasmSupport.canUseWasm) {\n try {\n return await sha256(viewData)\n } catch {\n PayloadHasher.wasmSupport.allowWasm = false\n }\n }\n\n return shajs('sha256').update(viewData).digest().toString()\n }\n\n private static bufferFromDataUrl(url: string): ArrayBuffer | 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)\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 compact(\n 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), 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 ),\n )\n }\n return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process()\n }\n\n private async createThumbnailDataUrl(sourceBuffer: ArrayBuffer, 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, '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: ArrayBuffer) {\n const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer)\n return this.createThumbnailDataUrl(imageBuffer)\n }\n\n // eslint-disable-next-line complexity\n private async fromHttp(url: string, sourceUrl?: string): Promise<ImageThumbnail> {\n let response: AxiosResponse\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: {\n code: error.code,\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n return result\n }\n try {\n response = await axios.get(url, {\n responseType: 'arraybuffer',\n })\n } catch (ex) {\n const axiosError = ex as AxiosError\n if (axiosError.isAxiosError) {\n // selectively pick fields from AxiosError\n const result: ImageThumbnail = {\n http: {\n ipAddress: dnsResult[0],\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n if (axiosError?.response?.status !== undefined) {\n result.http = result.http ?? {}\n result.http.status = axiosError?.response?.status\n }\n if (axiosError?.code !== undefined) {\n result.http = result.http ?? {}\n result.http.code = axiosError?.code\n }\n return result\n } else {\n throw ex\n }\n }\n\n const result: ImageThumbnail = {\n http: {\n status: response.status,\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n\n if (response.status >= 200 && response.status < 300) {\n const contentType: string | undefined = response.headers['content-type']?.toString()\n const sourceBuffer = Buffer.from(response.data, 'binary')\n\n return this.processMedia(sourceBuffer, result, contentType)\n }\n return result\n }\n\n private async processMedia(sourceBuffer: ArrayBuffer, 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 FileType.fromBuffer(sourceBuffer)\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 { Writable, WritableOptions } 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: ArrayBuffer) => {\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 // NOTE: Uncomment to debug CLI args to ffmpeg\n // .on('start', (commandLine) => console.log('Spawned Ffmpeg with command: ' + commandLine))\n .on('error', err => reject(err.message))\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/assert'\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: ArrayBuffer, contextType: string, encoding: 'base64' = 'base64') => {\n return `data:${contextType};${encoding},${fromByteArray(new Uint8Array(data))}`\n}\n","import { axios, AxiosResponse } from '@xylabs/axios'\nimport { toByteArray } from 'base64-js'\nimport { Builder, parseStringPromise } from 'xml2js'\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 = (await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgNode['image'].map(async (img: any) => [\n img.$,\n await axios.get(img.$.href, {\n responseType: 'arraybuffer',\n }),\n ]),\n )) as [string, AxiosResponse][]\n const image = imageResults.map(([href, response]) => {\n if (response.data) {\n const sourceBuffer = Buffer.from(response.data, 'binary')\n return { $: { href: `data:${response.headers['content-type']?.toString()};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"],"mappings":"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","names":["import_image_thumbnail_payload_plugin","ImageThumbnailWitnessConfigSchema","ImageThumbnailSchema","import_axios","import_image_thumbnail_payload_plugin","FfmpegOutputStream","Writable","chunks","constructor","options","_write","chunk","_encoding","callback","push","toBuffer","Buffer","concat","getVideoFrameAsImageFluent","videoBuffer","tmpFile","tmpdir","uuid","writeFile","Uint8Array","encoding","imageBuffer","Promise","resolve","reject","ffmpegOutput","ffmpeg","on","err","message","input","takeFrames","withNoAudio","outputOptions","videoCodec","pipe","unlink","allowIpfsIoRepair","checkIpfsUrl","urlToCheck","ipfsGateway","url","URL","protocol","host","path","pathname","query","search","assertEx","root","length","pathParts","split","shift","join","createDataUrl","data","contextType","encoding","fromByteArray","Uint8Array","import_base64_js","resolveDynamicSvg","base64Bytes","decoder","TextDecoder","bytes","toByteArray","svg","decode","svgObj","parseStringPromise","svgNode","imageResults","Promise","all","map","img","$","axios","get","href","responseType","image","response","_a","data","sourceBuffer","Buffer","from","headers","toString","updatedSVG","builder","Builder","buildObject","gm","graphicsMagick","subClass","imageMagick","ImageThumbnailWitness","AbstractWitness","_semaphore","Semaphore","maxAsyncProcesses","encoding","config","height","ipfsGateway","quality","width","binaryToSha256","data","viewData","Uint8Array","PayloadHasher","wasmInitialized","wasmSupport","canUseWasm","sha256","allowWasm","shajs","update","digest","toString","bufferFromDataUrl","url","startsWith","split","from","atob","c","codePointAt","error","message","name","observeHandler","payloads","hasbin","sync","Error","urlPayloads","filter","payload","schema","UrlSchema","process","compact","Promise","all","map","result","dataBuffer","dataUrlPassthrough","ImageThumbnailSchema","sourceHash","sourceUrl","cookedDataBuffer","urlParts","contentType","byteString","newSvg","resolveDynamicSvg","newSvgDataUrl","createDataUrl","Buffer","processMedia","mutatedUrl","checkIpfsUrl","fromHttp","runExclusive","createThumbnailDataUrl","sourceBuffer","thumb","resolve","reject","resize","flatten","toBuffer","buffer","createThumbnailFromVideo","videoBuffer","imageBuffer","getVideoFrameAsImageFluent","_a","response","dnsResult","urlObj","Url","dnsPromises","host","ex","http","code","axios","get","responseType","axiosError","isAxiosError","ipAddress","status","undefined","headers","imageThumbnail","mediaType","fileType","mime","returned","detected","FileType","fromBuffer","logger","processImage","processVideo","invalid","toUpperCase","type","detectedMediaType","configSchemas","ImageThumbnailWitnessConfigSchema","defaultConfigSchema","ImageThumbnailPlugin","createPayloadSetDualPlugin","required","ImageThumbnailSchema","schema","PayloadSetSchema","diviner","params","result","ImageThumbnailDiviner","create","witness","ImageThumbnailWitness"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../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"],"sourcesContent":["// eslint-disable-next-line import/no-default-export\nexport { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin.ts'\nexport * from './Witness/index.ts'\nexport * from '@xyo-network/diviner-image-thumbnail'\n","import { ImageThumbnailDiviner } from '@xyo-network/diviner-image-thumbnail'\nimport { ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { PayloadSetSchema } from '@xyo-network/payload-model'\nimport { createPayloadSetDualPlugin } from '@xyo-network/payloadset-plugin'\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 { WitnessConfig } from '@xyo-network/witness-model'\n\nexport const ImageThumbnailWitnessConfigSchema = `${ImageThumbnailSchema}.witness.config` as const\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 { compact } from '@xylabs/lodash'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { ImageThumbnail, ImageThumbnailSchema } from '@xyo-network/image-thumbnail-payload-plugin'\nimport { Schema } from '@xyo-network/payload-model'\nimport { UrlPayload, UrlSchema } from '@xyo-network/url-payload-plugin'\nimport { Semaphore } from 'async-mutex'\nimport type { AxiosError, AxiosResponse } from 'axios'\nimport axios from 'axios'\nimport FileType from 'file-type'\nimport graphicsMagick from 'gm'\nimport hasbin from 'hasbin'\nimport { sha256 } from 'hash-wasm'\nimport shajs from 'sha.js'\nimport Url from 'url-parse'\n\nimport { ImageThumbnailEncoding, ImageThumbnailWitnessConfigSchema } from './Config.ts'\nimport { getVideoFrameAsImageFluent } from './ffmpeg/index.ts'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib/index.ts'\nimport { 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: ArrayBuffer) {\n const viewData = new Uint8Array(data)\n await PayloadHasher.wasmInitialized\n if (PayloadHasher.wasmSupport.canUseWasm) {\n try {\n return await sha256(viewData)\n } catch {\n PayloadHasher.wasmSupport.allowWasm = false\n }\n }\n\n return shajs('sha256').update(viewData).digest().toString()\n }\n\n private static bufferFromDataUrl(url: string): ArrayBuffer | 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)\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 compact(\n 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), 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 ),\n )\n }\n return this.config.runExclusive ? await this._semaphore.runExclusive(() => process()) : process()\n }\n\n private async createThumbnailDataUrl(sourceBuffer: ArrayBuffer, 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, '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: ArrayBuffer) {\n const imageBuffer = await getVideoFrameAsImageFluent(videoBuffer)\n return this.createThumbnailDataUrl(imageBuffer)\n }\n\n // eslint-disable-next-line complexity\n private async fromHttp(url: string, sourceUrl?: string): Promise<ImageThumbnail> {\n let response: AxiosResponse\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: {\n code: error.code,\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n return result\n }\n try {\n response = await axios.get(url, {\n responseType: 'arraybuffer',\n })\n } catch (ex) {\n const axiosError = ex as AxiosError\n if (axiosError.isAxiosError) {\n // selectively pick fields from AxiosError\n const result: ImageThumbnail = {\n http: {\n ipAddress: dnsResult[0],\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n if (axiosError?.response?.status !== undefined) {\n result.http = result.http ?? {}\n result.http.status = axiosError?.response?.status\n }\n if (axiosError?.code !== undefined) {\n result.http = result.http ?? {}\n result.http.code = axiosError?.code\n }\n return result\n } else {\n throw ex\n }\n }\n\n const result: ImageThumbnail = {\n http: {\n status: response.status,\n },\n schema: ImageThumbnailSchema,\n sourceUrl: sourceUrl ?? url,\n }\n\n if (response.status >= 200 && response.status < 300) {\n const contentType: string | undefined = response.headers['content-type']?.toString()\n const sourceBuffer = Buffer.from(response.data, 'binary')\n\n return this.processMedia(sourceBuffer, result, contentType)\n }\n return result\n }\n\n private async processMedia(sourceBuffer: ArrayBuffer, 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 FileType.fromBuffer(sourceBuffer)\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 { Writable, WritableOptions } 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: ArrayBuffer) => {\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 // NOTE: Uncomment to debug CLI args to ffmpeg\n // .on('start', (commandLine) => console.log('Spawned Ffmpeg with command: ' + commandLine))\n .on('error', err => reject(err.message))\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/assert'\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: ArrayBuffer, contextType: string, encoding: 'base64' = 'base64') => {\n return `data:${contextType};${encoding},${fromByteArray(new Uint8Array(data))}`\n}\n","import axios, { AxiosResponse } from 'axios'\nimport { toByteArray } from 'base64-js'\nimport { Builder, parseStringPromise } from 'xml2js'\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 = (await Promise.all(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n svgNode['image'].map(async (img: any) => [\n img.$,\n await axios.get(img.$.href, {\n responseType: 'arraybuffer',\n }),\n ]),\n )) as [string, AxiosResponse][]\n const image = imageResults.map(([href, response]) => {\n if (response.data) {\n const sourceBuffer = Buffer.from(response.data, 'binary')\n return { $: { href: `data:${response.headers['content-type']?.toString()};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"],"mappings":"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","names":["import_image_thumbnail_payload_plugin","import_image_thumbnail_payload_plugin","import_axios","uuid","ffmpeg","import_base64_js","axios","graphicsMagick","shajs","hasbin","Url","dnsPromises","result","axios","FileType","encoding"]}