@xyo-network/image-thumbnail-plugin 2.84.5 → 2.85.1
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/dist/node/Plugin.d.cts +0 -3
- package/dist/node/Plugin.d.cts.map +1 -1
- package/dist/node/Plugin.d.mts +0 -3
- package/dist/node/Plugin.d.mts.map +1 -1
- package/dist/node/Plugin.d.ts +0 -3
- package/dist/node/Plugin.d.ts.map +1 -1
- package/dist/node/Witness/Witness.d.cts.map +1 -1
- package/dist/node/Witness/Witness.d.mts.map +1 -1
- package/dist/node/Witness/Witness.d.ts.map +1 -1
- package/dist/node/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.d.cts.map +1 -1
- package/dist/node/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.d.mts.map +1 -1
- package/dist/node/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.d.ts.map +1 -1
- package/dist/node/index.d.cts +1 -3
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.mts +1 -3
- package/dist/node/index.d.mts.map +1 -1
- package/dist/node/index.d.ts +1 -3
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +14 -13
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +12 -11
- package/dist/node/index.mjs.map +1 -1
- package/package.json +19 -19
- package/src/Witness/Witness.ts +7 -5
- package/src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts +4 -3
- package/src/Witness/ffmpeg/spawn/executeFfmpeg.ts +4 -4
- package/src/Witness/lib/checkIpfsUrl.ts +1 -1
- package/src/index.ts +1 -7
package/dist/node/Plugin.d.cts
CHANGED
|
@@ -3,7 +3,6 @@ import { ImageThumbnailWitness } from './Witness';
|
|
|
3
3
|
export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset-plugin").PayloadSetDualPlugin<ImageThumbnailWitness<import("@xyo-network/object").BaseParamsFields & {
|
|
4
4
|
account?: import("@xyo-network/account-model").AccountInstance | "random" | undefined;
|
|
5
5
|
config: import("@xyo-network/payload-model").SchemaFields & object & Omit<{
|
|
6
|
-
accountDerivationPath?: string | undefined;
|
|
7
6
|
readonly archivist?: string | undefined;
|
|
8
7
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
9
8
|
readonly name?: string | undefined;
|
|
@@ -20,7 +19,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
20
19
|
readonly storeQueries?: boolean | undefined;
|
|
21
20
|
readonly timestamp?: boolean | undefined;
|
|
22
21
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & import("@xyo-network/payload-model").SchemaFields & object & {
|
|
23
|
-
accountDerivationPath?: string | undefined;
|
|
24
22
|
readonly archivist?: string | undefined;
|
|
25
23
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
26
24
|
readonly name?: string | undefined;
|
|
@@ -54,7 +52,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
54
52
|
schema: string;
|
|
55
53
|
};
|
|
56
54
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
57
|
-
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
58
55
|
} & {
|
|
59
56
|
loaders?: string[] | undefined;
|
|
60
57
|
}>, ImageThumbnailDiviner>;
|
|
@@ -1 +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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB
|
|
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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAa9B,CAAA"}
|
package/dist/node/Plugin.d.mts
CHANGED
|
@@ -3,7 +3,6 @@ import { ImageThumbnailWitness } from './Witness';
|
|
|
3
3
|
export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset-plugin").PayloadSetDualPlugin<ImageThumbnailWitness<import("@xyo-network/object").BaseParamsFields & {
|
|
4
4
|
account?: import("@xyo-network/account-model").AccountInstance | "random" | undefined;
|
|
5
5
|
config: import("@xyo-network/payload-model").SchemaFields & object & Omit<{
|
|
6
|
-
accountDerivationPath?: string | undefined;
|
|
7
6
|
readonly archivist?: string | undefined;
|
|
8
7
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
9
8
|
readonly name?: string | undefined;
|
|
@@ -20,7 +19,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
20
19
|
readonly storeQueries?: boolean | undefined;
|
|
21
20
|
readonly timestamp?: boolean | undefined;
|
|
22
21
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & import("@xyo-network/payload-model").SchemaFields & object & {
|
|
23
|
-
accountDerivationPath?: string | undefined;
|
|
24
22
|
readonly archivist?: string | undefined;
|
|
25
23
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
26
24
|
readonly name?: string | undefined;
|
|
@@ -54,7 +52,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
54
52
|
schema: string;
|
|
55
53
|
};
|
|
56
54
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
57
|
-
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
58
55
|
} & {
|
|
59
56
|
loaders?: string[] | undefined;
|
|
60
57
|
}>, ImageThumbnailDiviner>;
|
|
@@ -1 +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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB
|
|
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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAa9B,CAAA"}
|
package/dist/node/Plugin.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { ImageThumbnailWitness } from './Witness';
|
|
|
3
3
|
export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset-plugin").PayloadSetDualPlugin<ImageThumbnailWitness<import("@xyo-network/object").BaseParamsFields & {
|
|
4
4
|
account?: import("@xyo-network/account-model").AccountInstance | "random" | undefined;
|
|
5
5
|
config: import("@xyo-network/payload-model").SchemaFields & object & Omit<{
|
|
6
|
-
accountDerivationPath?: string | undefined;
|
|
7
6
|
readonly archivist?: string | undefined;
|
|
8
7
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
9
8
|
readonly name?: string | undefined;
|
|
@@ -20,7 +19,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
20
19
|
readonly storeQueries?: boolean | undefined;
|
|
21
20
|
readonly timestamp?: boolean | undefined;
|
|
22
21
|
} & import("@xyo-network/module-model").ArchivingModuleConfig & import("@xyo-network/payload-model").SchemaFields & object & {
|
|
23
|
-
accountDerivationPath?: string | undefined;
|
|
24
22
|
readonly archivist?: string | undefined;
|
|
25
23
|
readonly labels?: import("@xyo-network/module-model").Labels | undefined;
|
|
26
24
|
readonly name?: string | undefined;
|
|
@@ -54,7 +52,6 @@ export declare const ImageThumbnailPlugin: () => import("@xyo-network/payloadset
|
|
|
54
52
|
schema: string;
|
|
55
53
|
};
|
|
56
54
|
ephemeralQueryAccountEnabled?: boolean | undefined;
|
|
57
|
-
wallet?: import("@xyo-network/wallet-model").WalletInstance | undefined;
|
|
58
55
|
} & {
|
|
59
56
|
loaders?: string[] | undefined;
|
|
60
57
|
}>, ImageThumbnailDiviner>;
|
|
@@ -1 +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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB
|
|
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,WAAW,CAAA;AAEjD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAa9B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;CA6E3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;CA6E3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;
|
|
1
|
+
{"version":3,"file":"Witness.d.ts","sourceRoot":"","sources":["../../../src/Witness/Witness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAwB,MAAM,6CAA6C,CAAA;AAClG,OAAO,EAAE,UAAU,EAAa,MAAM,iCAAiC,CAAA;AASvE,OAAO,EAAE,sBAAsB,EAAqC,MAAM,UAAU,CAAA;AAGpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAStD,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,OAAgB,aAAa,iDAAsC;IAEnE,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;YAyDjF,sBAAsB;IAiBpC;;;;OAIG;YACW,wBAAwB;YAMxB,QAAQ;YA+DR,YAAY;CA6E3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";AA8BA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,gBAAuB,WAAW,oBAoCxE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";AA8BA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,gBAAuB,WAAW,oBAoCxE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"getVideoFrameAsImageFluent.d.ts","sourceRoot":"","sources":["../../../../../src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts"],"names":[],"mappings":";AA8BA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,gBAAuB,WAAW,oBAoCxE,CAAA"}
|
package/dist/node/index.d.cts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin';
|
|
2
2
|
export * from './Witness';
|
|
3
3
|
export * from '@xyo-network/diviner-image-thumbnail';
|
|
4
|
-
export { ImageThumbnailPlugin };
|
|
5
|
-
export default ImageThumbnailPlugin;
|
|
6
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,IAAI,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAChF,cAAc,WAAW,CAAA;AACzB,cAAc,sCAAsC,CAAA"}
|
package/dist/node/index.d.mts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin';
|
|
2
2
|
export * from './Witness';
|
|
3
3
|
export * from '@xyo-network/diviner-image-thumbnail';
|
|
4
|
-
export { ImageThumbnailPlugin };
|
|
5
|
-
export default ImageThumbnailPlugin;
|
|
6
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,IAAI,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAChF,cAAc,WAAW,CAAA;AACzB,cAAc,sCAAsC,CAAA"}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin';
|
|
2
2
|
export * from './Witness';
|
|
3
3
|
export * from '@xyo-network/diviner-image-thumbnail';
|
|
4
|
-
export { ImageThumbnailPlugin };
|
|
5
|
-
export default ImageThumbnailPlugin;
|
|
6
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,IAAI,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAChF,cAAc,WAAW,CAAA;AACzB,cAAc,sCAAsC,CAAA"}
|
package/dist/node/index.js
CHANGED
|
@@ -34,7 +34,7 @@ __export(src_exports, {
|
|
|
34
34
|
ImageThumbnailPlugin: () => ImageThumbnailPlugin,
|
|
35
35
|
ImageThumbnailWitness: () => ImageThumbnailWitness,
|
|
36
36
|
ImageThumbnailWitnessConfigSchema: () => ImageThumbnailWitnessConfigSchema,
|
|
37
|
-
default: () =>
|
|
37
|
+
default: () => ImageThumbnailPlugin
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(src_exports);
|
|
40
40
|
|
|
@@ -66,12 +66,12 @@ var import_sha = __toESM(require("sha.js"));
|
|
|
66
66
|
var import_url_parse = __toESM(require("url-parse"));
|
|
67
67
|
|
|
68
68
|
// src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts
|
|
69
|
-
var import_fluent_ffmpeg = __toESM(require("fluent-ffmpeg"));
|
|
70
69
|
var import_promises = require("fs/promises");
|
|
71
|
-
var
|
|
72
|
-
var
|
|
70
|
+
var import_node_os = require("os");
|
|
71
|
+
var import_node_stream = require("stream");
|
|
72
|
+
var import_fluent_ffmpeg = __toESM(require("fluent-ffmpeg"));
|
|
73
73
|
var import_uuid = require("uuid");
|
|
74
|
-
var FfmpegOutputStream = class extends
|
|
74
|
+
var FfmpegOutputStream = class extends import_node_stream.Writable {
|
|
75
75
|
chunks = [];
|
|
76
76
|
constructor(options) {
|
|
77
77
|
super(options);
|
|
@@ -88,7 +88,7 @@ var FfmpegOutputStream = class extends import_stream.Writable {
|
|
|
88
88
|
toBuffer = () => Buffer.concat(this.chunks);
|
|
89
89
|
};
|
|
90
90
|
var getVideoFrameAsImageFluent = async (videoBuffer) => {
|
|
91
|
-
const tmpFile = `/${(0,
|
|
91
|
+
const tmpFile = `/${(0, import_node_os.tmpdir)()}/${(0, import_uuid.v4)()}`;
|
|
92
92
|
try {
|
|
93
93
|
await (0, import_promises.writeFile)(tmpFile, new Uint8Array(videoBuffer), { encoding: "binary" });
|
|
94
94
|
const imageBuffer = await new Promise((resolve, reject) => {
|
|
@@ -133,7 +133,7 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway) => {
|
|
|
133
133
|
} else {
|
|
134
134
|
return urlToCheck;
|
|
135
135
|
}
|
|
136
|
-
} catch
|
|
136
|
+
} catch {
|
|
137
137
|
return urlToCheck;
|
|
138
138
|
}
|
|
139
139
|
};
|
|
@@ -206,7 +206,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract
|
|
|
206
206
|
if (import_hash.PayloadHasher.wasmSupport.canUseWasm) {
|
|
207
207
|
try {
|
|
208
208
|
return await (0, import_hash_wasm.sha256)(viewData);
|
|
209
|
-
} catch
|
|
209
|
+
} catch {
|
|
210
210
|
import_hash.PayloadHasher.wasmSupport.allowWasm = false;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
@@ -216,7 +216,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract
|
|
|
216
216
|
if (url.startsWith("data:image")) {
|
|
217
217
|
const data = url.split(",")[1];
|
|
218
218
|
if (data) {
|
|
219
|
-
return Uint8Array.from(atob(data), (c) => c.
|
|
219
|
+
return Uint8Array.from(atob(data), (c) => c.codePointAt(0) ?? 0);
|
|
220
220
|
} else {
|
|
221
221
|
const error = {
|
|
222
222
|
message: "Invalid data Url",
|
|
@@ -229,7 +229,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract
|
|
|
229
229
|
}
|
|
230
230
|
async observeHandler(payloads = []) {
|
|
231
231
|
if (!import_hasbin.default.sync("magick")) {
|
|
232
|
-
throw Error("ImageMagick is required for this witness");
|
|
232
|
+
throw new Error("ImageMagick is required for this witness");
|
|
233
233
|
}
|
|
234
234
|
const urlPayloads = payloads.filter((payload) => payload.schema === import_url_payload_plugin.UrlSchema);
|
|
235
235
|
const process = async () => {
|
|
@@ -385,13 +385,15 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends import_abstract
|
|
|
385
385
|
};
|
|
386
386
|
let encoding = "PNG";
|
|
387
387
|
switch (fileType.toUpperCase()) {
|
|
388
|
-
case "GIF":
|
|
388
|
+
case "GIF": {
|
|
389
389
|
encoding = "GIF";
|
|
390
390
|
break;
|
|
391
|
+
}
|
|
391
392
|
case "JPG":
|
|
392
|
-
case "JPEG":
|
|
393
|
+
case "JPEG": {
|
|
393
394
|
encoding = "JPG";
|
|
394
395
|
break;
|
|
396
|
+
}
|
|
395
397
|
}
|
|
396
398
|
switch (mediaType) {
|
|
397
399
|
case "image": {
|
|
@@ -446,7 +448,6 @@ var ImageThumbnailPlugin = () => (0, import_payloadset_plugin.createPayloadSetDu
|
|
|
446
448
|
|
|
447
449
|
// src/index.ts
|
|
448
450
|
__reExport(src_exports, require("@xyo-network/diviner-image-thumbnail"), module.exports);
|
|
449
|
-
var src_default = ImageThumbnailPlugin;
|
|
450
451
|
// Annotate the CommonJS export names for ESM import in node:
|
|
451
452
|
0 && (module.exports = {
|
|
452
453
|
ImageThumbnailPlugin,
|
package/dist/node/index.js.map
CHANGED
|
@@ -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":["import { ImageThumbnailPlugin } from './Plugin'\n\nexport * from './Witness'\nexport * from '@xyo-network/diviner-image-thumbnail'\n\nexport { ImageThumbnailPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default ImageThumbnailPlugin\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'\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 { 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'\nimport { getVideoFrameAsImageFluent } from './ffmpeg'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib'\nimport { ImageThumbnailWitnessParams } from './Params'\n\n//TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\n// eslint-disable-next-line import/no-named-as-default-member\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 configSchemas = [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 (ex) {\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.charCodeAt(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 // eslint-disable-next-line import/no-named-as-default-member\n if (!hasbin.sync('magick')) {\n throw 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 // eslint-disable-next-line import/no-named-as-default-member\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 case 'JPG':\n case 'JPEG':\n encoding = 'JPG'\n break\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 ffmpeg from 'fluent-ffmpeg'\nimport { unlink, writeFile } from 'fs/promises'\nimport { tmpdir } from 'os'\nimport { Writable, WritableOptions } from 'stream'\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 (ex) {\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","import_axios","import_image_thumbnail_payload_plugin","uuid","ffmpeg","import_base64_js","graphicsMagick","shajs","hasbin","Url","dnsPromises","result","FileType","encoding"]}
|
|
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":["export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin'\nexport * from './Witness'\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'\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 { 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'\nimport { getVideoFrameAsImageFluent } from './ffmpeg'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib'\nimport { ImageThumbnailWitnessParams } from './Params'\n\n//TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\n// eslint-disable-next-line import/no-named-as-default-member\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 configSchemas = [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 // eslint-disable-next-line import/no-named-as-default-member\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 // eslint-disable-next-line import/no-named-as-default-member\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","import_axios","import_image_thumbnail_payload_plugin","uuid","ffmpeg","import_base64_js","graphicsMagick","shajs","hasbin","Url","dnsPromises","result","FileType","encoding"]}
|
package/dist/node/index.mjs
CHANGED
|
@@ -26,10 +26,10 @@ import shajs from "sha.js";
|
|
|
26
26
|
import Url from "url-parse";
|
|
27
27
|
|
|
28
28
|
// src/Witness/ffmpeg/fluent/getVideoFrameAsImageFluent.ts
|
|
29
|
+
import { unlink, writeFile } from "node:fs/promises";
|
|
30
|
+
import { tmpdir } from "node:os";
|
|
31
|
+
import { Writable } from "node:stream";
|
|
29
32
|
import ffmpeg from "fluent-ffmpeg";
|
|
30
|
-
import { unlink, writeFile } from "fs/promises";
|
|
31
|
-
import { tmpdir } from "os";
|
|
32
|
-
import { Writable } from "stream";
|
|
33
33
|
import { v4 as uuid } from "uuid";
|
|
34
34
|
var FfmpegOutputStream = class extends Writable {
|
|
35
35
|
chunks = [];
|
|
@@ -93,7 +93,7 @@ var checkIpfsUrl = (urlToCheck, ipfsGateway) => {
|
|
|
93
93
|
} else {
|
|
94
94
|
return urlToCheck;
|
|
95
95
|
}
|
|
96
|
-
} catch
|
|
96
|
+
} catch {
|
|
97
97
|
return urlToCheck;
|
|
98
98
|
}
|
|
99
99
|
};
|
|
@@ -166,7 +166,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness
|
|
|
166
166
|
if (PayloadHasher.wasmSupport.canUseWasm) {
|
|
167
167
|
try {
|
|
168
168
|
return await sha256(viewData);
|
|
169
|
-
} catch
|
|
169
|
+
} catch {
|
|
170
170
|
PayloadHasher.wasmSupport.allowWasm = false;
|
|
171
171
|
}
|
|
172
172
|
}
|
|
@@ -176,7 +176,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness
|
|
|
176
176
|
if (url.startsWith("data:image")) {
|
|
177
177
|
const data = url.split(",")[1];
|
|
178
178
|
if (data) {
|
|
179
|
-
return Uint8Array.from(atob(data), (c) => c.
|
|
179
|
+
return Uint8Array.from(atob(data), (c) => c.codePointAt(0) ?? 0);
|
|
180
180
|
} else {
|
|
181
181
|
const error = {
|
|
182
182
|
message: "Invalid data Url",
|
|
@@ -189,7 +189,7 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness
|
|
|
189
189
|
}
|
|
190
190
|
async observeHandler(payloads = []) {
|
|
191
191
|
if (!hasbin.sync("magick")) {
|
|
192
|
-
throw Error("ImageMagick is required for this witness");
|
|
192
|
+
throw new Error("ImageMagick is required for this witness");
|
|
193
193
|
}
|
|
194
194
|
const urlPayloads = payloads.filter((payload) => payload.schema === UrlSchema);
|
|
195
195
|
const process = async () => {
|
|
@@ -345,13 +345,15 @@ var ImageThumbnailWitness = class _ImageThumbnailWitness extends AbstractWitness
|
|
|
345
345
|
};
|
|
346
346
|
let encoding = "PNG";
|
|
347
347
|
switch (fileType.toUpperCase()) {
|
|
348
|
-
case "GIF":
|
|
348
|
+
case "GIF": {
|
|
349
349
|
encoding = "GIF";
|
|
350
350
|
break;
|
|
351
|
+
}
|
|
351
352
|
case "JPG":
|
|
352
|
-
case "JPEG":
|
|
353
|
+
case "JPEG": {
|
|
353
354
|
encoding = "JPG";
|
|
354
355
|
break;
|
|
356
|
+
}
|
|
355
357
|
}
|
|
356
358
|
switch (mediaType) {
|
|
357
359
|
case "image": {
|
|
@@ -406,11 +408,10 @@ var ImageThumbnailPlugin = () => createPayloadSetDualPlugin(
|
|
|
406
408
|
|
|
407
409
|
// src/index.ts
|
|
408
410
|
export * from "@xyo-network/diviner-image-thumbnail";
|
|
409
|
-
var src_default = ImageThumbnailPlugin;
|
|
410
411
|
export {
|
|
411
412
|
ImageThumbnailPlugin,
|
|
412
413
|
ImageThumbnailWitness,
|
|
413
414
|
ImageThumbnailWitnessConfigSchema,
|
|
414
|
-
|
|
415
|
+
ImageThumbnailPlugin as default
|
|
415
416
|
};
|
|
416
417
|
//# sourceMappingURL=index.mjs.map
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":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"],"sourcesContent":["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'\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 { 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'\nimport { getVideoFrameAsImageFluent } from './ffmpeg'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib'\nimport { ImageThumbnailWitnessParams } from './Params'\n\n//TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\n// eslint-disable-next-line import/no-named-as-default-member\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 configSchemas = [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 (ex) {\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.charCodeAt(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 // eslint-disable-next-line import/no-named-as-default-member\n if (!hasbin.sync('magick')) {\n throw 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 // eslint-disable-next-line import/no-named-as-default-member\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 case 'JPG':\n case 'JPEG':\n encoding = 'JPG'\n break\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 ffmpeg from 'fluent-ffmpeg'\nimport { unlink, writeFile } from 'fs/promises'\nimport { tmpdir } from 'os'\nimport { Writable, WritableOptions } from 'stream'\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 (ex) {\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","import { ImageThumbnailPlugin } from './Plugin'\n\nexport * from './Witness'\nexport * from '@xyo-network/diviner-image-thumbnail'\n\nexport { ImageThumbnailPlugin }\n\n// eslint-disable-next-line import/no-default-export\nexport default ImageThumbnailPlugin\n"],"mappings":"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","names":["ImageThumbnailSchema","Buffer","axios","ImageThumbnailSchema","ImageThumbnailSchema","Buffer","result","axios","encoding","ImageThumbnailSchema"]}
|
|
1
|
+
{"version":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"],"sourcesContent":["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'\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 { 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'\nimport { getVideoFrameAsImageFluent } from './ffmpeg'\nimport { checkIpfsUrl, createDataUrl, resolveDynamicSvg } from './lib'\nimport { ImageThumbnailWitnessParams } from './Params'\n\n//TODO: Break this into two Witnesses?\n\n// setFfmpegPath(ffmpegPath)\n\n// eslint-disable-next-line import/no-named-as-default-member\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 configSchemas = [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 // eslint-disable-next-line import/no-named-as-default-member\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 // eslint-disable-next-line import/no-named-as-default-member\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","export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin'\nexport * from './Witness'\nexport * from '@xyo-network/diviner-image-thumbnail'\n"],"mappings":"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","names":["ImageThumbnailSchema","Buffer","axios","ImageThumbnailSchema","ImageThumbnailSchema","Buffer","result","axios","encoding","ImageThumbnailSchema"]}
|
package/package.json
CHANGED
|
@@ -10,18 +10,18 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/plugins/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xylabs/assert": "^2.13.
|
|
14
|
-
"@xylabs/axios": "^2.13.
|
|
15
|
-
"@xylabs/lodash": "^2.13.
|
|
16
|
-
"@xyo-network/abstract-witness": "^2.
|
|
17
|
-
"@xyo-network/diviner-image-thumbnail": "~2.
|
|
18
|
-
"@xyo-network/hash": "^2.
|
|
19
|
-
"@xyo-network/image-thumbnail-payload-plugin": "~2.
|
|
20
|
-
"@xyo-network/module-model": "^2.
|
|
21
|
-
"@xyo-network/payload-model": "^2.
|
|
22
|
-
"@xyo-network/payloadset-plugin": "^2.
|
|
23
|
-
"@xyo-network/url-payload-plugin": "~2.
|
|
24
|
-
"@xyo-network/witness-model": "^2.
|
|
13
|
+
"@xylabs/assert": "^2.13.22",
|
|
14
|
+
"@xylabs/axios": "^2.13.22",
|
|
15
|
+
"@xylabs/lodash": "^2.13.22",
|
|
16
|
+
"@xyo-network/abstract-witness": "^2.85.3",
|
|
17
|
+
"@xyo-network/diviner-image-thumbnail": "~2.85.1",
|
|
18
|
+
"@xyo-network/hash": "^2.85.3",
|
|
19
|
+
"@xyo-network/image-thumbnail-payload-plugin": "~2.85.1",
|
|
20
|
+
"@xyo-network/module-model": "^2.85.3",
|
|
21
|
+
"@xyo-network/payload-model": "^2.85.3",
|
|
22
|
+
"@xyo-network/payloadset-plugin": "^2.85.3",
|
|
23
|
+
"@xyo-network/url-payload-plugin": "~2.85.1",
|
|
24
|
+
"@xyo-network/witness-model": "^2.85.3",
|
|
25
25
|
"async-mutex": "^0.4.0",
|
|
26
26
|
"base64-js": "^1.5.1",
|
|
27
27
|
"file-type": "^16.5.4",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
"@types/xml2js": "^0.4.14",
|
|
45
45
|
"@xylabs/ts-scripts-yarn3": "^3.2.25",
|
|
46
46
|
"@xylabs/tsconfig": "^3.2.25",
|
|
47
|
-
"@xyo-network/account": "^2.
|
|
48
|
-
"@xyo-network/memory-archivist": "^2.
|
|
49
|
-
"@xyo-network/node-memory": "^2.
|
|
50
|
-
"@xyo-network/payload-builder": "^2.
|
|
51
|
-
"@xyo-network/sentinel": "^2.
|
|
52
|
-
"@xyo-network/witness-timestamp": "^2.
|
|
47
|
+
"@xyo-network/account": "^2.85.3",
|
|
48
|
+
"@xyo-network/memory-archivist": "^2.85.3",
|
|
49
|
+
"@xyo-network/node-memory": "^2.85.3",
|
|
50
|
+
"@xyo-network/payload-builder": "^2.85.3",
|
|
51
|
+
"@xyo-network/sentinel": "^2.85.3",
|
|
52
|
+
"@xyo-network/witness-timestamp": "^2.85.3",
|
|
53
53
|
"jest": "^29.7.0",
|
|
54
54
|
"jest-mock-extended": "^3.0.5",
|
|
55
55
|
"typescript": "^5.3.3"
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"url": "https://github.com/XYOracleNetwork/plugins.git"
|
|
85
85
|
},
|
|
86
86
|
"sideEffects": false,
|
|
87
|
-
"version": "2.
|
|
87
|
+
"version": "2.85.1"
|
|
88
88
|
}
|
package/src/Witness/Witness.ts
CHANGED
|
@@ -72,7 +72,7 @@ export class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams =
|
|
|
72
72
|
if (PayloadHasher.wasmSupport.canUseWasm) {
|
|
73
73
|
try {
|
|
74
74
|
return await sha256(viewData)
|
|
75
|
-
} catch
|
|
75
|
+
} catch {
|
|
76
76
|
PayloadHasher.wasmSupport.allowWasm = false
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -84,7 +84,7 @@ export class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams =
|
|
|
84
84
|
if (url.startsWith('data:image')) {
|
|
85
85
|
const data = url.split(',')[1]
|
|
86
86
|
if (data) {
|
|
87
|
-
return Uint8Array.from(atob(data), (c) => c.
|
|
87
|
+
return Uint8Array.from(atob(data), (c) => c.codePointAt(0) ?? 0)
|
|
88
88
|
} else {
|
|
89
89
|
const error: ImageThumbnailWitnessError = {
|
|
90
90
|
message: 'Invalid data Url',
|
|
@@ -99,7 +99,7 @@ export class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams =
|
|
|
99
99
|
protected override async observeHandler(payloads: UrlPayload[] = []): Promise<ImageThumbnail[]> {
|
|
100
100
|
// eslint-disable-next-line import/no-named-as-default-member
|
|
101
101
|
if (!hasbin.sync('magick')) {
|
|
102
|
-
throw Error('ImageMagick is required for this witness')
|
|
102
|
+
throw new Error('ImageMagick is required for this witness')
|
|
103
103
|
}
|
|
104
104
|
const urlPayloads = payloads.filter((payload) => payload.schema === UrlSchema)
|
|
105
105
|
const process = async () => {
|
|
@@ -276,13 +276,15 @@ export class ImageThumbnailWitness<TParams extends ImageThumbnailWitnessParams =
|
|
|
276
276
|
let encoding: ImageThumbnailEncoding = 'PNG'
|
|
277
277
|
|
|
278
278
|
switch (fileType.toUpperCase()) {
|
|
279
|
-
case 'GIF':
|
|
279
|
+
case 'GIF': {
|
|
280
280
|
encoding = 'GIF'
|
|
281
281
|
break
|
|
282
|
+
}
|
|
282
283
|
case 'JPG':
|
|
283
|
-
case 'JPEG':
|
|
284
|
+
case 'JPEG': {
|
|
284
285
|
encoding = 'JPG'
|
|
285
286
|
break
|
|
287
|
+
}
|
|
286
288
|
}
|
|
287
289
|
|
|
288
290
|
switch (mediaType) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { unlink, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { Writable, WritableOptions } from 'node:stream'
|
|
4
|
+
|
|
1
5
|
import ffmpeg from 'fluent-ffmpeg'
|
|
2
|
-
import { unlink, writeFile } from 'fs/promises'
|
|
3
|
-
import { tmpdir } from 'os'
|
|
4
|
-
import { Writable, WritableOptions } from 'stream'
|
|
5
6
|
import { v4 as uuid } from 'uuid'
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn } from 'child_process'
|
|
1
|
+
import { spawn } from 'node:child_process'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Execute FFmpeg with the provided arguments.
|
|
@@ -15,10 +15,10 @@ export const executeFFmpeg = (videoBuffer: Buffer, ffmpegArgs: string[]): Promis
|
|
|
15
15
|
// how we're piping the data to ffmpeg. Works perfectly though.
|
|
16
16
|
ffmpeg.stdin.on('error', () => {})
|
|
17
17
|
ffmpeg.on('close', (code) => {
|
|
18
|
-
if (code
|
|
19
|
-
reject(new Error(`FFmpeg exited with code ${code}`))
|
|
20
|
-
} else {
|
|
18
|
+
if (code === 0) {
|
|
21
19
|
resolve(Buffer.concat(imageData))
|
|
20
|
+
} else {
|
|
21
|
+
reject(new Error(`FFmpeg exited with code ${code}`))
|
|
22
22
|
}
|
|
23
23
|
})
|
|
24
24
|
// Pipe the input stream to ffmpeg's stdin
|
|
@@ -34,7 +34,7 @@ export const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string): string =
|
|
|
34
34
|
} else {
|
|
35
35
|
return urlToCheck
|
|
36
36
|
}
|
|
37
|
-
} catch
|
|
37
|
+
} catch {
|
|
38
38
|
//const error = ex as Error
|
|
39
39
|
//console.error(`${error.name}:${error.message} [${urlToCheck}]`)
|
|
40
40
|
//console.log(error.stack)
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { ImageThumbnailPlugin as default, ImageThumbnailPlugin } from './Plugin'
|
|
3
2
|
export * from './Witness'
|
|
4
3
|
export * from '@xyo-network/diviner-image-thumbnail'
|
|
5
|
-
|
|
6
|
-
export { ImageThumbnailPlugin }
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line import/no-default-export
|
|
9
|
-
export default ImageThumbnailPlugin
|