import * as path from 'path' import * as fs from 'fs' import { wrapper, TypeOnEveryFile, TypeToolProp, TypeToolOptions, TypeOnBody } from '@asset-toolkit/core' export interface TypeProps extends TypeToolOptions { chunked?: boolean basePath?: string } /** * A tool to generate font face. * * @param props - { pathIn, pathOut } * @param options - { chunked, basePath } * @returns { Promise(returns) } */ const fontFaceGenerator: (_props: TypeToolProp, _options?: TypeProps) => Promise = wrapper( ({ file, wrapperProps, next }: TypeOnEveryFile) => { const fontName = file.replace(path.extname(file), '') if (!wrapperProps.files[fontName]) wrapperProps.files[fontName] = [] wrapperProps.files[fontName].push(file) next() }, ({ wrapperProps, options, pathOut }: TypeOnBody) => { const { basePath, chunked } = options || {} const cssOutput = (props: { fontFamily: string; src: string; fontDisplay: string }) => `@font-face { font-family: "${props.fontFamily}"; src: ${props.src}; font-display: "${props.fontDisplay}"; }`.trim() const outputAll = Object.keys(wrapperProps.files).map(fontName => { const files = wrapperProps.files[fontName] const fileCssList = files .map((file: string) => { const type = path.extname(file).replace('.', '') return `url("${path.join(basePath || '', file)}") format("${type}")` }) .join(',') const output = { fontFamily: fontName, src: fileCssList, fontDisplay: 'swap', } if (chunked) { fs.writeFileSync(path.join(pathOut, `${fontName}.css`), cssOutput(output)) fs.writeFileSync(path.join(pathOut, `${fontName}.json`), JSON.stringify(output, null, 4)) } return output }) if (!chunked) { fs.writeFileSync(path.join(pathOut, `template.css`), outputAll.map((output: any) => cssOutput(output)).join('\n')) fs.writeFileSync(path.join(pathOut, `template.json`), JSON.stringify(outputAll, null, 4)) } }, { exts: ['woff', 'woff2', 'eot', 'ttf'], name: 'Font Face Generator', files: {} }, ) export default fontFaceGenerator