UNPKG

@onesy/style

Version:

CSS in JS styling solution

259 lines (258 loc) 14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fast_glob_1 = __importDefault(require("fast-glob")); const fs_extra_1 = __importDefault(require("fs-extra")); const is_1 = __importDefault(require("@onesy/utils/is")); const getEnvironment_1 = __importDefault(require("@onesy/utils/getEnvironment")); const hash_1 = __importDefault(require("@onesy/utils/hash")); const merge_1 = __importDefault(require("@onesy/utils/merge")); const stringify_1 = __importDefault(require("@onesy/utils/stringify")); const to_1 = __importDefault(require("@onesy/utils/to")); const try_1 = __importDefault(require("@onesy/utils/try")); const unique_1 = __importDefault(require("@onesy/utils/unique")); const node_1 = __importDefault(require("@onesy/node")); const OnesyStyle_1 = __importDefault(require("./OnesyStyle")); const OnesyTheme_1 = __importDefault(require("./OnesyTheme")); const OnesyStyleSheetManager_1 = __importDefault(require("./OnesyStyleSheetManager")); const reset_1 = require("./reset"); const optionsDefault = { mode: 'regular', onesy_style: { get: OnesyStyle_1.default.first.bind(OnesyStyle_1.default), }, onesy_theme: { get: OnesyTheme_1.default.first.bind(OnesyTheme_1.default), }, css: { file: { hash: true }, minify: true }, html: { insert: { comment: '<!-- onesy style insert -->' }, add: true }, rule: { rtl: false, prefix: true, sort: true }, log: true }; const env = (0, getEnvironment_1.default)(); const getValuePaths = async (value, options = { onlyDirectories: true }) => { const wd = process.cwd(); let paths = ((0, is_1.default)('array', value) ? value : [value]) .map(item => (item === null || item === void 0 ? void 0 : item.url) || item) .filter(Boolean) .filter(item => (0, is_1.default)('string', item)) .map(item => path_1.default.isAbsolute(item) ? item : path_1.default.join(wd, item)); paths = (await (0, fast_glob_1.default)(paths, options)) .map(filePath => path_1.default.resolve(filePath)); return (0, unique_1.default)(paths); }; const minify = (value) => { if ((0, is_1.default)('string', value)) return value.replace(/\n/g, '').replace(/ ?(\{|:|,|>|~) ?/g, '$1').replace(/;(\})/g, '$1'); return value; }; function css(value__, options_ = {}) { var _a; const options = (0, merge_1.default)(options_, optionsDefault, { copy: true }); // Onesy style let onesyStyle = options.onesy_style.value || ((0, is_1.default)('function', options.onesy_style.get) && options.onesy_style.get()); if (onesyStyle === undefined) onesyStyle = new OnesyStyle_1.default(); // Onesy theme const onesyTheme = options.onesy_theme.value || ((0, is_1.default)('function', options.onesy_theme.get) && options.onesy_theme.get()); // Make value if it's a function let value_ = (0, is_1.default)('function', value__) ? (0, try_1.default)(() => value__(onesyTheme)) : value__; // For reset, add reset to value let method = 'css'; let priority = 'upper'; if (options.reset) { method = 'reset'; // Default const valueDefault = (0, merge_1.default)(reset_1.resetDefault, reset_1.normalize); // Add reset defaults // user provided values override reset default values if ((_a = options.resetProps) === null || _a === void 0 ? void 0 : _a.override) value_ = Object.assign(Object.assign({}, valueDefault), value_); else value_ = (0, merge_1.default)(value_, valueDefault); } // reset or pure update priority if (options.pure) method = 'pure'; if (options.reset || options.pure) priority = 'lower'; // Make an instance of onesyStyleSheetManager const onesyStyleSheetManager = new OnesyStyleSheetManager_1.default(value_, { mode: options.mode, pure: options.reset || options.pure, priority, onesyTheme, onesyStyle, rule: options.rule, style: { attributes: { method } } }); const responseManager = { ids: onesyStyleSheetManager.ids, onesy_style_sheet_manager: onesyStyleSheetManager, sheets: onesyStyleSheetManager.sheets, add: onesyStyleSheetManager.add.bind(onesyStyleSheetManager), props: onesyStyleSheetManager.props, update: onesyStyleSheetManager.update.bind(onesyStyleSheetManager), remove: onesyStyleSheetManager.remove.bind(onesyStyleSheetManager), addRule: onesyStyleSheetManager.sheets.static[0] && onesyStyleSheetManager.sheets.static[0].addRule.bind(onesyStyleSheetManager.sheets.static[0]), }; const response = { make: async () => { var _a, _b, _c, _d, _e; const wd = process.cwd(); // add const responseManagerValue = responseManager.add(); // All css let value = onesyStyleSheetManager.css; const minified = minify(value); if (options.css.minify) value = minified; // CSS // Make file name, only if at least 1 folder is provided // and it exists let made = false; const paths = { folders: { css: await getValuePaths(options.css.folders), }, files: { html: await getValuePaths(options.html.files, { onlyFiles: true }), }, }; const madeFiles = { css: [], }; const fileHash = (0, hash_1.default)(minified, { withPrefix: false }); if ((_a = paths.folders.css) === null || _a === void 0 ? void 0 : _a.length) { const folders = paths.folders.css; const name = `${((_c = (_b = options.css) === null || _b === void 0 ? void 0 : _b.file) === null || _c === void 0 ? void 0 : _c.name) || env.onesy_methods.makeName.next().value}${((_e = (_d = options.css) === null || _d === void 0 ? void 0 : _d.file) === null || _e === void 0 ? void 0 : _e.hash) ? `.${fileHash}` : ''}.css`; // Clear folder if clear const make = async (path_, index) => { const folder = options.css.folders.find(item => path_ === (path_1.default.isAbsolute(item.url) ? item.url : path_1.default.join(wd, item.url))); if (folder) { const clear = folder.clear !== undefined ? folder.clear : options.css.clear; // Empty folder if clear if (clear) await fs_extra_1.default.emptyDir(path_); // Make the file const nameWithPath = path_1.default.join(path_, name); await node_1.default.file.add(nameWithPath, value); // Add to files if (index === 0 || !madeFiles.css.length) madeFiles.css.push(nameWithPath); if (options.log) console.log(`Made \x1b[34m${nameWithPath}\x1b[0m \x1b[32m${(0, to_1.default)(value, 'size')}\x1b[0m`); } }; // Make files in all the folders if (options.log) console.log(); await Promise.all(folders.map((item, index) => make(item, index))); if (options.log) console.log(); made = true; } // HTML // Only if css is made and in folders // and html at least 1 file is provided and it exists // and html add: true if (made && paths.files.html.length && options.html.add) { const files = paths.files.html; const add = async (path_) => { var _a, _b, _c, _d; const file = options.html.files.find(item => path_ === (path_1.default.isAbsolute(item.url) ? item.url : path_1.default.join(wd, item.url))); if (file) { // Add path relative from the css file to the index path const valueHTML = await node_1.default.file.get(path_, false); const values = valueHTML.split('\n'); const filesRelative = madeFiles.css.map(item => path_1.default.relative(path_1.default.dirname(path_), item)); // Add css files to folders // Start from insert or file.insert comment or if none exists // start from the first group of onesy inserted links, or // start from first the bottom of head const insert = ((_a = file.insert) === null || _a === void 0 ? void 0 : _a.comment) || ((_c = (_b = options.html) === null || _b === void 0 ? void 0 : _b.insert) === null || _c === void 0 ? void 0 : _c.comment); const indexInsertComment = values.findIndex(item => item.indexOf(insert) > -1); const indexOnesyInserts = values.findIndex(item => item.indexOf('<link') > -1 && item.indexOf(`data-onesy='true'`) > -1); const indexBottomHead = values.findIndex(item => item.indexOf('</head>') > -1); const indexBottomBody = values.findIndex(item => item.indexOf('</body>') > -1); const indexStart = ((indexInsertComment > -1 && indexInsertComment + 1) || (indexOnesyInserts > -1 && indexOnesyInserts) || indexBottomHead); const inBody = indexStart > indexBottomHead; // Adding order depends on if it's reset, pure or regular style const allLinks = values.slice(indexStart, inBody ? indexBottomBody : indexBottomHead).filter(item => item.indexOf('<link') > -1); const onesyLinks = allLinks.filter(item => item.indexOf(`data-onesy='true'`) > -1); const onesyLinksPure = onesyLinks.filter(item => item.indexOf(`data-pure='true'`) > -1); const onesyLinksNoReset = onesyLinks.filter(item => item.indexOf(`data-reset='true'`) === -1); const onesyLinkReset = values.find(item => item.indexOf('<link') > -1 && item.indexOf(`data-reset='true'`) > -1); const onesyLinkResetIndex = values.findIndex(item => item === onesyLinkReset); let indexInsert = onesyLinkResetIndex > -1 ? onesyLinkResetIndex + 1 : indexStart; if (!!onesyLinksNoReset.length && !options.reset) { if (!options.pure) { const onesyLinkLastIndex = values.findIndex(item => item === onesyLinksNoReset[onesyLinksNoReset.length - 1]); indexInsert = onesyLinkLastIndex + 1; } else { const onesyLinkFirstIndex = values.findIndex(item => item === onesyLinksNoReset[0]); if (!onesyLinksPure.length) indexInsert = onesyLinkFirstIndex; else { const onesyLinkPureLast = values.findIndex(item => item === onesyLinksPure[onesyLinksPure.length - 1]); indexInsert = onesyLinkPureLast + 1; } } } // Take whitespace padding from other styles or links, or title or body + tab space let padding = ''; const element = values[(inBody ? indexBottomBody : indexBottomHead) - 1]; const main = values[(inBody ? indexBottomBody : indexBottomHead)]; padding = element.split(/(?! )/)[0]; if (padding[0] !== ' ') padding = main.split(/(?! )/)[0]; if (padding[0] !== ' ') padding = ' '; filesRelative.forEach(file_ => values.splice(indexInsert, 0, `${padding}<link rel='stylesheet' href='${file_}' data-onesy='true'${options.reset ? ` data-reset='true'` : ''}${options.pure ? ` data-pure='true'` : ''} />`)); // if not pure and reset // get names and add (update) as a script global variable to window // add at the bottom of head if (((_d = options.html) === null || _d === void 0 ? void 0 : _d.addNames) && !options.pure && !options.reset) { delete responseManagerValue.ids; values.splice(indexBottomHead + 1, 0, `${padding}<script> ${padding} if (!window.onesyStyleNames) window.onesyStyleNames = {}; ${padding} ${padding} window.onesyStyleNames['${fileHash}'] = ${(0, stringify_1.default)(responseManagerValue, padding.length + 2)}; ${padding}</script>`); } // Update the file await node_1.default.file.update(path_, values.join('\n')); } }; await Promise.all(files.map(item => add(item))); } }, }; // Response return response; } exports.default = css;