@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 +53 -1
- package/bin/uxf-resizer.js +3 -3
- package/index.js +29 -20
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,9 +1,61 @@
|
|
|
1
1
|
# @uxf/resizer
|
|
2
2
|
[](https://www.npmjs.com/package/@uxf/resizer)
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
4
6
|
```
|
|
5
|
-
//
|
|
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
|
package/bin/uxf-resizer.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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/
|
|
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 (
|
|
90
|
-
if (filenameRegexp === void 0) { filenameRegexp = ":originalFilename([a-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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.
|
|
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
|
-
"@
|
|
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": "^
|
|
38
|
-
"eslint-config-prettier": "8.3.0",
|
|
39
|
-
"eslint-plugin-prettier": "
|
|
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",
|