@massimo-cassandro/create-favicons 1.1.0 → 1.3.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/index.mjs CHANGED
@@ -9,12 +9,13 @@ import * as path from 'path';
9
9
 
10
10
  import chalk from 'chalk';
11
11
 
12
+ import { parseParams } from './src/parse-params.mjs';
13
+ import { default_params } from './src/default-params.mjs';
12
14
  import { createFavicons } from './src/create-favicons.mjs';
13
- import { defaults } from './src/defaults.mjs';
14
15
  import { init } from './src/init.mjs';
15
16
 
16
17
  // nome del file di configurazione, se utilizzato
17
- const cfg_filename = 'create-favicons-cfg.mjs';
18
+ const config_filename = 'create-favicons-cfg.mjs';
18
19
 
19
20
  try {
20
21
 
@@ -25,39 +26,39 @@ try {
25
26
 
26
27
  } else {
27
28
 
28
- let params = {};
29
+ let work_dir;
29
30
  const dir_param_idx = process.argv.findIndex(el => /^--dir/.test(el) );
30
31
 
31
32
  if(dir_param_idx !== -1) {
32
- [, params.work_dir] = process.argv[dir_param_idx].split('=');
33
+ [, work_dir] = process.argv[dir_param_idx].split('=');
33
34
 
34
35
  } else {
35
- params.work_dir = './';
36
+ work_dir = './';
36
37
  }
37
38
 
38
- if(fs.existsSync(path.resolve(params.work_dir, cfg_filename))) {
39
+ work_dir = path.resolve(process.cwd(), work_dir) ;
39
40
 
40
- import(path.resolve(params.work_dir, cfg_filename))
41
- .then((custom_params) => {
42
41
 
43
- if(Array.isArray(custom_params.default)) {
42
+ if(fs.existsSync(path.resolve(work_dir, config_filename))) {
44
43
 
45
- custom_params.default.forEach(item => {
46
- createFavicons({ ...defaults, ...params, ...item });
47
- });
44
+ import(path.resolve(work_dir, config_filename))
45
+ .then((config_params) => {
46
+
47
+ const imported_params = [...(Array.isArray(config_params.default)? config_params.default : [config_params.default])];
48
+
49
+ imported_params.forEach(params_item => {
50
+ createFavicons(parseParams(params_item, work_dir));
51
+ });
48
52
 
49
- } else {
50
- createFavicons({ ...defaults, ...params, ...custom_params.default });
51
- }
52
53
  });
53
54
 
54
- } else if(fs.existsSync(path.resolve(params.work_dir, defaults.src_img))) {
55
+ } else if(default_params.src_img && fs.existsSync(path.resolve(work_dir, default_params.src_img))) {
55
56
 
56
- createFavicons({...defaults, ...params});
57
+ createFavicons(parseParams(null, work_dir));
57
58
 
58
59
  } else {
59
60
 
60
- throw `'${cfg_filename}' e '${defaults.src_img}' non presenti`;
61
+ throw new Error( `'${config_filename}' e '${defaults.src_img}' non presenti`);
61
62
  }
62
63
 
63
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/create-favicons",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Favicon files builder",
5
5
  "bin": {
6
6
  "create-favicons": "./index.mjs"
@@ -14,7 +14,6 @@
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
17
-
18
17
  "author": "Massimo Cassandro",
19
18
  "license": "MIT",
20
19
  "repository": {
@@ -43,14 +42,8 @@
43
42
  },
44
43
  "dependencies": {
45
44
  "chalk": "^5.3.0",
46
- "imagemin": "^8.0.1",
47
- "imagemin-jpegtran": "^7.0.0",
48
- "imagemin-pngquant": "^9.0.2",
49
- "sharp": "^0.32.6",
50
- "svgo": "^3.0.4",
51
- "to-ico": "^1.1.5"
52
- },
53
- "devDependencies": {
54
- "@massimo-cassandro/linters-config": "^1.6.1"
45
+ "sharp": "^0.33.2",
46
+ "sharp-ico": "^0.1.5",
47
+ "svgo": "^3.2.0"
55
48
  }
56
49
  }
package/readme.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  Crea i file favicons come descritto in [How to Favicon in 2024](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs).
4
4
 
5
- Utilizzo:
5
+ I file da elaborare devono essere in formato SVG, mentre quelli generati sono in formato SVG (favicon), PNG (apple-touch-icon e altri file per android), e ICO (altro favicon per compatibilità con i browser meno recenti). Vengono inoltre genrati i file `manifest.webmanifest` e uno snippet html, opzionale, con i tag `link` per l'inserimento degli elementi generati.
6
+
7
+ Le immagini sono generate con [Sharp](https://sharp.pixelplumbing.com/), [SVGO](https://github.com/svg/svgo) e [sharp-ico](https://github.com/ssnangua/sharp-ico).
8
+
9
+ ## Utilizzo
6
10
 
7
11
  ```bash
8
12
  npx create-favicons [--dir=./path/to/dir]
@@ -32,7 +36,7 @@ const params = [{ /* ... */ }];
32
36
  export default params;
33
37
  ```
34
38
 
35
- `params` può essere un ogetto o un array. In quest'ultimo caso, ogni elemento dell'array corrisponde ad un diverso set di favicons.
39
+ `params` può essere un oggetto o un array. In quest'ultimo caso, ogni elemento dell'array corrisponde ad un diverso set di favicons.
36
40
 
37
41
  Per creare un file di cfg di esempio **nella directory corrente** (con tutti i valori di default e la loro descrizione),
38
42
  utilizzare il comando:
@@ -1,200 +1,36 @@
1
1
  /* eslint-disable no-console */
2
2
 
3
- import * as fs from 'fs';
4
- import * as path from 'path';
3
+ // import * as fs from 'fs';
4
+ // import * as path from 'path';
5
5
  import chalk from 'chalk';
6
6
 
7
- import sharp from 'sharp';
8
- import toIco from 'to-ico';
9
- import { optimize } from 'svgo';
10
- import imagemin from 'imagemin';
11
- import imageminJpegtran from 'imagemin-jpegtran';
12
- import imageminPngquant from 'imagemin-pngquant';
13
-
14
- import { printFrame } from './print-frame.mjs';
15
- import { remove_homedir_string } from './remove-homedir-string.mjs';
7
+ import { createIco } from './create-ico.mjs';
8
+ import { createPng } from './create-png.mjs';
9
+ import { createSvg } from './create-svg.mjs';
10
+ import { createWebmanifest } from './create-webmanifest.mjs';
11
+ import { createSnippet } from './create-snippet.mjs';
12
+ import { printResult } from './print-result.mjs';
16
13
 
17
14
 
18
15
  export function createFavicons(params) {
19
16
 
20
17
  try {
21
18
 
22
- const output_dir = path.resolve(params.work_dir, params.output_dir);
23
-
24
- if (!fs.existsSync(output_dir)){
25
- fs.mkdirSync(output_dir);
26
- }
27
-
19
+ console.error(chalk.green('Creating favicons...'));
28
20
 
29
- // https://sharp.pixelplumbing.com/api-constructor
30
21
  Promise.all([
31
- ['apple-touch-icon.png', 180],
32
- ['icon-192.png', 192],
33
- ['icon-512.png', 512]
34
- ].map(size => {
35
- sharp(path.resolve(params.work_dir, params.src_img))
36
- .resize({ width: size[1], fit: 'inside' })
37
- .png()
38
- // .then(info => console.log(info))
39
- // .toFile(`${output_dir}/${size[0]}`)
40
- .toBuffer()
41
- .then(bufferData => {
42
-
43
- // ottimizzazione PNG / JPG
44
- // https://github.com/imagemin/imagemin
45
- // https://github.com/imagemin/imagemin-pngquant
46
- // https://github.com/imagemin/imagemin-jpegtran
47
- // https://web.dev/use-imagemin-to-compress-images/
48
-
49
- imagemin.buffer(bufferData, {
50
- plugins: [
51
- imageminJpegtran(),
52
- imageminPngquant({
53
- quality: params.imagemin_png_quality,
54
- dithering: false,
55
- strip: true,
56
- verbose: true
57
- })
58
- ]
59
- }).then( result => {
60
- fs.writeFileSync(`${output_dir}/${size[0]}`, result);
61
- });
62
-
63
- })
64
- .catch(err => { throw err; });
65
-
66
- }));
67
-
68
- // favicon.ico
69
- // https://github.com/kevva/to-ico
70
- // alternativa: https://github.com/steambap/png-to-ico
71
-
72
- // const ico_source = fs.readFileSync(`${output_dir}/apple-touch-icon.png`);
73
-
74
- sharp(path.resolve(params.work_dir, params.small_src_img?? params.src_img))
75
- .png()
76
- // .then(info => console.log(info))
77
- .toBuffer()
78
- .then(bufferData => {
79
-
80
- toIco([bufferData], {
81
- sizes: [16, 32],
82
- resize: true
83
- }).then( result => {
84
- fs.writeFileSync(`${output_dir}/favicon.ico`, result);
85
- });
22
+ createSvg(params),
23
+ createPng(params),
24
+ createIco(params),
25
+ createWebmanifest(params),
26
+ createSnippet(params),
27
+ ])
28
+ .then(result => {
29
+ printResult(params);
86
30
 
87
31
  })
88
- .catch(err => { throw err; });
89
-
90
-
91
- // favicon.svg (SVGO)
92
- // TODO add extra config ???
93
- const svgString = fs.readFileSync(path.resolve(params.work_dir, params.small_src_img?? params.src_img), 'utf8');
94
- const svg_result = optimize(svgString, {
95
- multipass: true,
96
- });
97
- fs.writeFileSync(`${output_dir}/favicon.svg`, svg_result.data, {force: true});
98
-
99
- // web manifest
100
- const manifest = {
101
- icons: [192, 512].map( size => {
102
- return { src: `./icon-${size}.png`, type: 'image/png', sizes: `${size}x${size}` };
103
- }),
104
- ...(params.webmanifest_extra?? {})
105
- };
106
-
107
- fs.writeFileSync(`${output_dir}/manifest.webmanifest`, JSON.stringify(manifest, null, ' '));
108
-
109
-
110
- const snippet_path = params.snippet_path? path.resolve(params.work_dir, params.snippet_path) : output_dir;
111
-
112
- // snippet
113
- if(params.snippet_name || params.snippet_target_file) {
114
-
115
- if (!params.snippet_target_file && !fs.existsSync(snippet_path)){
116
- fs.mkdirSync(snippet_path);
117
- }
118
-
119
- params.snippet_language = params.snippet_language.toLowerCase();
120
-
121
- const cache_buster = params.add_cache_buster? `?_=${Date.now()}` : '',
122
- create_href = nome_file => params.href_template.replace('%_file_name_%', nome_file)
123
- .replace('%_cache_buster_%', cache_buster);
124
-
125
-
126
- let snippet_content = `<link rel="icon" href="${create_href('favicon.ico')}" sizes="any">\n` +
127
- `<link rel="icon" href="${create_href('favicon.svg')}" type="image/svg+xml">\n` +
128
- `<link rel="apple-touch-icon" href="${create_href('apple-touch-icon.png')}">\n` +
129
- `<link rel="manifest" href="${create_href('manifest.webmanifest')}">`;
130
-
131
- if (params.snippet_language === 'pug') {
132
- snippet_content = snippet_content.replace(/<link (.*?)>/g, 'link($1)');
133
- }
134
-
135
- snippet_content = params.snippet_template.replace('%_link_tags_%', snippet_content);
136
-
137
- if (params.snippet_target_file) {
138
-
139
- params.snippet_target_file = path.resolve(params.work_dir, params.snippet_target_file);
140
-
141
- if (fs.existsSync(params.snippet_target_file)) {
142
- const targetFileContent = fs.readFileSync(path.resolve(params.snippet_target_file), 'utf8'),
143
- regexp = /<!-- ?favicon-snippet-start ?-->(.*?)<!-- ?favicon-snippet-end ?-->/mis;
144
-
145
- fs.writeFileSync(params.snippet_target_file,
146
- targetFileContent.replace(regexp,
147
- `<!-- favicon-snippet-start -->\n${snippet_content}\n<!-- favicon-snippet-end -->`
148
- )
149
- );
150
-
151
- } else {
152
- throw `Il file '${params.snippet_target_file}' non esiste`;
153
- }
154
-
155
- } else {
156
-
157
- fs.writeFileSync(
158
- `${snippet_path}/${params.snippet_name}`,
159
- snippet_content
160
- );
161
-
162
- }
163
- }
164
-
165
- // print result
166
- let extra_strings = [];
167
-
168
- if(snippet_path !== output_dir && params.snippet_name !== null) {
169
- extra_strings = [
170
- {string: ''},
171
- {string: `Il file snippet '${params.snippet_name}' è stato salvato nella directory:`, color: 'green'},
172
- {string: remove_homedir_string(snippet_path), color: 'yellow'},
173
- ];
174
-
175
- } else if(params.snippet_name === null) {
176
- extra_strings = [
177
- {string: ''},
178
- {string: 'Il file snippet non è stato generato', color: 'magentaBright'},
179
- ];
180
- }
181
-
182
-
183
- printFrame({
184
- strings: [
185
- {string: '** Creazione favicons completata **', color: 'bgGreen'},
186
- {string: ''},
187
- {string: 'I file generati sono nella directory:', color: 'green'},
188
- {string: remove_homedir_string(output_dir), color: 'yellow'},
189
- ...extra_strings
190
- ],
191
- frameColor: 'green',
192
- frameType: 'single'
193
- });
194
-
195
32
 
196
33
  } catch(err) {
197
-
198
34
  console.error(chalk.bgRed(` ${err} `));
199
35
  }
200
36
 
@@ -0,0 +1,32 @@
1
+ import * as fs from 'fs';
2
+ import sharp from 'sharp';
3
+ import toIco from 'to-ico';
4
+
5
+
6
+ // https://github.com/kevva/to-ico
7
+ // alternativa: https://github.com/steambap/png-to-ico
8
+
9
+ // const ico_source = fs.readFileSync(`${output_dir}/apple-touch-icon.png`);
10
+
11
+ export async function createIco(params) {
12
+
13
+ await sharp(params.small_src_img?? params.src_img)
14
+ // .png()
15
+ // .then(info => console.log(info))
16
+ .toBuffer()
17
+ .then(bufferData => {
18
+
19
+ toIco([bufferData], {
20
+ sizes: [16, 32],
21
+ resize: true
22
+ }).then( async result => {
23
+ await fs.promises.writeFile(`${params.output_dir}/favicon.ico`, result, {
24
+ encoding: "utf8",
25
+ flag: "w",
26
+ mode: 0o666
27
+ });
28
+ });
29
+
30
+ })
31
+ .catch(err => { throw new Error( err + ' (createIco)'); });
32
+ }
@@ -0,0 +1,18 @@
1
+ import sharp from 'sharp';
2
+ import ico from 'sharp-ico';
3
+
4
+ // https://github.com/ssnangua/sharp-ico
5
+
6
+ export async function createIco(params) {
7
+
8
+ ico.sharpsToIco(
9
+ [sharp(params.small_src_img?? params.src_img)],
10
+ `${params.output_dir}/favicon.ico`,
11
+ {
12
+ sizes: [16, 32],
13
+ // sizes: "default", // equal to [256, 128, 64, 48, 32, 24, 16]
14
+ resizeOptions: {}, // sharp resize optinos
15
+ }
16
+ );
17
+
18
+ }
@@ -0,0 +1,21 @@
1
+ import sharp from 'sharp';
2
+
3
+ export async function createPng(params) {
4
+
5
+ // https://sharp.pixelplumbing.com/api-constructor
6
+ // https://sharp.pixelplumbing.com/api-output#png
7
+ Promise.all([
8
+ ['apple-touch-icon.png', 180],
9
+ ['icon-192.png', 192],
10
+ ['icon-512.png', 512]
11
+ ].map(file => {
12
+ sharp(params.src_img)
13
+ .resize({ width: file[1], fit: 'inside' })
14
+ .png(params.png_parameters)
15
+ .toFile(`${params.output_dir}/${file[0]}`)
16
+
17
+ }))
18
+ .catch(err => { throw new Error( err ); });
19
+
20
+
21
+ }
@@ -0,0 +1,50 @@
1
+ import * as fs from 'fs';
2
+
3
+ export async function createSnippet(params) {
4
+
5
+
6
+ if(params.create_snippet) {
7
+
8
+
9
+ const cache_buster = params.add_cache_buster? `?_=${Date.now()}` : '',
10
+ create_href = nome_file => params.href_template.replace('%_file_name_%', nome_file)
11
+ .replace('%_cache_buster_%', cache_buster);
12
+
13
+
14
+ let snippet_content = `<link rel="icon" href="${create_href('favicon.ico')}" sizes="any">\n` +
15
+ `<link rel="icon" href="${create_href('favicon.svg')}" type="image/svg+xml">\n` +
16
+ `<link rel="apple-touch-icon" href="${create_href('apple-touch-icon.png')}">\n` +
17
+ `<link rel="manifest" href="${create_href('manifest.webmanifest')}">`;
18
+
19
+ if (params.snippet_language === 'pug') {
20
+ snippet_content = snippet_content.replace(/<link (.*?)>/g, 'link($1)');
21
+ }
22
+
23
+ snippet_content = params.snippet_template.replace('%_link_tags_%', snippet_content);
24
+
25
+ if (params.snippet_target_file) {
26
+
27
+ if (fs.existsSync(params.snippet_target_file)) {
28
+ const targetFileContent = fs.readFileSync(params.snippet_target_file, 'utf8'),
29
+ regexp = /<!-- ?favicon-snippet-start ?-->(.*?)<!-- ?favicon-snippet-end ?-->/mis;
30
+
31
+ fs.promises.writeFile(params.snippet_target_file,
32
+ targetFileContent.replace(regexp,
33
+ `<!-- favicon-snippet-start -->\n${snippet_content}\n<!-- favicon-snippet-end -->`
34
+ )
35
+ );
36
+
37
+ } else {
38
+ throw new Error( `Il file '${params.snippet_target_file}' non esiste` );
39
+ }
40
+
41
+ } else {
42
+
43
+ fs.promises.writeFile(
44
+ `${params.snippet_path}/${params.snippet_name}`,
45
+ snippet_content
46
+ );
47
+
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,15 @@
1
+ import { optimize } from 'svgo';
2
+ import * as fs from 'fs/promises';
3
+
4
+ export async function createSvg(params) {
5
+
6
+ // TODO add extra config ???
7
+ fs.readFile(params.small_src_img?? params.src_img, { encoding: 'utf8' })
8
+ .then(svgString => {
9
+
10
+ const svg_result = optimize(svgString, { multipass: true});
11
+
12
+ fs.writeFile(`${params.output_dir}/favicon.svg`, svg_result.data);
13
+
14
+ });
15
+ }
@@ -0,0 +1,14 @@
1
+ import * as fs from 'fs/promises';
2
+
3
+ export async function createWebmanifest(params) {
4
+ // web manifest
5
+ const manifest = {
6
+ icons: [192, 512].map( size => {
7
+ return { src: `./icon-${size}.png`, type: 'image/png', sizes: `${size}x${size}` };
8
+ }),
9
+ ...(params.webmanifest_extra?? {})
10
+ };
11
+
12
+ fs.writeFile(`${params.output_dir}/manifest.webmanifest`, JSON.stringify(manifest, null, ' '));
13
+
14
+ }
@@ -1,4 +1,4 @@
1
- export const defaults = {
1
+ export const default_params = {
2
2
 
3
3
  // delimitazione porzione da copiare nel file init
4
4
  /*** INIT START ***/
@@ -73,16 +73,12 @@ export const defaults = {
73
73
  // problemi di caching del browser
74
74
  add_cache_buster: false,
75
75
 
76
-
77
- // IMAGEMIN PARAMETERS
78
76
  //****************************************************************************
77
+
78
+ // SHARP PNG PARAMETERS
79
79
  // parametri per i file PNG
80
- // vedi https://www.npmjs.com/package/imagemin-pngquant
81
- // Instructs pngquant to use the least amount of colors required to meet or
82
- // exceed the max quality. If conversion results in quality below the min quality
83
- // the image won't be saved.
84
- // Min and max are numbers in range 0 (worst) to 1 (perfect), similar to JPEG.
85
- imagemin_png_quality: [0.3, 0.6]
80
+ // vedi https://sharp.pixelplumbing.com/api-output#png
81
+ png_parameters: {compressionLevel: 5, quality: 60, palette: true}
86
82
 
87
83
 
88
84
  /*** INIT END ***/
package/src/init.mjs CHANGED
@@ -22,7 +22,7 @@ export function init() {
22
22
 
23
23
  const start_string = '/*** INIT START ***/',
24
24
  end_string = '/*** INIT END ***/',
25
- init_start_text = fs.readFileSync(src_dir +'./init-start.txt', 'utf8');
25
+ init_start_text = fs.readFileSync(src_dir +'./init-start-text.txt', 'utf8');
26
26
 
27
27
 
28
28
 
@@ -0,0 +1,48 @@
1
+ import { default_params } from './default-params.mjs';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+
5
+ export function parseParams(config_params = null, work_dir = process.cwd()) {
6
+
7
+ try {
8
+
9
+ const params = {...default_params, ...(config_params??{})}
10
+ params.work_dir = work_dir;
11
+
12
+ [
13
+ 'src_img',
14
+ 'small_src_img',
15
+ 'snippet_path',
16
+ 'snippet_target_file',
17
+ 'output_dir'
18
+ ].forEach(item =>
19
+ params[item] = params[item]? path.resolve(params.work_dir, params[item]) : null
20
+ );
21
+
22
+ // creazione dir output se non esiste
23
+ if (!fs.existsSync(params.output_dir)){
24
+ fs.mkdirSync(params.output_dir);
25
+ }
26
+
27
+ // definizione snippet_path e creazione dir se necessario
28
+ params.create_snippet = params.snippet_name || params.snippet_target_file;
29
+
30
+ if(params.create_snippet) {
31
+
32
+ params.snippet_path = params.snippet_path?? params.output_dir;
33
+
34
+ if (!params.snippet_target_file && !fs.existsSync(params.snippet_path )){
35
+ fs.mkdirSync(params.snippet_path );
36
+ }
37
+
38
+ params.snippet_language = params.snippet_language.toLowerCase();
39
+ }
40
+
41
+
42
+ return params;
43
+
44
+ } catch(e) {
45
+ console.error( e ); // eslint-disable-line
46
+ }
47
+
48
+ }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable no-console */
2
2
  import chalk from 'chalk';
3
3
 
4
+ // https://github.com/chalk/chalk
4
5
  export function printFrame(options) {
5
6
 
6
7
  /*
@@ -27,7 +28,6 @@ export function printFrame(options) {
27
28
 
28
29
  options.strings = options.strings.map(item => {return {...string_defaults, ...item }; });
29
30
 
30
- // TODO bold underline ecc...
31
31
  // aggiunta spazi sulle righe `bg`
32
32
  options.strings.forEach(item => {
33
33
  if(/^bg/.test(item.color)) {
@@ -0,0 +1,61 @@
1
+ import { printFrame } from './print-frame.mjs';
2
+ import { remove_homedir_string } from './remove-homedir-string.mjs';
3
+ import * as fs from 'fs';
4
+
5
+
6
+ // https://github.com/chalk/chalk
7
+ export function printResult(params) {
8
+
9
+ function printSize(size) {
10
+ if(size > 1024) {
11
+ return `${(size / 1024).toFixed(2)} KB`;
12
+ } else {
13
+ return `${size} B`;
14
+
15
+ }
16
+ }
17
+
18
+ // print result
19
+ let extra_strings = [];
20
+
21
+ // immagini generate e dimensioni
22
+ [
23
+ 'apple-touch-icon.png',
24
+ 'favicon.ico',
25
+ 'favicon.svg',
26
+ 'icon-192.png',
27
+ 'icon-512.png',
28
+ 'manifest.webmanifest'
29
+ ].forEach(item => {
30
+ const stats = fs.statSync(`${params.output_dir}/${item}`);
31
+ extra_strings.push({string: `${item}: ${printSize(stats.size)}`, color: 'greenBright'});
32
+ });
33
+
34
+ if(params.snippet_path !== params.output_dir && params.snippet_name !== null) {
35
+ extra_strings.push(
36
+ {string: ''},
37
+ {string: `Il file snippet '${params.snippet_name}' è stato salvato nella directory:`, color: 'green'},
38
+ {string: remove_homedir_string(params.snippet_path ), color: 'yellow'},
39
+ );
40
+
41
+ } else if(params.snippet_name === null) {
42
+ extra_strings.push(
43
+ {string: ''},
44
+ {string: 'Il file snippet non è stato generato', color: 'magentaBright'},
45
+ );
46
+ }
47
+
48
+
49
+ printFrame({
50
+ strings: [
51
+ {string: '** Creazione favicons completata **', color: 'bgGreen'},
52
+ {string: ''},
53
+ {string: 'I file generati sono nella directory:', color: 'green'},
54
+ {string: remove_homedir_string(params.output_dir), color: 'yellow'},
55
+ {string: ''},
56
+ ...extra_strings
57
+ ],
58
+ frameColor: 'green',
59
+ frameType: 'single'
60
+ });
61
+ }
File without changes