@uxf/resizer 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,61 @@
1
1
  # @uxf/resizer
2
2
  [![npm](https://img.shields.io/npm/v/@uxf/resizer)](https://www.npmjs.com/package/@uxf/resizer)
3
3
 
4
+
5
+ ## Installation
4
6
  ```
5
- // install resizer
7
+ // global installation
6
8
  yarn global add @uxf/resizer
9
+ export PATH="$(yarn global bin):$PATH"
10
+ UXF_RESIZER_SOURCE_PATH=${PWD}/example/source UXF_RESIZER_GENERATE_PATH=${PWD}/example/generated uxf-resizer
11
+
12
+ // local installation
13
+ yarn add @uxf/resizer
14
+ UXF_RESIZER_SOURCE_PATH=${PWD}/example/source UXF_RESIZER_GENERATE_PATH=${PWD}/example/generated ./node-modules/.bin/uxf-resizer
15
+ ```
16
+
17
+ ## Default filename regexp
18
+
19
+ ```
20
+ :originalFilename([a-f0-9\-]+)_:width(\d+)_:height(\d+)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:originalExtension.:toFormat
21
+ ```
22
+
23
+ ### fit
24
+ - `cv`: cover,
25
+ - `f`: fill,
26
+ - `cn`: contain,
27
+ - `in`: inside,
28
+ - `out`: outside,
29
+
30
+ ### position
31
+ - `a`: attention
32
+ - `b`: bottom
33
+ - `c`: centre
34
+ - `e`: entropy
35
+ - `l`: left
36
+ - `lb`: left bottom
37
+ - `lt`: left top
38
+ - `r`: right
39
+ - `rb`: right bottom
40
+ - `rt`: right top
41
+ - `t`: top
42
+
43
+ ### background
44
+ - `t`: transparent
45
+ - `FFFFF`: white (or other hex color)
46
+
47
+ ### trim
48
+ - `nt`: not trim
49
+ - `number`: number value
50
+
51
+ ### toFormat
52
+ - `webp | png | avif | or other`
53
+
54
+ ## Help
55
+
56
+ ```
57
+ Usage:
58
+ uxf-resizer
7
59
 
8
60
  Environment variables:
9
61
  UXF_RESIZER_SOURCE_PATH - required
@@ -97,13 +97,13 @@ var uxfResizer = function () { return __awaiter(void 0, void 0, void 0, function
97
97
  sourcePath_1 = process_1.env.UXF_RESIZER_SOURCE_PATH;
98
98
  if (!sourcePath_1) {
99
99
  // eslint-disable-next-line no-console
100
- console.log("Source directory must be set. Use environment variable UXF_RESIZER_SOURCE.");
100
+ console.error("Source directory must be set. Use environment variable UXF_RESIZER_SOURCE_PATH.");
101
101
  return [2 /*return*/, 1];
102
102
  }
103
103
  generatePath_1 = process_1.env.UXF_RESIZER_GENERATE_PATH;
104
104
  if (!generatePath_1) {
105
105
  // eslint-disable-next-line no-console
106
- console.log("Generated directory must be set. Use environment variable UXF_RESIZER_GENERATED.");
106
+ console.error("Generated directory must be set. Use environment variable UXF_RESIZER_GENERATED_PATH.");
107
107
  return [2 /*return*/, 1];
108
108
  }
109
109
  return [2 /*return*/, new Promise(function (resolve, reject) {
@@ -126,7 +126,7 @@ var uxfResizer = function () { return __awaiter(void 0, void 0, void 0, function
126
126
  console.log("\nImage resizer app listening on port 3000");
127
127
  if (process.env.NODE_ENV !== "production") {
128
128
  // eslint-disable-next-line no-console
129
- console.log("Example image: http://localhost:3000/generated/namespace/i/m/img_300_500_cv_c_t_nt_png.png");
129
+ console.log("Example image: http://localhost:3000/generated/namespace/a/b/ab7dea3a-ba56-4fa0-a407-d9c4a236d153_300_500_cv_c_t_nt_png.png");
130
130
  }
131
131
  app_1.on("close", function () {
132
132
  listenedApp_1.close();
package/index.js CHANGED
@@ -60,6 +60,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
60
60
  Object.defineProperty(exports, "__esModule", { value: true });
61
61
  exports.createApp = void 0;
62
62
  var express_1 = __importDefault(require("express"));
63
+ var node_fetch_1 = __importDefault(require("node-fetch"));
63
64
  var fs_1 = require("fs");
64
65
  var fs = __importStar(require("fs"));
65
66
  var sharp_1 = __importDefault(require("sharp"));
@@ -86,8 +87,8 @@ var POSITION_OPTIONS = {
86
87
  };
87
88
  var isTrim = function (value) { return value !== "nt"; };
88
89
  var getTrimValue = function (value) { return (isTrim(value) ? Number(value) : 0); };
89
- var createApp = function (sourcePath, generatePath, sourceFolderDepth, generatedFolderDepth, filenameRegexp, disableNamespace) {
90
- if (filenameRegexp === void 0) { filenameRegexp = ":originalFilename([a-z\\-]+)_:width(\\d+)_:height(\\d+)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:originalExtension.:toFormat"; }
90
+ var createApp = function (sourcePathOrUrl, generatePath, sourceFolderDepth, generatedFolderDepth, filenameRegexp, disableNamespace) {
91
+ if (filenameRegexp === void 0) { filenameRegexp = ":originalFilename([a-f0-9\\-]+)_:width(\\d+)_:height(\\d+)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:originalExtension.:toFormat"; }
91
92
  var parseFilename = path_to_regexp_1.match(filenameRegexp, { decode: decodeURIComponent });
92
93
  var generatedPxArray = Array.from({ length: generatedFolderDepth }, function (_, i) { return ":p" + (i + 1); });
93
94
  var sourcePxArray = Array.from({ length: sourceFolderDepth }, function (_, i) { return ":p" + (i + 1); });
@@ -107,7 +108,8 @@ var createApp = function (sourcePath, generatePath, sourceFolderDepth, generated
107
108
  _a = req.params, filename = _a.filename, namespace = _a.namespace;
108
109
  parsedFilename = parseFilename(filename);
109
110
  if (!parsedFilename) {
110
- throw new Error("Wrong filename.");
111
+ process.stdout.write("Filename '" + filename + "' not found.");
112
+ return [2 /*return*/, res.sendStatus(404)];
111
113
  }
112
114
  _b = parsedFilename.params, originalFilename = _b.originalFilename, originalExtension = _b.originalExtension, fit = _b.fit, height = _b.height, position = _b.position, toFormat = _b.toFormat, trim = _b.trim, width = _b.width, background = _b.background;
113
115
  generatedPxDirectories = generatedPxArray.map(function (_, index) { return originalFilename.charAt(index); });
@@ -116,29 +118,36 @@ var createApp = function (sourcePath, generatePath, sourceFolderDepth, generated
116
118
  ? generatedDirectoryPart + "/" + generatedPxDirectories.join("/")
117
119
  : generatedDirectoryPart;
118
120
  generatedFilePath = generatedDirectory + "/" + filename;
119
- sourcePxDirectories = sourcePxArray.map(function (_, index) { return originalFilename.charAt(index); });
120
- sourceDirectoryPart = disableNamespace ? sourcePath : sourcePath + "/" + namespace;
121
- sourceDirectory = sourcePxDirectories.length > 0
122
- ? sourceDirectoryPart + "/" + sourcePxDirectories.join("/")
123
- : sourceDirectoryPart;
124
- sourceFilename = originalFilename + "." + originalExtension;
125
- sourceFilePath = sourceDirectory + "/" + sourceFilename;
121
+ // try load from disk
126
122
  if (fs.existsSync(generatedFilePath)) {
127
123
  return [2 /*return*/, res.sendFile(generatedFilePath)];
128
124
  }
129
125
  if (!fs_1.existsSync(generatedDirectory)) {
130
126
  fs_1.mkdirSync(generatedDirectory, { recursive: true });
131
127
  }
132
- return [4 /*yield*/, sharp_1.default(sourceFilePath)
133
- .rotate()
134
- .resize(width ? Number(width) : undefined, height ? Number(height) : undefined, {
135
- background: background === "t" ? "transparent" : "#" + background,
136
- fastShrinkOnLoad: false,
137
- fit: FIT_OPTIONS[fit] || "cover",
138
- position: POSITION_OPTIONS[position] || "centre",
139
- withoutEnlargement: originalExtension !== "svg",
140
- })];
141
- case 1:
128
+ sourcePxDirectories = sourcePxArray.map(function (_, index) { return originalFilename.charAt(index); });
129
+ sourceDirectoryPart = disableNamespace ? sourcePathOrUrl : sourcePathOrUrl + "/" + namespace;
130
+ sourceDirectory = sourcePxDirectories.length > 0
131
+ ? sourceDirectoryPart + "/" + sourcePxDirectories.join("/")
132
+ : sourceDirectoryPart;
133
+ sourceFilename = originalFilename + "." + originalExtension;
134
+ sourceFilePath = sourceDirectory + "/" + sourceFilename;
135
+ if (!sourcePathOrUrl.startsWith("https://")) return [3 /*break*/, 3];
136
+ return [4 /*yield*/, node_fetch_1.default(sourceFilePath)];
137
+ case 1: return [4 /*yield*/, (_c.sent()).buffer()];
138
+ case 2:
139
+ sourceFilePath = _c.sent();
140
+ _c.label = 3;
141
+ case 3: return [4 /*yield*/, sharp_1.default(sourceFilePath)
142
+ .rotate()
143
+ .resize(width ? Number(width) : undefined, height ? Number(height) : undefined, {
144
+ background: background === "t" ? "transparent" : "#" + background,
145
+ fastShrinkOnLoad: false,
146
+ fit: FIT_OPTIONS[fit] || "cover",
147
+ position: POSITION_OPTIONS[position] || "centre",
148
+ withoutEnlargement: originalExtension !== "svg",
149
+ })];
150
+ case 4:
142
151
  pipeline = _c.sent();
143
152
  if (isTrim(trim)) {
144
153
  pipeline.trim(getTrimValue(trim));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/resizer",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "main": "index.js",
5
5
  "description": "UXF Resizer",
6
6
  "author": "UXFans <dev@uxf.cz>",
@@ -31,13 +31,13 @@
31
31
  "@types/path-to-regexp": "^1.7.0",
32
32
  "@types/sharp": "^0.28.5",
33
33
  "@types/supertest": "^2.0.11",
34
- "@uxf/eslint-config": "^1.0.3",
34
+ "@typescript-eslint/eslint-plugin": "^5.11.0",
35
+ "@uxf/eslint-config": "^1.2.3",
35
36
  "concurrently": "^6.2.1",
36
37
  "crypto-js": "^4.1.1",
37
- "eslint": "^7.32.0",
38
- "eslint-config-prettier": "8.3.0",
39
- "eslint-plugin-prettier": "3.4.0",
40
- "eslint-plugin-react": "7.24.0",
38
+ "eslint": "^8.8.0",
39
+ "eslint-config-prettier": "^8.3.0",
40
+ "eslint-plugin-prettier": "^4.0.0",
41
41
  "jest": "^27.0.6",
42
42
  "jest-junit": "^12.2.0",
43
43
  "node-fetch": "^2.6.1",