@massimo-cassandro/create-favicons 1.4.1 → 1.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/create-favicons",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Favicon files builder",
5
5
  "bin": {
6
6
  "create-favicons": "./index.mjs"
@@ -14,16 +14,21 @@ import { printResult } from './print-result.mjs';
14
14
 
15
15
  export async function createFavicons(params) {
16
16
 
17
+ if(params.snippet_language === 'ejs') {
18
+ params.manifest_file_name = 'manifest.webmanifest.ejs';
19
+ params.webmanifest_add_hash_to_files = false;
20
+ }
21
+
17
22
  try {
18
23
 
19
24
  log('green', 'Creating favicons...');
20
25
 
21
26
  await Promise.all([
22
- createSvg(params),
23
- createPng(params),
24
- createIco(params),
25
- createWebmanifest(params),
26
- createSnippet(params),
27
+ await createSvg(params),
28
+ await createPng(params),
29
+ await createIco(params),
30
+ await createWebmanifest(params), // after create png
31
+ await createSnippet(params),
27
32
  ])
28
33
  .then(result => {
29
34
  printResult(params);
@@ -5,19 +5,32 @@ export async function createSnippet(params) {
5
5
 
6
6
  if(params.create_snippet) {
7
7
 
8
+ let snippet_content;
8
9
 
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);
10
+ if (params.snippet_language === 'ejs') {
12
11
 
12
+ snippet_content = '<link rel="icon" href="<%= require(\'./favicon.ico\') %>" sizes="32x32"/>\n' +
13
+ '<link rel="icon" href="<%= require(\'./favicon.svg\') %>" type="image/svg+xml"/>\n' +
14
+ '<link rel="apple-touch-icon" href="<%= require(\'./apple-touch-icon.png\') %>"/>\n' +
15
+ '<link rel="manifest" href="./manifest.webmanifest"/>\n' +
16
+ '<!-- <link rel="manifest" href="<%= require(\'./manifest.webmanifest.ejs\')() %>"/> -->';
13
17
 
14
- let snippet_content = `<link rel="icon" href="${create_href('favicon.ico')}" sizes="32x32"/>\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
+ } else {
19
+
20
+ const cache_buster = params.add_cache_buster? `?_=${Date.now()}` : '',
21
+ create_href = nome_file => params.href_template.replace('%_file_name_%', nome_file)
22
+ .replace('%_cache_buster_%', cache_buster);
23
+
24
+
25
+ snippet_content = `<link rel="icon" href="${create_href('favicon.ico')}" sizes="32x32"/>\n` +
26
+ `<link rel="icon" href="${create_href('favicon.svg')}" type="image/svg+xml"/>\n` +
27
+ `<link rel="apple-touch-icon" href="${create_href('apple-touch-icon.png')}"/>\n` +
28
+ `<link rel="manifest" href="${create_href('manifest.webmanifest')}"/>`;
29
+
30
+ if (params.snippet_language === 'pug') {
31
+ snippet_content = snippet_content.replace(/<link (.*?)\/?>/g, 'link($1)');
32
+ }
18
33
 
19
- if (params.snippet_language === 'pug') {
20
- snippet_content = snippet_content.replace(/<link (.*?)\/?>/g, 'link($1)');
21
34
  }
22
35
 
23
36
  snippet_content = params.snippet_template.replace('%_link_tags_%', snippet_content);
@@ -41,7 +54,7 @@ export async function createSnippet(params) {
41
54
  } else {
42
55
 
43
56
  fs.promises.writeFile(
44
- `${params.snippet_path}/${params.snippet_name}`,
57
+ `${params.snippet_path}/${params.snippet_language === 'ejs'? 'favicons.incl.ejs' : params.snippet_name}`,
45
58
  snippet_content
46
59
  );
47
60
 
@@ -1,14 +1,64 @@
1
- import * as fs from 'fs/promises';
1
+ // web manifest
2
+
3
+ // import * as fs from 'fs/promises';
4
+ import * as fs from 'fs';
5
+ import { createHash } from 'node:crypto'
6
+
7
+
8
+ async function getHash(path) {
9
+
10
+ const fileHash = await new Promise((resolve, reject) => {
11
+ const hash = createHash('sha256');
12
+ const rs = fs.createReadStream(path);
13
+ rs.on('error', reject);
14
+ rs.on('data', chunk => hash.update(chunk));
15
+ rs.on('end', () => resolve(hash.digest('hex')));
16
+ })
17
+
18
+ return fileHash;
19
+ }
2
20
 
3
21
  export async function createWebmanifest(params) {
4
- // web manifest
22
+
23
+ const sizes = [192, 512];
24
+
25
+ let files = {};
26
+ for await (const size of sizes) {
27
+
28
+ if(params.snippet_language === 'ejs') {
29
+ files[size] = `<%= require('./icon-${size}.png') %>`;
30
+
31
+ } else if(params.webmanifest_add_hash_to_files) {
32
+ const hashValue = await getHash(`${params.output_dir}/icon-${size}.png`);
33
+ files[size] = `./icon-${size}.png?_=${hashValue}`;
34
+
35
+ } else {
36
+ files[size] = `./icon-${size}.png`;
37
+ }
38
+
39
+ }
40
+
5
41
  const manifest = {
6
- icons: [192, 512].map( size => {
7
- return { src: `./icon-${size}.png`, type: 'image/png', sizes: `${size}x${size}` };
42
+ icons: sizes.map( size => {
43
+
44
+ return {
45
+ src: files[size],
46
+ type: 'image/png',
47
+ sizes: `${size}x${size}`
48
+ };
8
49
  }),
9
50
  ...(params.webmanifest_extra?? {})
10
51
  };
11
52
 
12
- await fs.writeFile(`${params.output_dir}/manifest.webmanifest`, JSON.stringify(manifest, null, ' '));
53
+ // await fs.writeFile(`${params.output_dir}/manifest.webmanifest`, JSON.stringify(manifest, null, ' '));
54
+
55
+ await fs.writeFile(
56
+ `${params.output_dir}/${params.manifest_file_name}`,
57
+ JSON.stringify(manifest, null, ' '),
58
+ (err) => {
59
+ if (err) {throw err}
60
+ // console.log('The file has been saved!');
61
+ }
62
+ );
13
63
 
14
64
  }
@@ -13,7 +13,7 @@ export const default_params = {
13
13
 
14
14
  // directory output (percorso relativo alla dir di lavoro)
15
15
  // se la dir non esiste, viene creata
16
- output_dir: 'favicons-output',
16
+ output_dir: './output',
17
17
 
18
18
 
19
19
  // WEBMANIFEST
@@ -30,12 +30,17 @@ export const default_params = {
30
30
  // }
31
31
  webmanifest_extra: null,
32
32
 
33
+ // if true, all files linked in manifest will end with
34
+ // '?_=[hash]'
35
+ webmanifest_add_hash_to_files: true,
36
+
33
37
 
34
38
  // SNIPPET
35
39
  //****************************************************************************
36
40
 
37
41
  // nome del file snippet, compresa l'estensione
38
42
  // se questo parametro è null e anche `snippet_target_file` lo è, lo snippet non viene generato
43
+ // se il linguaggio è ejs il nome è sempre 'favicons.incl.ejs' e snippet_name viene ignorato
39
44
  snippet_name: 'favicon.html',
40
45
 
41
46
  // path (relativo a questo file) in cui salvare lo snippet
@@ -54,8 +59,8 @@ export const default_params = {
54
59
  snippet_target_file: null,
55
60
 
56
61
  // linguaggio da utilizzare per la sintassi dello snippet html
57
- // html o pug
58
- snippet_language: 'html',
62
+ // html, pug, ejs
63
+ snippet_language: 'ejs',
59
64
 
60
65
  // template per la costruzione dello snippet.
61
66
  // si tratta di una stringa (anche su più righe) in cui deve essere presente
@@ -24,7 +24,7 @@ export function printResult(params) {
24
24
  'favicon.svg',
25
25
  'icon-192.png',
26
26
  'icon-512.png',
27
- 'manifest.webmanifest'
27
+ params.manifest_file_name
28
28
  ].forEach(item => {
29
29
  const stats = fs.statSync(`${params.output_dir}/${item}`);
30
30
  extra_strings.push({string: `${item}: ${printSize(stats.size)}`, color: 'greenBright'});