diff --git a/src/__mocks__/glob.ts b/src/__mocks__/glob.ts index 30855f1b..66140a35 100644 --- a/src/__mocks__/glob.ts +++ b/src/__mocks__/glob.ts @@ -17,9 +17,10 @@ module.exports = ( const paths = mockGlobs[glob]; if (!paths) { - return callback(new Error(`Invalid glob: ${glob}`), null); + callback(new Error(`Invalid glob: ${glob}`), null); + return; } - return callback(null, paths); + callback(null, paths); }); }; diff --git a/src/__mocks__/path.ts b/src/__mocks__/path.ts index 9974f859..60941c07 100644 --- a/src/__mocks__/path.ts +++ b/src/__mocks__/path.ts @@ -7,19 +7,17 @@ const resolve = (...paths: string[]) => { let path = ''; for (const cur of paths) { - path = !path ? normalize(cur) : _path.join(path, normalize(cur)); + path = path ? _path.join(path, normalize(cur)) : normalize(cur); } if (path.startsWith(projectDir)) { path = _path.join('/root/project', path.substr(projectDir.length)); } else if (path.startsWith('/') && !path.startsWith('/root')) { path = _path.join('/root/', path.substr(1)); - } else { - if (path.startsWith('./')) { - path = _path.join('/root/project/', path.substr(2)); - } else if (!path.startsWith('/')) { - path = _path.join('/root/project/', path); - } + } else if (path.startsWith('./')) { + path = _path.join('/root/project/', path.substr(2)); + } else if (!path.startsWith('/')) { + path = _path.join('/root/project/', path); } return normalize(path); @@ -31,7 +29,7 @@ const relative = (a: string, b: string) => const join = (...segments: string[]): string => { const trimmed: string[] = []; - segments.forEach((current, i) => { + for (let [i, current] of segments.entries()) { const isFirst = i === 0; const isLast = i === segments.length - 1; @@ -44,7 +42,7 @@ const join = (...segments: string[]): string => { } trimmed.push(current); - }); + } return trimmed.join('/'); }; diff --git a/src/cli/config-loader.ts b/src/cli/config-loader.ts index cb3273dd..c68f43c4 100644 --- a/src/cli/config-loader.ts +++ b/src/cli/config-loader.ts @@ -1,5 +1,6 @@ import { readFile } from 'fs/promises'; import { join } from 'path'; +import process from 'process'; import { checkPath } from '../utils/fs-async'; export const DEFAULT_FILEPATHS = [ @@ -11,17 +12,17 @@ export const DEFAULT_FILEPATHS = [ 'fantasticonrc.js' ]; -const attemptLoading = async (filepath: string): Promise => { +const attemptLoading = async (filepath: string) => { const fileExists = await checkPath(filepath, 'file'); if (fileExists) { try { return require(join(process.cwd(), filepath)); - } catch (err) {} + } catch {} try { const content = await readFile(filepath, 'utf8'); return JSON.parse(content); - } catch (err) {} + } catch {} throw new Error(`Failed parsing configuration at '${filepath}'`); } diff --git a/src/cli/index.ts b/src/cli/index.ts index 054cac9a..3c74f417 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1,16 +1,13 @@ +import process from 'process'; import commander from 'commander'; import { FontAssetType, OtherAssetType } from '../types/misc'; -import { loadConfig, DEFAULT_FILEPATHS } from './config-loader'; import { DEFAULT_OPTIONS } from '../constants'; import { generateFonts } from '../core/runner'; import { removeUndefined } from '../utils/validation'; +import { loadConfig, DEFAULT_FILEPATHS } from './config-loader'; import { getLogger } from './logger'; - -const { - bin, - name: packageName, - version -} = require('../../package.json') as any; +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { bin, name: packageName, version } = require('../../package.json'); const getCommandName = () => (bin && Object.keys(bin)[0]) || packageName; @@ -37,11 +34,9 @@ const printList = (available: { [key: string]: string }, defaults: string[]) => ).join(', ')})`; const printDefaultValue = (value: any) => { - let printVal = String(value); + const printVal = String(value); - if (typeof value === 'undefined') { - return ''; - } + if (value === undefined) return ''; return ` (default: ${printVal})`; }; @@ -137,6 +132,7 @@ const buildOptions = async (cmd: commander.Command, loadedConfig = {}) => { }; }; -const run = async (options: any) => await generateFonts(options, true); +const run = async (options: any) => generateFonts(options, true); +// eslint-disable-next-line @typescript-eslint/no-floating-promises cli(); diff --git a/src/cli/logger.ts b/src/cli/logger.ts index 3de00393..85b51465 100644 --- a/src/cli/logger.ts +++ b/src/cli/logger.ts @@ -24,6 +24,7 @@ export const getLogger = (debug = false, silent = false) => ({ this.log(picocolor.yellow('Generating font kit...')); if (!loadedConfigPath) return; + this.log( picocolor.green( `${figures.tick} Using configuration file: ${picocolor.green( diff --git a/src/constants.ts b/src/constants.ts index 811c4b70..a789d02a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,6 +1,6 @@ import { resolve } from 'path'; -import { RunnerOptions } from './types/runner'; import { FontAssetType, OtherAssetType } from './types/misc'; +import { RunnerOptions } from './types/runner'; import { getIconId } from './utils/icon-id'; export const TEMPLATES_DIR = resolve(__dirname, '../templates'); @@ -26,7 +26,7 @@ export const DEFAULT_OPTIONS: Omit = { tag: 'i', prefix: 'icon', fontsUrl: undefined, - getIconId: getIconId + getIconId }; export const DEFAULT_START_CODEPOINT = 0xf101; diff --git a/src/core/__tests__/config-parser.ts b/src/core/__tests__/config-parser.ts index c59a61c0..3cbebb68 100644 --- a/src/core/__tests__/config-parser.ts +++ b/src/core/__tests__/config-parser.ts @@ -38,19 +38,19 @@ const mockConfig = { }; const testError = async (options: object, key: string, message: string) => - expect(() => parseConfig({ ...mockConfig, ...options })).rejects.toThrow( - `Invalid option ${key}: ${message}` - ); + expect(async () => + parseConfig({ ...mockConfig, ...options }) + ).rejects.toThrow(`Invalid option ${key}: ${message}`); -const testParsed = async (key: string, input: any, output: any) => - expect((await parseConfig({ ...mockConfig, [key]: input }))[key]).toEqual( - output - ); +const testParsed = async (key: string, input: any, output: any) => { + const config = await parseConfig({ ...mockConfig, [key]: input }); + expect(config[key]).toEqual(output); +}; describe('Config parser', () => { beforeEach(() => { checkPathMock.mockClear(); - checkPathMock.mockImplementation(() => Promise.resolve(true)); + checkPathMock.mockImplementation(async () => true); }); test('returns correctly parsed input when valid', async () => { @@ -93,11 +93,11 @@ describe('Config parser', () => { }); test('correctly validates existance of input and output paths', async () => { - checkPathMock.mockImplementationOnce(() => Promise.resolve(false)); + checkPathMock.mockImplementationOnce(async () => false); await testError({ inputDir: 'foo' }, 'inputDir', 'foo is not a directory'); - checkPathMock.mockImplementation(val => Promise.resolve(val !== 'bar')); + checkPathMock.mockImplementation(async val => val !== 'bar'); await testError( { outputDir: 'bar' }, @@ -107,7 +107,7 @@ describe('Config parser', () => { }); test('throws expected error when passing an unrecognised option', async () => { - await expect(() => + await expect(async () => parseConfig({ ...mockConfig, foo: 'bar' }) ).rejects.toThrow("The option 'foo' is not recognised"); }); diff --git a/src/core/__tests__/runner.ts b/src/core/__tests__/runner.ts index a19288dc..45732802 100644 --- a/src/core/__tests__/runner.ts +++ b/src/core/__tests__/runner.ts @@ -16,9 +16,9 @@ jest.mock('../../constants', () => ({ })); jest.mock('../../generators', () => ({ - generateAssets: jest.fn(options => - Promise.resolve({ mockGenerated: { assets: {}, options } }) - ) + generateAssets: jest.fn(async options => ({ + mockGenerated: { assets: {}, options } + })) })); jest.mock('../../generators/generator-options', () => ({ @@ -26,8 +26,8 @@ jest.mock('../../generators/generator-options', () => ({ })); jest.mock('../../utils/assets', () => ({ - writeAssets: jest.fn(() => Promise.resolve([{ mock: 'writeResult' }])), - loadAssets: jest.fn(() => Promise.resolve({ mock: 'assets' })) + writeAssets: jest.fn(async () => [{ mock: 'writeResult' }]), + loadAssets: jest.fn(async () => ({ mock: 'assets' })) })); jest.mock('../config-parser', () => ({ @@ -82,7 +82,7 @@ describe('Runner', () => { test('`generateFonts` throws error if `outputDir` is not given and `mustWrite` is `true`', async () => { const optionsIn = { inputDir: 'foo' } as any; - await expect(() => generateFonts(optionsIn, true)).rejects.toThrow( + await expect(async () => generateFonts(optionsIn, true)).rejects.toThrow( 'You must specify an output directory' ); }); @@ -90,7 +90,7 @@ describe('Runner', () => { test('`generateFonts` throws error if `inputDir` is not given', async () => { const optionsIn = {} as any; - await expect(() => generateFonts(optionsIn)).rejects.toThrow( + await expect(async () => generateFonts(optionsIn)).rejects.toThrow( 'You must specify an input directory' ); }); diff --git a/src/core/config-parser.ts b/src/core/config-parser.ts index e44d1a6a..df06fb24 100644 --- a/src/core/config-parser.ts +++ b/src/core/config-parser.ts @@ -55,8 +55,8 @@ export const parseConfig = async (input: object = {}) => { for (const fn of validators) { val = await fn(val, val); } - } catch (err) { - throw new Error(`Invalid option ${key}: ${err.message}`); + } catch (error) { + throw new Error(`Invalid option ${key}: ${error.message}`); } out[key] = val; diff --git a/src/core/runner.ts b/src/core/runner.ts index d5152937..cbc96c6f 100644 --- a/src/core/runner.ts +++ b/src/core/runner.ts @@ -9,8 +9,8 @@ import { import { CodepointsMap } from '../utils/codepoints'; import { getGeneratorOptions } from '../generators/generator-options'; import { GeneratedAssets } from '../generators/generate-assets'; -import { parseConfig } from './config-parser'; import { generateAssets } from '../generators'; +import { parseConfig } from './config-parser'; export interface RunnerResults { options: RunnerOptions; @@ -20,7 +20,7 @@ export interface RunnerResults { codepoints: CodepointsMap; } -export const sanitiseOptions = (userOptions: any) => +export const sanitiseOptions = async (userOptions: any) => parseConfig({ ...DEFAULT_OPTIONS, ...userOptions diff --git a/src/generators/asset-types/__tests__/css.ts b/src/generators/asset-types/__tests__/css.ts index b83d587f..b6e20ae0 100644 --- a/src/generators/asset-types/__tests__/css.ts +++ b/src/generators/asset-types/__tests__/css.ts @@ -1,6 +1,7 @@ -import cssGen from '../css'; -import { renderSrcAttribute } from '../../../utils/css'; +import { Buffer } from 'buffer'; import { resolve } from 'path'; +import { renderSrcAttribute } from '../../../utils/css'; +import cssGen from '../css'; const renderSrcMock = renderSrcAttribute as any as jest.Mock; diff --git a/src/generators/asset-types/__tests__/eot.ts b/src/generators/asset-types/__tests__/eot.ts index c6e917d1..d6f02e49 100644 --- a/src/generators/asset-types/__tests__/eot.ts +++ b/src/generators/asset-types/__tests__/eot.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import _ttf2eot from 'ttf2eot'; import { FontGeneratorOptions } from '../../../types/generator'; import eotGen from '../eot'; @@ -9,7 +10,7 @@ jest.mock('ttf2eot', () => ); const mockOptions = (eotOptions = { __mock: 'options__' } as any) => - ({}) as unknown as FontGeneratorOptions; + ({} as unknown as FontGeneratorOptions); const ttf = '::ttf::' as unknown as Buffer; diff --git a/src/generators/asset-types/__tests__/html.ts b/src/generators/asset-types/__tests__/html.ts index 1d7df909..e3cb034a 100644 --- a/src/generators/asset-types/__tests__/html.ts +++ b/src/generators/asset-types/__tests__/html.ts @@ -1,5 +1,5 @@ -import htmlGen from '../html'; import { resolve } from 'path'; +import htmlGen from '../html'; const mockOptions = { name: 'test-font', diff --git a/src/generators/asset-types/__tests__/json.ts b/src/generators/asset-types/__tests__/json.ts index 57808888..dd1f47a7 100644 --- a/src/generators/asset-types/__tests__/json.ts +++ b/src/generators/asset-types/__tests__/json.ts @@ -1,6 +1,6 @@ -import jsonGen from '../json'; -import { OtherAssetType } from '../../../types/misc'; import { DEFAULT_OPTIONS } from '../../../constants'; +import { OtherAssetType } from '../../../types/misc'; +import jsonGen from '../json'; const mockCodepoints = { foo: 'oof', bar: 'baz' }; @@ -8,7 +8,7 @@ const mockOptions = (jsonOptions: any = {}) => ({ codepoints: mockCodepoints, formatOptions: { [OtherAssetType.JSON]: jsonOptions } - }) as any; + } as any); const renderAndParse = async (jsonOptions?: any) => JSON.parse( diff --git a/src/generators/asset-types/__tests__/sass.ts b/src/generators/asset-types/__tests__/sass.ts index 9c96038a..868ecdc9 100644 --- a/src/generators/asset-types/__tests__/sass.ts +++ b/src/generators/asset-types/__tests__/sass.ts @@ -1,6 +1,7 @@ -import sassGen from '../sass'; -import { renderSrcAttribute } from '../../../utils/css'; +import { Buffer } from 'buffer'; import { resolve } from 'path'; +import { renderSrcAttribute } from '../../../utils/css'; +import sassGen from '../sass'; const renderSrcMock = renderSrcAttribute as any as jest.Mock; diff --git a/src/generators/asset-types/__tests__/scss.ts b/src/generators/asset-types/__tests__/scss.ts index 248e616a..a0f9a926 100644 --- a/src/generators/asset-types/__tests__/scss.ts +++ b/src/generators/asset-types/__tests__/scss.ts @@ -1,6 +1,7 @@ -import scssGen from '../scss'; -import { renderSrcAttribute } from '../../../utils/css'; +import { Buffer } from 'buffer'; import { resolve } from 'path'; +import { renderSrcAttribute } from '../../../utils/css'; +import scssGen from '../scss'; const renderSrcMock = renderSrcAttribute as any as jest.Mock; diff --git a/src/generators/asset-types/__tests__/svg.ts b/src/generators/asset-types/__tests__/svg.ts index 1b7dc9dd..3200dcfb 100644 --- a/src/generators/asset-types/__tests__/svg.ts +++ b/src/generators/asset-types/__tests__/svg.ts @@ -1,6 +1,8 @@ +import { Buffer } from 'buffer'; +import EventEmitter from 'events'; import * as _SVGIcons2SVGFontStream from 'svgicons2svgfont'; -import { FontAssetType } from '../../../types/misc'; import { FontGeneratorOptions } from '../../../types/generator'; +import { FontAssetType } from '../../../types/misc'; import svgGen from '../svg'; const SVGIcons2SVGFontStream = _SVGIcons2SVGFontStream as unknown as jest.Mock< @@ -14,8 +16,6 @@ jest.mock('fs', () => ({ })); jest.mock('svgicons2svgfont', () => { - const { EventEmitter } = require('events'); - class MockStream { public events = new EventEmitter(); public content = ''; @@ -56,7 +56,7 @@ const mockOptions = (svgOptions = { __mock: 'options__' } as any) => foo: { id: 'foo', absolutePath: '/root/foo.svg' }, bar: { id: 'bar', absolutePath: '/root/bar.svg' } } - }) as unknown as FontGeneratorOptions; + } as unknown as FontGeneratorOptions); describe('`SVG` font generator', () => { beforeEach(() => { diff --git a/src/generators/asset-types/__tests__/ts.ts b/src/generators/asset-types/__tests__/ts.ts index 3f425945..87133bd3 100644 --- a/src/generators/asset-types/__tests__/ts.ts +++ b/src/generators/asset-types/__tests__/ts.ts @@ -1,5 +1,5 @@ +import { dirname, join } from 'path'; import tsGen from '../ts'; -import { join, dirname } from 'path'; const mockAssets = { foo: { diff --git a/src/generators/asset-types/__tests__/ttf.ts b/src/generators/asset-types/__tests__/ttf.ts index 7167c985..e715ab51 100644 --- a/src/generators/asset-types/__tests__/ttf.ts +++ b/src/generators/asset-types/__tests__/ttf.ts @@ -1,6 +1,7 @@ +import { Buffer } from 'buffer'; import _svg2ttf from 'svg2ttf'; -import { FontAssetType } from '../../../types/misc'; import { FontGeneratorOptions } from '../../../types/generator'; +import { FontAssetType } from '../../../types/misc'; import ttfGen from '../ttf'; const svg2ttf = _svg2ttf as unknown as jest.Mock; @@ -12,7 +13,7 @@ jest.mock('svg2ttf', () => const mockOptions = (ttfOptions = { __mock: 'options__' } as any) => ({ formatOptions: { [FontAssetType.TTF]: ttfOptions } - }) as unknown as FontGeneratorOptions; + } as unknown as FontGeneratorOptions); const svg = '::svg::'; diff --git a/src/generators/asset-types/__tests__/woff.ts b/src/generators/asset-types/__tests__/woff.ts index 08bdd878..dbbe1721 100644 --- a/src/generators/asset-types/__tests__/woff.ts +++ b/src/generators/asset-types/__tests__/woff.ts @@ -1,6 +1,7 @@ +import { Buffer } from 'buffer'; import _ttf2woff from 'ttf2woff'; -import { FontAssetType } from '../../../types/misc'; import { FontGeneratorOptions } from '../../../types/generator'; +import { FontAssetType } from '../../../types/misc'; import woffGen from '../woff'; const ttf2woff = _ttf2woff as unknown as jest.Mock; @@ -12,7 +13,7 @@ jest.mock('ttf2woff', () => const mockOptions = (woffOptions = { __mock: 'options__' } as any) => ({ formatOptions: { [FontAssetType.WOFF]: woffOptions } - }) as unknown as FontGeneratorOptions; + } as unknown as FontGeneratorOptions); const ttf = '::ttf::' as unknown as Buffer; diff --git a/src/generators/asset-types/__tests__/woff2.ts b/src/generators/asset-types/__tests__/woff2.ts index ecec214a..dd608872 100644 --- a/src/generators/asset-types/__tests__/woff2.ts +++ b/src/generators/asset-types/__tests__/woff2.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import _ttf2woff2 from 'ttf2woff2'; import { FontGeneratorOptions } from '../../../types/generator'; import woff2Gen from '../woff2'; @@ -9,7 +10,7 @@ jest.mock('ttf2woff2', () => ); const mockOptions = (woffOptions = { __mock: 'options__' } as any) => - ({}) as unknown as FontGeneratorOptions; + ({} as unknown as FontGeneratorOptions); const ttf = '::ttf::' as unknown as Buffer; diff --git a/src/generators/asset-types/css.ts b/src/generators/asset-types/css.ts index 847d0221..f55b9586 100644 --- a/src/generators/asset-types/css.ts +++ b/src/generators/asset-types/css.ts @@ -1,12 +1,13 @@ +import { Buffer } from 'buffer'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; -import { renderTemplate } from '../../utils/template'; import { renderSrcAttribute } from '../../utils/css'; +import { renderTemplate } from '../../utils/template'; const generator: FontGenerator = { dependsOn: FontAssetType.SVG, - generate: (options, svg: Buffer) => + generate: async (options, svg: Buffer) => renderTemplate(options.templates.css, { ...options, fontSrc: renderSrcAttribute(options, svg) diff --git a/src/generators/asset-types/eot.ts b/src/generators/asset-types/eot.ts index c48797a7..bcfb4412 100644 --- a/src/generators/asset-types/eot.ts +++ b/src/generators/asset-types/eot.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import ttf2eot from 'ttf2eot'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; diff --git a/src/generators/asset-types/html.ts b/src/generators/asset-types/html.ts index 67087801..384fa759 100644 --- a/src/generators/asset-types/html.ts +++ b/src/generators/asset-types/html.ts @@ -2,7 +2,7 @@ import { FontGenerator } from '../../types/generator'; import { renderTemplate } from '../../utils/template'; const generator: FontGenerator = { - generate: async options => { + async generate(options) { return renderTemplate(options.templates.html, options); } }; diff --git a/src/generators/asset-types/index.ts b/src/generators/asset-types/index.ts index 77de9e82..de149768 100644 --- a/src/generators/asset-types/index.ts +++ b/src/generators/asset-types/index.ts @@ -1,16 +1,16 @@ -import { AssetType, FontAssetType, OtherAssetType } from '../../types/misc'; import { FontGenerator } from '../../types/generator'; -import svg from './svg'; -import ttf from './ttf'; -import woff from './woff'; -import woff2 from './woff2'; -import eot from './eot'; +import { AssetType, FontAssetType, OtherAssetType } from '../../types/misc'; import css from './css'; +import eot from './eot'; import html from './html'; import json from './json'; -import ts from './ts'; import sass from './sass'; import scss from './scss'; +import svg from './svg'; +import ts from './ts'; +import ttf from './ttf'; +import woff from './woff'; +import woff2 from './woff2'; const generators: { [key in AssetType]: FontGenerator } = { [FontAssetType.SVG]: svg, diff --git a/src/generators/asset-types/sass.ts b/src/generators/asset-types/sass.ts index 7ac2daac..02d1719e 100644 --- a/src/generators/asset-types/sass.ts +++ b/src/generators/asset-types/sass.ts @@ -1,12 +1,13 @@ +import { Buffer } from 'buffer'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; -import { renderTemplate } from '../../utils/template'; import { renderSrcAttribute } from '../../utils/css'; +import { renderTemplate } from '../../utils/template'; const generator: FontGenerator = { dependsOn: FontAssetType.SVG, - generate: (options, svg: Buffer) => + generate: async (options, svg: Buffer) => renderTemplate(options.templates.sass, { ...options, fontSrc: renderSrcAttribute(options, svg) diff --git a/src/generators/asset-types/scss.ts b/src/generators/asset-types/scss.ts index 252f9a72..1453f6bd 100644 --- a/src/generators/asset-types/scss.ts +++ b/src/generators/asset-types/scss.ts @@ -1,12 +1,13 @@ +import { Buffer } from 'buffer'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; -import { renderTemplate } from '../../utils/template'; import { renderSrcAttribute } from '../../utils/css'; +import { renderTemplate } from '../../utils/template'; const generator: FontGenerator = { dependsOn: FontAssetType.SVG, - generate: (options, svg: Buffer) => + generate: async (options, svg: Buffer) => renderTemplate( options.templates.scss, { ...options, fontSrc: renderSrcAttribute(options, svg) }, diff --git a/src/generators/asset-types/svg.ts b/src/generators/asset-types/svg.ts index 4a39e6da..4021cd02 100644 --- a/src/generators/asset-types/svg.ts +++ b/src/generators/asset-types/svg.ts @@ -1,11 +1,12 @@ +import { Buffer } from 'buffer'; import { createReadStream, ReadStream } from 'fs'; import SVGIcons2SVGFontStream from 'svgicons2svgfont'; import { FontGenerator } from '../../types/generator'; type GglyphStream = ReadStream & { metadata?: any }; -const generator: FontGenerator = { - generate: ({ +const generator: FontGenerator = { + generate: async ({ name: fontName, fontHeight, descent, @@ -25,8 +26,13 @@ const generator: FontGenerator = { log: () => null, ...svg }) - .on('data', data => (font = Buffer.concat([font, data]))) - .on('end', () => resolve(font.toString())); + .on('data', data => { + font = Buffer.concat([font, data]); + return font; + }) + .on('end', () => { + resolve(font.toString()); + }); for (const { id, absolutePath } of Object.values(assets)) { const glyph: GglyphStream = createReadStream(absolutePath); diff --git a/src/generators/asset-types/ts.ts b/src/generators/asset-types/ts.ts index 159bb0cc..a943f056 100644 --- a/src/generators/asset-types/ts.ts +++ b/src/generators/asset-types/ts.ts @@ -5,7 +5,7 @@ const generateEnumKeys = (assetKeys: string[]): Record => assetKeys .map(name => { const enumName = pascalCase(name); - const prefix = enumName.match(/^\d/) ? 'i' : ''; + const prefix = /^\d/.test(enumName) ? 'i' : ''; return { [name]: `${prefix}${enumName}` @@ -80,15 +80,10 @@ const generateStringLiterals = ( ].join('\n'); const generator: FontGenerator = { - generate: async ({ - name, - codepoints, - assets, - formatOptions: { ts } = {} - }) => { - const quote = Boolean(ts?.singleQuotes) ? "'" : '"'; + async generate({ name, codepoints, assets, formatOptions: { ts } = {} }) { + const quote = ts?.singleQuotes ? "'" : '"'; const generateKind: Record = ( - Boolean(ts?.types?.length) + ts?.types?.length ? ts.types : ['enum', 'constant', 'literalId', 'literalKey'] ) diff --git a/src/generators/asset-types/ttf.ts b/src/generators/asset-types/ttf.ts index 69662f09..e1d0991b 100644 --- a/src/generators/asset-types/ttf.ts +++ b/src/generators/asset-types/ttf.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import svg2ttf from 'svg2ttf'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; @@ -6,7 +7,7 @@ const generator: FontGenerator = { dependsOn: FontAssetType.SVG, async generate({ formatOptions }, svg) { - const font = svg2ttf(svg, { ts: 0, ...(formatOptions?.ttf || {}) }); + const font = svg2ttf(svg, { ts: 0, ...formatOptions?.ttf }); return Buffer.from(font.buffer); } }; diff --git a/src/generators/asset-types/woff.ts b/src/generators/asset-types/woff.ts index e202e3a0..697d0dee 100644 --- a/src/generators/asset-types/woff.ts +++ b/src/generators/asset-types/woff.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import ttf2woff from 'ttf2woff'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; diff --git a/src/generators/asset-types/woff2.ts b/src/generators/asset-types/woff2.ts index a834ce67..1f2b4f1f 100644 --- a/src/generators/asset-types/woff2.ts +++ b/src/generators/asset-types/woff2.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import ttf2woff2 from 'ttf2woff2'; import { FontGenerator } from '../../types/generator'; import { FontAssetType } from '../../types/misc'; diff --git a/src/generators/generate-assets.ts b/src/generators/generate-assets.ts index ef4f9d9e..51601a76 100644 --- a/src/generators/generate-assets.ts +++ b/src/generators/generate-assets.ts @@ -1,5 +1,6 @@ -import { AssetType, FontAssetType, OtherAssetType } from '../types/misc'; +import { Buffer } from 'buffer'; import { FontGeneratorOptions } from '../types/generator'; +import { AssetType, FontAssetType, OtherAssetType } from '../types/misc'; import generators from './asset-types'; export type GeneratedAssets = { @@ -24,18 +25,19 @@ export const generateAssets = async ( generated[dependsOn] = await generateAsset(dependsOn); } - return (generated[type] = await generator.generate( + generated[type] = await generator.generate( options, dependsOn ? generated[dependsOn] : null - )); + ); + + return generated[type]; }; for (const type of generateTypes) { await generateAsset(type); } - return generateTypes.reduce( - (out, type: AssetType) => ({ ...out, [type]: generated[type] }), - {} + return Object.fromEntries( + generateTypes.map((type: AssetType) => [type, generated[type]]) ); }; diff --git a/src/generators/generator-options.ts b/src/generators/generator-options.ts index abb9b01a..bff55b32 100644 --- a/src/generators/generator-options.ts +++ b/src/generators/generator-options.ts @@ -1,16 +1,16 @@ import { join } from 'path'; import { DEFAULT_OPTIONS, TEMPLATES_DIR } from '../constants'; -import { RunnerOptions } from '../types/runner'; import { FormatOptions } from '../types/format'; -import { getCodepoints } from '../utils/codepoints'; import { FontGeneratorOptions } from '../types/generator'; import { AssetType, - OtherAssetType, ASSET_TYPES, - ASSET_TYPES_WITH_TEMPLATE + ASSET_TYPES_WITH_TEMPLATE, + OtherAssetType } from '../types/misc'; +import { RunnerOptions } from '../types/runner'; import { AssetsMap } from '../utils/assets'; +import { getCodepoints } from '../utils/codepoints'; export const getGeneratorOptions = ( options: RunnerOptions, diff --git a/src/index.ts b/src/index.ts index 49fb275a..a1336b7d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,12 @@ +export { generateFonts as default, generateFonts } from './core/runner'; + export { - FontAssetType, - OtherAssetType, - ASSET_TYPES, AssetType, + ASSET_TYPES, + FontAssetType, GetIconIdFn, - GetIconIdOptions + GetIconIdOptions, + OtherAssetType } from './types/misc'; export { RunnerOptions } from './types/runner'; - -export { generateFonts, generateFonts as default } from './core/runner'; diff --git a/src/types/format.ts b/src/types/format.ts index b7f15b85..bdc42229 100644 --- a/src/types/format.ts +++ b/src/types/format.ts @@ -1,7 +1,7 @@ import svg2ttf from 'svg2ttf'; -import ttf2woff from 'ttf2woff'; import { SvgIcons2FontOptions } from 'svgicons2svgfont'; -import { Arguments } from '../types/utils'; +import ttf2woff from 'ttf2woff'; +import { Arguments } from './utils'; type WoffOptions = Arguments[1]; type TtfOptions = svg2ttf.FontOptions; @@ -15,7 +15,7 @@ interface JsonOptions { } interface TsOptions { - types?: ('enum' | 'constant' | 'literalId' | 'literalKey')[]; + types?: Array<'enum' | 'constant' | 'literalId' | 'literalKey'>; singleQuotes?: boolean; enumName?: string; constantName?: string; diff --git a/src/types/generator.ts b/src/types/generator.ts index 17e1176a..bd2cedef 100644 --- a/src/types/generator.ts +++ b/src/types/generator.ts @@ -1,7 +1,8 @@ +import { Buffer } from 'buffer'; import { AssetsMap } from '../utils/assets'; +import { FormatOptions } from './format'; import { AssetType, OtherAssetType } from './misc'; import { RunnerOptions } from './runner'; -import { FormatOptions } from './format'; export type FontGeneratorOptions = RunnerOptions & { assets: AssetsMap; diff --git a/src/types/runner.ts b/src/types/runner.ts index 176422c3..e89f29c5 100644 --- a/src/types/runner.ts +++ b/src/types/runner.ts @@ -1,6 +1,6 @@ import { CodepointsMap } from '../utils/codepoints'; -import { FontAssetType, OtherAssetType, AssetType, GetIconIdFn } from './misc'; import { FormatOptions } from './format'; +import { AssetType, FontAssetType, GetIconIdFn, OtherAssetType } from './misc'; export interface RunnerMandatoryOptions { inputDir: string; diff --git a/src/utils/__tests__/assets.ts b/src/utils/__tests__/assets.ts index f8952305..515e3927 100644 --- a/src/utils/__tests__/assets.ts +++ b/src/utils/__tests__/assets.ts @@ -8,7 +8,7 @@ const writeFileMock = writeFile as any as jest.Mock; jest.mock('path'); jest.mock('glob'); jest.mock('fs/promises', () => ({ - writeFile: jest.fn(() => Promise.resolve()) + writeFile: jest.fn() })); describe('Assets utilities', () => { @@ -27,7 +27,7 @@ describe('Assets utilities', () => { expect(paths).toBeInstanceOf(Array); expect(paths.length).toBeTruthy(); - paths.forEach(path => expect(typeof path).toBe('string')); + for (const path of paths) expect(typeof path).toBe('string'); }); it('resolves an Array of the correct filepaths within the given directory', async () => { @@ -144,12 +144,12 @@ describe('Assets utilities', () => { it('rejects correctly if `getIconId` resolves the same `key` while processing different assets', async () => { const getIconId: GetIconIdFn = () => 'xxx'; - await expect(() => + await expect(async () => loadAssets({ ...DEFAULT_OPTIONS, inputDir: './valid', outputDir: './output', - getIconId: getIconId + getIconId }) ).rejects.toEqual( new Error( diff --git a/src/utils/__tests__/css.ts b/src/utils/__tests__/css.ts index e18e36fb..ccee606b 100644 --- a/src/utils/__tests__/css.ts +++ b/src/utils/__tests__/css.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import { renderSrcAttribute } from '../css'; import { FontAssetType } from '../../types/misc'; import * as hashUtils from '../hash'; diff --git a/src/utils/__tests__/fs-async.ts b/src/utils/__tests__/fs-async.ts index b0d7d639..de5d28a6 100644 --- a/src/utils/__tests__/fs-async.ts +++ b/src/utils/__tests__/fs-async.ts @@ -16,7 +16,8 @@ describe('Async FS utilities', () => { it('calls `stat` correctly and correctly check the existance of a path', async () => { const mockPath = '/dev/null'; - statMock.mockImplementationOnce(() => Promise.resolve()); + // eslint-disable-next-line @typescript-eslint/no-empty-function + statMock.mockImplementationOnce(async () => {}); expect(await checkPath(mockPath)).toBe(true); expect(statMock).toHaveBeenCalledTimes(1); @@ -34,7 +35,7 @@ describe('Async FS utilities', () => { const mockPath = '/dev/null'; const isDirectory = jest.fn(() => false); - statMock.mockImplementation(() => Promise.resolve({ isDirectory })); + statMock.mockImplementation(async () => ({ isDirectory })); expect(await checkPath(mockPath, 'directory')).toBe(false); expect(statMock).toHaveBeenCalledTimes(1); @@ -50,7 +51,7 @@ describe('Async FS utilities', () => { const mockPath = '/dev/null'; const isFile = jest.fn(() => false); - statMock.mockImplementation(() => Promise.resolve({ isFile })); + statMock.mockImplementation(async () => ({ isFile })); expect(await checkPath(mockPath, 'file')).toBe(false); expect(statMock).toHaveBeenCalledTimes(1); diff --git a/src/utils/__tests__/hash.ts b/src/utils/__tests__/hash.ts index d2d8e4ab..76265ffd 100644 --- a/src/utils/__tests__/hash.ts +++ b/src/utils/__tests__/hash.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import { getHash } from '../hash'; describe('Hash utilities', () => { diff --git a/src/utils/__tests__/validation.ts b/src/utils/__tests__/validation.ts index 63752809..cf07677a 100644 --- a/src/utils/__tests__/validation.ts +++ b/src/utils/__tests__/validation.ts @@ -32,7 +32,7 @@ describe('Cli utilities', () => { it.each(['a', {}, undefined, true, false, null])( 'throws an error when given a non-numeric value - input: %s', input => { - expect(() => parseNumeric(input as any)).toThrow( + expect(() => parseNumeric(input as unknown as any)).toThrow( `${input} is not a valid number` ); } @@ -48,9 +48,10 @@ describe('Cli utilities', () => { ); it('throws an error when given a non-string value', () => { - for (const value of [1, true, {}, undefined, null, false]) { + const values = [1, true, {}, undefined, null, false]; + for (const value of values) { expect(() => parseString(value as any)).toThrow( - `${value} is not a string` + `${value} is not a string` // eslint-disable-line @typescript-eslint/no-base-to-string ); } }); @@ -63,6 +64,7 @@ describe('Cli utilities', () => { expect(parseFunction(fn)).toBe(fn); }); + // eslint-disable-next-line prefer-regex-literals it.each([null, undefined, '', 'foo', 10, {}, new RegExp('foo')])( '`parseFunction` throws expected error if given path is found not to be a function - input: %s', input => { @@ -164,7 +166,7 @@ describe('Cli utilities', () => { it('calls `checkPath` correctly and returns unchanged path if found to be an existing directory', async () => { const dirname = '/foo/bar'; - checkPathMock.mockImplementationOnce(() => Promise.resolve(true)); + checkPathMock.mockImplementationOnce(async () => true); expect(await parseDir(dirname)).toBe(dirname); expect(checkPathMock).toHaveBeenCalledTimes(1); @@ -174,9 +176,9 @@ describe('Cli utilities', () => { it('throws expected error if given path is found not to be a directory', async () => { const dirname = '/foo/bar'; - checkPathMock.mockImplementationOnce(() => Promise.resolve(false)); + checkPathMock.mockImplementationOnce(async () => false); - await expect(() => parseDir(dirname)).rejects.toThrow( + await expect(async () => parseDir(dirname)).rejects.toThrow( '/foo/bar is not a directory' ); }); diff --git a/src/utils/assets.ts b/src/utils/assets.ts index 12e615d7..ba7e9e43 100644 --- a/src/utils/assets.ts +++ b/src/utils/assets.ts @@ -1,10 +1,11 @@ +import { Buffer } from 'buffer'; import { writeFile } from 'fs/promises'; -import glob from 'glob'; import { join, relative, resolve } from 'path'; import { promisify } from 'util'; +import glob from 'glob'; import { GeneratedAssets } from '../generators/generate-assets'; import { RunnerOptions } from '../types/runner'; -import { removeExtension, splitSegments } from '../utils/path'; +import { removeExtension, splitSegments } from './path'; export type WriteResult = { content: string | Buffer; writePath: string }; @@ -27,7 +28,7 @@ export const loadPaths = async (dir: string): Promise => { const files = await promisify(glob)(globPath, {}); - if (!files.length) { + if (files.length === 0) { throw new Error(`No SVGs found in ${dir}`); } diff --git a/src/utils/css.ts b/src/utils/css.ts index afbe76f2..424a7502 100644 --- a/src/utils/css.ts +++ b/src/utils/css.ts @@ -1,6 +1,7 @@ +import { Buffer } from 'buffer'; import { FontGeneratorOptions } from '../types/generator'; -import { getHash } from './hash'; import { FontAssetType } from '../types/misc'; +import { getHash } from './hash'; interface RenderSrcOptions { formatValue: string; diff --git a/src/utils/fs-async.ts b/src/utils/fs-async.ts index 668ebae1..f2a1d720 100644 --- a/src/utils/fs-async.ts +++ b/src/utils/fs-async.ts @@ -12,7 +12,7 @@ export const checkPath = async ( } return true; - } catch (err) { + } catch { return false; } }; diff --git a/src/utils/hash.ts b/src/utils/hash.ts index 10519ebe..b9555a27 100644 --- a/src/utils/hash.ts +++ b/src/utils/hash.ts @@ -1,3 +1,4 @@ +import { Buffer } from 'buffer'; import crypto from 'crypto'; export const getHash = (...contents: Array) => { diff --git a/src/utils/icon-id.ts b/src/utils/icon-id.ts index d75f5777..f4c246f2 100644 --- a/src/utils/icon-id.ts +++ b/src/utils/icon-id.ts @@ -1,9 +1,9 @@ +import slug from 'slugify'; import { GetIconIdFn } from '../types/misc'; import { removeExtension } from './path'; -import slug from 'slugify'; export const getIconId: GetIconIdFn = ({ relativeFilePath }) => - slug(removeExtension(relativeFilePath).replace(/(\/|\\|\.)+/g, '-'), { + slug(removeExtension(relativeFilePath).replace(/([./\\])+/g, '-'), { replacement: '-', remove: /['"`]/g }); diff --git a/src/utils/template.ts b/src/utils/template.ts index ab9ed8de..064367bc 100644 --- a/src/utils/template.ts +++ b/src/utils/template.ts @@ -1,6 +1,7 @@ import { readFile } from 'fs/promises'; -import Handlebars from 'handlebars'; import { isAbsolute, resolve } from 'path'; +import process from 'process'; +import Handlebars from 'handlebars'; import { getHexCodepoint } from './codepoints'; export const TEMPLATE_HELPERS: Record = { @@ -23,6 +24,6 @@ export const renderTemplate = async ( return Handlebars.compile(template)(context, { ...options, - helpers: { ...TEMPLATE_HELPERS, ...(options.helpers || {}) } + helpers: { ...TEMPLATE_HELPERS, ...options.helpers } }); }; diff --git a/src/utils/validation.ts b/src/utils/validation.ts index a40ebd14..df9fc54a 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -48,8 +48,8 @@ export const listMembersParser = export const removeUndefined = (object: Object) => { for (const key of Object.keys(object)) { - if (typeof object[key] === 'undefined') { - delete object[key]; + if (object[key] === undefined) { + delete object[key]; // eslint-disable-line @typescript-eslint/no-dynamic-delete } } @@ -59,9 +59,13 @@ export const removeUndefined = (object: Object) => { export const parseBoolean = (val: any) => { if (typeof val === 'string' && ['1', '0', 'true', 'false'].includes(val)) { return val === 'true' || val === '1'; - } else if (typeof val === 'number' && [0, 1].includes(val)) { + } + + if (typeof val === 'number' && [0, 1].includes(val)) { return val === 1; - } else if (typeof val === 'boolean') { + } + + if (typeof val === 'boolean') { return val; }