@knapsack/app
Version:
Build Design Systems with Knapsack
178 lines • 7.44 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetSets = void 0;
const utils_1 = require("@knapsack/utils");
const file_utils_1 = require("@knapsack/file-utils");
const url_join_1 = __importDefault(require("url-join"));
const path_1 = require("path");
const schemaKnapsackAssetSetsConfig_json_1 = __importDefault(require("@knapsack/types/json-schemas/schemaKnapsackAssetSetsConfig.json"));
const file_db_1 = require("../../server/dbs/file-db");
const log_1 = require("../../cli/log");
const events_1 = require("../../server/events");
function getExtension(path) {
const type = (0, path_1.parse)(path).ext.replace('.', '');
if (type !== 'css' && type !== 'js' && type !== 'mjs') {
throw new Error(`Only CSS or JS extensions are allowed in Asset Sets and this was attempted: "${path}"`);
}
return type;
}
/**
* Collections of CSS & JS assets
*/
class AssetSets extends file_db_1.FileDb {
data;
dataDir;
missingFileVerbosity;
publicDir;
config;
publicPaths;
constructor({ dataDir, publicDir }) {
super({
filePath: (0, path_1.join)(dataDir, 'knapsack.asset-sets.json'),
type: 'json',
validationSchema: schemaKnapsackAssetSetsConfig_json_1.default,
writeFileIfAbsent: true,
defaults: {
globalAssetSetIds: [],
allAssetSets: {},
},
});
this.dataDir = dataDir;
this.publicPaths = [];
this.publicDir = publicDir;
}
init = async (opt) => {
await super.init(opt);
this.missingFileVerbosity = opt.missingFileVerbosity;
const userConfig = super.getDataSync();
this.config = userConfig;
this.data = await this.convertConfigToData(this.config);
};
hydrate = async ({ appClientData: { assetSetsState } }) => {
this.data = assetSetsState;
};
async convertConfigToData(config) {
const { allAssetSets, globalAssetSetIds } = config;
const data = {
globalAssetSetIds,
allAssetSets: {},
};
if (!allAssetSets)
return data;
const publicPaths = [];
await Promise.all(Object.keys(allAssetSets).map(async (assetSetId) => {
const assetSet = allAssetSets[assetSetId];
data.allAssetSets[assetSetId] = {
...assetSet,
assets: await Promise.all(assetSet.assets.map(async (asset, i) => {
if ((0, utils_1.isRemoteUrl)(asset.src)) {
const type = getExtension(asset.src);
return {
...asset,
src: asset.src,
publicPath: asset.src,
type,
tagLocation: asset.tagLocation || type === 'css' ? 'head' : 'foot',
};
}
const { absolutePath, exists, originalPath } = await (0, file_utils_1.resolvePath)({
path: asset.src,
resolveFromDir: this.dataDir,
});
// we create this b/c even if the file does not exist yet, the directory still needs to be hosted by server so it can serve the file once it is created
const fallbackPath = (0, path_1.join)(this.dataDir, originalPath);
const absPath = absolutePath || fallbackPath;
if (!exists) {
const msg = `This asset set file does not exist! ${asset.src}`;
const meta = {
assetSetId,
src: asset.src,
absolutePath: absPath,
};
if (this.missingFileVerbosity === 'error') {
log_1.log.error(msg, meta);
process.exit(1);
}
else if (this.missingFileVerbosity === 'warn') {
log_1.log.warn(msg, meta);
}
(0, file_utils_1.ensureDirSync)((0, path_1.dirname)(absPath));
}
const { base: filename, dir } = (0, path_1.parse)(absPath);
// creating asset set virtual directories
// express makes a static route at `publicPathBase` over in `src/server/routes.ts`
// `./dir/dist/main.css` will be assessible via `/ks-asset-sets/dir/dist/main.css`
let publicPathBase = publicPaths.find(({ dirPath }) => dir === dirPath)?.publicPathBase;
if (!publicPathBase) {
publicPathBase = `/ks-asset-sets/${(0, utils_1.slugify)(assetSetId)}-${i}`;
publicPaths.push({
dirPath: dir,
publicPathBase,
});
}
const type = getExtension(absPath);
return {
...asset,
src: absPath,
publicPath: (0, url_join_1.default)(publicPathBase, filename),
type,
tagLocation: asset.tagLocation || type === 'css' ? 'head' : 'foot',
};
})),
};
}));
this.publicPaths = publicPaths;
return data;
}
static convertDataToConfig(data) {
const { allAssetSets, globalAssetSetIds } = data;
const config = {
globalAssetSetIds,
allAssetSets: {},
};
Object.keys(allAssetSets).forEach((assetSetId) => {
const assetSet = allAssetSets[assetSetId];
config.allAssetSets[assetSetId] = {
...assetSet,
assets: assetSet.assets.map(({ publicPath, type, ...asset }) => asset),
};
});
return data;
}
async getData() {
const userConfig = await super.getData();
// this.config = this.config;
this.data = await this.convertConfigToData(userConfig);
return this.data;
}
savePrep = async (data) => {
// const config = AssetSets.convertDataToConfig(data);
return [];
};
getAssetSet(assetSetId) {
return this.data.allAssetSets[assetSetId];
}
getGlobalAssetSets() {
return this.data.globalAssetSetIds.map((id) => this.data.allAssetSets[id]);
}
watch() {
log_1.log.verbose('Watch started for asset sets');
const paths = new Set();
Object.values(this.data.allAssetSets).forEach(({ assets }) => {
assets.forEach((asset) => paths.add(asset.src));
});
const localAssetPaths = [...paths];
super.watchFiles({
extraPaths: localAssetPaths,
handleChange: (path) => {
events_1.knapsackEvents.emitPatternAssetChanged({ path });
events_1.knapsackEvents.emitRequestRendererClientReload();
},
});
}
}
exports.AssetSets = AssetSets;
//# sourceMappingURL=asset-sets.js.map