@hibi_10000/grunt-webfont 2.0.1 → 2.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/tasks/webfont.ts CHANGED
@@ -10,42 +10,32 @@ import path from 'node:path';
10
10
  import crypto from 'node:crypto';
11
11
  import { globSync } from 'glob';
12
12
  import chalk from 'chalk';
13
- import _ from 'lodash';
13
+ import { Eta } from 'eta';
14
14
  import ttf2woff2 from 'ttf2woff2';
15
15
 
16
16
  import fontforge from './engines/fontforge.ts';
17
17
  import node from './engines/node.ts';
18
18
  import * as wf from './util/util.ts';
19
- import type { Logger, CustomOutput, TemplateOptions, Config, Options, OptionsInternal, Context } from './types.ts';
19
+ import type { Logger, FontFormat, CustomOutput, TemplateOptions, Config, Options, OptionsInternal, Context } from './types.ts';
20
20
 
21
21
  import packageJson from '../package.json' with { type: "json" };
22
22
 
23
- export default (grunt: IGrunt): void => {
23
+ export const webfontGrunt = (grunt: IGrunt): void => {
24
24
  grunt.registerMultiTask('webfont', 'Compile separate SVG files to webfont', function() {
25
25
  /**
26
26
  * Consola to Grunt logger adapter.
27
27
  */
28
28
  const logger: Logger = {
29
29
  log: {
30
- warn: (...args) => {
31
- grunt.log.warn.apply(null, args);
32
- },
33
- error: (...args) => {
34
- grunt.warn.apply(null, args);
35
- },
36
- info: (...args) => {
37
- grunt.log.writeln.apply(null, args);
38
- },
39
- verbose: (...args) => {
40
- grunt.log.verbose.writeln.apply(null, args);
41
- },
30
+ error: grunt.warn,
31
+ warn: grunt.log.warn,
32
+ info: grunt.log.writeln,
33
+ verbose: grunt.log.verbose.writeln,
42
34
  },
43
35
  fail: {
44
- fatal: (...args) => {
45
- grunt.fail.fatal.apply(null, args);
46
- },
36
+ fatal: grunt.fail.fatal,
47
37
  },
48
- };
38
+ } as const;
49
39
 
50
40
  const allDone = this.async();
51
41
  const params = this.data;
@@ -56,12 +46,31 @@ export default (grunt: IGrunt): void => {
56
46
  */
57
47
  this.requiresConfig([this.name, this.target, 'src'].join('.'));
58
48
 
59
- webfont(this.name, this.target, this.filesSrc, params, options, logger).finally(allDone);
49
+ webfontMain(this.name, this.target, this.filesSrc, params, options, logger).finally(allDone);
60
50
  });
61
51
  };
62
52
 
63
- export const webfont = async (name: string, target: string, filesSrc: string[], params: Config, options: Options, logger?: Logger): Promise<void> => {
64
- if (!logger) logger = wf.consolaLogger;
53
+ export const webfont = async (targetName: string, config: Config): Promise<void> => {
54
+ const filesSrc = globSync(config.src, { posix: true });
55
+ await webfontMain("webfont", targetName, filesSrc, config);
56
+ }
57
+
58
+ const webfontGruntCjs = (grunt: IGrunt): void => webfontGrunt(grunt);
59
+ Object.assign(webfontGruntCjs, {
60
+ default: webfontGrunt,
61
+ webfont: webfont,
62
+ });
63
+
64
+ export { webfontGrunt as default, webfontGruntCjs as "module.exports" };
65
+
66
+ const webfontMain = async (
67
+ name: string,
68
+ target: string,
69
+ filesSrc: string[],
70
+ params: Config,
71
+ options: Options = params.options ?? {},
72
+ logger: Logger = wf.consolaLogger,
73
+ ): Promise<void> => {
65
74
  const md5 = crypto.createHash('md5');
66
75
 
67
76
  /*
@@ -110,10 +119,10 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
110
119
  htmlDemo: options.htmlDemo !== false,
111
120
  htmlDemoTemplate: options.htmlDemoTemplate,
112
121
  htmlDemoFilename: options.htmlDemoFilename,
113
- styles: optionToArray(options.styles, 'font,icon'),
114
- types: optionToArray(options.types, 'eot,woff,ttf'),
115
- order: optionToArray(options.order, wf.fontFormats),
116
- embed: options.embed === true ? ['woff'] : optionToArray(options.embed, false),
122
+ styles: optionToArray(options.styles, ['font', 'icon']),
123
+ types: optionToArray<FontFormat>(options.types, ['eot', 'woff', 'ttf']),
124
+ order: optionToArray<FontFormat>(options.order, wf.fontFormats),
125
+ embed: options.embed === true ? ['woff'] : optionToArray<FontFormat>(options.embed, false),
117
126
  rename: options.rename || path.basename,
118
127
  engine: options.engine || 'fontforge',
119
128
  autoHint: options.autoHint !== false,
@@ -174,7 +183,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
174
183
 
175
184
  // Check if we need to generate font
176
185
  const previousHash = readHash(name, target);
177
- logger.log.verbose('New hash:', o.hash, '- previous hash:', previousHash);
186
+ logger.log.verbose(`New hash: ${o.hash} - previous hash: ${previousHash}`);
178
187
  if (o.hash === previousHash) {
179
188
  logger.log.verbose('Config and source files weren’t changed since last run, checking resulting files...');
180
189
  let regenerationNeeded = false;
@@ -191,7 +200,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
191
200
  regenerationNeeded = generatedFiles.some((filename) => {
192
201
  if (!filename) return false;
193
202
  if (!fs.existsSync(filename)) {
194
- logger.log.verbose('File', filename, ' is missed.');
203
+ logger.log.verbose(`File ${filename} is missed.`);
195
204
  return true;
196
205
  }
197
206
  return false;
@@ -347,8 +356,8 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
347
356
  o.relativeFontPath = normalizePath(o.relativeFontPath);
348
357
 
349
358
  // Generate font URLs to use in @font-face
350
- const fontSrcs: { 0: string[], 1: string[] } = { 0: [], 1: [] };
351
- o.order.forEach((type: 'eot'|'woff2'|'woff'|'ttf'|'svg') => {
359
+ const fontSrcs: { readonly 0: string[], readonly 1: string[] } = { 0: [], 1: [] };
360
+ o.order.forEach((type) => {
352
361
  if (!has(o.types, type)) return;
353
362
  const fontSrc1 = wf.fontsSrcsMap[type][0];
354
363
  if (fontSrc1) fontSrcs[0].push(generateFontSrc(type, fontSrc1, stylesheet));
@@ -411,7 +420,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
411
420
  fs.writeFileSync(o.codepointsFile, codepointsToString);
412
421
  logger.log.verbose(`Codepoints saved to file "${o.codepointsFile}".`);
413
422
  } catch (err) {
414
- logger.log.error(err.message);
423
+ logger.log.error((err as Error).message);
415
424
  }
416
425
  }
417
426
 
@@ -431,10 +440,10 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
431
440
 
432
441
  let context = prepareBaseTemplateContext();
433
442
 
434
- let htmlStyles;
443
+ let htmlStyles: string;
435
444
 
436
445
  // Prepare relative font paths for injection into @font-face refs in HTML
437
- const relativeRe = new RegExp(_.escapeRegExp(o.relativeFontPath).replace(/[=!:\/]/g, '\\$&'), 'g');
446
+ const relativeRe = new RegExp(o.relativeFontPath.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&').replace(/[=!:\/]/g, '\\$&'), 'g');
438
447
  const htmlRelativeFontPath = normalizePath(path.relative(o.destHtml, o.dest));
439
448
  const _fontSrc1 = o.fontSrc1.replace(relativeRe, htmlRelativeFontPath);
440
449
  const _fontSrc2 = o.fontSrc2.replace(relativeRe, htmlRelativeFontPath);
@@ -483,9 +492,9 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
483
492
  // Prepares config attributes related to destination filepath
484
493
  const dest = outputConfig.dest || o.dest;
485
494
 
486
- let filepath;
487
- let destParent;
488
- let destName;
495
+ let filepath: string;
496
+ let destParent: string;
497
+ let destName: string;
489
498
 
490
499
  if (path.extname(dest) === '') {
491
500
  // If user specifies a directory, filename should be same as template
@@ -533,7 +542,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
533
542
  await fs.promises.mkdir(getDemoPath(), { recursive: true });
534
543
  } catch (err) {
535
544
  if (err) {
536
- logger.log.info(err);
545
+ logger.log.info(err as string);
537
546
  return;
538
547
  }
539
548
  }
@@ -560,9 +569,9 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
560
569
  * @param val Input string
561
570
  * @param defVal Default value
562
571
  */
563
- function optionToArray(val: string | false, defVal: string | false): string[] {
572
+ function optionToArray<T extends string>(val: string | false, defVal: T[] | false): T[] {
564
573
  if (val === undefined) {
565
- val = defVal;
574
+ return defVal || [];
566
575
  }
567
576
  if (!val) {
568
577
  return [];
@@ -570,7 +579,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
570
579
  if (typeof val !== 'string') {
571
580
  return val;
572
581
  }
573
- return val.split(',').map((value) => value.trim());
582
+ return val.split(',').map((value) => value.trim() as T);
574
583
  }
575
584
 
576
585
  /**
@@ -580,7 +589,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
580
589
  * @param needle Value to find
581
590
  * @return Needle was found
582
591
  */
583
- function has(haystack: string[] | string, needle: string): boolean {
592
+ function has(haystack: readonly string[] | string, needle: string): boolean {
584
593
  return haystack.indexOf(needle) !== -1;
585
594
  }
586
595
 
@@ -590,7 +599,7 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
590
599
  * @param map Options object
591
600
  * @param key Option to find in the object
592
601
  */
593
- function option(map: { _default?: string, [key: string]: string }, key: string): string {
602
+ function option(map: { readonly _default?: string, readonly [key: string]: string }, key: string): string {
594
603
  if (key in map) {
595
604
  return map[key];
596
605
  } else {
@@ -661,11 +670,11 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
661
670
  * @param font URL or Base64 string
662
671
  * @param stylesheet type: css, scss, ...
663
672
  */
664
- function generateFontSrc(type: string, font: { ext: string, format?: string, embeddable?: boolean }, stylesheet: string): string {
673
+ function generateFontSrc(type: FontFormat, font: { readonly ext: string, readonly format?: string, readonly embeddable?: boolean }, stylesheet: string): string {
665
674
  const filename = template(`${o.fontFilename}${font.ext}`, o);
666
675
  let fontPathVariableName = `${o.fontFamilyName}-font-path`;
667
676
 
668
- let url;
677
+ let url: string;
669
678
  if (font.embeddable && has(o.embed, type)) {
670
679
  url = embedFont(path.join(o.dest, filename));
671
680
  } else {
@@ -739,10 +748,17 @@ export const webfont = async (name: string, target: string, filesSrc: string[],
739
748
  */
740
749
  function renderTemplate(template: { filename: string, template: string }, context: Context): string {
741
750
  try {
742
- const func = _.template(template.template);
743
- return func(context);
751
+ return new Eta({
752
+ autoTrim: ["nl", false],
753
+ parse: {
754
+ exec: "",
755
+ interpolate: "~",
756
+ raw: "=",
757
+ },
758
+ useWith: true,
759
+ }).renderString(template.template, context);
744
760
  } catch (e) {
745
- logger.fail.fatal(`Error while rendering template ${template.filename}: ${e.message}`);
761
+ logger.fail.fatal(`Error while rendering template ${template.filename}: ${(e as Error).message}`);
746
762
  }
747
763
  }
748
764
 
@@ -81,7 +81,7 @@
81
81
  <pre><code>&lt;i class=&quot;ligature-icons&quot;&gt;<span id="name2">name</span>&lt;/i&gt;</code></pre>
82
82
  <% } %>
83
83
 
84
- <footer>Generated by <a href="https://github.com/sapegin/grunt-webfont">grunt-webfont</a>.</footer>
84
+ <footer>Generated by <a href="https://github.com/Hibi-10000/grunt-webfont">grunt-webfont</a>.</footer>
85
85
 
86
86
  <script>
87
87
  (function() {
package/tsconfig.json CHANGED
@@ -1,19 +1,13 @@
1
1
  {
2
- "typeAcquisition": {
3
- "enable": true,
4
- },
5
2
  "compilerOptions": {
6
3
  "module": "ESNext",
7
4
  "moduleResolution": "bundler",
8
- "target": "ESNext",
9
- "lib": ["ESNext"],
5
+ "target": "ES2023",
6
+ "lib": ["ES2023"],
7
+ "types": ["grunt"],
10
8
  "noEmit": true,
11
- "allowJs": true,
12
- "checkJs": true,
13
9
  "strict": true,
14
10
  "strictNullChecks": false,
15
- "strictFunctionTypes": false,
16
- "useUnknownInCatchVariables": false,
17
11
  "resolveJsonModule": true,
18
12
  "esModuleInterop": true,
19
13
  "allowImportingTsExtensions": true,
@@ -26,6 +20,5 @@
26
20
  },
27
21
  "exclude": [
28
22
  "dist",
29
- "node_modules",
30
23
  ],
31
24
  }