postcss-d-ts
Version:
PostCSS plugin to generate `.d.ts` of all used CSS classes and ids in imported stylesheets
79 lines (78 loc) • 3.51 kB
JavaScript
;
const path_1 = require("path");
const utils_1 = require("./utils");
const fs_1 = require("./fs");
const schema = require("./schema.json");
const replaceMultiplicated = require("./replaceMultiplicated");
const collector = require("./collector");
const rewrite = require("./rewrite");
const { keys: $keys } = Object, defaultOptions = utils_1.extractDefaults(schema), { title, signature, templateEol, properties: { template: { $comment: templatePath } } } = schema, defaultTemplate = fs_1.readlineSync(path_1.resolve(__dirname, templatePath), templateEol), creator8 = (opts) => {
const options = makeOpts(opts);
return {
postcssPlugin: title,
prepare: (result) => {
var _a, _b;
if (!((_b = (_a = result.root) === null || _a === void 0 ? void 0 : _a.source) === null || _b === void 0 ? void 0 : _b.input.file))
return {};
try {
const warn = optsCheck(options);
warn && result.warn(warn);
}
catch ({ message }) {
result.warn(message);
return {};
}
const identifiers = {};
return {
RuleExit: collector(identifiers, options),
RootExit: writer(identifiers, options)
};
}
};
};
creator8.postcss = true;
function optsCheck({ destination, identifierParser }) {
if (!(destination === false || destination !== null && typeof destination === "object"))
throw new Error("Destination is of wrong type");
if (!identifierParser.flags.includes('g'))
return 'identifierParser without global flag may take only first occurance';
return;
}
function makeOpts(opts) {
const options = !opts ? defaultOptions : { ...defaultOptions, ...opts }, { eol, destination, identifierKeyword, identifierMatchIndex, identifierCleanupReplace } = options;
return {
eol,
destination,
identifierKeyword,
identifierMatchIndex,
identifierCleanupReplace,
...internalOpts(options)
};
}
function internalOpts({ eol, template: templatePath, identifierPattern: cssP, identifierCleanupPattern: escapedP, allowedAtRules: atRules, checkMode }) {
const identifierParser = utils_1.regexpize(cssP, "g"), identifierCleanupParser = utils_1.regexpize(escapedP, "g"), templateContent = typeof templatePath === "string"
? fs_1.readlineSync(templatePath, eol)
: defaultTemplate, allowedAtRuleNames = new Set(atRules);
return {
identifierParser,
identifierCleanupParser,
templateContent,
allowedAtRuleNames,
checkMode: checkMode !== null && checkMode !== void 0 ? checkMode : process.env.NODE_ENV === "production"
};
}
function writer(identifiers, { eol, templateContent, identifierKeyword, destination, checkMode }) {
return async ({ source }) => {
const keys = $keys(identifiers).sort(), file = source.input.file, target = `${file}.d.ts`, lines = replaceMultiplicated(signature.concat(templateContent), identifierKeyword, keys);
if (destination === false) {
if (keys.length !== 0)
return await rewrite(target, lines, eol, checkMode);
if (checkMode && await fs_1.$exists(target))
throw new Error(`File "${target}" should not exist`);
await fs_1.$unlink(target);
}
else
destination[file] = lines;
};
}
module.exports = creator8;