delphirtl
Version:
RTL functions from Delphi
459 lines • 24.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ENV_REACT_PREFIX = exports.ENV_NEXT_PREFIX = exports.FormatDateTime = exports.faAnyFile = exports.faVirtual = exports.faEncrypted = exports.faCompressed = exports.faSymLink = exports.faTemporary = exports.faNormal = exports.faArchive = exports.faDirectory = exports.faVolumeID = exports.faSysFile = exports.faHidden = exports.faReadOnly = exports.faInvalid = void 0;
exports.CreateDir = CreateDir;
exports.DirectoryExists = DirectoryExists;
exports.GetDirectories = GetDirectories;
exports.GetCurrentDir = GetCurrentDir;
exports.SetCurrentDir = SetCurrentDir;
exports.RemoveDir = RemoveDir;
exports.ExtractFileDir = ExtractFileDir;
exports.ExtractFileExt = ExtractFileExt;
exports.ExtractFileName = ExtractFileName;
exports.FileExists = FileExists;
exports.IncludeTrailingPathDelimiter = IncludeTrailingPathDelimiter;
exports.LowerCase = LowerCase;
exports.lowerCase = LowerCase;
exports.UpperCase = UpperCase;
exports.upperCase = UpperCase;
exports.DeleteEnvironmentVariable = DeleteEnvironmentVariable;
exports.ExistsEnvironmentVariable = ExistsEnvironmentVariable;
exports.GetEnvironmentVariable = GetEnvironmentVariable;
exports.SetEnvironmentVariable = SetEnvironmentVariable;
exports.hasMessageField = hasMessageField;
exports.hasFieldOfType = hasFieldOfType;
exports.isArbitraryObject = isArbitraryObject;
exports.IsLeapYear = IsLeapYear;
const path_1 = __importDefault(require("path"));
const fs = __importStar(require("fs"));
const assert_1 = __importDefault(require("assert"));
const process_1 = require("process");
const dateutils_1 = require("./dateutils");
Object.defineProperty(exports, "FormatDateTime", { enumerable: true, get: function () { return dateutils_1.FormatDateTime; } });
/**
* Returs true if the given year is a leap year
*
* @param {number} Year
* @returns {boolean}
* @category SysUtils
*/
function IsLeapYear(Year) {
// Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
const result = (Year % 4 == 0) && ((Year % 100 != 0) || (Year % 400 == 0));
return result;
}
const MonthDays = [
[0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
[0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
];
// ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
// (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
// { Days between 1/1/0001 and 12/31/1899 }
const DateDelta = 693594;
/**
* Returns 1 if the given boolean is true, 0 otherwise
*
* @param {boolean} value
* @returns {number}
* @category SysUtils
*/
function boolToInt(value) {
return value ? 1 : 0;
}
/**
* Description placeholder
*
* @class TDateTime
* @typedef {TDateTime}
* @category SysUtils
*/
class TDateTime {
constructor(AValue) { this.Value = AValue; }
}
/**
* Description placeholder
*
* @class TYMD
* @typedef {TYMD}
* @category SysUtils
*/
class TYMD {
constructor() {
this.Year = 0;
this.Month = 0;
this.Day = 0;
this.DOW = 0;
}
}
/**
* Creates the given directory, Dir
*
* @param {string} Dir
* @returns {boolean}
* @category SysUtils
*/
function CreateDir(Dir) {
let result = true;
try {
fs.mkdirSync(Dir, { recursive: true });
}
catch (e) {
result = false;
}
return result;
}
/**
* Checks if the given Dir exists or not.
*
* @param {string} Dir
* @returns {boolean}
* @category SysUtils
*/
function DirectoryExists(Dir) {
let result;
try {
const exists = fs.existsSync(Dir);
const statSync = fs.statSync(Dir);
result = statSync.isDirectory() && exists;
}
catch (e) {
result = false;
}
return result;
}
// File attribute constants
exports.faInvalid = -1;
exports.faReadOnly = 0x00000001;
exports.faHidden = 0x00000002; // only a convention on POSIX
exports.faSysFile = 0x00000004; // on POSIX system files are not regular files and not directories
exports.faVolumeID = 0x00000008; // not used in Win32
/**
* The referenced item is a directory
*/
exports.faDirectory = 0x00000010;
exports.faArchive = 0x00000020;
/**
* * The referenced item is a file
*
* @type {128}
*/
exports.faNormal = 0x00000080;
exports.faTemporary = 0x00000100;
exports.faSymLink = 0x00000400; // Available on POSIX and Vista and above
exports.faCompressed = 0x00000800;
exports.faEncrypted = 0x00004000;
exports.faVirtual = 0x00010000;
exports.faAnyFile = 0x000001FF;
/**
* Get subdirectories from the given path, using the optional predicate to filter out items.
*
* @param {string} path
* @param {?TFilterPredicate} [predicate]
* @returns {string[]}
* @category SysUtils
*/
function GetDirectories(path, predicate) {
let result = [];
if (predicate) {
// filters through the callback
const rdsResult = fs.readdirSync(path, { withFileTypes: true });
const filterResult = rdsResult.filter(dirent => {
const path = dirent.path;
const filename = IncludeTrailingPathDelimiter(path) + dirent.name;
const fsstatResult = fs.statSync(filename);
const attr = (fsstatResult.isDirectory() ? exports.faDirectory : 0) | (fsstatResult.isFile() ? exports.faNormal : 0);
const creationTime = fsstatResult.birthtime.getTime();
const sr = {
Size: fsstatResult.size,
Attr: attr,
Name: dirent.name,
ExcludeAttr: 0,
LastAccessTime: (fsstatResult.atime > fsstatResult.mtime) ? fsstatResult.atime : fsstatResult.mtime,
TimeStamp: fsstatResult.mtime,
Time: creationTime,
CreationTime: creationTime
};
const result = predicate(path, sr);
return result;
});
const mapResult = filterResult.map(dirent => dirent.name);
result = mapResult;
}
else {
result = fs.readdirSync(path, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
}
return result;
}
/**
* Removes the given directory, Dir
*
* @param {string} Dir
* @param {?boolean} [Recursive]
* @returns {boolean}
* @throws ENOENT
* @throws ENOTDIR
* @category SysUtils
*/
function RemoveDir(Dir, Recursive) {
let result = true;
try {
const opt = { recursive: Recursive ? true : false };
fs.rmdirSync(Dir, opt);
}
catch (e) {
result = false;
}
return result;
}
/**
* Gets the current working directory
* @returns The current working directory
* @category SysUtils
*/
function GetCurrentDir() {
const result = (0, process_1.cwd)();
return result;
}
/**
* Changes the current working directory to the specified directory
* @param newDir New working directory
* @category SysUtils
*/
function SetCurrentDir(newDir) {
(0, process_1.chdir)(newDir);
}
/**
* Extracts the drive and directory parts from AFileName.
* Regardless of whether AFileName is a path or filename,
* this routine returns the path up to the last path.sep
* eg, AFileName contains K:\\Development\\TypeScript\\delphirtl\\tests
* the result is K:\\Development\\TypeScript\\delphirtl
*
* @param {string} AFileNameOrPath
* @returns {string}
* @category SysUtils
*/
function ExtractFileDir(AFileNameOrPath) {
const index = AFileNameOrPath.lastIndexOf(path_1.default.sep);
const result = AFileNameOrPath.substring(0, index);
return result;
}
/**
* Extracts the file extension, given the filename, AFileName
* For example, if given "Nothing.pas", returns "pas"
* If given "Nothing", returns ""
*
* @param {string} AFilename
* @returns {string}
* @category SysUtils
*/
function ExtractFileExt(AFilename) {
let result = "";
const LPathDelimIndex = AFilename.lastIndexOf(path_1.default.sep);
const index = AFilename.lastIndexOf(".");
if (index > LPathDelimIndex) { // ensure . is after path separator
result = (index == -1) ? "" : AFilename.substring(index + 1, AFilename.length);
}
return result;
}
/**
* Extracts the name and extension parts of a file name.
*
* The resulting string is the rightmost characters of FileName, starting with the first character after
* the colon or backslash that separates the path information from the name and extension. The resulting
* string is equal to FileName, if FileName contains no drive and directory parts.
* @param AFileName
* @returns
* @category SysUtils
*/
function ExtractFileName(AFileName) {
const index = AFileName.lastIndexOf(path_1.default.sep) + 1;
const result = AFileName.substring(index);
return result;
}
/**
* Checks if the given filename exists
*
* @param {string} AFileName Filename to check existence for.
* @returns {boolean} true if the given filename exists, false otherwise.
* @category SysUtils
*/
function FileExists(AFileName) {
let result = false;
try {
const statSync = fs.statSync(AFileName);
result = fs.existsSync(AFileName) && statSync.isFile();
}
catch (e) {
// silent
}
return result;
}
/**
* Adds a path delimiter to the given string. If the path delimiter is already at the end of the string, does nothing.
*
* @param {string} APath Given path to check for delimiter to add to
* @returns {string} The path with added delimiter
* @category SysUtils
*/
function IncludeTrailingPathDelimiter(APath) {
const result = (APath.charAt(APath.length - 1) != path_1.default.sep) ? (APath + path_1.default.sep) : APath;
return result;
}
/**
* Description placeholder
*
* @param {string} str
* @returns {string}
* @category SysUtils
*/
function LowerCase(str) {
return str.toLowerCase();
}
/**
* Description placeholder
*
* @param {string} str
* @returns {string}
* @category SysUtils
*/
function UpperCase(str) {
return str.toUpperCase();
}
/**
* Deletes the given name from the environment variable
*
* @param {string} Name
* @category SysUtils
*/
function DeleteEnvironmentVariable(Name) {
delete process.env[Name];
}
/**
* Only environment variables starting with ENV_REACT_PREFIX are returned in React
*
* @type {"REACT_APP_"}
* @category Constants
*/
const ENV_REACT_PREFIX = "REACT_APP_";
exports.ENV_REACT_PREFIX = ENV_REACT_PREFIX;
/**
* Only environment variables starting with ENV_NEXT_PREFIX are returned in Nextjs
*
* @type {"NEXT_PUBLIC_"}
* @category Constants
*/
const ENV_NEXT_PREFIX = "NEXT_PUBLIC_";
exports.ENV_NEXT_PREFIX = ENV_NEXT_PREFIX;
// In Reactjs, only env vars starting with REACT_APP_ is allowed
// Anything else will not show up
// Nextjs, only env vars starting with NEXT_PUBLIC_ are allowed
/**
* Retrieves the contents of the specified variable from the environment block
*
* @param Name The name of the environment variable to retrieve
* @returns The value of the given environment variable
* @category SysUtils
*/
function GetEnvironmentVariable(Name) {
const result = process.env[Name] || "";
return result;
}
/**
* Checks if an environment variable exists
*
* @param {string} Name
* @returns {boolean}
* @category SysUtils
*/
function ExistsEnvironmentVariable(Name) {
const EnvValue = process.env[Name];
const result = EnvValue !== undefined;
return result;
}
/**
* Sets the specified variable in the environment with the given value
*
* @param {string} Name
* @param {string} Value
* @category SysUtils
*/
function SetEnvironmentVariable(Name, Value) {
(0, assert_1.default)(Name);
(0, assert_1.default)(Value);
process.env[Name] = Value;
}
/**
* Checks if the given parameter is an object
* @param potentialObj item to check as an object
* @returns boolean
* @category SysUtils
*/
function isArbitraryObject(potentialObj) {
// an array/date is identified as an object in JavaScript
// so this function checks that the potentialObject is not an array/date, and not a regex
const result = (potentialObj !== null) &&
(!Array.isArray(potentialObj)) &&
(!(potentialObj instanceof RegExp)) &&
(!(potentialObj instanceof Date)) &&
(typeof potentialObj === "object");
return result;
}
/**
* Checks that obj is an object, and it has a field named fieldName and that its type is fieldType
* Assuming e is an object with the field code of type string.
* * If you use this, then the expression following it is valid, for example:
* - hasFieldOfType<string>(e, "code", "string") && e.code === "INSUFFICIENT_FUNDS")
* * If you do not use it, then
* - e.code is invalid when checked by code analyzer
* @param obj
* @param fieldName
* @param fieldType
* @returns
* @category SysUtils
*/
function hasFieldOfType(obj, fieldName, fieldType) {
const result = isArbitraryObject(obj) &&
typeof obj[fieldName] === fieldType;
return result;
}
/**
* Checks if the given object has a message field of string type
*
* @param obj
* @returns
* @category SysUtils
*/
function hasMessageField(obj) {
const result = hasFieldOfType(obj, "message", "string");
return result;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3lzdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUErZUksOEJBQVM7QUFBRSwwQ0FBZTtBQUMxQix3Q0FBYztBQUFFLHNDQUFhO0FBQUUsc0NBQWE7QUFDNUMsOEJBQVM7QUFDVCx3Q0FBYztBQUNkLHdDQUFjO0FBQ2QsMENBQWU7QUFDZixnQ0FBVTtBQUVWLG9FQUE0QjtBQUM1Qiw4QkFBUztBQUEwQiw4QkFBUztBQUFqQyw4QkFBUztBQUF1Qyw4QkFBUztBQUNwRSw4REFBeUI7QUFBRSw4REFBeUI7QUFDcEQsd0RBQXNCO0FBQUUsd0RBQXNCO0FBQzlDLDBDQUFlO0FBQUUsd0NBQWM7QUFBRSw4Q0FBaUI7QUFDbEQsZ0NBQVU7QUE1ZmQsZ0RBQXdCO0FBQ3hCLHVDQUF5QjtBQUN6QixvREFBNEI7QUFDNUIscUNBQXFDO0FBQ3JDLDJDQUE2QztBQWtmekMsK0ZBbGZLLDBCQUFjLE9Ba2ZMO0FBaGZsQjs7Ozs7O0dBTUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzVCLGdGQUFnRjtJQUNoRixNQUFNLE1BQU0sR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDMUUsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQUVELE1BQU0sU0FBUyxHQUFHO0lBQ2QsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDbkQs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