Comparing version 4.0.0 to 4.0.1
import { ProcessingResult } from '../helpers/processing-result'; | ||
declare class AftConfigManager { | ||
private _aftConfig; | ||
private _logMgr; | ||
constructor(); | ||
/** | ||
@@ -36,4 +34,2 @@ * loads the specified file and attempts to return it as the declared type | ||
getFrom<T>(obj: any, keys: string): Promise<T>; | ||
} | ||
declare module AftConfigManager { | ||
/** | ||
@@ -46,3 +42,3 @@ * will check if the passed in 'str' string is a | ||
*/ | ||
function isEnvVar(str: string): ProcessingResult; | ||
static isEnvVar(str: string): ProcessingResult; | ||
/** | ||
@@ -54,5 +50,5 @@ * verifies that the passed in string is a valid | ||
*/ | ||
function isJsonString(str: string): ProcessingResult; | ||
static isJsonString(str: string): ProcessingResult; | ||
} | ||
export declare const aftconfigMgr: AftConfigManager; | ||
export {}; |
@@ -42,8 +42,4 @@ "use strict"; | ||
var path = require("path"); | ||
var logging_plugin_manager_1 = require("../plugins/logging/logging-plugin-manager"); | ||
var logging_level_1 = require("../plugins/logging/logging-level"); | ||
var ts_simple_nameof_1 = require("ts-simple-nameof"); | ||
var AftConfigManager = /** @class */ (function () { | ||
function AftConfigManager() { | ||
this._logMgr = new logging_plugin_manager_1.LoggingPluginManager({ logName: ts_simple_nameof_1.nameof(AftConfigManager), pluginNames: [] }); | ||
} | ||
@@ -108,8 +104,4 @@ /** | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this._logMgr.warn(err)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/, {}]; // empty config | ||
} | ||
console.warn(err); | ||
return [2 /*return*/, {}]; // empty config | ||
}); | ||
@@ -165,2 +157,5 @@ }); })]; | ||
case 0: | ||
if (obj === undefined || obj === null) { | ||
return [2 /*return*/, result]; | ||
} | ||
keysArray = keys.split('.'); | ||
@@ -174,3 +169,3 @@ currentKey = keysArray.shift(); | ||
} | ||
return [3 /*break*/, 5]; | ||
return [3 /*break*/, 6]; | ||
case 1: return [4 /*yield*/, this.getFrom(obj[currentKey], keysArray.join('.'))]; | ||
@@ -188,9 +183,5 @@ case 2: | ||
result = _b.sent(); | ||
return [3 /*break*/, 7]; | ||
case 5: | ||
result = null; | ||
return [4 /*yield*/, this._logMgr.log(logging_level_1.LoggingLevel.trace, "invalid Argument: " + obj + ", Type: " + typeof obj + " passed to getFrom}")]; | ||
case 6: | ||
_b.sent(); | ||
return [3 /*break*/, 7]; | ||
_b.label = 5; | ||
case 5: return [3 /*break*/, 7]; | ||
case 6: return [2 /*return*/, Promise.reject("invalid Argument: " + obj + ", Type: " + typeof obj + " passed to aftconfigMgr.getFrom")]; | ||
case 7: return [3 /*break*/, 9]; | ||
@@ -224,5 +215,2 @@ case 8: | ||
}; | ||
return AftConfigManager; | ||
}()); | ||
(function (AftConfigManager) { | ||
/** | ||
@@ -235,3 +223,3 @@ * will check if the passed in 'str' string is a | ||
*/ | ||
function isEnvVar(str) { | ||
AftConfigManager.isEnvVar = function (str) { | ||
if (str) { | ||
@@ -245,4 +233,3 @@ var matchResults = str.match(/^%(.*)%$/); | ||
return { success: false }; | ||
} | ||
AftConfigManager.isEnvVar = isEnvVar; | ||
}; | ||
/** | ||
@@ -254,3 +241,3 @@ * verifies that the passed in string is a valid | ||
*/ | ||
function isJsonString(str) { | ||
AftConfigManager.isJsonString = function (str) { | ||
var err = null; | ||
@@ -270,6 +257,6 @@ if (str) { | ||
return { success: false, message: err }; | ||
} | ||
AftConfigManager.isJsonString = isJsonString; | ||
})(AftConfigManager || (AftConfigManager = {})); | ||
}; | ||
return AftConfigManager; | ||
}()); | ||
exports.aftconfigMgr = new AftConfigManager(); | ||
//# sourceMappingURL=aftconfig-manager.js.map |
@@ -47,7 +47,8 @@ "use strict"; | ||
if (options === void 0) { options = SafeStringOption.defaults; } | ||
var output = input; | ||
for (var i = 0; i < options.length; i++) { | ||
var o = options[i]; | ||
input = input.replace(o.exclude, o.replaceWith); | ||
output = output.replace(o.exclude, o.replaceWith); | ||
} | ||
return input; | ||
return output; | ||
}; | ||
@@ -54,0 +55,0 @@ return Converter; |
@@ -10,3 +10,3 @@ "use strict"; | ||
})(EllipsisLocation = exports.EllipsisLocation || (exports.EllipsisLocation = {})); | ||
exports.ellide = function (original, finalLength, ellipsisLocation, ellipsis) { | ||
var ellide = function (original, finalLength, ellipsisLocation, ellipsis) { | ||
if (ellipsisLocation === void 0) { ellipsisLocation = EllipsisLocation.end; } | ||
@@ -45,2 +45,3 @@ if (ellipsis === void 0) { ellipsis = '...'; } | ||
}; | ||
exports.ellide = ellide; | ||
//# sourceMappingURL=ellide.js.map |
@@ -10,3 +10,3 @@ "use strict"; | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
@@ -13,0 +13,0 @@ Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -14,2 +14,6 @@ import { AbstractPlugin, IPluginOptions } from "./abstract-plugin"; | ||
/** | ||
* [OPTIONAL] a directory to start searching for Plugins from | ||
*/ | ||
searchDir?: string; | ||
/** | ||
* [OPTIONAL] if none specified a new {OptionsManager} will be created | ||
@@ -48,5 +52,6 @@ * in the constructor to manage options from either `aftconfig.json` or | ||
* "pluginNames": [ | ||
* "./path/to/plugin", | ||
* "some-custom-plugin", | ||
* "/full/path/to/other/plugin" | ||
* ], | ||
* "searchDirRoot": "./directory/to/search/for/plugins/from" | ||
* "foo": "specify 'foo' for loaded plugin instances", | ||
@@ -64,4 +69,8 @@ * "bar": false | ||
private _opts; | ||
private _pluginNames; | ||
private _searchDir; | ||
readonly optionsMgr: OptionsManager; | ||
constructor(key: string, options?: Topts); | ||
getPluginNames(): Promise<string[]>; | ||
getSearchDir(): Promise<string>; | ||
getFirstEnabledPlugin(): Promise<T>; | ||
@@ -68,0 +77,0 @@ getEnabledPlugins(): Promise<T[]>; |
@@ -70,5 +70,6 @@ "use strict"; | ||
* "pluginNames": [ | ||
* "./path/to/plugin", | ||
* "some-custom-plugin", | ||
* "/full/path/to/other/plugin" | ||
* ], | ||
* "searchDirRoot": "./directory/to/search/for/plugins/from" | ||
* "foo": "specify 'foo' for loaded plugin instances", | ||
@@ -89,2 +90,36 @@ * "bar": false | ||
} | ||
AbstractPluginManager.prototype.getPluginNames = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (!!this._pluginNames) return [3 /*break*/, 2]; | ||
_a = this; | ||
return [4 /*yield*/, this.optionsMgr.getOption(ts_simple_nameof_1.nameof(function (o) { return o.pluginNames; }), [])]; | ||
case 1: | ||
_a._pluginNames = _b.sent(); | ||
_b.label = 2; | ||
case 2: return [2 /*return*/, this._pluginNames]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AbstractPluginManager.prototype.getSearchDir = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (!!this._searchDir) return [3 /*break*/, 2]; | ||
_a = this; | ||
return [4 /*yield*/, this.optionsMgr.getOption(ts_simple_nameof_1.nameof(function (p) { return p.searchDir; }))]; | ||
case 1: | ||
_a._searchDir = _b.sent(); | ||
_b.label = 2; | ||
case 2: return [2 /*return*/, this._searchDir]; | ||
} | ||
}); | ||
}); | ||
}; | ||
AbstractPluginManager.prototype.getFirstEnabledPlugin = function () { | ||
@@ -162,3 +197,3 @@ return __awaiter(this, void 0, void 0, function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var plugins, pNames, i, name_1, p; | ||
var plugins, pNames, searchRoot, i, name_1; | ||
return __generator(this, function (_a) { | ||
@@ -168,22 +203,25 @@ switch (_a.label) { | ||
plugins = new Map(); | ||
return [4 /*yield*/, this.optionsMgr.getOption(ts_simple_nameof_1.nameof(function (p) { return p.pluginNames; }))]; | ||
return [4 /*yield*/, this.getPluginNames()]; | ||
case 1: | ||
pNames = _a.sent(); | ||
if (!(pNames === null || pNames === void 0 ? void 0 : pNames.length)) return [3 /*break*/, 5]; | ||
return [4 /*yield*/, this.getSearchDir()]; | ||
case 2: | ||
searchRoot = _a.sent(); | ||
if (!(pNames === null || pNames === void 0 ? void 0 : pNames.length)) return [3 /*break*/, 6]; | ||
i = 0; | ||
_a.label = 2; | ||
case 2: | ||
if (!(i < pNames.length)) return [3 /*break*/, 5]; | ||
_a.label = 3; | ||
case 3: | ||
if (!(i < pNames.length)) return [3 /*break*/, 6]; | ||
name_1 = pNames[i]; | ||
return [4 /*yield*/, plugin_loader_1.pluginLoader.load(name_1, this._opts)]; | ||
case 3: | ||
p = _a.sent(); | ||
if (p) { | ||
plugins.set(p.constructor.name, p); | ||
} | ||
_a.label = 4; | ||
return [4 /*yield*/, plugin_loader_1.pluginLoader.load(name_1, searchRoot, this._opts) | ||
.then(function (p) { | ||
plugins.set(p.constructor.name, p); | ||
})]; | ||
case 4: | ||
_a.sent(); | ||
_a.label = 5; | ||
case 5: | ||
i++; | ||
return [3 /*break*/, 2]; | ||
case 5: return [2 /*return*/, plugins]; | ||
return [3 /*break*/, 3]; | ||
case 6: return [2 /*return*/, plugins]; | ||
} | ||
@@ -190,0 +228,0 @@ }); |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -249,3 +251,4 @@ function __() { this.constructor = d; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var plugins, i, p, e_1, _a, _b, _c, _d, _e; | ||
var plugins, i, p, e_1, _a, _b, _c, _d; | ||
var _e; | ||
return __generator(this, function (_f) { | ||
@@ -296,3 +299,4 @@ switch (_f.label) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var plugins, i, p, r, e_2, _a, _b, _c, _d, _e; | ||
var plugins, i, p, r, e_2, _a, _b, _c, _d; | ||
var _e; | ||
return __generator(this, function (_f) { | ||
@@ -344,3 +348,4 @@ switch (_f.label) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var plugins, i, p, e_3, _a, _b, _c, _d, _e; | ||
var plugins, i, p, e_3, _a, _b, _c, _d; | ||
var _e; | ||
return __generator(this, function (_f) { | ||
@@ -347,0 +352,0 @@ switch (_f.label) { |
@@ -15,3 +15,3 @@ import { AbstractPlugin } from './abstract-plugin'; | ||
*/ | ||
load<T extends AbstractPlugin<any>>(pluginName: string, options?: any): Promise<T>; | ||
load<T extends AbstractPlugin<any>>(pluginName: string, searchRoot?: string, options?: any): Promise<T>; | ||
private _validatePlugin; | ||
@@ -18,0 +18,0 @@ private _findPlugin; |
@@ -42,2 +42,3 @@ "use strict"; | ||
var path = require("path"); | ||
var converter_1 = require("../helpers/converter"); | ||
var Loader = /** @class */ (function () { | ||
@@ -58,11 +59,13 @@ function Loader() { | ||
*/ | ||
Loader.prototype.load = function (pluginName, options) { | ||
Loader.prototype.load = function (pluginName, searchRoot, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var p; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this._validatePlugin(pluginName, options)]; | ||
case 1: | ||
p = _a.sent(); | ||
return [2 /*return*/, p]; | ||
case 0: | ||
searchRoot = searchRoot || process.cwd(); | ||
if (!path.isAbsolute(searchRoot)) { | ||
searchRoot = path.join(process.cwd(), searchRoot); | ||
} | ||
return [4 /*yield*/, this._validatePlugin(pluginName, searchRoot, options)]; | ||
case 1: return [2 /*return*/, _a.sent()]; | ||
} | ||
@@ -72,13 +75,13 @@ }); | ||
}; | ||
Loader.prototype._validatePlugin = function (pluginName, options) { | ||
Loader.prototype._validatePlugin = function (pluginName, searchRoot, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var plugin, e_1, pathToPlugin, ee_1, constructorName, p, e_2; | ||
var plugin, e_1, pathToPlugin, ee_1, constructorName, keys, name_1, i, key, p, e_2; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 8]); | ||
_a.trys.push([0, 2, , 10]); | ||
return [4 /*yield*/, Promise.resolve().then(function () { return require(pluginName); })]; | ||
case 1: | ||
plugin = _a.sent(); | ||
return [3 /*break*/, 8]; | ||
return [3 /*break*/, 10]; | ||
case 2: | ||
@@ -88,6 +91,8 @@ e_1 = _a.sent(); | ||
case 3: | ||
_a.trys.push([3, 6, , 7]); | ||
return [4 /*yield*/, this._findPlugin(process.cwd(), pluginName + ".js")]; | ||
_a.trys.push([3, 8, , 9]); | ||
return [4 /*yield*/, this._findPlugin(searchRoot, pluginName + ".js")]; | ||
case 4: | ||
pathToPlugin = _a.sent(); | ||
if (!pathToPlugin) return [3 /*break*/, 6]; | ||
// console.debug(`found plugin '${pluginName}' at: ${pathToPlugin}`); | ||
pathToPlugin = pathToPlugin.replace('.js', ''); | ||
@@ -98,23 +103,34 @@ return [4 /*yield*/, Promise.resolve().then(function () { return require(pathToPlugin); })]; | ||
return [3 /*break*/, 7]; | ||
case 6: | ||
case 6: throw new Error("plugin could not be located"); | ||
case 7: return [3 /*break*/, 9]; | ||
case 8: | ||
ee_1 = _a.sent(); | ||
console.warn("unable to load plugin: '" + pluginName + "' due to: " + ee_1); | ||
return [3 /*break*/, 7]; | ||
case 7: return [3 /*break*/, 8]; | ||
case 8: | ||
if (!plugin) return [3 /*break*/, 12]; | ||
_a.label = 9; | ||
case 9: | ||
_a.trys.push([9, 11, , 12]); | ||
constructorName = Object.keys(plugin)[0]; | ||
return [2 /*return*/, Promise.reject("unable to load plugin: '" + pluginName + "' due to: " + ee_1)]; | ||
case 9: return [3 /*break*/, 10]; | ||
case 10: | ||
if (!plugin) return [3 /*break*/, 14]; | ||
_a.label = 11; | ||
case 11: | ||
_a.trys.push([11, 13, , 14]); | ||
constructorName = void 0; | ||
keys = Object.keys(plugin); | ||
name_1 = converter_1.convert.toSafeString(pluginName, [{ exclude: /[-_.\s\d]/gi, replaceWith: '' }]); | ||
// console.debug(`searching for plugin constructor name for ${pluginName}...`); | ||
for (i = 0; i < keys.length; i++) { | ||
key = keys[i]; | ||
if (name_1.toLowerCase() == key.toLowerCase()) { | ||
// console.debug(`found constructor name of ${key} for ${pluginName}`); | ||
constructorName = key; | ||
break; | ||
} | ||
} | ||
p = new plugin[constructorName](options); | ||
return [4 /*yield*/, p.onLoad()]; | ||
case 10: | ||
case 12: | ||
_a.sent(); | ||
return [2 /*return*/, p]; | ||
case 11: | ||
case 13: | ||
e_2 = _a.sent(); | ||
console.warn("unable to create instance of loaded plugin '" + pluginName + "' due to: " + e_2); | ||
return [3 /*break*/, 12]; | ||
case 12: return [2 /*return*/, null]; | ||
return [2 /*return*/, Promise.reject("unable to create instance of loaded plugin '" + pluginName + "' due to: " + e_2)]; | ||
case 14: return [2 /*return*/, Promise.reject("unable to load plugin named: '" + pluginName + "'")]; | ||
} | ||
@@ -153,2 +169,3 @@ }); | ||
resolve(found); | ||
return [3 /*break*/, 6]; | ||
} | ||
@@ -155,0 +172,0 @@ return [3 /*break*/, 5]; |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -6,6 +6,8 @@ "use strict"; | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
@@ -12,0 +14,0 @@ function __() { this.constructor = d; } |
@@ -54,3 +54,3 @@ "use strict"; | ||
*/ | ||
exports.should = function (options) { | ||
var should = function (options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -68,2 +68,3 @@ var t; | ||
}; | ||
exports.should = should; | ||
//# sourceMappingURL=should.js.map |
@@ -54,5 +54,6 @@ "use strict"; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
@@ -234,3 +235,3 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
_a.label = 9; | ||
case 9: return [4 /*yield*/, this._generateTestResults.apply(this, __spread([status, message], this._testCases))]; | ||
case 9: return [4 /*yield*/, this._generateTestResults.apply(this, __spreadArray([status, message], __read(this._testCases)))]; | ||
case 10: | ||
@@ -489,3 +490,4 @@ results = _a.sent(); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result, _a, _b, exceptionsStr; | ||
var result, exceptionsStr; | ||
var _a, _b; | ||
return __generator(this, function (_c) { | ||
@@ -492,0 +494,0 @@ switch (_c.label) { |
{ | ||
"name": "aft-core", | ||
"version": "4.0.0", | ||
"version": "4.0.1", | ||
"description": "Automation Framework for Testing (AFT) package supporting JavaScript unit, integration and functional testing", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/bicarbon8/aft-core.git" | ||
"url": "https://github.com/bicarbon8/automated-functional-testing.git" | ||
}, | ||
@@ -13,6 +13,6 @@ "main": "./dist/src/index.js", | ||
"clean": "rimraf ./dist", | ||
"build": "npm run clean && tsc --declaration", | ||
"pretest": "npm run build", | ||
"test": "./node_modules/.bin/jasmine JASMINE_CONFIG_PATH=./jasmine.json", | ||
"coverage": "nyc npm run test" | ||
"build": "yarn clean && tsc --build", | ||
"pretest": "yarn build", | ||
"test": "jasmine **/*-spec.js", | ||
"coverage": "nyc yarn test" | ||
}, | ||
@@ -30,21 +30,21 @@ "keywords": [ | ||
"bugs": { | ||
"url": "https://github.com/bicarbon8/aft-core/issues" | ||
"url": "https://github.com/bicarbon8/automated-functional-testing/issues" | ||
}, | ||
"homepage": "https://github.com/bicarbon8/aft-core#readme", | ||
"homepage": "https://github.com/bicarbon8/automated-functional-testing/packages/aft-core#readme", | ||
"dependencies": { | ||
"colors": "^1.4.0", | ||
"es6-promise": "^4.2.8", | ||
"lodash": "^4.17.21", | ||
"ts-simple-nameof": "^1.3.1", | ||
"uuid": "3.3.3" | ||
"uuid": "^8.3.2" | ||
}, | ||
"devDependencies": { | ||
"@types/jasmine": "^3.4.4", | ||
"@types/node": "^12.12.35", | ||
"@types/uuid": "3.4.6", | ||
"jasmine": "^3.6.3", | ||
"@types/jasmine": "^3.6.10", | ||
"@types/node": "^15.0.1", | ||
"@types/uuid": "^8.3.0", | ||
"jasmine": "^3.7.0", | ||
"nyc": "^15.1.0", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^3.9.7" | ||
} | ||
"typescript": "^4.2.4" | ||
}, | ||
"gitHead": "64a740a2dba7f011d06c6d3c83a2345c4e1a0adf" | ||
} |
149
README.md
# AFT-Core | ||
the Automated Functional Testing (AFT) library provides a framework for creating Functional Test Automation that needs to integrate with external systems and can be used for post-deployment verification testing, end-user acceptance testing, end-to-end testing as well as high-level integration testing scenarios. it enables test execution flow control and reporting as well as streamlined test development for JavaScript and TypeScript test automation by integrating with common test framworks as well as external test and defect tracking systems (via a robust plugin structure). | ||
the base AFT library providing support for Plugins and some test configuration and helper classes and functions | ||
@@ -7,62 +7,18 @@ ## Installation | ||
## Usage: | ||
### Example Jasmine Test: | ||
```typescript | ||
describe('Sample Test', () => { | ||
it('can perform a demonstration of AFT-Core', async () => { | ||
let feature: FeatureObj = new FeatureObj(); | ||
/** | ||
* the `should(options)` function | ||
* checks any specified `AbstractTestCasePlugin` | ||
* and `AbstractDefectPlugin` implementations | ||
* to ensure the test should be run. It will then | ||
* report to any `AbstractLoggingPlugin` implementations | ||
* with an `ITestResult` indicating the success, | ||
* failure or skipped status | ||
*/ | ||
await should({expect: () => expect(feature.performAction()).toBe('result of action'), | ||
testCases: ['C1234'], | ||
description: 'expect that performAction will return \'result of action\'' | ||
}); | ||
}); | ||
}); | ||
## Configuration | ||
the `aft-core` package contains classes for reading in configuration from a .json file and performing automatic environment variable replacements on values read in from configuration. | ||
- **aftconfigMgr** - provides functions for reading in .json files and extracting environment variables from values. setting a field's value to `"%your_env_var%"` will instruct `aftconfigMgr` to read in the value of `your_env_var` from the environment variables and return this value when you request the field from your configuration | ||
- **OptionsManager** - provides support for passing in options objects with fallback to configuration file sections with a final fallback to an optional default value. | ||
```json | ||
{ | ||
"config-section-name": { | ||
"config-field1": "%your_env_var%", | ||
"config-field2": "some-value" | ||
} | ||
} | ||
``` | ||
the above results in the following console output if the expectation does not return false or throw an exception: | ||
``` | ||
5:29:55 PM - expect_that_performAction_will_return_result_of_action - PASS - C1234 | ||
``` | ||
in more complex scenarios you can perform multiple actions inside the _expectation_ like in the following example: | ||
```typescript | ||
describe('Sample Test', () => { | ||
it('can perform a more complex demonstration of AFT-Core', async () => { | ||
let feature: FeatureObj = new FeatureObj(); | ||
/** | ||
* the passed in expectation can accept a `TestWrapper` which can be used | ||
* during more complex actions | ||
*/ | ||
await should({ | ||
expect: async (tw) => { | ||
await tw.logMgr.step('about to call performAction'); | ||
let result: string = feature.performAction(); | ||
await tw.logMgr.info(`result of performAction was '${result}'`); | ||
let success: boolean = expect(result).toBe('result of action'); | ||
await tw.logMgr.trace('successfully executed expectation'); | ||
return success; | ||
}, | ||
testCases: ['C2345', 'C3344'], | ||
description: 'more complex expectation actions' | ||
}); | ||
}); | ||
}); | ||
``` | ||
which would output the following logs: | ||
``` | ||
5:29:55 PM - more_complex_expectation_actions - STEP - 1: about to call performAction | ||
5:29:55 PM - more_complex_expectation_actions - INFO - result of performAction was 'result of action' | ||
5:29:56 PM - more_complex_expectation_actions - TRACE - successfully executed expectation | ||
5:29:56 PM - more_complex_expectation_actions - PASS - C2345 | ||
5:29:56 PM - more_complex_expectation_actions - PASS - C3344 | ||
``` | ||
## Helpers / Utilities | ||
the AFT-Core package contains several helper and utility classes, interfaces and functions to make functional testing and test development easier. These include: | ||
the `aft-core` package contains several helper and utility classes, interfaces and functions to make functional testing and test development easier. These include: | ||
- **rand** - random string, boolean, number and uuid generation | ||
@@ -78,24 +34,6 @@ - **convert** - string manipulation like Base64 encode / decode and replacement | ||
- **Clazz<T>** - a class of type `T` accepting 0 or more arguments on the constructor | ||
## Plugins | ||
the AFT-Core package on it's own contains some helpers for testing, but the actual benefit comes from the plugins. Because the above logging will also send to any registered logging plugins, it becomes easy to create logging plugins that send to any external system such as TestRail or to log results to Elasticsearch. Additionally, before running any _expectation_ passed to a `should(options)` function, AFT will confirm if the expectation should actually be run based on the results of a query to any supplied `AbstractTestCasePlugin` implementations and a subsequent query to any supplied `AbstractDefectPlugin` implementations. | ||
### Logging Plugins | ||
AFT-Core comes bundled with a built-in `ConsoleLoggingPlugin` which can be enabled by adding `console-logging-plugin` to the `pluginNames` array under the `loggingpluginmanager` section of your `aftconfig.json` | ||
To create a logging plugin you simply need to extend from the `AbstractLoggingPlugin` class in a class with a constructor accepting a simple object and from the constructor, call `super(key, options)` where the `key` is the name of the section in your `aftconfig.json` where configuration can be specified for your plugin. Then, in your `aftconfig.json` add the following (where plugins `console-logging-plugin.js` is bundled with `aft-core` and `logging-plugin2.js` is some bespoke plugin that is contained within the test execution directory or a subdirectory of it and `loggingpluginmanager` is the logging plugin manager): | ||
```json | ||
{ | ||
"loggingpluginmanager": { | ||
"pluginNames": [ | ||
"console-logging-plugin", | ||
"logging-plugin2" | ||
], | ||
"level": "info" | ||
} | ||
} | ||
``` | ||
> NOTE: it is also possible to specify a full path to the plugin like: '/full/path/to/logging-plugin2' leaving off the suffix (useful for plugins not contained in a directory or subdirectory of the test execution directory) | ||
> NOTE: setting the `level` in the `loggingpluginmanager` will override any settings in the plugins own configuration setting (this can be useful to disable all logging by setting it to a value of `none`) | ||
#### Example Logging Plugin | ||
### Example Logging Plugin | ||
to create your own simple logging plugin that stores all logs until the `dispose` function is called you would implement the code below. | ||
@@ -141,15 +79,4 @@ | ||
``` | ||
### Test Case Plugin | ||
the purpose of an `AbstractTestCasePlugin` implementation is to provide execution control over any expectations by way of supplied _Test IDs_. to specify an implementation of the plugin to load you can add the following to your `aftconfig.json` (where plugins `test-case-plugin.js` is contained within the test execution directory or a subdirectory of it): | ||
```json | ||
{ | ||
"testcasepluginmanager": { | ||
"pluginNames": ["test-case-plugin"] | ||
} | ||
} | ||
``` | ||
if no plugin is specified then external Test Case Management integration will be disabled and expectations will be executed without checking their status before execution | ||
> NOTE: it is also possible to specify a full path to the plugin like: '/full/path/to/test-case-plugin' leaving off the suffix | ||
#### Example Test Case Plugin (TestRail) | ||
### Example Test Case Plugin (TestRail) | ||
```typescript | ||
@@ -175,15 +102,3 @@ export class TestRailTestCasePlugin extends AbstractTestCasePlugin { | ||
``` | ||
### Defect Plugin | ||
the purpose of an `AbstractDefectPlugin` implementation is to provide execution control over any expectations by way of supplied _Test IDs_ referenced in an external ticket tracking system like Bugzilla or Jira. to specify an implementation of the plugin to load you can add the following to your `aftconfig.json` (where plugins `defect-plugin.js` is contained within the test execution directory or a subdirectory of it): | ||
```json | ||
{ | ||
"defectpluginmanager": { | ||
"pluginNames": ["defect-plugin"] | ||
} | ||
} | ||
``` | ||
if no plugin is specified then external Defect Management integration will be disabled and expectations will be executed without checking their status before execution, however if a Defect Management plugin is specified, the execution of any expectations passed into a `should(options)` function will be halted if any non-closed defects are found when searching for defects that contain reference to the specified _Test IDs_ | ||
> NOTE: it is also possible to specify a full path to the plugin like: '/full/path/to/defect-plugin' leaving off the suffix | ||
#### Example Defect Plugin (Bugzilla) | ||
### Example Defect Plugin (Bugzilla) | ||
```typescript | ||
@@ -206,1 +121,27 @@ export class BugzillaDefectPlugin extends AbstractDefectPlugin { | ||
``` | ||
## Wrappers | ||
the `TestWrapper` and `should` functions of `aft-core` enable testing with pre-execution filtering based on integration with external test case and defect managers via plugin packages supporting each (see examples above). | ||
- **should** - a function accepting a `TestWrapperOptions` object that simplifies usage of a `TestWrapper` within your _Jasmine_ or _Mocha_ tests | ||
- **TestWrapper** - the primary way tests should be executed to enable integration with external systems and logging to any supported logging plugins | ||
```typescript | ||
describe('Sample Test', () => { | ||
it('can perform a demonstration of AFT', async () => { | ||
let feature: FeatureObj = new FeatureObj(); | ||
/** | ||
* the `should(options)` function | ||
* checks any specified `AbstractTestCasePlugin` | ||
* and `AbstractDefectPlugin` implementations | ||
* to ensure the test should be run. It will then | ||
* report to any `AbstractLoggingPlugin` implementations | ||
* with an `ITestResult` indicating the success, | ||
* failure or skipped status | ||
*/ | ||
await should({expect: () => expect(feature.performAction()).toEqual('result of action'), | ||
testCases: ['C1234'], | ||
description: 'expect that performAction will return \'result of action\'' | ||
}); | ||
}); | ||
}); | ||
``` |
{ | ||
"extends": "../../tsconfig-settings.json", | ||
"compilerOptions": { | ||
"experimentalDecorators": true, | ||
"target": "es5", | ||
"module": "commonjs", | ||
"outDir": "./dist", | ||
"mapRoot": "./dist", | ||
"sourceMap": true, | ||
"lib": ["es5", "dom", "scripthost", "es2018.promise"], | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"noEmit": false, | ||
"declaration": true, | ||
"downlevelIteration": true | ||
"outDir": "dist", | ||
"composite": true | ||
}, | ||
"exclude": [ | ||
"node_modules", | ||
"dist" | ||
] | ||
"include": ["src", "test"] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
702357
4
219
9212
0
1
142
7
+ Addeduuid@8.3.2(transitive)
- Removedes6-promise@^4.2.8
- Removedes6-promise@4.2.8(transitive)
- Removeduuid@3.3.3(transitive)
Updateduuid@^8.3.2