227 lines
32 KiB
JavaScript
227 lines
32 KiB
JavaScript
|
"use strict";
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
const path_1 = require("path");
|
||
|
const debug_1 = __importDefault(require("debug"));
|
||
|
const json5_1 = __importDefault(require("json5"));
|
||
|
const lodash_1 = require("lodash");
|
||
|
const promisified_functions_1 = require("../utils/promisified-functions");
|
||
|
const option_1 = __importDefault(require("./option"));
|
||
|
const option_source_1 = __importDefault(require("./option-source"));
|
||
|
const resolve_path_relatively_cwd_1 = __importDefault(require("../utils/resolve-path-relatively-cwd"));
|
||
|
const render_template_1 = __importDefault(require("../utils/render-template"));
|
||
|
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
|
||
|
const log_1 = __importDefault(require("../cli/log"));
|
||
|
const formats_1 = require("./formats");
|
||
|
const DEBUG_LOGGER = (0, debug_1.default)('testcafe:configuration');
|
||
|
class Configuration {
|
||
|
constructor(configurationFilesNames) {
|
||
|
var _a;
|
||
|
this._options = {};
|
||
|
this._defaultPaths = this._resolveFilePaths(configurationFilesNames);
|
||
|
this._filePath = (_a = this._defaultPaths) === null || _a === void 0 ? void 0 : _a[0];
|
||
|
this._overriddenOptions = [];
|
||
|
}
|
||
|
static _fromObj(obj) {
|
||
|
const result = Object.create(null);
|
||
|
Object.entries(obj).forEach(([key, value]) => {
|
||
|
result[key] = new option_1.default(key, value);
|
||
|
});
|
||
|
return result;
|
||
|
}
|
||
|
static _showConsoleWarning(message) {
|
||
|
log_1.default.write(message);
|
||
|
}
|
||
|
static _showWarningForError(error, warningTemplate, ...args) {
|
||
|
const message = (0, render_template_1.default)(warningTemplate, ...args);
|
||
|
Configuration._showConsoleWarning(message);
|
||
|
DEBUG_LOGGER(message);
|
||
|
DEBUG_LOGGER(error);
|
||
|
}
|
||
|
static _resolveFilePath(path) {
|
||
|
if (!path)
|
||
|
return null;
|
||
|
return (0, path_1.isAbsolute)(path) ? path : (0, resolve_path_relatively_cwd_1.default)(path);
|
||
|
}
|
||
|
_resolveFilePaths(filesNames) {
|
||
|
if (!filesNames)
|
||
|
return void 0;
|
||
|
return (0, lodash_1.castArray)(filesNames).reduce((result, name) => {
|
||
|
const resolveFilePath = Configuration._resolveFilePath(name);
|
||
|
if (resolveFilePath)
|
||
|
result.push(resolveFilePath);
|
||
|
return result;
|
||
|
}, []);
|
||
|
}
|
||
|
async init() {
|
||
|
this._overriddenOptions = [];
|
||
|
}
|
||
|
mergeOptions(options) {
|
||
|
Object.entries(options).map(([key, value]) => {
|
||
|
const option = this._ensureOption(key, value, option_source_1.default.Input);
|
||
|
if (value === void 0)
|
||
|
return;
|
||
|
this._setOptionValue(option, value);
|
||
|
});
|
||
|
}
|
||
|
mergeDeep(option, source) {
|
||
|
(0, lodash_1.mergeWith)(option.value, source, (targetValue, sourceValue, property) => {
|
||
|
this._addOverriddenOptionIfNecessary(targetValue, sourceValue, option.source, `${option.name}.${property}`);
|
||
|
return sourceValue !== void 0 ? sourceValue : targetValue;
|
||
|
});
|
||
|
}
|
||
|
getOption(key) {
|
||
|
if (!key)
|
||
|
return void 0;
|
||
|
const option = this._options[key];
|
||
|
if (!option)
|
||
|
return void 0;
|
||
|
return option.value;
|
||
|
}
|
||
|
getOptions(predicate) {
|
||
|
const result = Object.create(null);
|
||
|
let includeInResult = true;
|
||
|
Object.entries(this._options).forEach(([name, option]) => {
|
||
|
includeInResult = predicate ? predicate(name, option) : true;
|
||
|
if (includeInResult)
|
||
|
result[name] = option.value;
|
||
|
});
|
||
|
return result;
|
||
|
}
|
||
|
clone(nonClonedOptions) {
|
||
|
const configuration = (0, lodash_1.cloneDeep)(this);
|
||
|
if (nonClonedOptions) {
|
||
|
(0, lodash_1.castArray)(nonClonedOptions).forEach(key => {
|
||
|
if (configuration._options[key])
|
||
|
configuration._options[key].value = this._options[key].value;
|
||
|
});
|
||
|
}
|
||
|
return configuration;
|
||
|
}
|
||
|
get filePath() {
|
||
|
return this._filePath;
|
||
|
}
|
||
|
get defaultPaths() {
|
||
|
return this._defaultPaths;
|
||
|
}
|
||
|
async _load() {
|
||
|
var _a;
|
||
|
if (!((_a = this.defaultPaths) === null || _a === void 0 ? void 0 : _a.length))
|
||
|
return null;
|
||
|
const configs = await Promise.all(this.defaultPaths.map(async (filePath) => {
|
||
|
if (!await this._isConfigurationFileExists(filePath))
|
||
|
return { filePath, options: null };
|
||
|
let options = null;
|
||
|
if (this._isJSConfiguration(filePath))
|
||
|
options = this._readJsConfigurationFileContent(filePath);
|
||
|
else {
|
||
|
const configurationFileContent = await this._readConfigurationFileContent(filePath);
|
||
|
if (configurationFileContent)
|
||
|
options = this._parseConfigurationFileContent(configurationFileContent, filePath);
|
||
|
}
|
||
|
return { filePath, options };
|
||
|
}));
|
||
|
const existedConfigs = configs.filter(config => !!config.options);
|
||
|
if (!existedConfigs.length)
|
||
|
return null;
|
||
|
this._filePath = existedConfigs[0].filePath;
|
||
|
if (existedConfigs.length > 1)
|
||
|
Configuration._showConsoleWarning((0, render_template_1.default)(warning_message_1.default.multipleConfigurationFilesFound, this._filePath));
|
||
|
return existedConfigs[0].options;
|
||
|
}
|
||
|
async _isConfigurationFileExists(filePath = this.filePath) {
|
||
|
try {
|
||
|
await (0, promisified_functions_1.stat)(filePath);
|
||
|
return true;
|
||
|
}
|
||
|
catch (error) {
|
||
|
DEBUG_LOGGER((0, render_template_1.default)(warning_message_1.default.cannotFindConfigurationFile, filePath, error.stack));
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
static _hasExtention(filePath, extention) {
|
||
|
return !!filePath && (0, path_1.extname)(filePath) === extention;
|
||
|
}
|
||
|
_isJSConfiguration(filePath = this.filePath) {
|
||
|
return Configuration._hasExtention(filePath, formats_1.JS_CONFIGURATION_EXTENSION);
|
||
|
}
|
||
|
_isJSONConfiguration(filePath = this.filePath) {
|
||
|
return Configuration._hasExtention(filePath, formats_1.JSON_CONFIGURATION_EXTENSION);
|
||
|
}
|
||
|
_readJsConfigurationFileContent(filePath = this.filePath) {
|
||
|
if (filePath) {
|
||
|
try {
|
||
|
delete require.cache[filePath];
|
||
|
return require(filePath);
|
||
|
}
|
||
|
catch (error) {
|
||
|
Configuration._showWarningForError(error, warning_message_1.default.cannotReadConfigFile, filePath);
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
async _readConfigurationFileContent(filePath = this.filePath) {
|
||
|
try {
|
||
|
return await (0, promisified_functions_1.readFile)(filePath);
|
||
|
}
|
||
|
catch (error) {
|
||
|
Configuration._showWarningForError(error, warning_message_1.default.cannotReadConfigFile, filePath);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
_parseConfigurationFileContent(configurationFileContent, filePath = this.filePath) {
|
||
|
try {
|
||
|
return json5_1.default.parse(configurationFileContent.toString());
|
||
|
}
|
||
|
catch (error) {
|
||
|
Configuration._showWarningForError(error, warning_message_1.default.cannotParseConfigFile, filePath);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
_ensureArrayOption(name) {
|
||
|
const options = this._options[name];
|
||
|
if (!options)
|
||
|
return;
|
||
|
// NOTE: a hack to fix lodash type definitions
|
||
|
// @ts-ignore
|
||
|
options.value = (0, lodash_1.castArray)(options.value);
|
||
|
}
|
||
|
_ensureOption(name, value, source) {
|
||
|
let option = null;
|
||
|
if (name in this._options)
|
||
|
option = this._options[name];
|
||
|
else {
|
||
|
option = new option_1.default(name, value, source);
|
||
|
this._options[name] = option;
|
||
|
}
|
||
|
return option;
|
||
|
}
|
||
|
_ensureOptionWithValue(name, defaultValue, source) {
|
||
|
const option = this._ensureOption(name, defaultValue, source);
|
||
|
if (option.value !== void 0)
|
||
|
return;
|
||
|
option.value = defaultValue;
|
||
|
option.source = source;
|
||
|
}
|
||
|
_addOverriddenOptionIfNecessary(value1, value2, source, optionName) {
|
||
|
if (source === option_source_1.default.Default)
|
||
|
return;
|
||
|
if (value1 === void 0 || value2 === void 0 || value1 === value2 || source !== option_source_1.default.Configuration)
|
||
|
return;
|
||
|
this._overriddenOptions.push(optionName);
|
||
|
}
|
||
|
_setOptionValue(option, value) {
|
||
|
if ((0, lodash_1.isPlainObject)(option.value) && (0, lodash_1.isPlainObject)(value))
|
||
|
this.mergeDeep(option, value);
|
||
|
else {
|
||
|
this._addOverriddenOptionIfNecessary(option.value, value, option.source, option.name);
|
||
|
option.value = value;
|
||
|
}
|
||
|
option.source = option_source_1.default.Input;
|
||
|
}
|
||
|
}
|
||
|
exports.default = Configuration;
|
||
|
module.exports = exports.default;
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTJDO0FBQzNDLGtEQUEwQjtBQUMxQixrREFBMEI7QUFFMUIsbUNBS2dCO0FBRWhCLDBFQUFnRTtBQUNoRSxzREFBOEI7QUFDOUIsb0VBQTJDO0FBQzNDLHVHQUE0RTtBQUM1RSwrRUFBc0Q7QUFDdEQsdUZBQWdFO0FBQ2hFLHFEQUE2QjtBQUU3Qix1Q0FBcUY7QUFFckYsTUFBTSxZQUFZLEdBQUcsSUFBQSxlQUFLLEVBQUMsd0JBQXdCLENBQUMsQ0FBQztBQUVyRCxNQUFxQixhQUFhO0lBTTlCLFlBQW9CLHVCQUFpRDs7UUFDakUsSUFBSSxDQUFDLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBUSxJQUFJLENBQUMsaUJBQWlCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsU0FBUyxHQUFZLE1BQUEsSUFBSSxDQUFDLGFBQWEsMENBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRVMsTUFBTSxDQUFDLFFBQVEsQ0FBRSxHQUFXO1FBQ2xDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO1lBQ3pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLGdCQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUM7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
|