UNPKG

@knapsack/app

Version:

Build Design Systems on top of knapsack, by Basalt

208 lines (174 loc) • 6.82 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AssetSets = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _getFileSizes = require("get-file-sizes"); var _path = require("path"); var _chokidar = _interopRequireDefault(require("chokidar")); var _fileDb = require("./dbs/file-db"); var _schemaKnapsackAssetSetsConfig = _interopRequireDefault(require("../json-schemas/schemaKnapsackAssetSetsConfig")); var _serverUtils = require("./server-utils"); var log = _interopRequireWildcard(require("../cli/log")); var _events = require("./events"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Collections of CSS & JS assets * @todo use Express to serve it from wherever it is on file system and not just inside the `config.public` dir */ class AssetSets extends _fileDb.FileDb2 { constructor({ dataDir, publicDir }) { super({ filePath: (0, _path.join)(dataDir, 'knapsack.asset-sets.json'), type: 'json', validationSchema: _schemaKnapsackAssetSetsConfig.default, defaults: { globalAssetSetIds: [], allAssetSets: { example: { id: 'example', title: 'Example', inlineCss: '', inlineJs: '', assets: [{ src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css' }, { src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js' }] } } } }); (0, _defineProperty2.default)(this, "data", void 0); (0, _defineProperty2.default)(this, "dataDir", void 0); (0, _defineProperty2.default)(this, "publicDir", void 0); this.dataDir = dataDir; this.publicDir = publicDir; const userConfig = super.getDataSync(); this.data = this.convertConfigToData(userConfig); } convertConfigToData(config) { const { allAssetSets, globalAssetSetIds } = config; const data = { globalAssetSetIds, allAssetSets: {} }; if (!allAssetSets) return data; Object.keys(allAssetSets).forEach(assetSetId => { const assetSet = allAssetSets[assetSetId]; data.allAssetSets[assetSetId] = _objectSpread({}, assetSet, { assets: assetSet.assets.map(asset => { const isRemote = (0, _serverUtils.isRemoteUrl)(asset.src); const src = isRemote ? asset.src : (0, _path.resolve)(this.dataDir, asset.src); const { ext } = (0, _path.parse)(src); if (!isRemote) { (0, _serverUtils.fileExistsOrExit)(src); if ((0, _path.relative)(this.publicDir, src).includes('..')) { log.error(`Some CSS or JS is not publically accessible! These must be either remote or places inside the "public" dir (${this.publicDir})`, { asset }); process.exit(1); } } else { return _objectSpread({}, asset, { src, publicPath: src, type: ext.replace('.', '') }); } const [size] = (0, _getFileSizes.getFileSizes)([src]); return _objectSpread({}, asset, { src, // isInHead: asset.isInHead === true, publicPath: isRemote ? src : `/${(0, _path.relative)(this.publicDir, src)}`, type: ext.replace('.', ''), sizeRaw: size.sizeRaw, sizeKb: size.sizeKb }); }) }); }); return data; } /** * @todo evaluate - perhaps it's best to compute these type of values as needed instead of all up front when "config" is turned into "data"? * @param assetSrc */ getAssetPublicPath(assetSrc) { const isRemote = (0, _serverUtils.isRemoteUrl)(assetSrc); const src = isRemote ? assetSrc : (0, _path.resolve)(this.dataDir, assetSrc); if (!isRemote) { (0, _serverUtils.fileExistsOrExit)(src); if ((0, _path.relative)(this.publicDir, src).includes('..')) { log.error(`Some CSS or JS is not publically accessible! These must be either remote or places inside the "public" dir (${this.publicDir})`); process.exit(1); } } return isRemote ? src : `/${(0, _path.relative)(this.publicDir, src)}`; } static convertDataToConfig(data) { const { allAssetSets, globalAssetSetIds } = data; const config = { globalAssetSetIds, allAssetSets: {} }; Object.keys(allAssetSets).forEach(assetSetId => { const assetSet = allAssetSets[assetSetId]; config.allAssetSets[assetSetId] = _objectSpread({}, assetSet, { assets: assetSet.assets.map(({ src }) => { return { src }; }) }); }); return data; } async getData() { const userConfig = await super.getData(); // this.config = this.config; this.data = this.convertConfigToData(userConfig); return this.data; } getAssetSet(assetSetId) { return this.data.allAssetSets[assetSetId]; } getGlobalAssetSets() { return this.data.globalAssetSetIds.map(id => this.data.allAssetSets[id]); } watch() { const paths = new Set(); Object.values(this.data.allAssetSets).forEach(({ assets }) => { assets.forEach(asset => paths.add(asset.src)); }); const localAssetPaths = [...paths]; const assetWatcher = _chokidar.default.watch(localAssetPaths, { ignoreInitial: true }); assetWatcher.on('all', (event, path) => { _events.knapsackEvents.emit(_events.EVENTS.PATTERN_ASSET_CHANGED, { event, path }); }); } } exports.AssetSets = AssetSets;