@thelabnyc/typed-scss-modules
Version:
TypeScript type definition generator for SCSS CSS Modules
54 lines (53 loc) • 2.35 kB
JavaScript
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));
};