@uxf/resizer 1.0.2 → 1.1.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 +16 -2
- package/bin/uxf-resizer.js +70 -20
- package/index.js +46 -18
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -5,6 +5,20 @@
|
|
|
5
5
|
// install resizer
|
|
6
6
|
yarn global add @uxf/resizer
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Environment variables:
|
|
9
|
+
UXF_RESIZER_SOURCE_PATH - required
|
|
10
|
+
UXF_RESIZER_GENERATE_PATH - required
|
|
11
|
+
|
|
12
|
+
Options
|
|
13
|
+
--disable-namespace [boolean] [default: false]
|
|
14
|
+
--source-folder-depth Depth of the source folder [number] [default: 2]
|
|
15
|
+
--generated-folder-depth Depth of the generated folder
|
|
16
|
+
[number] [default: 2]
|
|
17
|
+
--filename-regexp Filename regexp (see:
|
|
18
|
+
https://github.com/pillarjs/path-to-regexp)
|
|
19
|
+
[string]
|
|
20
|
+
-h, --help Show help [boolean]
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--version Show version number [boolean]
|
|
10
24
|
```
|
package/bin/uxf-resizer.js
CHANGED
|
@@ -36,6 +36,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
40
|
+
var t = {};
|
|
41
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
42
|
+
t[p] = s[p];
|
|
43
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
44
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
45
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
46
|
+
t[p[i]] = s[p[i]];
|
|
47
|
+
}
|
|
48
|
+
return t;
|
|
49
|
+
};
|
|
39
50
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
51
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
52
|
};
|
|
@@ -44,19 +55,45 @@ var process_1 = require("process");
|
|
|
44
55
|
var yargs_1 = __importDefault(require("yargs"));
|
|
45
56
|
var index_1 = require("../index");
|
|
46
57
|
var uxfResizer = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
47
|
-
var help, sourcePath_1, generatePath_1;
|
|
48
|
-
return __generator(this, function (
|
|
58
|
+
var _a, help, options, sourceFolderDepth_1, generatedFolderDepth_1, filenameRegexp_1, disableNamespace_1, sourcePath_1, generatePath_1;
|
|
59
|
+
return __generator(this, function (_b) {
|
|
49
60
|
yargs_1.default.command("$0", "UXF Resizer", function (yargs) {
|
|
50
|
-
yargs.demandCommand(0, 0).usage("
|
|
61
|
+
yargs.demandCommand(0, 0).usage("\nUsage:\n uxf-resizer\n \nEnvironment variables:\n UXF_RESIZER_SOURCE_PATH - required\n UXF_RESIZER_GENERATE_PATH - required");
|
|
62
|
+
})
|
|
63
|
+
.option("disable-namespace", {
|
|
64
|
+
group: "Options",
|
|
65
|
+
default: false,
|
|
66
|
+
type: "boolean",
|
|
67
|
+
})
|
|
68
|
+
.option("source-folder-depth", {
|
|
69
|
+
group: "Options",
|
|
70
|
+
description: "Depth of the source folder",
|
|
71
|
+
default: 2,
|
|
72
|
+
type: "number",
|
|
73
|
+
})
|
|
74
|
+
.option("generated-folder-depth", {
|
|
75
|
+
group: "Options",
|
|
76
|
+
description: "Depth of the generated folder",
|
|
77
|
+
default: 2,
|
|
78
|
+
type: "number",
|
|
79
|
+
})
|
|
80
|
+
.option("filename-regexp", {
|
|
81
|
+
group: "Options",
|
|
82
|
+
description: "Filename regexp (see: https://github.com/pillarjs/path-to-regexp)",
|
|
83
|
+
type: "string",
|
|
51
84
|
})
|
|
52
85
|
.option("h", { alias: "help", group: "Options" })
|
|
53
86
|
.strict(false)
|
|
54
87
|
.exitProcess(false);
|
|
55
88
|
try {
|
|
56
|
-
|
|
89
|
+
_a = yargs_1.default.parse(process_1.argv.slice(2)), help = _a.help, options = __rest(_a, ["help"]);
|
|
57
90
|
if (help) {
|
|
58
91
|
return [2 /*return*/, 0];
|
|
59
92
|
}
|
|
93
|
+
sourceFolderDepth_1 = options["source-folder-depth"];
|
|
94
|
+
generatedFolderDepth_1 = options["generated-folder-depth"];
|
|
95
|
+
filenameRegexp_1 = options["filename-regexp"];
|
|
96
|
+
disableNamespace_1 = options["disable-namespace"];
|
|
60
97
|
sourcePath_1 = process_1.env.UXF_RESIZER_SOURCE_PATH;
|
|
61
98
|
if (!sourcePath_1) {
|
|
62
99
|
// eslint-disable-next-line no-console
|
|
@@ -69,24 +106,37 @@ var uxfResizer = function () { return __awaiter(void 0, void 0, void 0, function
|
|
|
69
106
|
console.log("Generated directory must be set. Use environment variable UXF_RESIZER_GENERATED.");
|
|
70
107
|
return [2 /*return*/, 1];
|
|
71
108
|
}
|
|
72
|
-
return [2 /*return*/, new Promise(function (resolve) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
109
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
110
|
+
try {
|
|
111
|
+
var app_1 = index_1.createApp(sourcePath_1, generatePath_1, sourceFolderDepth_1, generatedFolderDepth_1, filenameRegexp_1, disableNamespace_1);
|
|
112
|
+
var listenedApp_1 = app_1.listen(3000, function () {
|
|
113
|
+
// eslint-disable-next-line no-console
|
|
114
|
+
console.log("\nSOURCE_PATH: " + sourcePath_1);
|
|
115
|
+
// eslint-disable-next-line no-console
|
|
116
|
+
console.log("GENERATED_PATH: " + generatePath_1);
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.log("Source folder depth: " + sourceFolderDepth_1);
|
|
119
|
+
// eslint-disable-next-line no-console
|
|
120
|
+
console.log("Generated folder depth: " + generatedFolderDepth_1);
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.log("Filename regexp: " + filenameRegexp_1);
|
|
123
|
+
// eslint-disable-next-line no-console
|
|
124
|
+
console.log("Namespace: " + (disableNamespace_1 ? "disabled" : "enabled"));
|
|
82
125
|
// eslint-disable-next-line no-console
|
|
83
|
-
console.log("
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
126
|
+
console.log("\nImage resizer app listening on port 3000");
|
|
127
|
+
if (process.env.NODE_ENV !== "production") {
|
|
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");
|
|
130
|
+
}
|
|
131
|
+
app_1.on("close", function () {
|
|
132
|
+
listenedApp_1.close();
|
|
133
|
+
resolve(true);
|
|
134
|
+
});
|
|
88
135
|
});
|
|
89
|
-
}
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
reject(e);
|
|
139
|
+
}
|
|
90
140
|
})];
|
|
91
141
|
}
|
|
92
142
|
catch (e) {
|
package/index.js
CHANGED
|
@@ -63,6 +63,7 @@ var express_1 = __importDefault(require("express"));
|
|
|
63
63
|
var fs_1 = require("fs");
|
|
64
64
|
var fs = __importStar(require("fs"));
|
|
65
65
|
var sharp_1 = __importDefault(require("sharp"));
|
|
66
|
+
var path_to_regexp_1 = require("path-to-regexp");
|
|
66
67
|
var FIT_OPTIONS = {
|
|
67
68
|
cv: "cover",
|
|
68
69
|
f: "fill",
|
|
@@ -85,33 +86,60 @@ var POSITION_OPTIONS = {
|
|
|
85
86
|
};
|
|
86
87
|
var isTrim = function (value) { return value !== "nt"; };
|
|
87
88
|
var getTrimValue = function (value) { return (isTrim(value) ? Number(value) : 0); };
|
|
88
|
-
var createApp = function (sourcePath, generatePath) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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"; }
|
|
91
|
+
var parseFilename = path_to_regexp_1.match(filenameRegexp, { decode: decodeURIComponent });
|
|
92
|
+
var generatedPxArray = Array.from({ length: generatedFolderDepth }, function (_, i) { return ":p" + (i + 1); });
|
|
93
|
+
var sourcePxArray = Array.from({ length: sourceFolderDepth }, function (_, i) { return ":p" + (i + 1); });
|
|
94
|
+
var routeRegexpBase = disableNamespace ? "/generated" : "/generated/:namespace";
|
|
95
|
+
var routeRegexp = generatedFolderDepth > 0
|
|
96
|
+
? routeRegexpBase + "/" + generatedPxArray.join("/") + "/:filename"
|
|
97
|
+
: routeRegexpBase + "/:filename";
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.log("\nExpress route regexp: " + routeRegexp);
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.log("Filename regexp: " + filenameRegexp);
|
|
102
|
+
return express_1.default().get(routeRegexp, function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
103
|
+
var _a, filename, namespace, parsedFilename, _b, originalFilename, originalExtension, fit, height, position, toFormat, trim, width, background, generatedPxDirectories, generatedDirectoryPart, generatedDirectory, generatedFilePath, sourcePxDirectories, sourceDirectoryPart, sourceDirectory, sourceFilename, sourceFilePath, pipeline, contentType, cacheMaxAge;
|
|
104
|
+
return __generator(this, function (_c) {
|
|
105
|
+
switch (_c.label) {
|
|
93
106
|
case 0:
|
|
94
|
-
_a = req.params,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (fs.existsSync(filePath)) {
|
|
99
|
-
return [2 /*return*/, res.sendFile(filePath)];
|
|
107
|
+
_a = req.params, filename = _a.filename, namespace = _a.namespace;
|
|
108
|
+
parsedFilename = parseFilename(filename);
|
|
109
|
+
if (!parsedFilename) {
|
|
110
|
+
throw new Error("Wrong filename.");
|
|
100
111
|
}
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
_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
|
+
generatedPxDirectories = generatedPxArray.map(function (_, index) { return originalFilename.charAt(index); });
|
|
114
|
+
generatedDirectoryPart = disableNamespace ? generatePath : generatePath + "/" + namespace;
|
|
115
|
+
generatedDirectory = generatedPxDirectories.length > 0
|
|
116
|
+
? generatedDirectoryPart + "/" + generatedPxDirectories.join("/")
|
|
117
|
+
: generatedDirectoryPart;
|
|
118
|
+
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;
|
|
126
|
+
if (fs.existsSync(generatedFilePath)) {
|
|
127
|
+
return [2 /*return*/, res.sendFile(generatedFilePath)];
|
|
103
128
|
}
|
|
104
|
-
|
|
129
|
+
if (!fs_1.existsSync(generatedDirectory)) {
|
|
130
|
+
fs_1.mkdirSync(generatedDirectory, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
return [4 /*yield*/, sharp_1.default(sourceFilePath)
|
|
105
133
|
.rotate()
|
|
106
134
|
.resize(width ? Number(width) : undefined, height ? Number(height) : undefined, {
|
|
107
135
|
background: background === "t" ? "transparent" : "#" + background,
|
|
108
136
|
fastShrinkOnLoad: false,
|
|
109
137
|
fit: FIT_OPTIONS[fit] || "cover",
|
|
110
138
|
position: POSITION_OPTIONS[position] || "centre",
|
|
111
|
-
withoutEnlargement:
|
|
139
|
+
withoutEnlargement: originalExtension !== "svg",
|
|
112
140
|
})];
|
|
113
141
|
case 1:
|
|
114
|
-
pipeline =
|
|
142
|
+
pipeline = _c.sent();
|
|
115
143
|
if (isTrim(trim)) {
|
|
116
144
|
pipeline.trim(getTrimValue(trim));
|
|
117
145
|
}
|
|
@@ -139,8 +167,8 @@ var createApp = function (sourcePath, generatePath) {
|
|
|
139
167
|
pipeline
|
|
140
168
|
.withMetadata({ density: 72 })
|
|
141
169
|
.toColorspace("srgb")
|
|
142
|
-
.toFile(
|
|
143
|
-
.then(function () { return res.sendFile(
|
|
170
|
+
.toFile(generatedFilePath)
|
|
171
|
+
.then(function () { return res.sendFile(generatedFilePath); })
|
|
144
172
|
.catch(function (e) {
|
|
145
173
|
// eslint-disable-next-line no-console
|
|
146
174
|
console.log(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/resizer",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"description": "UXF Resizer",
|
|
6
6
|
"author": "UXFans <dev@uxf.cz>",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"express": "^4.17.1",
|
|
20
20
|
"fs": "^0.0.1-security",
|
|
21
|
+
"path-to-regexp": "^6.2.0",
|
|
21
22
|
"process": "^0.11.10",
|
|
22
23
|
"sharp": "^0.28.3",
|
|
23
24
|
"yargs": "^17.2.1"
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"@types/express": "^4.17.13",
|
|
28
29
|
"@types/jest": "^27.0.1",
|
|
29
30
|
"@types/node-fetch": "^2.5.12",
|
|
31
|
+
"@types/path-to-regexp": "^1.7.0",
|
|
30
32
|
"@types/sharp": "^0.28.5",
|
|
31
33
|
"@types/supertest": "^2.0.11",
|
|
32
34
|
"@uxf/eslint-config": "^1.0.3",
|