Source: compiler.js

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { StyleError, CompileError } from './error.js';
import fs from 'fs';
/**
 * Compile AuraJS stylesheets into CSS
 * @param {string | StyleSheet}input The input file. You can also directly specify a Stylesheet object.
 * @param {string} outpath output file path
 * @param {boolean} silent Define wether or not the compiler should log messages (default: true)
 * @returns A written file containing the generated CSS. It also returns the CSS string.
 */
export function compile(opts = { input: undefined }) {
    return __awaiter(this, void 0, void 0, function* () {
        if (!opts.input)
            throw new CompileError('Missing required input option');
        let styleSheet;
        if (typeof opts.input === 'string') {
            styleSheet = yield import(opts.input);
            // Get the default export from the stylesheet.
            styleSheet = styleSheet.default;
        }
        else if (typeof opts.input === 'object') {
            styleSheet = opts.input;
        }
        if (!styleSheet)
            throw new CompileError('No default export found in stylesheet. This must be set to a StyleSheet object.');
        if (!opts.silent)
            compilerLog(`Starting compilation of '${opts.input}'`);
        // Check if there are any obvious errors in the stylesheet.
        errorCheckSheet(styleSheet.styles);
        // Loop over all styles and generate CSS, then write it to a file.
        const css = loopStyles(styleSheet.styles);
        if (opts.outpath) {
            if (!opts.silent)
                compilerLog(`Writing compiled CSS to '${opts.outpath}'`);
            fs.writeFileSync(opts.outpath, css);
        }
        if (!opts.silent)
            compilerLog(`Finished compilation of '${opts.input}'\n`);
        return css;
    });
}
/**
 * Loop over all styles, including nested ones.
 * @param {Array<Object>} styles Array containing styles / selectors
 * @param {string} parent Optional parent selector. Do not set manually.
 * @returns CSS string
 */
function loopStyles(styles, parent) {
    let css = '';
    let closed = false;
    styles.forEach((style) => {
        let addedCSS = '';
        if (style.selector) {
            if (parent) {
                if (style.selector.startsWith('&')) {
                    style.selector = `${parent}${style.selector.slice(1)}`;
                }
                else {
                    style.selector = `${parent} ${style.selector}`;
                }
                addedCSS += '}';
                closed = true;
            }
            addedCSS += `${style.selector} {`;
            addedCSS += loopStyles(style.style, style.selector);
            if (!closed)
                addedCSS += '}';
        }
        // If it is an import, add the styles
        else if (style.include) {
            addedCSS += loopStyles(style.include.styles, parent);
        }
        // Media queries need to be handled separately
        else if (style.media) {
            addedCSS += `@media ${style.media} {`;
            addedCSS += loopStyles(style.styles, parent);
            addedCSS += '}';
        }
        else if (style.name) {
            // now it is a CSS animation
            addedCSS += `@keyframes ${style.name} {`;
            addedCSS += loopStyles(style.keyframes, parent);
            addedCSS += '}';
        }
        else if (style.percent !== undefined) {
            addedCSS += `${style.percent}% {`;
            addedCSS += loopStyles(style.styles, parent);
            addedCSS += '}';
        }
        // If it is an array of styles, loop over them
        else if (style instanceof (Array)) {
            addedCSS += loopStyles(style, parent);
        }
        // If it is none of the above, it is a style.
        else {
            addedCSS += Object.keys(style).map((key, i) => {
                return `${key}: ${Object.values(style)[i]};`;
            }).join('');
        }
        css += addedCSS;
    });
    return css;
}
/**
 * Check to see if the Stylesheet contains anything that is deemed invalid
 * @param {Array<Object>} styles Array containing styles / selectors
 */
function errorCheckSheet(styles, parent = undefined) {
    let selectorFound = false;
    styles.forEach(style => {
        if (style.selector) {
            selectorFound = true;
            errorCheckSheet(style.style, style.selector);
        }
        else {
            if (style instanceof Array || style.name != undefined)
                return;
            if (selectorFound) {
                throw new StyleError(style, parent);
            }
        }
    });
}
/**
 * A simple logging function. Just a wrapper for console.log.
 * @param {string} msg Message to log
 */
function compilerLog(msg) {
    console.log(`[AuraJSS] ${msg}`);
}