@meistericons/meistericons
Version:
Meistericons, an icon library,
113 lines (94 loc) • 4.41 kB
JavaScript
import { appendFileSync, existsSync, mkdirSync, writeFileSync, readdirSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
var generateExportFile = (iconFile, outputDir) => {
const targetDir = path.resolve(`${outputDir}/icons`);
const importIconString = `export {default as ${toPascalCase(
iconFile
)}} from './${toPascalCase(iconFile)}';
`;
appendFileSync(path.resolve(targetDir, `index.ts`), importIconString, "utf-8");
};
var generateIconFile = (iconNodes, outputDir) => {
const name = iconNodes[0];
const paths = iconNodes[1];
const targetDir = path.resolve(`${outputDir}/icons`);
if (!existsSync(targetDir)) {
mkdirSync(targetDir);
}
const template = `
import createMeisterIcons from '../src/createMeisterIcons';
const ${toPascalCase(name)} = createMeisterIcons("${name}", ${JSON.stringify(
paths
)})
export default ${toPascalCase(name)}
`;
writeFileSync(path.join(targetDir, `${toPascalCase(name)}.ts`), template, "utf-8");
};
const defaultAttributes = {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
fill: "currentColor"
};
var generateTypes = (iconName, iconPackage, outputDir) => {
const targetDir = path.resolve(`${outputDir}/lib`);
let pkg = iconPackage.includes("../") ? iconPackage.replaceAll("../", "") : iconPackage;
const vuePackage = pkg === "static" ? "static" : pkg === "vue" ? "vue" : "vue-latest";
const typesFileName = `meistericons-${pkg === "react" ? "react" : vuePackage}.d.ts`;
if (!existsSync(targetDir)) {
mkdirSync(targetDir);
const vueImport = pkg === "vue" ? `import { Component } from "vue"` : pkg === "vue-latest" ? `import { FunctionalComponent, SVGAttributes } from "vue"` : "";
const importStatement = pkg === "react" ? `import { MeisterIcon } from '../src/createMeisterIcons'` : vueImport;
const types = pkg === "vue-latest" ? `interface SVGProps extends Partial<SVGAttributes> {
size: 24;
fill: "currentColor";
}
export type Icon = (props: SVGProps) => FunctionalComponent<SVGProps>;
` : pkg === "static" ? `` : `export interface SVGProps extends Partial<SVGElement> ${JSON.stringify(
defaultAttributes,
null,
2
)}
export declare type IconNodeChild = readonly [string, object];
export declare type IconNode = readonly [tag: string, attrs: SVGProps, children?: IconNodeChild[]];
export declare type CustomAttrs = { [attr:string]: any }
export type Icons = { [key: string]: IconNode }
export interface CreateIconsOptions {
icons: Icons;
nameAttr?: string;
attrs?: CustomAttrs;
}
export function createElement(icon: IconNode): SVGSVGElement;
export function createIcons(options: CreateIconsOptions): void;
export declare const icons: Icons;
`;
const typeDefinitions = ` ${importStatement}
declare module '@meistericons/${pkg}'
${types}
// Generated icons
`;
writeFileSync(path.resolve(targetDir, typesFileName), typeDefinitions, "utf-8");
}
const vueReturnType = pkg === "vue-latest" ? "Icon;" : pkg === "static" ? "string" : "Component;";
appendFileSync(
path.resolve(targetDir, typesFileName),
`export declare const ${iconName}: ${pkg === "react" ? "MeisterIcon;" : vueReturnType}
`,
"utf-8"
);
console.log(`Added icon type ${iconName} - @meistericons/${pkg}`);
};
const toCamelCase = (string) => string.replace(
/^([A-Z])|[\s-_]+(\w)/g,
(match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
);
const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
const toPascalCase = (string) => toCamelCase(string).charAt(0).toUpperCase() + toCamelCase(string).slice(1);
const getCurrentDir = (filePath) => fileURLToPath(new URL(filePath));
const readIconFiles = (iconDir) => readdirSync(iconDir).map((iconFile) => iconFile.replace(/.svg/, ""));
const readSvgCode = (file) => readFileSync(file);
const readAllMetadata = (dir) => readdirSync(dir).reduce((acc, fileName, i) => {
acc[path.basename(fileName, ".svg")] = readSvgCode(fileName);
return acc;
}, {});
export { generateExportFile, generateIconFile, generateTypes, getCurrentDir, readAllMetadata, readIconFiles, readSvgCode, toCamelCase, toKebabCase, toPascalCase };