implement new structure for npm scripts and test them ...
This commit is contained in:
@@ -0,0 +1,506 @@
|
|||||||
|
/**
|
||||||
|
* XColor Tools Module ...
|
||||||
|
* a module for handle colorify text contents in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Imports ...
|
||||||
|
const XValueTools = require("./x-value.tools");
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* these are available style which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_STYLES = {
|
||||||
|
//
|
||||||
|
Bold: "\x1b[1m",
|
||||||
|
Dim: "\x1b[2m",
|
||||||
|
Underlined: "\x1b[4m",
|
||||||
|
Blink: "\x1b[5m",
|
||||||
|
ReverseFandB: "\x1b[7m",
|
||||||
|
Hidden: "\x1b[8m",
|
||||||
|
//
|
||||||
|
// Commonly used for reset all Styles ...
|
||||||
|
Reset: "\x1b[0m"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available foreground colors which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_FOREGROUND_COLORS = {
|
||||||
|
Default: "\x1b[39m",
|
||||||
|
Black: "\x1b[30m",
|
||||||
|
Red: "\x1b[31m",
|
||||||
|
Green: "\x1b[32m",
|
||||||
|
Yellow: "\x1b[33m",
|
||||||
|
Blue: "\x1b[34m",
|
||||||
|
Magenta: "\x1b[35m",
|
||||||
|
Cyan: "\x1b[36m",
|
||||||
|
LightGray: "\x1b[37m",
|
||||||
|
DarkGray: "\x1b[90m",
|
||||||
|
LightRed: "\x1b[91m",
|
||||||
|
LightGreen: "\x1b[92m",
|
||||||
|
LightYellow: "\x1b[93m",
|
||||||
|
LightBlue: "\x1b[94m",
|
||||||
|
LightMagenta: "\x1b[95m",
|
||||||
|
LightCyan: "\x1b[96m",
|
||||||
|
White: "\x1b[97m",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available background colors which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_BACKGROUND_COLORS = {
|
||||||
|
Default: "\x1b[49m",
|
||||||
|
Black: "\x1b[40m",
|
||||||
|
Red: "\x1b[41m",
|
||||||
|
Green: "\x1b[42m",
|
||||||
|
Yellow: "\x1b[43m",
|
||||||
|
Blue: "\x1b[44m",
|
||||||
|
Magenta: "\x1b[45m",
|
||||||
|
Cyan: "\x1b[46m",
|
||||||
|
LightGray: "\x1b[47m",
|
||||||
|
DarkGray: "\x1b[100m",
|
||||||
|
LightRed: "\x1b[101m",
|
||||||
|
LightGreen: "\x1b[102m",
|
||||||
|
LightYellow: "\x1b[103m",
|
||||||
|
LightBlue: "\x1b[104m",
|
||||||
|
LightMagenta: "\x1b[105m",
|
||||||
|
LightCyan: "\x1b[106m",
|
||||||
|
White: "\x1b[107m",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available style names, which exports from module and
|
||||||
|
* users can use them ...
|
||||||
|
*/
|
||||||
|
const STYLE_NAMES = {
|
||||||
|
Bold: "Bold",
|
||||||
|
Dim: "Dim",
|
||||||
|
Underlined: "Underlined",
|
||||||
|
Blink: "Blink",
|
||||||
|
ReverseFandB: "ReverseFandB",
|
||||||
|
Hidden: "Hidden",
|
||||||
|
Reset: "Reset",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available color names, which exports from module and
|
||||||
|
* users can use them ...
|
||||||
|
*/
|
||||||
|
const COLOR_NAMES = {
|
||||||
|
Default: "Default",
|
||||||
|
Black: "Black",
|
||||||
|
Red: "Red",
|
||||||
|
Green: "Green",
|
||||||
|
Yellow: "Yellow",
|
||||||
|
Blue: "Blue",
|
||||||
|
Magenta: "Magenta",
|
||||||
|
Cyan: "Cyan",
|
||||||
|
LightGray: "LightGray",
|
||||||
|
DarkGray: "DarkGray",
|
||||||
|
LightRed: "LightRed",
|
||||||
|
LightGreen: "LightGreen",
|
||||||
|
LightYellow: "LightYellow",
|
||||||
|
LightBlue: "LightBlue",
|
||||||
|
LightMagenta: "LightMagenta",
|
||||||
|
LightCyan: "LightCyan",
|
||||||
|
White: "White",
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
/**
|
||||||
|
* apply specified style and color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} styled content ...
|
||||||
|
*/
|
||||||
|
function apply(
|
||||||
|
content,
|
||||||
|
color,
|
||||||
|
style,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific style on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to styled ...
|
||||||
|
* @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ...
|
||||||
|
* @returns {string} styled content ...
|
||||||
|
*/
|
||||||
|
function applyStyle(content, style) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (eStyle === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific foreground color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to colorified ...
|
||||||
|
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||||
|
* @returns {string} colorified content ...
|
||||||
|
*/
|
||||||
|
function applyForegroundColor(content, color) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (eColor === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific background color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to colorified ...
|
||||||
|
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||||
|
* @returns {string} colorified content ...
|
||||||
|
*/
|
||||||
|
function applyBackgroundColor(content, color) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (eColor === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate style and color applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} style and color applier string ...
|
||||||
|
*/
|
||||||
|
function getApplier(
|
||||||
|
style = "",
|
||||||
|
color = "",
|
||||||
|
reset = false,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate style applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @returns {string} style applier string ...
|
||||||
|
*/
|
||||||
|
function getStyleApplier(
|
||||||
|
style = "",
|
||||||
|
reset = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate color applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} color applier string ...
|
||||||
|
*/
|
||||||
|
function getColorApplier(
|
||||||
|
color = "",
|
||||||
|
reset = false,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* colorified specific content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function colorifyContent(
|
||||||
|
content = "",
|
||||||
|
color = "",
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Finde Colors ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
result.length > 0
|
||||||
|
&& (
|
||||||
|
XValueTools.isValidArg(eFColor) ||
|
||||||
|
XValueTools.isValidArg(eBColor)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply style on specific content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function stylifiyContent(
|
||||||
|
content = "",
|
||||||
|
style = "",
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
result.length > 0
|
||||||
|
&& XValueTools.isValidArg(eStyle)
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
STYLE_NAMES,
|
||||||
|
COLOR_NAMES,
|
||||||
|
//
|
||||||
|
apply,
|
||||||
|
applyStyle,
|
||||||
|
getApplier,
|
||||||
|
getColorApplier,
|
||||||
|
getStyleApplier,
|
||||||
|
colorifyContent,
|
||||||
|
stylifiyContent,
|
||||||
|
applyForegroundColor,
|
||||||
|
applyBackgroundColor,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
/**
|
||||||
|
* XFile Tools Module ...
|
||||||
|
* a module for handle all file/folder manipulating task in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Imports ...
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const Path = require('path');
|
||||||
|
const http = require('http');
|
||||||
|
const https = require('https');
|
||||||
|
const XValueTools = require('./x-value.tools');
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* current os path separators ...
|
||||||
|
*/
|
||||||
|
const PathSeparator = Path.sep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current directory ...
|
||||||
|
*/
|
||||||
|
const CurrentDir = __dirname;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
//
|
||||||
|
//#region Global ...
|
||||||
|
/**
|
||||||
|
* retrieve a path status ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path value to check ...
|
||||||
|
* @returns an stat object ...
|
||||||
|
*/
|
||||||
|
function getStatus(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return fs.statSync(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve user's Home path ...
|
||||||
|
*
|
||||||
|
* @returns {string} a path ...
|
||||||
|
*/
|
||||||
|
function getHomePath() {
|
||||||
|
return os.homedir();
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Path ...
|
||||||
|
/**
|
||||||
|
* retrieve the base name of specific address path ...
|
||||||
|
*
|
||||||
|
* @param {string} path address of file or folder ...
|
||||||
|
* @returns string ...
|
||||||
|
*/
|
||||||
|
function basename(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = Path.basename(path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* join several path segments together ...
|
||||||
|
*
|
||||||
|
* @param {...string} path path params ...
|
||||||
|
* @returns a joined paths ...
|
||||||
|
*/
|
||||||
|
function joinPath(...path) {
|
||||||
|
return Path.join(...path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resolve a relative path to absolute ...
|
||||||
|
*
|
||||||
|
* @param {string[]} path a path value to check ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function resolvePath(...path) {
|
||||||
|
return Path.resolve(...path);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region File ...
|
||||||
|
/**
|
||||||
|
* determines a path destination is a file or not ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path value to check ...
|
||||||
|
* @returns a boolean value ...
|
||||||
|
*/
|
||||||
|
function isFileExists(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
const stat = getStatus(path);
|
||||||
|
if (!stat) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return stat.isFile();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function removeFile(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.unlink(path, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy a file to destination path ...
|
||||||
|
*
|
||||||
|
* @param {string} source source file path ...
|
||||||
|
* @param {string} dest dest folder path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function copyFile(
|
||||||
|
source = '',
|
||||||
|
dest = ''
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!isFileExists(source) ||
|
||||||
|
!isDirectoryExists(dest)
|
||||||
|
) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const destFilePath = Path.join(dest, Path.basename(source));
|
||||||
|
fs.copyFile(source, destFilePath, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reading specified file content ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @returns {Promise<string>} file content ...
|
||||||
|
*/
|
||||||
|
function readFile(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
resolve('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readFile(path, 'utf8', (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write content to a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @param {string} content the content which going to write to the file ...
|
||||||
|
* @param {bool} overwrite determines file overwrite if exists ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function writeFile(
|
||||||
|
path = '',
|
||||||
|
content = '',
|
||||||
|
overwrite = true
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (isFileExists(path) && !overwrite) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Content ...
|
||||||
|
content = XValueTools.isValidArg(content) ?
|
||||||
|
content :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.writeFile(path, content, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path file path ...
|
||||||
|
* @param {string} fileName file name ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function createFile(
|
||||||
|
path = '',
|
||||||
|
fileName = ''
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
const filePath = Path.join(path, fileName);
|
||||||
|
if (
|
||||||
|
isFileExists(filePath) ||
|
||||||
|
!XValueTools.isValidArg(path) ||
|
||||||
|
!XValueTools.isValidArg(fileName)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.writeFile(filePath, '', (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a file name extension ...
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
* @returns {string} name without extension ...
|
||||||
|
*/
|
||||||
|
function removeFileExtension(name = '') {
|
||||||
|
return name.substring(0, name.lastIndexOf('.')) || name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a file extension ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path which locate a file ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getFileExtension(path = '') {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
|| !isFileExists(path)
|
||||||
|
) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve just file name ...
|
||||||
|
const fileName = basename(path);
|
||||||
|
result = fileName.replace(
|
||||||
|
removeFileExtension(fileName),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve all files list recursively from specific path ...
|
||||||
|
*
|
||||||
|
* @param {string} path a source folder path ...
|
||||||
|
* @param {string[]} extensions which file extensions need to be listed, live empty for all files ...
|
||||||
|
* @returns {Promise<string[]>}
|
||||||
|
*/
|
||||||
|
async function getRecursiveFilesList(
|
||||||
|
path = "",
|
||||||
|
extensions = []
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
|| !isDirectoryExists(path)
|
||||||
|
) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const contents = await getDirectoryContents(path);
|
||||||
|
for(const item of contents) {
|
||||||
|
//
|
||||||
|
const itemPath = joinPath(
|
||||||
|
path,
|
||||||
|
item
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
const isItemFile = isFileExists(itemPath);
|
||||||
|
if (isItemFile) {
|
||||||
|
//
|
||||||
|
const itemFileExtension = getFileExtension(itemPath);
|
||||||
|
const isFileInSupportedExtensions =
|
||||||
|
extensions === undefined || extensions.length === 0
|
||||||
|
? true
|
||||||
|
: extensions.includes(itemFileExtension)
|
||||||
|
;
|
||||||
|
if (isFileInSupportedExtensions) {
|
||||||
|
result.push(itemPath);
|
||||||
|
}
|
||||||
|
} else if (isDirectoryExists(itemPath)) {
|
||||||
|
//
|
||||||
|
const itemPathFiles = await getRecursiveFilesList(itemPath, extensions);
|
||||||
|
result.push(...itemPathFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Directory ...
|
||||||
|
/**
|
||||||
|
* create a directory ...
|
||||||
|
*
|
||||||
|
* @param {string} path destination path including dir name ...
|
||||||
|
* @param {boolean} recursive create directories recursively ...
|
||||||
|
* @returns action done or not ...
|
||||||
|
*/
|
||||||
|
function createDirectory(
|
||||||
|
path = '',
|
||||||
|
recursive = true
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
isDirectoryExists(path) ||
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
fs.mkdirSync(path, { recursive: recursive });
|
||||||
|
result = true;
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a directory ...
|
||||||
|
*
|
||||||
|
* @param {string} path destination path including dir name ...
|
||||||
|
* @param {boolean} recursive removes directories recursively ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function removeDirectory(
|
||||||
|
path = '',
|
||||||
|
recursive = false
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.rm(path, {
|
||||||
|
recursive
|
||||||
|
}, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines a path destination is a directory or not ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns represent destnation path is Directory or not ...
|
||||||
|
*/
|
||||||
|
function isDirectoryExists(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
const isExists = fs.existsSync(path);
|
||||||
|
if (!isExists) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const stat = getStatus(path);
|
||||||
|
if (!stat) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = stat.isDirectory();
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory content ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder files ...
|
||||||
|
*/
|
||||||
|
function getDirectoryContents(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory files ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder files ...
|
||||||
|
*/
|
||||||
|
function getDirectoryFiles(
|
||||||
|
path = '',
|
||||||
|
containsHiddenFiles = false
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!containsHiddenFiles) {
|
||||||
|
content = content.filter(c => !c.startsWith('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = [];
|
||||||
|
content
|
||||||
|
.forEach(c => {
|
||||||
|
//
|
||||||
|
const cPath = Path.join(path, c);
|
||||||
|
if (isFileExists(cPath)) {
|
||||||
|
result.push(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory folders ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder names ...
|
||||||
|
*/
|
||||||
|
function getDirectoryFolders(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = [];
|
||||||
|
content.forEach(c => {
|
||||||
|
//
|
||||||
|
const cPath = Path.join(path, c);
|
||||||
|
if (isDirectoryExists(cPath)) {
|
||||||
|
result.push(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy a folder with all of it's content to dest ...
|
||||||
|
*
|
||||||
|
* @param {string} source source folder path ...
|
||||||
|
* @param {string} dest dest folder path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
async function copyFolder(
|
||||||
|
source = '',
|
||||||
|
dest = ''
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!isDirectoryExists(source) ||
|
||||||
|
!XValueTools.isValidArg(dest) ||
|
||||||
|
!XValueTools.isValidArg(source)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const folderName = Path.basename(source);
|
||||||
|
const destPath = Path.join(dest, folderName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Dest Path folder if not exists ...
|
||||||
|
if (!isDirectoryExists(destPath)) {
|
||||||
|
//
|
||||||
|
let result = createDirectory(destPath, true);
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Files ...
|
||||||
|
const files = await getDirectoryFiles(source);
|
||||||
|
if (files && files.constructor === Array && files.length > 0) {
|
||||||
|
//
|
||||||
|
const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath));
|
||||||
|
const filesResult = (await Promise.all(filesPromises)).every(r => !!r);
|
||||||
|
if (!filesResult) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Folders ...
|
||||||
|
const folders = await getDirectoryFolders(source);
|
||||||
|
if (folders && folders.constructor === Array && folders.length > 0) {
|
||||||
|
//
|
||||||
|
const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath));
|
||||||
|
const filesResult = (await Promise.all(folderPromises)).every(r => !!r);
|
||||||
|
if (!filesResult) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Downloader ...
|
||||||
|
/**
|
||||||
|
* download a file from specific url and store it ...
|
||||||
|
*
|
||||||
|
* @param {string} filepath the file name and path which required to put download file on it ...
|
||||||
|
* @param {string} url the web url for downloading ...
|
||||||
|
*/
|
||||||
|
function download(filepath, url) {
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(url)
|
||||||
|
|| !XValueTools.isValidURL(url)
|
||||||
|
|| !XValueTools.isValidArg(filepath)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
var file = fs.createWriteStream(filepath);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (url.startsWith('https:')) {
|
||||||
|
https.get(url, function (response) {
|
||||||
|
response.pipe(file);
|
||||||
|
});
|
||||||
|
} else if (url.startsWith('http:')) {
|
||||||
|
http.get(url, function (response) {
|
||||||
|
response.pipe(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region JSON ...
|
||||||
|
/**
|
||||||
|
* read and parse a JSON content from a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path source file path ...
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
function readJSON(path = "") {
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let result = undefined;
|
||||||
|
try {
|
||||||
|
result = require(path);
|
||||||
|
} catch {
|
||||||
|
result = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write a JSON Object content into a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path dest file path ...
|
||||||
|
* @param {any} content an object which required to write to file ...
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
async function writeJSON(
|
||||||
|
path = "",
|
||||||
|
content = undefined
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normallize Content ...
|
||||||
|
if (content === undefined) {
|
||||||
|
content = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const contentString = XValueTools.beautifyJSON(content);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = await writeFile(
|
||||||
|
path,
|
||||||
|
contentString,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
CurrentDir,
|
||||||
|
PathSeparator,
|
||||||
|
|
||||||
|
//
|
||||||
|
getStatus,
|
||||||
|
getHomePath,
|
||||||
|
|
||||||
|
//
|
||||||
|
basename,
|
||||||
|
joinPath,
|
||||||
|
resolvePath,
|
||||||
|
|
||||||
|
//
|
||||||
|
download,
|
||||||
|
|
||||||
|
//
|
||||||
|
readJSON,
|
||||||
|
writeJSON,
|
||||||
|
|
||||||
|
//
|
||||||
|
copyFile,
|
||||||
|
readFile,
|
||||||
|
writeFile,
|
||||||
|
createFile,
|
||||||
|
removeFile,
|
||||||
|
isFileExists,
|
||||||
|
getFileExtension,
|
||||||
|
removeFileExtension,
|
||||||
|
getRecursiveFilesList,
|
||||||
|
|
||||||
|
//
|
||||||
|
copyFolder,
|
||||||
|
createDirectory,
|
||||||
|
removeDirectory,
|
||||||
|
createDirectory,
|
||||||
|
removeDirectory,
|
||||||
|
isDirectoryExists,
|
||||||
|
isDirectoryExists,
|
||||||
|
getDirectoryFiles,
|
||||||
|
getDirectoryFolders,
|
||||||
|
getDirectoryContents,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/**
|
||||||
|
* XShell Tools Module ...
|
||||||
|
* a module for handling shell actions and retrieve OS Info in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Imports ...
|
||||||
|
const os = require('os');
|
||||||
|
const process = require('process');
|
||||||
|
const { exec } = require("child_process");
|
||||||
|
const XFileTools = require('./x-file.tools');
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
//
|
||||||
|
const OS = {
|
||||||
|
Aix: 'aix',
|
||||||
|
Darwin: 'darwin',
|
||||||
|
FreeBSD: 'freebsd',
|
||||||
|
Linux: 'linux',
|
||||||
|
OpenBSD: 'openbsd',
|
||||||
|
SnOS: 'sunos',
|
||||||
|
Windows: 'win32'
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
const isWindows = process.platform === OS.Windows;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
//
|
||||||
|
//#region Pure shell commands ...
|
||||||
|
/**
|
||||||
|
* execute a command using NodeJS on shell ...
|
||||||
|
*
|
||||||
|
* @param {string} cmd command to execute ...
|
||||||
|
* @param {string} cwd working directory ...
|
||||||
|
*
|
||||||
|
* @returns Promise<any, errr> instance ...
|
||||||
|
*/
|
||||||
|
function execute(cmd, cwd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
//
|
||||||
|
if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) {
|
||||||
|
reject('invalid args ...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
exec(cmd, { cwd }, (err, result, stdError) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (stdError) {
|
||||||
|
//
|
||||||
|
// reject(stdError);
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines a command exists on host or not ...
|
||||||
|
*
|
||||||
|
* @param {string} name specific command name ...
|
||||||
|
*
|
||||||
|
* @returns boolean Promise ...
|
||||||
|
*/
|
||||||
|
function checkCommandExists(name) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
//
|
||||||
|
if (!name) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`;
|
||||||
|
execute(cmd).then(result => {
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region required commands state ...
|
||||||
|
/**
|
||||||
|
* check al required commands exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function isRequiredCommandsExists() {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// const isTarExists = await isTarCommandExists();
|
||||||
|
// const isCatExists = await isCatCommandExists();
|
||||||
|
// const isGrepExists = await isGrepCommandExists();
|
||||||
|
// const isSedExists = await isSedCommandExists();
|
||||||
|
const isNpmExists = await isNpmCommandExists();
|
||||||
|
const isNgExists = await isNgCommandExists();
|
||||||
|
const isIonicExists = await isIonicCommandExists();
|
||||||
|
const isCordovaExists = await isCordovaCommandExists();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isNpmExists
|
||||||
|
&& isNgExists
|
||||||
|
&& isIonicExists
|
||||||
|
&& isCordovaExists
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve required commands state object ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function getRequiredCommandsStates() {
|
||||||
|
//
|
||||||
|
const result = {};
|
||||||
|
|
||||||
|
//
|
||||||
|
// const isTarExists = await isTarCommandExists();
|
||||||
|
// const isCatExists = await isCatCommandExists();
|
||||||
|
// const isGrepExists = await isGrepCommandExists();
|
||||||
|
// const isSedExists = await isSedCommandExists();
|
||||||
|
const isNpmExists = await isNpmCommandExists();
|
||||||
|
const isNgExists = await isNgCommandExists();
|
||||||
|
const isIonicExists = await isIonicCommandExists();
|
||||||
|
const isCordovaExists = await isCordovaCommandExists();
|
||||||
|
|
||||||
|
//
|
||||||
|
result['npm'] = isNpmExists;
|
||||||
|
result['ng'] = isNgExists;
|
||||||
|
result['ionic'] = isIonicExists;
|
||||||
|
result['cordova'] = isCordovaExists;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Commonly used Command Checkers ...
|
||||||
|
/**
|
||||||
|
* determines npm command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNpmCommandExists() {
|
||||||
|
return checkCommandExists('npm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines ng command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNgCommandExists() {
|
||||||
|
return checkCommandExists('ng');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines ionic command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isIonicCommandExists() {
|
||||||
|
return checkCommandExists('ionic');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines cordova command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isCordovaCommandExists() {
|
||||||
|
return checkCommandExists('cordova');
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
execute,
|
||||||
|
checkCommandExists,
|
||||||
|
isRequiredCommandsExists,
|
||||||
|
getRequiredCommandsStates,
|
||||||
|
|
||||||
|
//
|
||||||
|
isNgCommandExists,
|
||||||
|
isIonicCommandExists,
|
||||||
|
isCordovaCommandExists,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
/**
|
||||||
|
* DataType Tools Module ...
|
||||||
|
* a module for manipulate and detect supported data types in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* all supported data types ...
|
||||||
|
*/
|
||||||
|
const DataTypes = {
|
||||||
|
Null: 'null',
|
||||||
|
Date: 'date',
|
||||||
|
Array: 'array',
|
||||||
|
Object: 'object',
|
||||||
|
String: 'string',
|
||||||
|
Number: 'number',
|
||||||
|
Unknown: 'unknown',
|
||||||
|
Boolean: 'boolean',
|
||||||
|
Function: 'function',
|
||||||
|
Undefined: 'undefined',
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
/**
|
||||||
|
* detect type of a content ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getType(value) {
|
||||||
|
//
|
||||||
|
const type = typeof value;
|
||||||
|
|
||||||
|
//
|
||||||
|
let result = DataTypes.Unknown;
|
||||||
|
let dateIdentifier = '[object Date]';
|
||||||
|
let constructor = value && value.constructor ?
|
||||||
|
value.constructor.toString() :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (type) {
|
||||||
|
//
|
||||||
|
case 'undefined':
|
||||||
|
result = DataTypes.Undefined;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'boolean':
|
||||||
|
result = DataTypes.Boolean;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'string':
|
||||||
|
result = DataTypes.String;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'number':
|
||||||
|
result = DataTypes.Number;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'function':
|
||||||
|
result = DataTypes.Function;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'object':
|
||||||
|
//
|
||||||
|
// Null ...
|
||||||
|
if (value === null) {
|
||||||
|
result = DataTypes.Null;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Array ...
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result = DataTypes.Array;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Data ...
|
||||||
|
if (
|
||||||
|
value instanceof Date ||
|
||||||
|
isFunction(value.getMonth) ||
|
||||||
|
constructor.includes(dateIdentifier) ||
|
||||||
|
Object.prototype.toString.call(value) === dateIdentifier
|
||||||
|
) {
|
||||||
|
result = DataTypes.Date;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Object ...
|
||||||
|
{
|
||||||
|
result = DataTypes.Object;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
default:
|
||||||
|
result = DataTypes.Unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve an object constructor ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getConstructor(value) {
|
||||||
|
//
|
||||||
|
const result = value && value.constructor ?
|
||||||
|
value.constructor.toString() :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve an object prototype ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getPrototype(value) {
|
||||||
|
//
|
||||||
|
const result = value ?
|
||||||
|
Object.prototype.toString.call(value) :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is null or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNull(value) {
|
||||||
|
return getType(value) === DataTypes.Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is undefined or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isUndefined(value) {
|
||||||
|
return getType(value) === DataTypes.Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is null or undefined or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNullOrUndefined(value) {
|
||||||
|
return isNull(value) || isUndefined(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is a date or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isDate(value) {
|
||||||
|
return getType(value) === DataTypes.Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is number or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNumber(value) {
|
||||||
|
return getType(value) === DataTypes.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is string or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isString(value) {
|
||||||
|
return getType(value) === DataTypes.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is boolean or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isBoolean(value) {
|
||||||
|
return getType(value) === DataTypes.Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is an Array or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isArray(value) {
|
||||||
|
return getType(value) === DataTypes.Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is and Object or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isObject(value) {
|
||||||
|
return getType(value) === DataTypes.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is a Function or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isFunction(value) {
|
||||||
|
return getType(value) === DataTypes.Function;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
DataTypes,
|
||||||
|
|
||||||
|
//
|
||||||
|
getType,
|
||||||
|
getConstructor,
|
||||||
|
getPrototype,
|
||||||
|
isNull,
|
||||||
|
isUndefined,
|
||||||
|
isNullOrUndefined,
|
||||||
|
isDate,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isBoolean,
|
||||||
|
isArray,
|
||||||
|
isObject,
|
||||||
|
isFunction,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,133 +0,0 @@
|
|||||||
isXTMPeak
|
|
||||||
isXTMVale
|
|
||||||
isXTMBullish
|
|
||||||
isXTMBearish
|
|
||||||
isXTMNeutural
|
|
||||||
isXTMEndBullish
|
|
||||||
isXTMEndBearish
|
|
||||||
isXTMStartBullish
|
|
||||||
isXTMStartBearish
|
|
||||||
isXTMEndBullishByNeutural
|
|
||||||
isXTMEndBearishByNeutural
|
|
||||||
isXTMStartBullishAfterNeutural
|
|
||||||
isXTMStartBearishAfterNeutural
|
|
||||||
|
|
||||||
isXAMAPeak
|
|
||||||
isXAMAVale
|
|
||||||
isXAMABullish
|
|
||||||
isXAMABearish
|
|
||||||
isXAMANeutural
|
|
||||||
isXAMAEndBullish
|
|
||||||
isXAMAEndBearish
|
|
||||||
isXAMAStartBullish
|
|
||||||
isXAMAStartBearish
|
|
||||||
isXAMAEndBullishByNeutural
|
|
||||||
isXAMAEndBearishByNeutural
|
|
||||||
isXAMAStartBullishAfterNeutural
|
|
||||||
isXAMAStartBearishAfterNeutural
|
|
||||||
|
|
||||||
isXLHHHIncreased
|
|
||||||
isXLHHHDecreased
|
|
||||||
isXLHLLIncreased
|
|
||||||
isXLHLLDecreased
|
|
||||||
isXLHLowAttachedLL
|
|
||||||
isXLHHighAttachedHH
|
|
||||||
isXLHHHSameInLength
|
|
||||||
isXLHLLSameInLength
|
|
||||||
isXLHPriceOverSignal
|
|
||||||
isXLHPriceUnderSignal
|
|
||||||
isXLHPriceInSignalRange
|
|
||||||
isXLHPriceCrossedOverSignal
|
|
||||||
isXLHPriceCrossedUnderSignal
|
|
||||||
|
|
||||||
isXTDSignalPeak
|
|
||||||
isXTDSignalVale
|
|
||||||
isXTDBullishPeak
|
|
||||||
isXTDBullishVale
|
|
||||||
isXTDBearishPeak
|
|
||||||
isXTDBearishVale
|
|
||||||
isXTDBullOverBear
|
|
||||||
isXTDBullUnderBear
|
|
||||||
isXTDSignalOverBear
|
|
||||||
isXTDSignalUnderBear
|
|
||||||
isXTDBullCrossedOverBear
|
|
||||||
isXTDBullCrossedUnderBear
|
|
||||||
isXTDSignalCrossedOverBear
|
|
||||||
isXTDSignalCrossedUnderBear
|
|
||||||
|
|
||||||
isXFIPeak
|
|
||||||
isXFIVale
|
|
||||||
isXFICrossedOverZero
|
|
||||||
isXFIOverZero
|
|
||||||
isXFICrossedUnderZero
|
|
||||||
isXFIUnderZero
|
|
||||||
|
|
||||||
isXTSAllSame
|
|
||||||
isXTSCurrentMin
|
|
||||||
isXTSCurrentMax
|
|
||||||
isXTSCurrentOverFarest
|
|
||||||
isXTSCurrentOverNearest
|
|
||||||
isXTSCurrentOverMediest
|
|
||||||
isXTSCurrentUnderFarest
|
|
||||||
isXTSCurrentUnderNearest
|
|
||||||
isXTSCurrentUnderMediest
|
|
||||||
isXTSCurrentCrossedOverFarest
|
|
||||||
isXTSCurrentCrossedOverNearest
|
|
||||||
isXTSCurrentCrossedOverMediest
|
|
||||||
isXTSCurrentCrossedUnderFarest
|
|
||||||
isXTSCurrentCrossedUnderNearest
|
|
||||||
isXTSCurrentCrossedUnderMediest
|
|
||||||
|
|
||||||
isXRSIPeak
|
|
||||||
isXRSIVale
|
|
||||||
isXRSICrossedOverLongExit
|
|
||||||
isXRSICrossedOverLongEntry
|
|
||||||
isXRSICrossedUnderShortExit
|
|
||||||
isXRSICrossedUnderShortEntry
|
|
||||||
|
|
||||||
isXOBDSwingLow
|
|
||||||
isXOBDSwingHigh
|
|
||||||
|
|
||||||
isXCHLHSameHHs
|
|
||||||
isXCHLHSameLLs
|
|
||||||
isXCHLHSCMCHHSame
|
|
||||||
isXCHLHSCMCLLSame
|
|
||||||
isXCHLHSCLCHHSame
|
|
||||||
isXCHLHSCLCLLSame
|
|
||||||
isXCHLHMCLCHHSame
|
|
||||||
isXCHLHMCLCLLSame
|
|
||||||
isXCHLHMCOnTopOfLC
|
|
||||||
isXCHLHMCInBottomOfLC
|
|
||||||
|
|
||||||
isXCHMASCOverMax
|
|
||||||
isXCHMASCOverMin
|
|
||||||
isXCHMASCUnderMax
|
|
||||||
isXCHMASCUnderMin
|
|
||||||
isXCHMASCCrossedOverMax
|
|
||||||
isXCHMASCCrossedUnderMax
|
|
||||||
isXCHMASCCrossedOverMin
|
|
||||||
isXCHMASCCrossedUnderMin
|
|
||||||
isXCHMASCPeak
|
|
||||||
isXCHMASCVale
|
|
||||||
isXCHMASCTrendsUp
|
|
||||||
isXCHMASCTrendsDown
|
|
||||||
isXCHMASCFastOverSlow
|
|
||||||
isXCHMASCFastUnderSlow
|
|
||||||
isXCHMASCFastCrossedOverSlow
|
|
||||||
isXCHMASCFastCrossedUnderSlow
|
|
||||||
isXCHMAMCPeak
|
|
||||||
isXCHMAMCVale
|
|
||||||
isXCHMAMCTrendsUp
|
|
||||||
isXCHMAMCTrendsDown
|
|
||||||
isXCHMAMCFastOverSlow
|
|
||||||
isXCHMAMCFastUnderSlow
|
|
||||||
isXCHMAMCFastCrossedOverSlow
|
|
||||||
isXCHMAMCFastCrossedUnderSlow
|
|
||||||
isXCHMALCPeak
|
|
||||||
isXCHMALCVale
|
|
||||||
isXCHMALCTrendsUp
|
|
||||||
isXCHMALCTrendsDown
|
|
||||||
isXCHMALCFastOverSlow
|
|
||||||
isXCHMALCFastUnderSlow
|
|
||||||
isXCHMALCFastCrossedOverSlow
|
|
||||||
isXCHMALCFastCrossedUnderSlow
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
///////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SaherElm IT Center X5EA MQL5 Expert Advisor
|
|
||||||
// -------------------------------------------------
|
|
||||||
// Name: X5EA
|
|
||||||
// Description: an Exper Advisor which used RSI and MA
|
|
||||||
// to Analyse Market ...
|
|
||||||
//
|
|
||||||
// Maintainer:
|
|
||||||
// ------------
|
|
||||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////x
|
|
||||||
//
|
|
||||||
// Global Properties ...
|
|
||||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
||||||
#property link "https://saherelm.ir"
|
|
||||||
#property version "1.00"
|
|
||||||
#property description "SaherElm X5EA"
|
|
||||||
#property strict
|
|
||||||
|
|
||||||
//
|
|
||||||
#define ShortName "X5EA"
|
|
||||||
|
|
||||||
//
|
|
||||||
#include "../Classes/x-saherelm.x5.provider.class.mq5"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inputs ...
|
|
||||||
long x5EAMagicNumber = 78692110; // Magic Number
|
|
||||||
int x5EASlippage = 10; // Slippgae
|
|
||||||
string x5EASymbols = "EURUSDb,USDCHFb,USDJPYb,XAUUSDb";
|
|
||||||
|
|
||||||
//
|
|
||||||
double x5EAVolume = 0.01;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Vars ...
|
|
||||||
string x5EASymbol;
|
|
||||||
ENUM_TIMEFRAMES x5EAPeriod;
|
|
||||||
|
|
||||||
//
|
|
||||||
MqlTick x5EATick;
|
|
||||||
|
|
||||||
//
|
|
||||||
// X5Provider ...
|
|
||||||
XSignal signal;
|
|
||||||
|
|
||||||
//
|
|
||||||
X5ProviderDescriptor mProviderDescriptors[];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Event Handlers ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialization ...
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if (x5EASymbol == NULL || StringLen(x5EASymbol) <= 0)
|
|
||||||
{
|
|
||||||
x5EASymbol = _Symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
if (x5EAPeriod == NULL)
|
|
||||||
{
|
|
||||||
x5EAPeriod = _Period;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Inputs ...
|
|
||||||
if (!X5EAValidateInputs())
|
|
||||||
{
|
|
||||||
return INIT_PARAMETERS_INCORRECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// //
|
|
||||||
// // Initial Providers ...
|
|
||||||
// if (!InitialProviders())
|
|
||||||
// {
|
|
||||||
// return INIT_PARAMETERS_INCORRECT;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Testing SymbolsTotal ...
|
|
||||||
string symbols[];
|
|
||||||
int symbolsCount = FilterUSDSymbols(
|
|
||||||
symbols
|
|
||||||
);
|
|
||||||
if (symbolsCount > 0) {
|
|
||||||
//
|
|
||||||
ArrayPrint(symbols);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Init Succeed ...
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// DeInitialization ...
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
||||||
// REASON_REMOVE 1 Program removed from a chart
|
|
||||||
// REASON_RECOMPILE 2 Program recompiled
|
|
||||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
||||||
// REASON_CHARTCLOSE 4 Chart closed
|
|
||||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
||||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
||||||
// REASON_TEMPLATE 7 Another chart template applied
|
|
||||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
||||||
// REASON_CLOSE 9 Terminal closed
|
|
||||||
|
|
||||||
//
|
|
||||||
// De Initialize X5EA Providers ...
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// On Tick Handler ...
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Reading Tick ...
|
|
||||||
if (!SymbolInfoTick(x5EASymbol, x5EATick))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
ProcessProvidersTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Custom Functions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Variables nd Inputs ...
|
|
||||||
bool X5EAValidateInputs()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
//
|
|
||||||
x5EASlippage > 0 &&
|
|
||||||
x5EAMagicNumber > 0
|
|
||||||
//
|
|
||||||
;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize Specific Providers ...
|
|
||||||
bool InitialProviders()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Here We Have to Initial 4 instance of X5Provider ...
|
|
||||||
// - EURUSD/M5;
|
|
||||||
// - USDCHF/M5;
|
|
||||||
// - USDJPY/M5;
|
|
||||||
// - XAUUSD/M5;
|
|
||||||
|
|
||||||
//
|
|
||||||
result = IsValid(x5EASymbols);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
string symbols[];
|
|
||||||
int symbolsCount = SplitContent(
|
|
||||||
symbols,
|
|
||||||
x5EASymbols);
|
|
||||||
result = symbolsCount > 0;
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Define Signallers ...
|
|
||||||
ENUM_X5_SIGNAL_PROVIDERS signallers[];
|
|
||||||
GetAllX5SignalProviders(signallers);
|
|
||||||
|
|
||||||
//
|
|
||||||
for (int i = 0; i < symbolsCount; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Define Structure ...
|
|
||||||
X5ProviderDescriptor iDescriptor;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set Inputs to Default ...
|
|
||||||
iDescriptor.inputs.Default();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Inputs ...
|
|
||||||
bool isInputsValid = iDescriptor.inputs.IsValid();
|
|
||||||
if (!isInputsValid)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize Provider Class ...
|
|
||||||
iDescriptor.provider = new XSCX5Provider(
|
|
||||||
symbols[i],
|
|
||||||
PERIOD_M5 //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Enable Required Signallers and Types ...
|
|
||||||
// TODO: add Support for TYPE Specifications ...
|
|
||||||
iDescriptor.provider
|
|
||||||
.SetSignalTypeState(
|
|
||||||
POSITION_TYPE_BUY,
|
|
||||||
true //
|
|
||||||
);
|
|
||||||
iDescriptor.provider
|
|
||||||
.SetSignalTypeState(
|
|
||||||
POSITION_TYPE_SELL,
|
|
||||||
true //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Enable Required Signallers ...
|
|
||||||
iDescriptor.provider
|
|
||||||
.SetSignalProviderStates(signallers, true);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try to Initialize Provider Instance ...
|
|
||||||
bool isInitialized = iDescriptor.provider
|
|
||||||
.Init(iDescriptor.inputs);
|
|
||||||
if (!isInitialized)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add Prepared Descriptor to Collection ...
|
|
||||||
AddRef(
|
|
||||||
iDescriptor,
|
|
||||||
mProviderDescriptors
|
|
||||||
//
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Result ...
|
|
||||||
result = ArraySize(mProviderDescriptors) == symbolsCount;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check Providers Signals ...
|
|
||||||
void ProcessProvidersTick()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Here We Have to Check 4 instance of X5Provider for Signals ...
|
|
||||||
// - EURUSD/M5;
|
|
||||||
// - USDCHF/M5;
|
|
||||||
// - USDJPY/M5;
|
|
||||||
// - XAUUSD/M5;
|
|
||||||
|
|
||||||
//
|
|
||||||
int descriptorsCount = ArraySize(mProviderDescriptors);
|
|
||||||
if (descriptorsCount <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
int signalsCount = 0;
|
|
||||||
for (int i = 0; i < descriptorsCount; i++)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
X5ProviderDescriptor iDescriptor = mProviderDescriptors[i];
|
|
||||||
|
|
||||||
//
|
|
||||||
bool iHasSignal = iDescriptor.HasSignal(0);
|
|
||||||
|
|
||||||
//
|
|
||||||
if (iHasSignal)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
signalsCount++;
|
|
||||||
Print("Signal: " + iDescriptor.provider.GetSymbol() + ", " + ToString(iDescriptor.provider.GetPeriod()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
///////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SaherElm IT Center X5EA MQL5 Expert Advisor
|
|
||||||
// -------------------------------------------------
|
|
||||||
// Name: X5EA
|
|
||||||
// Description: an Exper Advisor which used RSI and MA
|
|
||||||
// to Analyse Market ...
|
|
||||||
//
|
|
||||||
// Maintainer:
|
|
||||||
// ------------
|
|
||||||
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////x
|
|
||||||
//
|
|
||||||
// Global Properties ...
|
|
||||||
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
||||||
#property link "https://saherelm.ir"
|
|
||||||
#property version "1.00"
|
|
||||||
#property description "SaherElm X5EA"
|
|
||||||
#property strict
|
|
||||||
|
|
||||||
//
|
|
||||||
#define ShortName "X5EA"
|
|
||||||
|
|
||||||
//
|
|
||||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
|
||||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
||||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inputs ...
|
|
||||||
long x5EAMagicNumber = 78692110; // Magic Number
|
|
||||||
int x5EASlippage = 10; // Slippgae
|
|
||||||
|
|
||||||
//
|
|
||||||
double x5EAVolume = 0.01;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Vars ...
|
|
||||||
string x5EASymbol;
|
|
||||||
ENUM_TIMEFRAMES x5EAPeriod;
|
|
||||||
|
|
||||||
//
|
|
||||||
MqlTick x5EATick;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Event Handlers ...
|
|
||||||
//
|
|
||||||
// Initialization ...
|
|
||||||
int OnInit()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
if (x5EASymbol == NULL || StringLen(x5EASymbol) <= 0)
|
|
||||||
{
|
|
||||||
x5EASymbol = _Symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
if (x5EAPeriod == NULL)
|
|
||||||
{
|
|
||||||
x5EAPeriod = _Period;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Inputs ...
|
|
||||||
if (!X5EAValidateInputs())
|
|
||||||
{
|
|
||||||
return INIT_PARAMETERS_INCORRECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
drawPrefix = ShortName;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Init Succeed ...
|
|
||||||
return INIT_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// DeInitialization ...
|
|
||||||
void OnDeinit(const int reason)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
||||||
// REASON_REMOVE 1 Program removed from a chart
|
|
||||||
// REASON_RECOMPILE 2 Program recompiled
|
|
||||||
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
||||||
// REASON_CHARTCLOSE 4 Chart closed
|
|
||||||
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
||||||
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
||||||
// REASON_TEMPLATE 7 Another chart template applied
|
|
||||||
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
||||||
// REASON_CLOSE 9 Terminal closed
|
|
||||||
|
|
||||||
//
|
|
||||||
// De Initialize X5EA Providers ...
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// On Tick Handler ...
|
|
||||||
void OnTick()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Reading Tick ...
|
|
||||||
if (!SymbolInfoTick(x5EASymbol, x5EATick))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Custom Functions ...
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate Variables nd Inputs ...
|
|
||||||
bool X5EAValidateInputs()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
//
|
|
||||||
x5EASlippage > 0 &&
|
|
||||||
x5EAMagicNumber > 0
|
|
||||||
//
|
|
||||||
;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
+16
@@ -52,6 +52,22 @@ if (!projectName ||
|
|||||||
doPackProject = false;
|
doPackProject = false;
|
||||||
const workSpacePath = XFileTools.joinPath(".", __dirname, "Experts");
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Experts");
|
||||||
|
|
||||||
|
//
|
||||||
|
doWorkspaceCompile(workSpacePath);
|
||||||
|
} else if (projectName == "--helpers" || projectName == "**helpers") {
|
||||||
|
//
|
||||||
|
// Compile Helpers on Workspace ...
|
||||||
|
doPackProject = false;
|
||||||
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Helpers");
|
||||||
|
|
||||||
|
//
|
||||||
|
doWorkspaceCompile(workSpacePath);
|
||||||
|
} else if (projectName == "--classes" || projectName == "**classes") {
|
||||||
|
//
|
||||||
|
// Compile Classes on Workspace ...
|
||||||
|
doPackProject = false;
|
||||||
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Classes");
|
||||||
|
|
||||||
//
|
//
|
||||||
doWorkspaceCompile(workSpacePath);
|
doWorkspaceCompile(workSpacePath);
|
||||||
} else if (projectName == "--indicators" || projectName == "**indicators") {
|
} else if (projectName == "--indicators" || projectName == "**indicators") {
|
||||||
|
|||||||
+14
-187
@@ -1,211 +1,38 @@
|
|||||||
{
|
{
|
||||||
"name": "mql5",
|
"name": "mql5",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "MQL5 Workspace",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"true": "",
|
"true": "",
|
||||||
"aaa": "|----------|",
|
"aaa": "|----------|",
|
||||||
"aab": "| Projects |",
|
"aab": "| Commons |",
|
||||||
"aac": "|----------|",
|
"aac": "|----------|",
|
||||||
"compile": "node compile.js",
|
"compile": "node compile.js",
|
||||||
"compileWorkspace": "npm run compile",
|
"compileWorkspace": "npm run compile",
|
||||||
"compileExperts": "npm run compile **experts",
|
"compileExperts": "npm run compile **experts",
|
||||||
|
"compileLibraries": "npm run compile **libraries",
|
||||||
|
"compileHelpers": "npm run compile **helpers",
|
||||||
|
"compileClasses": "npm run compile **classes",
|
||||||
"compileIndicators": "npm run compile **indicators",
|
"compileIndicators": "npm run compile **indicators",
|
||||||
|
"compileProject": "npm run compileExperts && npm run compileLibraries && npm run compileHelpers && npm run compileClasses && npm run compileIndicators",
|
||||||
"rmExperts": "shx --silent rm ./Experts/* || npm run true",
|
"rmExperts": "shx --silent rm ./Experts/* || npm run true",
|
||||||
"rmHelpers": "shx --silent rm ./Helpers/* || npm run true",
|
"rmHelpers": "shx --silent rm ./Helpers/* || npm run true",
|
||||||
"rmClasses": "shx --silent rm ./Classes/* || npm run true",
|
"rmClasses": "shx --silent rm ./Classes/* || npm run true",
|
||||||
"rmLibraries": "shx --silent rm ./Libraries/* || npm run true",
|
"rmLibraries": "shx --silent rm ./Libraries/* || npm run true",
|
||||||
"rmProviders": "shx --silent rm ./Providers/* || npm run true",
|
|
||||||
"rmIndicators": "shx --silent rm ./Indicators/* || npm run true",
|
"rmIndicators": "shx --silent rm ./Indicators/* || npm run true",
|
||||||
"bkpExperts": "shx --silent mkdir -p ./BKP/Main/Experts && shx --silent cp -r ./Experts/*.mq5 ./BKP/Main/Experts || npm run true",
|
"rmExpertsEx": "shx --silent rm -r ./Experts/*.ex5 || npm run true",
|
||||||
"bkpHelpers": "shx --silent mkdir -p ./BKP/Main/Helpers && shx --silent cp -r ./Helpers/*.mq5 ./BKP/Main/Helpers || npm run true",
|
"rmLibrariesEx": "shx --silent rm -r ./Libraries/*.ex5 || npm run true",
|
||||||
"bkpClasses": "shx --silent mkdir -p ./BKP/Main/Classes && shx --silent cp -r ./Classes/*.mq5 ./BKP/Main/Classes || npm run true",
|
"rmHelpersEx": "shx --silent rm -r ./Helpers/*.ex5 || npm run true",
|
||||||
"bkpLibraries": "shx --silent mkdir -p ./BKP/Main/Libraries && shx --silent cp -r ./Libraries/*.mq5 ./BKP/Main/Libraries || npm run true",
|
"rmClassesEx": "shx --silent rm -r ./Classes/*.ex5 || npm run true",
|
||||||
"bkpProviders": "shx --silent mkdir -p ./BKP/Main/Providers && shx --silent cp -r ./Providers/*.mq5 ./BKP/Main/Providers || npm run true",
|
"rmIndicatorsEx": "shx --silent rm -r ./Indicators/*.ex5 || npm run true",
|
||||||
"bkpIndicators": "shx --silent mkdir -p ./BKP/Main/Indicators && shx --silent cp -r ./Indicators/*.mq5 ./BKP/Main/Indicators || npm run true",
|
"cleanupEx": "npm run rmExpertsEx && npm run rmLibrariesEx && npm run rmHelpersEx && npm run rmClassesEx && npm run rmIndicatorsEx",
|
||||||
"cleanupWorkspace": "npm run rmExperts && npm run rmHelpers && npm run rmClasses && npm run rmLibraries && npm run rmProviders && npm run rmIndicators",
|
"prepareWorkspace": "npm run cleanupEx && npm run compileProject"
|
||||||
"backupWorkspace": "shx --silent rm -rf ./BKP/Main && npm run bkpExperts && npm run bkpHelpers && npm run bkpClasses && npm run bkpLibraries && npm run bkpProviders && npm run bkpIndicators",
|
|
||||||
"bba": "|----------|",
|
|
||||||
"bbb": "| XTEST |",
|
|
||||||
"bbc": "|----------|",
|
|
||||||
"xTESTCpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XTEST/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xTESTCpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XTEST/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xTESTCpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XTEST/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xTESTCpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XTEST/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xTESTCpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XTEST/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xTESTCpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XTEST/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xTESTUpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XTEST/Experts || npm run true",
|
|
||||||
"xTESTUpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XTEST/Helpers || npm run true",
|
|
||||||
"xTESTUpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XTEST/Classes || npm run true",
|
|
||||||
"xTESTUpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XTEST/Providers || npm run true",
|
|
||||||
"xTESTUpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XTEST/Libraries || npm run true",
|
|
||||||
"xTESTUpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XTEST/Indicators || npm run true",
|
|
||||||
"xTESTCpWorkspace": "npm run xTESTCpExperts && npm run xTESTCpProviders && npm run xTESTCpIndicators && npm run xTESTCpLibraries && npm run xTESTCpHelpers && npm run xTESTCpClasses",
|
|
||||||
"xTESTUpSourceFromWorkspace": "npm run xTESTUpSourceExperts && npm run xTESTUpSourceProviders && npm run xTESTUpSourceIndicators && npm run xTESTUpSourceLibraries && npm run xTESTUpSourceHelpers && npm run xTESTUpSourceClasses",
|
|
||||||
"xTESTPrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xTESTCpWorkspace",
|
|
||||||
"xTESTApplyFromWorkspace": "npm run backupWorkspace && npm run xTESTUpSourceFromWorkspace",
|
|
||||||
"xTESTCompile": "npm run compile XTEST",
|
|
||||||
"xTESTCompileAndPack": "npm run compile XTEST true",
|
|
||||||
"bbd": "|----------|",
|
|
||||||
"bbe": "| /XTEST |",
|
|
||||||
"bbf": "|----------|",
|
|
||||||
"aba": "|----------|",
|
|
||||||
"abb": "| XEU5 |",
|
|
||||||
"abc": "|----------|",
|
|
||||||
"xEU5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XEU5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xEU5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XEU5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xEU5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XEU5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xEU5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XEU5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xEU5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XEU5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xEU5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XEU5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xEU5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XEU5/Experts || npm run true",
|
|
||||||
"xEU5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XEU5/Helpers || npm run true",
|
|
||||||
"xEU5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XEU5/Classes || npm run true",
|
|
||||||
"xEU5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XEU5/Providers || npm run true",
|
|
||||||
"xEU5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XEU5/Libraries || npm run true",
|
|
||||||
"xEU5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XEU5/Indicators || npm run true",
|
|
||||||
"xEU5CpWorkspace": "npm run xEU5CpExperts && npm run xEU5CpProviders && npm run xEU5CpIndicators && npm run xEU5CpLibraries && npm run xEU5CpHelpers && npm run xEU5CpClasses",
|
|
||||||
"xEU5UpSourceFromWorkspace": "npm run xEU5UpSourceExperts && npm run xEU5UpSourceProviders && npm run xEU5UpSourceIndicators && npm run xEU5UpSourceLibraries && npm run xEU5UpSourceHelpers && npm run xEU5UpSourceClasses",
|
|
||||||
"xEU5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xEU5CpWorkspace",
|
|
||||||
"xEU5ApplyFromWorkspace": "npm run backupWorkspace && npm run xEU5UpSourceFromWorkspace",
|
|
||||||
"xEU5Compile": "npm run compile XEU5",
|
|
||||||
"xEU5CompileAndPack": "npm run compile XEU5 true",
|
|
||||||
"abd": "|----------|",
|
|
||||||
"abe": "| /XEU5 |",
|
|
||||||
"abf": "|----------|",
|
|
||||||
"aca": "|----------|",
|
|
||||||
"acb": "| XAU5 |",
|
|
||||||
"acc": "|----------|",
|
|
||||||
"xAU5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XAU5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xAU5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XAU5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xAU5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XAU5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xAU5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XAU5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xAU5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XAU5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xAU5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XAU5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xAU5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XAU5/Experts || npm run true",
|
|
||||||
"xAU5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XAU5/Helpers || npm run true",
|
|
||||||
"xAU5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XAU5/Classes || npm run true",
|
|
||||||
"xAU5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XAU5/Providers || npm run true",
|
|
||||||
"xAU5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XAU5/Libraries || npm run true",
|
|
||||||
"xAU5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XAU5/Indicators || npm run true",
|
|
||||||
"xAU5CpWorkspace": "npm run xAU5CpExperts && npm run xAU5CpProviders && npm run xAU5CpIndicators && npm run xAU5CpLibraries && npm run xAU5CpHelpers && npm run xAU5CpClasses",
|
|
||||||
"xAU5UpSourceFromWorkspace": "npm run xAU5UpSourceExperts && npm run xAU5UpSourceProviders && npm run xAU5UpSourceIndicators && npm run xAU5UpSourceLibraries && npm run xAU5UpSourceHelpers && npm run xAU5UpSourceClasses",
|
|
||||||
"xAU5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xAU5CpWorkspace",
|
|
||||||
"xAU5ApplyFromWorkspace": "npm run backupWorkspace && npm run xAU5UpSourceFromWorkspace",
|
|
||||||
"xAU5Compile": "npm run compile XAU5",
|
|
||||||
"xAU5CompileAndPack": "npm run compile XAU5 true",
|
|
||||||
"acd": "|----------|",
|
|
||||||
"ace": "| /XAU5 |",
|
|
||||||
"acf": "|----------|",
|
|
||||||
"bda": "|-----------|",
|
|
||||||
"bdb": "| XUSCHF5 |",
|
|
||||||
"bdc": "|-----------|",
|
|
||||||
"xUSCHF5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XUSCHF5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xUSCHF5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XUSCHF5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xUSCHF5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XUSCHF5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xUSCHF5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XUSCHF5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xUSCHF5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XUSCHF5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xUSCHF5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XUSCHF5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xUSCHF5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XUSCHF5/Experts || npm run true",
|
|
||||||
"xUSCHF5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XUSCHF5/Helpers || npm run true",
|
|
||||||
"xUSCHF5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XUSCHF5/Classes || npm run true",
|
|
||||||
"xUSCHF5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XUSCHF5/Providers || npm run true",
|
|
||||||
"xUSCHF5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XUSCHF5/Libraries || npm run true",
|
|
||||||
"xUSCHF5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XUSCHF5/Indicators || npm run true",
|
|
||||||
"xUSCHF5CpWorkspace": "npm run xUSCHF5CpExperts && npm run xUSCHF5CpProviders && npm run xUSCHF5CpIndicators && npm run xUSCHF5CpLibraries && npm run xUSCHF5CpHelpers && npm run xUSCHF5CpClasses",
|
|
||||||
"xUSCHF5UpSourceFromWorkspace": "npm run xUSCHF5UpSourceExperts && npm run xUSCHF5UpSourceProviders && npm run xUSCHF5UpSourceIndicators && npm run xUSCHF5UpSourceLibraries && npm run xUSCHF5UpSourceHelpers && npm run xUSCHF5UpSourceClasses",
|
|
||||||
"xUSCHF5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xUSCHF5CpWorkspace",
|
|
||||||
"xUSCHF5ApplyFromWorkspace": "npm run backupWorkspace && npm run xUSCHF5UpSourceFromWorkspace",
|
|
||||||
"xUSCHF5Compile": "npm run compile XUSCHF5",
|
|
||||||
"xUSCHF5CompileAndPack": "npm run compile XUSCHF5 true",
|
|
||||||
"bdd": "|-----------|",
|
|
||||||
"bde": "| /XUSCHF5 |",
|
|
||||||
"bdf": "|-----------|",
|
|
||||||
"bwa": "|-----------|",
|
|
||||||
"bwb": "| XBTUS5 |",
|
|
||||||
"bwc": "|-----------|",
|
|
||||||
"xBTUS5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XBTUS5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xBTUS5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XBTUS5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xBTUS5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XBTUS5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xBTUS5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XBTUS5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xBTUS5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XBTUS5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xBTUS5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XBTUS5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xBTUS5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XBTUS5/Experts || npm run true",
|
|
||||||
"xBTUS5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XBTUS5/Helpers || npm run true",
|
|
||||||
"xBTUS5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XBTUS5/Classes || npm run true",
|
|
||||||
"xBTUS5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XBTUS5/Providers || npm run true",
|
|
||||||
"xBTUS5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XBTUS5/Libraries || npm run true",
|
|
||||||
"xBTUS5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XBTUS5/Indicators || npm run true",
|
|
||||||
"xBTUS5CpWorkspace": "npm run xBTUS5CpExperts && npm run xBTUS5CpProviders && npm run xBTUS5CpIndicators && npm run xBTUS5CpLibraries && npm run xBTUS5CpHelpers && npm run xBTUS5CpClasses",
|
|
||||||
"xBTUS5UpSourceFromWorkspace": "npm run xBTUS5UpSourceExperts && npm run xBTUS5UpSourceProviders && npm run xBTUS5UpSourceIndicators && npm run xBTUS5UpSourceLibraries && npm run xBTUS5UpSourceHelpers && npm run xBTUS5UpSourceClasses",
|
|
||||||
"xBTUS5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xBTUS5CpWorkspace",
|
|
||||||
"xBTUS5ApplyFromWorkspace": "npm run backupWorkspace && npm run xBTUS5UpSourceFromWorkspace",
|
|
||||||
"xBTUS5Compile": "npm run compile XBTUS5",
|
|
||||||
"xBTUS5CompileAndPack": "npm run compile XBTUS5 true",
|
|
||||||
"bwd": "|-----------|",
|
|
||||||
"bwe": "| /XBTUS5 |",
|
|
||||||
"bwf": "|-----------|",
|
|
||||||
"ada": "|-----------|",
|
|
||||||
"adb": "| XUSPY5 |",
|
|
||||||
"adc": "|-----------|",
|
|
||||||
"xUSPY5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XUSPY5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xUSPY5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XUSPY5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xUSPY5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XUSPY5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xUSPY5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XUSPY5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xUSPY5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XUSPY5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xUSPY5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XUSPY5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xUSPY5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XUSPY5/Experts || npm run true",
|
|
||||||
"xUSPY5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XUSPY5/Helpers || npm run true",
|
|
||||||
"xUSPY5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XUSPY5/Classes || npm run true",
|
|
||||||
"xUSPY5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XUSPY5/Providers || npm run true",
|
|
||||||
"xUSPY5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XUSPY5/Libraries || npm run true",
|
|
||||||
"xUSPY5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XUSPY5/Indicators || npm run true",
|
|
||||||
"xUSPY5CpWorkspace": "npm run xUSPY5CpExperts && npm run xUSPY5CpProviders && npm run xUSPY5CpIndicators && npm run xUSPY5CpLibraries && npm run xUSPY5CpHelpers && npm run xUSPY5CpClasses",
|
|
||||||
"xUSPY5UpSourceFromWorkspace": "npm run xUSPY5UpSourceExperts && npm run xUSPY5UpSourceProviders && npm run xUSPY5UpSourceIndicators && npm run xUSPY5UpSourceLibraries && npm run xUSPY5UpSourceHelpers && npm run xUSPY5UpSourceClasses",
|
|
||||||
"xUSPY5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xUSPY5CpWorkspace",
|
|
||||||
"xUSPY5ApplyFromWorkspace": "npm run backupWorkspace && npm run xUSPY5UpSourceFromWorkspace",
|
|
||||||
"xUSPY5Compile": "npm run compile XUSPY5",
|
|
||||||
"xUSPY5CompileAndPack": "npm run compile XUSPY5 true",
|
|
||||||
"add": "|-----------|",
|
|
||||||
"ade": "| /XUSPY5 |",
|
|
||||||
"adf": "|-----------|",
|
|
||||||
"aea": "|-----------|",
|
|
||||||
"aeb": "| XGPUS5 |",
|
|
||||||
"aec": "|-----------|",
|
|
||||||
"xGPUS5CpExperts": "shx --silent mkdir -p ./Experts && shx --silent cp -r ./Projects/XGPUS5/Experts/*.mq5 ./Experts || npm run true",
|
|
||||||
"xGPUS5CpHelpers": "shx --silent mkdir -p ./Helpers && shx --silent cp -r ./Projects/XGPUS5/Helpers/*.mq5 ./Helpers || npm run true",
|
|
||||||
"xGPUS5CpClasses": "shx --silent mkdir -p ./Classes && shx --silent cp -r ./Projects/XGPUS5/Classes/*.mq5 ./Classes || npm run true",
|
|
||||||
"xGPUS5CpProviders": "shx --silent mkdir -p ./Providers && shx --silent cp -r ./Projects/XGPUS5/Providers/*.mq5 ./Providers || npm run true",
|
|
||||||
"xGPUS5CpLibraries": "shx --silent mkdir -p ./Libraries && shx --silent cp -r ./Projects/XGPUS5/Libraries/*.mq5 ./Libraries || npm run true",
|
|
||||||
"xGPUS5CpIndicators": "shx --silent mkdir -p ./Indicators && shx --silent cp -r ./Projects/XGPUS5/Indicators/*.mq5 ./Indicators || npm run true",
|
|
||||||
"xGPUS5UpSourceExperts": "shx --silent cp -r ./Experts/*.mq5 ./Projects/XGPUS5/Experts || npm run true",
|
|
||||||
"xGPUS5UpSourceHelpers": "shx --silent cp -r ./Helpers/*.mq5 ./Projects/XGPUS5/Helpers || npm run true",
|
|
||||||
"xGPUS5UpSourceClasses": "shx --silent cp -r ./Classes/*.mq5 ./Projects/XGPUS5/Classes || npm run true",
|
|
||||||
"xGPUS5UpSourceProviders": "shx --silent cp -r ./Providers/*.mq5 ./Projects/XGPUS5/Providers || npm run true",
|
|
||||||
"xGPUS5UpSourceLibraries": "shx --silent cp -r ./Libraries/*.mq5 ./Projects/XGPUS5/Libraries || npm run true",
|
|
||||||
"xGPUS5UpSourceIndicators": "shx --silent cp -r ./Indicators/*.mq5 ./Projects/XGPUS5/Indicators || npm run true",
|
|
||||||
"xGPUS5CpWorkspace": "npm run xGPUS5CpExperts && npm run xGPUS5CpProviders && npm run xGPUS5CpIndicators && npm run xGPUS5CpLibraries && npm run xGPUS5CpHelpers && npm run xGPUS5CpClasses",
|
|
||||||
"xGPUS5UpSourceFromWorkspace": "npm run xGPUS5UpSourceExperts && npm run xGPUS5UpSourceProviders && npm run xGPUS5UpSourceIndicators && npm run xGPUS5UpSourceLibraries && npm run xGPUS5UpSourceHelpers && npm run xGPUS5UpSourceClasses",
|
|
||||||
"xGPUS5PrepareWorkspace": "npm run backupWorkspace && npm run cleanupWorkspace && npm run xGPUS5CpWorkspace",
|
|
||||||
"xGPUS5ApplyFromWorkspace": "npm run backupWorkspace && npm run xGPUS5UpSourceFromWorkspace",
|
|
||||||
"xGPU5Compile": "npm run compile XGPU5",
|
|
||||||
"xGPU5CompileAndPack": "npm run compile XGPU5 true",
|
|
||||||
"aed": "|-----------|",
|
|
||||||
"aee": "| /XGPUS5 |",
|
|
||||||
"aef": "|-----------|",
|
|
||||||
"aad": "|-----------|",
|
|
||||||
"aae": "| /Projects |",
|
|
||||||
"aaf": "|-----------|"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://pm.saherelmhub.ir/source/MQL5Data.git"
|
"url": "https://git.saherelmhub.ir/saherelm/MQL5TestWorkspace.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
|
||||||
"MQL5",
|
|
||||||
"ROBOT"
|
|
||||||
],
|
|
||||||
"author": "Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)",
|
"author": "Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Reference in New Issue
Block a user