UNPKG

@thelabnyc/typed-scss-modules

Version:

TypeScript type definition generator for SCSS CSS Modules

54 lines (53 loc) 2.35 kB
import fs from "node:fs/promises"; import { pathToFileURL } from "node:url"; import { camelCase, kebabCase, snakeCase } from "change-case"; import * as sass from "sass"; import { customImporters, } from "./importer.js"; import { sourceToClassNames } from "./source-to-class-names.js"; const transformersMap = { camel: (className) => camelCase(className, { mergeAmbiguousCharacters: true }), dashes: (className) => /-/.test(className) ? camelCase(className) : className, kebab: (className) => kebabCase(className), none: (className) => className, param: (className) => kebabCase(className), snake: (className) => snakeCase(className), }; const NAME_FORMATS_WITH_TRANSFORMER = Object.keys(transformersMap); export const NAME_FORMATS = [...NAME_FORMATS_WITH_TRANSFORMER, "all"]; export const nameFormatDefault = "camel"; export const fileToClassNames = async (file, { additionalData, includePaths = [], nameFormat: rawNameFormat, aliases = {}, aliasPrefixes = {}, importers, } = {}) => { const nameFormat = (typeof rawNameFormat === "string" ? [rawNameFormat] : rawNameFormat); /* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition */ const nameFormats = nameFormat ? nameFormat.includes("all") ? NAME_FORMATS_WITH_TRANSFORMER : nameFormat : [nameFormatDefault]; const fileContents = additionalData ? `${additionalData}\n${(await fs.readFile(file)).toString()}` : null; const compileOpts = { loadPaths: includePaths, importers: customImporters({ aliases, aliasPrefixes, importers, includePaths, }), }; const result = await (fileContents ? sass.compileStringAsync(fileContents, { ...compileOpts, url: pathToFileURL(file), }) : sass.compileAsync(file, compileOpts)); const classNames = await sourceToClassNames(result.css, file); const transformers = nameFormats.map((item) => transformersMap[item]); const transformedClassNames = new Set([]); classNames.forEach((className) => { transformers.forEach((transformer) => { transformedClassNames.add(transformer(className)); }); }); return Array.from(transformedClassNames).sort((a, b) => a.localeCompare(b)); };