UNPKG

postcss-qute

Version:

Provides saas like markup, color-mod function, custom @import resolvers and theme support

193 lines (178 loc) 6.33 kB
'use strict'; var fs = require('fs'); var path = require('path'); var postcss = require('postcss'); var postcssAdvancedVariables = require('postcss-advanced-variables'); var postcssAtroot = require('postcss-atroot'); var postcssExtendRule = require('postcss-extend-rule'); var postcssNested = require('postcss-nested'); var postcssPropertyLookup = require('postcss-property-lookup'); var postcssCcolorMod = require('postcss-color-mod-function'); var nodeResolve = require('resolve'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); var path__default = /*#__PURE__*/_interopDefaultLegacy(path); var postcss__default = /*#__PURE__*/_interopDefaultLegacy(postcss); var postcssAdvancedVariables__default = /*#__PURE__*/_interopDefaultLegacy(postcssAdvancedVariables); var postcssAtroot__default = /*#__PURE__*/_interopDefaultLegacy(postcssAtroot); var postcssExtendRule__default = /*#__PURE__*/_interopDefaultLegacy(postcssExtendRule); var postcssNested__default = /*#__PURE__*/_interopDefaultLegacy(postcssNested); var postcssPropertyLookup__default = /*#__PURE__*/_interopDefaultLegacy(postcssPropertyLookup); var postcssCcolorMod__default = /*#__PURE__*/_interopDefaultLegacy(postcssCcolorMod); var nodeResolve__default = /*#__PURE__*/_interopDefaultLegacy(nodeResolve); function ContentCache() { this.cache = {}; } ContentCache.prototype = { get(file) { let content = this.cache[file]; if (content == null) { content = fs__default['default'].readFileSync(file); this.cache[file] = content; } return content; }, lookup(file) { return this.cache[file]; }, put(file) { this.cache[file] = fs__default['default'].readFileSync(res); } }; function ImportResolver() { this.cache = new ContentCache(); this.resolvers = []; } ImportResolver.prototype = { resolve(id, cwd, opts) { for (const r of this.resolvers) { const res = r.resolve(id, cwd, opts); if (res) { return { file: res, contents: this.cache.get(res) }; } } return this.defaultResolve(id, cwd, opts); }, defaultResolve(id, cwd, opts) { return new Promise((resolve, reject) => { nodeResolve__default['default'](id, {basedir: cwd}, (err, res) => { if (err) { reject(err); } else { resolve({ file: res, contents: this.cache.get(res) }); } }); }); }, push(resolver) { this.resolvers.push(resolver); } }; function findPackageDir(cwd) { if (fs__default['default'].existsSync(path__default['default'].join(cwd, 'package.json'))) { return cwd; } else { var parent = path__default['default'].dirname(cwd); if (parent && parent !== cwd) { return findPackageDir(parent); } else { return null; } } } function MaterialTheme(theme, cwd) { this.cwd = cwd || process.cwd(); this.package = findPackageDir(this.cwd); if (!this.package) throw new Error('No package.json was found from '+ this.cwd); this.themesDirs = []; this.themeDir = null; this.theme = null; this.addThemesDir(this.package); this.addThemesDir(path__default['default'].join(this.package, 'node_modules', '@qutejs', 'material')); this.setTheme(theme || 'default'); } MaterialTheme.prototype = { addThemesDir(root) { const themesDir = path__default['default'].join(root, 'themes'); if (fs__default['default'].existsSync(themesDir)) { this.themesDirs.push(themesDir); } }, findThemeDir(theme) { var dirs = this.themesDirs; for (const dir of dirs) { let themeDir = path__default['default'].join(dir, theme); if (fs__default['default'].existsSync(themeDir)) { return themeDir; } } return null; }, setTheme(theme) { this.theme = theme; const themeDir = this.findThemeDir(theme); if (themeDir) { this.themeDir = path__default['default'].resolve(themeDir); } else { this.themeDir = null; } }, resolve(importId, cwd) { if (importId === '%theme') { if (!this.themeDir) { throw new Error('Could not import theme: No themes directory was found in the project context'); } return path__default['default'].join(this.themeDir, 'index.css'); } else if (importId.startsWith('%theme/')) { if (!this.themeDir) { throw new Error('Could not import theme: No themes directory was found in the project context'); } return path__default['default'].join(this.themeDir, importId.substring('%theme'.length)); } else { return null; } } }; // plugin chain const plugins = [ postcssExtendRule__default['default'], postcssAdvancedVariables__default['default'], postcssAtroot__default['default'], postcssPropertyLookup__default['default'], postcssNested__default['default'], postcssCcolorMod__default['default'] ]; // plugin var index = postcss__default['default'].plugin('postcss-qute', rawopts => { if (!rawopts) rawopts = {}; const resolver = new ImportResolver(); if (rawopts.importResolvers) { for (const r of rawopts.importResolvers) { resolver.push(r); } } resolver.push(new MaterialTheme(rawopts.theme, rawopts.cwd)); const opts = Object.assign({ importResolve: function(id, cwd, opts) { return resolver.resolve(id, cwd, opts); } }, rawopts); // initialize all plugins const initializedPlugins = plugins.map( plugin => plugin(opts) ); // process css with all plugins return (root, result) => initializedPlugins.reduce( (promise, plugin) => promise.then( () => plugin(result.root, result) ), Promise.resolve() ); }); module.exports = index;