@pi-r/jimp 0.8.3 → 0.9.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/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
- Copyright 2024 An Pham
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
-
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright 2024 An Pham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -4,4 +4,4 @@ https://e-mc.readthedocs.io/en/latest/image
4
4
 
5
5
  ### LICENSE
6
6
 
7
- MIT
7
+ MIT
package/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
- const path = require("path");
3
- const fs = require("fs");
4
- const child_process = require("child_process");
2
+ const path = require("node:path");
3
+ const fs = require("node:fs");
4
+ const child_process = require("node:child_process");
5
5
  const jimp = require("jimp");
6
6
  const gifwrap = require("gifwrap");
7
7
  const bmp = require("bmp-js");
8
- const crypto_1 = require("crypto");
8
+ const node_crypto_1 = require("node:crypto");
9
9
  const types_1 = require("@e-mc/types");
10
+ const util_1 = require("@pi-r/jimp/util");
10
11
  const Image = require('@e-mc/image');
11
12
  let WEBPMUX = null, WEBPMUX_INIT = false;
12
13
  try {
@@ -15,7 +16,6 @@ try {
15
16
  }
16
17
  catch {
17
18
  }
18
- const util_1 = require("@pi-r/jimp/util");
19
19
  const CACHE_TRANSFORM = {};
20
20
  let CACHE_INIT = false;
21
21
  let TEMP_DIR = '';
@@ -31,7 +31,7 @@ const METHOD_ALIAS = {
31
31
  composite: 'cp',
32
32
  mask: 'ma',
33
33
  convolute: 'cl',
34
- convolution: 'cl',
34
+ convolution: 'cu',
35
35
  flip: 'fl',
36
36
  mirror: 'mi',
37
37
  rotate: 'ro',
@@ -68,22 +68,22 @@ const METHOD_ALIAS = {
68
68
  threshold: 'th'
69
69
  };
70
70
  function getMethodName(value) {
71
- const name = value.toLowerCase();
72
- if (METHOD_ALIAS[name]) {
73
- return name;
74
- }
75
- if (name.length === 2) {
71
+ if (value.length === 2) {
72
+ value = value.toLowerCase();
76
73
  for (const alias in METHOD_ALIAS) {
77
- if (METHOD_ALIAS[alias] === name) {
74
+ if (METHOD_ALIAS[alias] === value) {
78
75
  return alias;
79
76
  }
80
77
  }
81
78
  }
79
+ else if (METHOD_ALIAS[value] || METHOD_ALIAS[value = value.toLowerCase()]) {
80
+ return value;
81
+ }
82
82
  }
83
- async function performCommand(host, instance, localUri, command, outputType, finalAs, buffer, parent) {
83
+ async function performCommand(host, instance, localUri, command, outputType, outputAs, buffer, parent) {
84
84
  return await jimp.read((buffer || localUri))
85
85
  .then(async (img) => {
86
- return await transformCommand(localUri, new JimpHandler(img, instance, host), command, outputType, finalAs, parent);
86
+ return await transformCommand(localUri, new JimpHandler(img, instance, host), command, outputType, outputAs, parent);
87
87
  });
88
88
  }
89
89
  function execOptions(settings) {
@@ -120,22 +120,22 @@ async function transformCommand(localFile, handler, command, outputType, outputA
120
120
  return handler.rotate();
121
121
  }
122
122
  return handler.rotate(localFile, (err, result) => {
123
- if (!err && handler.host?.moduleName === 'filemanager') {
123
+ if (!err) {
124
124
  try {
125
- handler.host.add(result, parent);
125
+ handler.host?.add(result, parent);
126
126
  }
127
127
  catch {
128
128
  }
129
129
  }
130
130
  });
131
131
  }
132
- function setImageCache(instance, tempKey, tempFile, output, localFile) {
132
+ async function setImageCache(instance, tempKey, tempFile, output, localFile) {
133
133
  try {
134
134
  if (typeof output === 'string') {
135
- fs.copyFileSync(output, tempFile);
135
+ await fs.promises.copyFile(output, tempFile);
136
136
  }
137
137
  else {
138
- fs.writeFileSync(tempFile, output);
138
+ await fs.promises.writeFile(tempFile, output);
139
139
  }
140
140
  const stored = getCacheData(instance);
141
141
  if (localFile) {
@@ -174,7 +174,7 @@ function getImageCache(instance, tempKey) {
174
174
  delete stored[tempKey];
175
175
  }
176
176
  TEMP_DIR ||= instance.getTempDir({ moduleDir: true, increment: 5 });
177
- return [null, TEMP_DIR ? path.join(TEMP_DIR, (0, crypto_1.randomUUID)()) : ''];
177
+ return [null, TEMP_DIR ? path.join(TEMP_DIR, (0, node_crypto_1.randomUUID)()) : ''];
178
178
  }
179
179
  function getCacheData(instance) {
180
180
  if (!CACHE_INIT) {
@@ -228,7 +228,7 @@ function formatMessage(instance, value, startTime, failed, cTimeMs) {
228
228
  }
229
229
  function getTempPath(instance, ext) {
230
230
  const tempDir = TEMP_DIR || instance.getTempDir({ moduleDir: true, createDir: true }) || instance.getTempDir();
231
- return path.join(tempDir, (0, crypto_1.randomUUID)() + '.' + ext);
231
+ return path.join(tempDir, (0, node_crypto_1.randomUUID)() + '.' + ext);
232
232
  }
233
233
  function rotateAnim(cmd) {
234
234
  const rotate = cmd.rotate;
@@ -239,18 +239,16 @@ function rotateAnim(cmd) {
239
239
  function removeFile(pathname) {
240
240
  fs.unlink(pathname, () => { });
241
241
  }
242
- const hasTransform = (cmd) => !!(cmd.rotate || cmd.opacity >= 0 && cmd.opacity < 1 || cmd.resize || cmd.crop || cmd.method);
242
+ const hasTransform = (cmd) => !!(cmd.rotate || cmd.resize || cmd.crop || cmd.method || typeof cmd.opacity === 'number' && cmd.opacity >= 0 && cmd.opacity < 1);
243
243
  const emptyResult = (options) => (options.tempFile ? '' : null);
244
244
  class JimpHandler {
245
245
  handler;
246
246
  instance;
247
- _host = null;
248
- constructor(handler, instance, host) {
247
+ _host;
248
+ constructor(handler, instance, _host = null) {
249
249
  this.handler = handler;
250
250
  this.instance = instance;
251
- if (host) {
252
- this._host = host;
253
- }
251
+ this._host = _host;
254
252
  }
255
253
  async rotate(localFile, callback) {
256
254
  if (this.aborted) {
@@ -479,20 +477,23 @@ class JimpHandler {
479
477
  }
480
478
  }
481
479
  async getBuffer(tempFile, saveAs) {
482
- const empty = () => tempFile ? '' : null;
483
- const output = getTempPath(this.instance, this.instance.outputAs || (saveAs && util_1.MIME_OUTPUT.has('image/' + (saveAs === 'jpg' ? 'jpeg' : saveAs)) ? saveAs : this.handler.getMIME().split('/').pop()));
484
- return !output ? empty() : new Promise(resolve => {
480
+ const emptyData = () => tempFile ? '' : null;
481
+ const output = getTempPath(this.instance, saveAs && util_1.MIME_OUTPUT.has('image/' + (saveAs === 'jpg' ? 'jpeg' : saveAs)) ? saveAs : this.handler.getMIME().split('/').pop());
482
+ if (!output) {
483
+ return emptyData();
484
+ }
485
+ return new Promise(resolve => {
485
486
  this.handler.write(output, error => {
486
487
  if (error) {
487
- resolve(empty());
488
+ resolve(emptyData());
488
489
  return;
489
490
  }
490
491
  this.finalize(output, (error, result) => {
491
492
  if (error) {
492
- resolve(empty());
493
+ resolve(emptyData());
493
494
  }
494
495
  else if (tempFile) {
495
- resolve(output);
496
+ resolve(result || output);
496
497
  }
497
498
  else {
498
499
  try {
@@ -589,7 +590,7 @@ class JimpHandler {
589
590
  }
590
591
  class Jimp extends Image {
591
592
  static async transform(file, command, options = {}) {
592
- const [outputType, saveAs, finalAs] = (0, util_1.parseFormat)(command = command.trim(), options.mimeType);
593
+ const [outputType, saveAs, outputAs] = (0, util_1.parseFormat)(command = command.trim(), options.mimeType);
593
594
  if (!outputType) {
594
595
  return emptyResult(options);
595
596
  }
@@ -603,7 +604,7 @@ class Jimp extends Image {
603
604
  try {
604
605
  const { ext } = await this.resolveMime(file) || { ext: 'unknown' };
605
606
  buffer = file;
606
- fs.writeFileSync(file = path.join(tempDir, (0, crypto_1.randomUUID)() + '.' + ext), buffer);
607
+ fs.writeFileSync(file = path.join(tempDir, (0, node_crypto_1.randomUUID)() + '.' + ext), buffer);
607
608
  }
608
609
  catch {
609
610
  return emptyResult(options);
@@ -625,7 +626,7 @@ class Jimp extends Image {
625
626
  }
626
627
  const writeMessage = (failed, cTimeMs) => {
627
628
  if (cTimeMs || options.startTime) {
628
- formatMessage(instance, filename + (0, util_1.showOutputType)(options.mimeType, outputType, finalAs), options.startTime, failed, cTimeMs);
629
+ formatMessage(instance, filename + (0, util_1.showOutputType)(options.mimeType, outputType, outputAs), options.startTime, failed, cTimeMs);
629
630
  }
630
631
  };
631
632
  let tempKey, tempFile;
@@ -639,13 +640,13 @@ class Jimp extends Image {
639
640
  }
640
641
  instance.formatMessage(Image.LOG_TYPE.IMAGE, "jimp", ["Transforming image...", filename], command);
641
642
  Image.initCpuUsage(instance);
642
- return performCommand(null, instance, file, command, outputType, finalAs)
643
+ return performCommand(null, instance, file, command, outputType, outputAs)
643
644
  .then(async (handler) => {
644
645
  const result = await handler.getBuffer(options.tempFile, saveAs);
645
646
  instance.flushLog();
646
647
  writeMessage(!result || instance.errors.length > 0);
647
648
  if (result && tempKey && tempFile) {
648
- setImageCache(instance, tempKey, tempFile, result, file);
649
+ void setImageCache(instance, tempKey, tempFile, result, file);
649
650
  }
650
651
  return result;
651
652
  })
@@ -660,6 +661,12 @@ class Jimp extends Image {
660
661
  }
661
662
  _moduleName = "jimp";
662
663
  _threadable = true;
664
+ resizeData = null;
665
+ cropData = null;
666
+ rotateData = null;
667
+ qualityData = null;
668
+ methodData = null;
669
+ opacityValue = NaN;
663
670
  parseRotate(value) {
664
671
  const data = super.parseRotate(value);
665
672
  if (data && this.settings.jimp?.rotate_clockwise) {
@@ -686,7 +693,7 @@ class Jimp extends Image {
686
693
  reject((0, types_1.errorValue)("Not permitted to read file", localUri));
687
694
  return;
688
695
  }
689
- const [outputType, saveAs, finalAs] = (0, util_1.parseFormat)(command = command.trim(), mimeType, true);
696
+ const [outputType, saveAs, outputAs] = (0, util_1.parseFormat)(command = command.trim(), mimeType, true);
690
697
  if (!outputType) {
691
698
  reject((0, types_1.errorValue)("Invalid format", /^\w+/.exec(command)?.[0] || "Unknown"));
692
699
  return;
@@ -728,7 +735,7 @@ class Jimp extends Image {
728
735
  if (replace && file.localUri !== output && !host.assets.find(item => item.localUri === output && !item.invalid)) {
729
736
  host.filesToRemove.add(output);
730
737
  }
731
- formatMessage(this, (0, util_1.showInputType)(mimeType, outputType, finalAs) + filename, startTime, false, ctimeMs);
738
+ formatMessage(this, (0, util_1.showInputType)(mimeType, outputType, outputAs) + filename, startTime, false, ctimeMs);
732
739
  resolve();
733
740
  };
734
741
  let tempKey, tempFile;
@@ -736,7 +743,7 @@ class Jimp extends Image {
736
743
  let buffer, ctimeMs;
737
744
  [buffer, tempFile] = getImageCache(this, tempKey = (file.etag || Image.asHash(file.buffer)) + command + mimeType);
738
745
  if (buffer) {
739
- const result = finalAs === 'webp' ? (0, util_1.renameExt)(output, 'webp', replace) : output;
746
+ const result = outputAs === 'webp' ? (0, util_1.renameExt)(output, 'webp', replace) : output;
740
747
  fs.writeFileSync(result, file.buffer = buffer);
741
748
  success(result, ctimeMs);
742
749
  return;
@@ -744,7 +751,7 @@ class Jimp extends Image {
744
751
  }
745
752
  const finalize = (value) => {
746
753
  if (tempFile && tempKey) {
747
- setImageCache(this, tempKey, tempFile, value);
754
+ void setImageCache(this, tempKey, tempFile, value);
748
755
  }
749
756
  if (replace) {
750
757
  delete file.buffer;
@@ -753,7 +760,7 @@ class Jimp extends Image {
753
760
  };
754
761
  const transformBuffer = (bmpFile) => {
755
762
  startMessage();
756
- performCommand(host, this, localUri, command, outputType, finalAs, bmpFile || file.buffer, file)
763
+ performCommand(host, this, localUri, command, bmpFile ? jimp.MIME_BMP : outputType, outputAs, bmpFile || file.buffer, file)
757
764
  .then((img) => {
758
765
  if (typeof bmpFile === 'string') {
759
766
  removeFile(bmpFile);
@@ -804,7 +811,7 @@ class Jimp extends Image {
804
811
  if (outputType === jimp.MIME_GIF || outputType === "image/webp") {
805
812
  const cmd = this.parseCommand(command);
806
813
  const transformWebP = (target, modified) => {
807
- if (finalAs === 'webp') {
814
+ if (outputAs === 'webp') {
808
815
  if (!modified) {
809
816
  startMessage();
810
817
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-r/jimp",
3
- "version": "0.8.3",
4
- "description": "Jimp image constructor for E-mc.",
3
+ "version": "0.9.1",
4
+ "description": "Jimp V0 image constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -13,15 +13,14 @@
13
13
  },
14
14
  "keywords": [
15
15
  "squared",
16
- "e-mc",
17
- "squared-functions"
16
+ "e-mc"
18
17
  ],
19
18
  "author": "An Pham <anpham6@gmail.com>",
20
19
  "license": "MIT",
21
20
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
21
  "dependencies": {
23
- "@e-mc/image": "^0.10.3",
24
- "@e-mc/types": "^0.10.3",
22
+ "@e-mc/image": "^0.11.2",
23
+ "@e-mc/types": "^0.11.2",
25
24
  "bmp-js": "^0.1.0",
26
25
  "gifwrap": "^0.10.1",
27
26
  "jimp": "^0.22.12"
package/types/index.d.ts CHANGED
@@ -21,13 +21,14 @@ export type ResultCallback<T = unknown, U = void, V = unknown> = (err: V, result
21
21
 
22
22
  export interface IJimpHandler<T extends IHost = IHost, U extends ImageModule = ImageModule> extends ImageHandler<jimp, T, IImage<T, U>> {
23
23
  method(): Promise<void>;
24
+ quality(): void;
24
25
  rotate(localFile?: string, callback?: ResultCallback<string>): Promise<this>;
25
26
  background(value: number | [number, number, number, number]): void;
26
27
  writeAsync(output: string, callback?: ResultCallback): Promise<void>;
27
28
  }
28
29
 
29
30
  export interface JimpImageConstructor<T extends IFileManager<U>, U extends ExternalAsset = ExternalAsset, V extends ImageModule = ImageModule<JimpSettings>> extends ConstructorDerived<ImageConstructor<T, V>> {
30
- transform<W extends TransformOptions>(file: string, command: string, options?: W): Promise<W extends { tempFile: true } ? string : Null<Buffer>>;
31
+ transform<W extends TransformOptions>(file: string, command: string, options?: W): Promise<W extends { tempFile: true } ? string : Buffer | null>;
31
32
  readonly prototype: IImage<T, V>;
32
33
  new(module?: V, ...args: unknown[]): IImage<T, V>;
33
34
  }
package/util.js CHANGED
@@ -6,34 +6,38 @@ exports.normalizePath = normalizePath;
6
6
  exports.getWebP_bin = getWebP_bin;
7
7
  exports.showInputType = showInputType;
8
8
  exports.showOutputType = showOutputType;
9
- const path = require("path");
10
- const fs = require("fs");
9
+ const path = require("node:path");
10
+ const fs = require("node:fs");
11
11
  const jimp = require("jimp");
12
- const types_1 = require("@e-mc/types");
12
+ const types = require("@e-mc/types");
13
13
  const Image = require("@e-mc/image");
14
- exports.MIME_INPUT = new Set([jimp.MIME_PNG, jimp.MIME_JPEG, jimp.MIME_BMP, jimp.MIME_GIF, jimp.MIME_TIFF, "image/webp"]);
15
- exports.MIME_OUTPUT = new Set([jimp.MIME_PNG, jimp.MIME_JPEG, jimp.MIME_BMP, jimp.MIME_GIF, "image/webp"]);
14
+ exports.MIME_INPUT = new Set([
15
+ jimp.MIME_PNG,
16
+ jimp.MIME_JPEG,
17
+ jimp.MIME_BMP,
18
+ jimp.MIME_GIF,
19
+ jimp.MIME_TIFF,
20
+ "image/webp"
21
+ ]);
22
+ exports.MIME_OUTPUT = new Set([
23
+ jimp.MIME_PNG,
24
+ jimp.MIME_JPEG,
25
+ jimp.MIME_BMP,
26
+ jimp.MIME_GIF,
27
+ "image/webp"
28
+ ]);
16
29
  function parseFormat(command, mimeType, gif) {
17
30
  command = command.toLowerCase();
18
31
  for (let mime of exports.MIME_OUTPUT) {
19
32
  let saveAs = mime.split('/')[1];
20
33
  if (command.startsWith(saveAs)) {
21
- let finalAs = '';
34
+ let outputAs = '';
22
35
  if (saveAs !== 'gif') {
23
36
  switch (saveAs) {
24
37
  case 'jpeg':
25
38
  saveAs = 'jpg';
26
39
  break;
27
40
  case 'webp':
28
- if (mimeType === "image/webp") {
29
- try {
30
- require('node-webpmux');
31
- mime = "image/webp";
32
- break;
33
- }
34
- catch {
35
- }
36
- }
37
41
  if (mimeType === jimp.MIME_JPEG) {
38
42
  mime = jimp.MIME_JPEG;
39
43
  saveAs = 'jpg';
@@ -42,24 +46,28 @@ function parseFormat(command, mimeType, gif) {
42
46
  mime = jimp.MIME_GIF;
43
47
  saveAs = 'gif';
44
48
  }
45
- else {
49
+ else if (mimeType === jimp.MIME_PNG) {
46
50
  mime = jimp.MIME_PNG;
47
51
  saveAs = 'png';
48
52
  }
49
- finalAs = 'webp';
53
+ else {
54
+ mime = jimp.MIME_BMP;
55
+ saveAs = 'bmp';
56
+ }
57
+ outputAs = 'webp';
50
58
  break;
51
59
  }
52
60
  }
53
61
  else if (!gif) {
54
62
  break;
55
63
  }
56
- return [mime, saveAs, finalAs];
64
+ return [mime, saveAs, outputAs];
57
65
  }
58
66
  }
59
67
  return ['', '', ''];
60
68
  }
61
69
  function renameExt(output, ext, replace) {
62
- let result = (0, types_1.renameExt)(output.replace('.__copy__.', '.'), ext);
70
+ let result = types.renameExt(output.replace('.__copy__.', '.'), ext);
63
71
  if (!replace) {
64
72
  const pathname = result;
65
73
  let i = 0;
@@ -80,15 +88,15 @@ function getWebP_bin(name, pathname) {
80
88
  }
81
89
  return require(name + '-bin');
82
90
  }
83
- function showInputType(value, outputType, finalAs) {
84
- if (finalAs) {
85
- outputType = 'image/' + finalAs;
91
+ function showInputType(value, outputType, outputAs) {
92
+ if (outputAs) {
93
+ outputType = 'image/' + outputAs;
86
94
  }
87
95
  return value && outputType !== value ? value.split('/').pop() + ' -> ' : '';
88
96
  }
89
- function showOutputType(value, outputType, finalAs) {
90
- if (finalAs) {
91
- outputType = 'image/' + finalAs;
97
+ function showOutputType(value, outputType, outputAs) {
98
+ if (outputAs) {
99
+ outputType = 'image/' + outputAs;
92
100
  }
93
101
  return value !== outputType ? ' -> ' + outputType.split('/').pop() : '';
94
102
  }