picslim 0.0.7 → 0.0.8

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.
Files changed (3) hide show
  1. package/config.json +8 -0
  2. package/package.json +23 -2
  3. package/picslim.js +115 -127
package/config.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "inputDir": "./in",
3
+ "outputDir": "./min",
4
+ "quality": 80,
5
+ "maxWidth": null,
6
+ "maxHeight": null,
7
+ "compressionLevel": 9
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "picslim",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Picslim is a Node.js package that allows you to optimize images in a specified directory.",
5
5
  "main": "picslim.js",
6
6
  "bin": {
@@ -8,7 +8,9 @@
8
8
  },
9
9
  "source": "picslim.js",
10
10
  "scripts": {
11
- "start": "node picslim.js -q 80"
11
+ "start": "node picslim.js -q 80",
12
+ "format": "standard --fix",
13
+ "prepare": "husky install"
12
14
  },
13
15
  "keywords": [
14
16
  "optimization",
@@ -26,11 +28,30 @@
26
28
  "license": "MIT",
27
29
  "files": [
28
30
  "picslim.js",
31
+ "config.json",
29
32
  "package.json",
30
33
  "README.md"
31
34
  ],
35
+ "eslintConfig": {
36
+ "extends": "./node_modules/standard/eslintrc.json"
37
+ },
38
+ "husky": {
39
+ "hooks": {
40
+ "pre-commit": "lint-staged"
41
+ }
42
+ },
43
+ "lint-staged": {
44
+ "*.{js}": [
45
+ "standard --fix"
46
+ ]
47
+ },
32
48
  "dependencies": {
33
49
  "sharp": "^0.32.6",
34
50
  "yargs": "^17.7.2"
51
+ },
52
+ "devDependencies": {
53
+ "husky": "^8.0.0",
54
+ "lint-staged": "^15.0.2",
55
+ "standard": "^17.1.0"
35
56
  }
36
57
  }
package/picslim.js CHANGED
@@ -1,22 +1,21 @@
1
1
  #!/usr/bin/env node
2
- const fs = require("fs").promises;
3
- const sharp = require("sharp");
4
- const yargs = require("yargs");
2
+ const fs = require('fs').promises
3
+ const sharp = require('sharp')
4
+ const yargs = require('yargs')
5
5
 
6
6
  /**
7
7
  * Parses command line arguments using yargs library.
8
8
  */
9
- function parseArguments()
10
- {
11
- return yargs.options({
12
- c: {
13
- alias: "config",
14
- describe: "Path to the configuration file",
15
- demandOption: false,
16
- type: "string",
17
- default: "config.json",
18
- },
19
- }).argv;
9
+ function parseArguments () {
10
+ return yargs.options({
11
+ c: {
12
+ alias: 'config',
13
+ describe: 'Path to the configuration file',
14
+ demandOption: false,
15
+ type: 'string',
16
+ default: 'config.json'
17
+ }
18
+ }).argv
20
19
  }
21
20
 
22
21
  /**
@@ -24,13 +23,12 @@ function parseArguments()
24
23
  *
25
24
  * @param {string} dir - The directory to verify.
26
25
  */
27
- async function createOutputDirectory(dir)
28
- {
29
- try {
30
- await fs.access(dir);
31
- } catch ( error ) {
32
- await fs.mkdir(dir);
33
- }
26
+ async function createOutputDirectory (dir) {
27
+ try {
28
+ await fs.access(dir)
29
+ } catch (error) {
30
+ await fs.mkdir(dir)
31
+ }
34
32
  }
35
33
 
36
34
  /**
@@ -44,90 +42,83 @@ async function createOutputDirectory(dir)
44
42
  * @param {number} quality - Image quality.
45
43
  * @param {number} compressionLevel - PNG compression level.
46
44
  */
47
- async function processImage(inputPath, outputPath, file, maxWidth, maxHeight, quality, compressionLevel)
48
- {
49
- try {
50
- const image = sharp(inputPath);
51
- const metadata = await image.metadata();
52
- const originalWidth = metadata.width;
53
- const originalHeight = metadata.height;
54
- const imageProcessor = image.resize(
55
- originalWidth > maxWidth ? maxWidth : null,
56
- originalHeight > maxHeight ? maxHeight : null
57
- );
58
-
59
- if ( file.match(/\.(jpg|jpeg)$/i) ) {
60
- await imageProcessor.jpeg({quality}).toFile(outputPath);
61
- console.log(`Optimized JPEG image: ${file}`);
62
- } else if ( file.match(/\.(png)$/i) ) {
63
- await imageProcessor.png({quality, compressionLevel}).toFile(outputPath);
64
- console.log(`Optimized PNG image: ${file}`);
65
- }
66
- } catch ( error ) {
67
- console.error(`Optimization error ${file}: `, error);
68
- }
45
+ async function processImage (inputPath, outputPath, file, maxWidth, maxHeight, quality, compressionLevel) {
46
+ try {
47
+ const image = sharp(inputPath)
48
+ const metadata = await image.metadata()
49
+ const originalWidth = metadata.width
50
+ const originalHeight = metadata.height
51
+ const imageProcessor = image.resize(
52
+ originalWidth > maxWidth ? maxWidth : null,
53
+ originalHeight > maxHeight ? maxHeight : null
54
+ )
55
+
56
+ if (file.match(/\.(jpg|jpeg)$/i)) {
57
+ await imageProcessor.jpeg({ quality }).toFile(outputPath)
58
+ console.log(`Optimized JPEG image: ${file}`)
59
+ } else if (file.match(/\.(png)$/i)) {
60
+ await imageProcessor.png({ quality, compressionLevel }).toFile(outputPath)
61
+ console.log(`Optimized PNG image: ${file}`)
62
+ }
63
+ } catch (error) {
64
+ console.error(`Optimization error ${file}: `, error)
65
+ }
69
66
  }
70
67
 
71
-
72
68
  /**
73
69
  * Load settings from a configuration file.
74
70
  *
75
71
  * @param {string} configFile - Path to the configuration file.
76
72
  */
77
- async function loadConfig(configFile)
78
- {
79
- try {
80
-
81
- const configData = await fs.readFile(configFile, "utf8");
82
-
83
- if ( configData.trim() === '' ) {
84
- console.error("Configuration file is empty.");
85
- process.exit(1);
86
- }
87
-
88
- if ( !validateJson(configData) ) {
89
- console.error("Configuration file is not a valid JSON object.");
90
- process.exit(1);
91
- }
92
-
93
- const config = JSON.parse(configData);
94
-
95
- validateConfig(config);
96
-
97
- if ( typeof config !== 'object' || Array.isArray(config) ) {
98
- console.error("Configuration file is not a valid JSON object.");
99
- process.exit(1);
100
- }
73
+ async function loadConfig (configFile) {
74
+ try {
75
+ const configData = await fs.readFile(configFile, 'utf8')
76
+
77
+ if (configData.trim() === '') {
78
+ console.error('Configuration file is empty.')
79
+ process.exit(1)
80
+ }
81
+
82
+ if (!validateJson(configData)) {
83
+ console.error('Configuration file is not a valid JSON object.')
84
+ process.exit(1)
85
+ }
86
+
87
+ const config = JSON.parse(configData)
88
+
89
+ validateConfig(config)
90
+
91
+ if (typeof config !== 'object' || Array.isArray(config)) {
92
+ console.error('Configuration file is not a valid JSON object.')
93
+ process.exit(1)
94
+ }
95
+
96
+ if (!config.inputDir || !config.outputDir) {
97
+ console.error("Configuration error: 'inputDir' and 'outputDir' are required fields.")
98
+ process.exit(1)
99
+ }
100
+
101
+ return config
102
+ } catch (error) {
103
+ console.error('Error loading or parsing the configuration file: ', error)
104
+ process.exit(1)
105
+ }
106
+ }
101
107
 
108
+ function validateJson (json) {
109
+ const isJson = (str) => {
110
+ try {
111
+ JSON.parse(str)
112
+ } catch (e) {
113
+ // Error
114
+ // JSON is not okay
115
+ return false
116
+ }
102
117
 
103
- if ( !config.inputDir || !config.outputDir ) {
104
- console.error("Configuration error: 'inputDir' and 'outputDir' are required fields.");
105
- process.exit(1);
106
- }
118
+ return true
119
+ }
107
120
 
108
- return config;
109
- } catch ( error ) {
110
- console.error("Error loading or parsing the configuration file: ", error);
111
- process.exit(1);
112
- }
113
- }
114
-
115
- function validateJson(json)
116
- {
117
- const isJson = (str) =>
118
- {
119
- try {
120
- JSON.parse(str);
121
- } catch ( e ) {
122
- //Error
123
- //JSON is not okay
124
- return false;
125
- }
126
-
127
- return true;
128
- }
129
-
130
- return isJson(json);
121
+ return isJson(json)
131
122
  }
132
123
 
133
124
  /**
@@ -135,42 +126,39 @@ function validateJson(json)
135
126
  *
136
127
  * @param {object} config - The loaded configuration object.
137
128
  */
138
- function validateConfig(config)
139
- {
140
-
141
- if ( !config.inputDir || !config.outputDir ) {
142
- console.error("Configuration error: 'inputDir' and 'outputDir' are required fields.");
143
- process.exit(1);
144
- }
129
+ function validateConfig (config) {
130
+ if (!config.inputDir || !config.outputDir) {
131
+ console.error("Configuration error: 'inputDir' and 'outputDir' are required fields.")
132
+ process.exit(1)
133
+ }
145
134
  }
146
135
 
147
136
  /**
148
137
  * The main function that processes all image files in the input directory.
149
138
  */
150
- async function main()
151
- {
152
- const argv = parseArguments();
153
- const config = await loadConfig(argv.config);
154
-
155
- const inputDir = config.inputDir;
156
- const outputDir = config.outputDir;
157
- const quality = config.quality;
158
- const maxWidth = config.maxWidth;
159
- const maxHeight = config.maxHeight;
160
- const compressionLevel = config.compressionLevel;
161
-
162
- await createOutputDirectory(outputDir);
163
-
164
- try {
165
- const files = await fs.readdir(inputDir);
166
- for ( const file of files ) {
167
- const inputPath = `${inputDir}/${file}`;
168
- const outputPath = `${outputDir}/${file}`;
169
- await processImage(inputPath, outputPath, file, maxWidth, maxHeight, quality, compressionLevel);
170
- }
171
- } catch ( error ) {
172
- console.error("Error reading input directory: ", error);
173
- }
139
+ async function main () {
140
+ const argv = parseArguments()
141
+ const config = await loadConfig(argv.config)
142
+
143
+ const inputDir = config.inputDir
144
+ const outputDir = config.outputDir
145
+ const quality = config.quality
146
+ const maxWidth = config.maxWidth
147
+ const maxHeight = config.maxHeight
148
+ const compressionLevel = config.compressionLevel
149
+
150
+ await createOutputDirectory(outputDir)
151
+
152
+ try {
153
+ const files = await fs.readdir(inputDir)
154
+ for (const file of files) {
155
+ const inputPath = `${inputDir}/${file}`
156
+ const outputPath = `${outputDir}/${file}`
157
+ await processImage(inputPath, outputPath, file, maxWidth, maxHeight, quality, compressionLevel)
158
+ }
159
+ } catch (error) {
160
+ console.error('Error reading input directory: ', error)
161
+ }
174
162
  }
175
163
 
176
- main();
164
+ main()