boats
Version:
Beautiful Open / Async Template System - Write less yaml with BOATS and Nunjucks.
75 lines (74 loc) • 3.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PathInjector = void 0;
const tslib_1 = require("tslib");
const upath = tslib_1.__importStar(require("upath"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
require("ts-replace-all");
class PathInjector {
constructor(paths, sourceFolderInWorkspace) {
this.paths = paths;
this.sourceFolderInWorkspace = sourceFolderInWorkspace;
this.paths = this.enrichForSpecialCases(paths, sourceFolderInWorkspace);
this.sourceFolderInWorkspace = sourceFolderInWorkspace || '';
if (paths) {
// If we have paths, setup a working strategy and assign it
// Sort the patterns so the most specific ones are first (crudely using longest as most specific)
this.keyPatterns = Object.keys(paths).sort((a, b) => b.length - a.length);
// trim trailing slashes to avoid stripping them out later
this.mixinExpressions = this.keyPatterns.map((str) => str.replace(/\/$/, '')).map((str) => new RegExp(str, 'g'));
this.refExpressions = this.keyPatterns
.map((str) => str.replace(/\/$/, ''))
.map((str) => new RegExp(`(\\$ref[ '"]*:[ '"]*)(${str})`, 'gs'));
this.injectMixin = this.doInject;
this.injectRefs = this.doInjectRefs;
}
else {
// Inject the null strategy
this.injectMixin = this.skip;
this.injectRefs = (str, _) => str;
}
}
enrichForSpecialCases(paths, sourceRoot) {
if (!sourceRoot) {
return paths;
}
// When the root of the source is a valid path under one of the absolute paths
// Then we need to add a special case to ensure it is converted into a relative path
const validPaths = Object.keys(paths)
.filter((prefix) => fs_extra_1.default.pathExistsSync(upath.join(paths[prefix], sourceRoot)));
if (validPaths.length > 0) {
validPaths.forEach((prefix) => {
paths[upath.join(prefix, sourceRoot)] = upath.join(paths[prefix], sourceRoot);
});
}
return paths;
}
skip(target) {
return [target, false];
}
doInject(target) {
for (let i = 0; i < this.mixinExpressions.length; i++) {
const keyPattern = this.mixinExpressions[i];
if (keyPattern.test(target)) {
const value = this.paths[this.keyPatterns[i]];
return [upath.normalize(target.replace(keyPattern, value)), true];
}
}
return [target, false];
}
doInjectRefs(target, relativeRoot) {
for (let i = 0; i < this.refExpressions.length; i++) {
const keyPattern = this.refExpressions[i];
if (keyPattern.test(target)) {
// First remove the relative path from the .boatsrc to the index file,
// as the templating has already happened
// files are no longer where they were, and have all moved to locations relative to the index file
const value = upath.join(relativeRoot, upath.relative(this.sourceFolderInWorkspace, this.paths[this.keyPatterns[i]]));
target = target.replaceAll(keyPattern, `$1${value.replace('//', '/')}`);
}
}
return target;
}
}
exports.PathInjector = PathInjector;