yaml-js-include
Version:
Extension for yaml-js library to be able to include files/directories in yaml files
158 lines • 6.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDirectoryIncludeType = exports.recursiveReaddirSync = void 0;
const fs = require("fs");
const p = require("path");
const yaml = require("js-yaml");
const merge = require("lodash.merge");
function recursiveReaddirSync(path, recursive = true) {
let list = [];
const files = fs.readdirSync(path);
files.forEach(function (file) {
const stats = fs.lstatSync(p.join(path, file));
if (recursive && stats.isDirectory()) {
list = list.concat(recursiveReaddirSync(p.join(path, file)));
}
else {
list.push(p.join(path, file));
}
});
return list;
}
exports.recursiveReaddirSync = recursiveReaddirSync;
const DefaultIncludeDirOptions = {
include: [],
exclude: [],
allowEmpty: false,
recursive: true,
extensions: ['.yaml', '.yml'],
lowerKeys: false,
ignoreIndicator: '_',
ignoreTopLevelDir: true,
ignoreDirStructure: true,
excludeTopLevelDirSeparator: true,
pathSeparator: '_'
};
/**
* Gets a schema for including directories
* @param yamlInclude YAML include object
* @returns {yaml.Type} YAML type for a schema
*/
const getDirectoryIncludeType = (yamlInclude) => {
return new yaml.Type('tag:yaml.org,2002:inc/dir', {
kind: 'sequence',
// Data should be an array of 1 or 2 items (path and optional options)
resolve: (data) => Array.isArray(data) && data.length > 0 && data.length < 3,
construct: (data) => {
var _a;
const basePath = yamlInclude.basePath;
let files = [];
if (!data[1]) {
data[1] = {};
}
const options = Object.assign(Object.assign(Object.assign({}, DefaultIncludeDirOptions), ((_a = yamlInclude.directoryOptions) !== null && _a !== void 0 ? _a : {})), data[1]);
let result = {};
options.extensions.sort((a, b) => b.length - a.length);
if (Array.isArray(data[0])) {
files = data[0];
}
else {
const fullPath = p.join(basePath, data[0]);
files = recursiveReaddirSync(fullPath, options.recursive);
files = files.map((filePath) => filePath.replace(basePath + p.sep, ''));
}
// sort the by length of filepath
files.sort(function (a, b) {
return a.length - b.length;
});
const getKeepingFileName = (filePath) => {
const extension = options.extensions.find((ext) => filePath.endsWith(ext));
if (!extension) {
return undefined;
}
const filename = p.basename(filePath, extension);
// check whitelist for filepath and file name
if (options.include &&
(options.include.indexOf(filePath) !== -1 ||
options.include.indexOf(filename) !== -1 ||
options.include.indexOf(filename + extension) !== -1)) {
return filename;
}
// if ANY part of the path has an ignorePrefix,
// skip it
if (filePath.indexOf(p.sep + options.ignoreIndicator) !== -1) {
return undefined;
}
// check blacklist for filepath and file name
if (options.exclude &&
(options.exclude.indexOf(filePath) !== -1 ||
options.exclude.indexOf(filename) !== -1 ||
options.exclude.indexOf(filename + extension) !== -1)) {
return undefined;
}
return filename;
};
files.forEach(function (filePath) {
let filename = getKeepingFileName(filePath);
if (!filename) {
return;
}
const splitDirPath = filePath.split(p.sep);
splitDirPath.pop();
// we generally don't want the top dir.
if (options.ignoreTopLevelDir) {
splitDirPath.shift();
}
if (options.lowerKeys) {
filename = filename.toLowerCase();
}
// get the source at last
let included = {};
const fullFilePath = p.join(basePath, filePath);
const src = fs.readFileSync(fullFilePath, yamlInclude.encoding);
if (src.length > 0) {
included = yamlInclude.parse(src, fullFilePath);
yamlInclude.basePath = basePath;
}
const tmp = {};
if (options.recursive) {
let key = options.excludeTopLevelDirSeparator
? ''
: options.pathSeparator;
key += splitDirPath.join(options.pathSeparator);
if (options.allowEmpty) {
tmp[key] = {};
tmp[key][filename] = included;
}
else {
if (Object.getOwnPropertyNames(included).length > 0) {
if (key.length > 0 && !options.ignoreDirStructure) {
tmp[key] = {};
tmp[key][filename] = included;
}
else {
// this implements the opt.excludeTopLevelDirSeparator option when at the top level
tmp[filename] = included;
}
}
}
}
else {
if (options.allowEmpty) {
tmp[filename] = included;
}
else {
if (Object.getOwnPropertyNames(included).length > 0) {
tmp[filename] = included;
}
}
}
result = merge(result, tmp);
});
return result;
},
instanceOf: Object,
});
};
exports.getDirectoryIncludeType = getDirectoryIncludeType;
//# sourceMappingURL=dir.js.map