mirror of
https://github.com/swc-project/swc.git
synced 2024-12-22 05:01:42 +03:00
6511 lines
346 KiB
TypeScript
6511 lines
346 KiB
TypeScript
|
class DenoStdInternalError extends Error {
|
|||
|
constructor(message){
|
|||
|
super(message);
|
|||
|
this.name = "DenoStdInternalError";
|
|||
|
}
|
|||
|
}
|
|||
|
function assert(expr, msg = "") {
|
|||
|
if (!expr) {
|
|||
|
throw new DenoStdInternalError(msg);
|
|||
|
}
|
|||
|
}
|
|||
|
function get(obj, key) {
|
|||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|||
|
return obj[key];
|
|||
|
}
|
|||
|
}
|
|||
|
function getForce(obj, key) {
|
|||
|
const v = get(obj, key);
|
|||
|
assert(v != null);
|
|||
|
return v;
|
|||
|
}
|
|||
|
function isNumber(x) {
|
|||
|
if (typeof x === "number") return true;
|
|||
|
if (/^0x[0-9a-f]+$/i.test(String(x))) return true;
|
|||
|
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(String(x));
|
|||
|
}
|
|||
|
function hasKey(obj, keys) {
|
|||
|
let o = obj;
|
|||
|
keys.slice(0, -1).forEach((key)=>{
|
|||
|
o = get(o, key) ?? {
|
|||
|
};
|
|||
|
});
|
|||
|
const key = keys[keys.length - 1];
|
|||
|
return key in o;
|
|||
|
}
|
|||
|
function parse(args, { "--": doubleDash = false , alias ={
|
|||
|
} , boolean: __boolean = false , default: defaults = {
|
|||
|
} , stopEarly =false , string =[] , unknown =(i)=>i
|
|||
|
} = {
|
|||
|
}) {
|
|||
|
const flags = {
|
|||
|
bools: {
|
|||
|
},
|
|||
|
strings: {
|
|||
|
},
|
|||
|
unknownFn: unknown,
|
|||
|
allBools: false
|
|||
|
};
|
|||
|
if (__boolean !== undefined) {
|
|||
|
if (typeof __boolean === "boolean") {
|
|||
|
flags.allBools = !!__boolean;
|
|||
|
} else {
|
|||
|
const booleanArgs = typeof __boolean === "string" ? [
|
|||
|
__boolean
|
|||
|
] : __boolean;
|
|||
|
for (const key of booleanArgs.filter(Boolean)){
|
|||
|
flags.bools[key] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
const aliases = {
|
|||
|
};
|
|||
|
if (alias !== undefined) {
|
|||
|
for(const key in alias){
|
|||
|
const val = getForce(alias, key);
|
|||
|
if (typeof val === "string") {
|
|||
|
aliases[key] = [
|
|||
|
val
|
|||
|
];
|
|||
|
} else {
|
|||
|
aliases[key] = val;
|
|||
|
}
|
|||
|
for (const alias1 of getForce(aliases, key)){
|
|||
|
aliases[alias1] = [
|
|||
|
key
|
|||
|
].concat(aliases[key].filter((y)=>alias1 !== y
|
|||
|
));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (string !== undefined) {
|
|||
|
const stringArgs = typeof string === "string" ? [
|
|||
|
string
|
|||
|
] : string;
|
|||
|
for (const key of stringArgs.filter(Boolean)){
|
|||
|
flags.strings[key] = true;
|
|||
|
const alias1 = get(aliases, key);
|
|||
|
if (alias1) {
|
|||
|
for (const al of alias1){
|
|||
|
flags.strings[al] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
const argv = {
|
|||
|
_: []
|
|||
|
};
|
|||
|
function argDefined(key, arg) {
|
|||
|
return flags.allBools && /^--[^=]+$/.test(arg) || get(flags.bools, key) || !!get(flags.strings, key) || !!get(aliases, key);
|
|||
|
}
|
|||
|
function setKey(obj, keys, value) {
|
|||
|
let o = obj;
|
|||
|
keys.slice(0, -1).forEach(function(key) {
|
|||
|
if (get(o, key) === undefined) {
|
|||
|
o[key] = {
|
|||
|
};
|
|||
|
}
|
|||
|
o = get(o, key);
|
|||
|
});
|
|||
|
const key = keys[keys.length - 1];
|
|||
|
if (get(o, key) === undefined || get(flags.bools, key) || typeof get(o, key) === "boolean") {
|
|||
|
o[key] = value;
|
|||
|
} else if (Array.isArray(get(o, key))) {
|
|||
|
o[key].push(value);
|
|||
|
} else {
|
|||
|
o[key] = [
|
|||
|
get(o, key),
|
|||
|
value
|
|||
|
];
|
|||
|
}
|
|||
|
}
|
|||
|
function setArg(key, val, arg = undefined) {
|
|||
|
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
|||
|
if (flags.unknownFn(arg, key, val) === false) return;
|
|||
|
}
|
|||
|
const value = !get(flags.strings, key) && isNumber(val) ? Number(val) : val;
|
|||
|
setKey(argv, key.split("."), value);
|
|||
|
const alias1 = get(aliases, key);
|
|||
|
if (alias1) {
|
|||
|
for (const x of alias1){
|
|||
|
setKey(argv, x.split("."), value);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
function aliasIsBoolean(key) {
|
|||
|
return getForce(aliases, key).some((x)=>typeof get(flags.bools, x) === "boolean"
|
|||
|
);
|
|||
|
}
|
|||
|
for (const key of Object.keys(flags.bools)){
|
|||
|
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
|||
|
}
|
|||
|
let notFlags = [];
|
|||
|
if (args.includes("--")) {
|
|||
|
notFlags = args.slice(args.indexOf("--") + 1);
|
|||
|
args = args.slice(0, args.indexOf("--"));
|
|||
|
}
|
|||
|
for(let i = 0; i < args.length; i++){
|
|||
|
const arg = args[i];
|
|||
|
if (/^--.+=/.test(arg)) {
|
|||
|
const m = arg.match(/^--([^=]+)=(.*)$/s);
|
|||
|
assert(m != null);
|
|||
|
const [, key1, value] = m;
|
|||
|
if (flags.bools[key1]) {
|
|||
|
const booleanValue = value !== "false";
|
|||
|
setArg(key1, booleanValue, arg);
|
|||
|
} else {
|
|||
|
setArg(key1, value, arg);
|
|||
|
}
|
|||
|
} else if (/^--no-.+/.test(arg)) {
|
|||
|
const m = arg.match(/^--no-(.+)/);
|
|||
|
assert(m != null);
|
|||
|
setArg(m[1], false, arg);
|
|||
|
} else if (/^--.+/.test(arg)) {
|
|||
|
const m = arg.match(/^--(.+)/);
|
|||
|
assert(m != null);
|
|||
|
const [, key1] = m;
|
|||
|
const next = args[i + 1];
|
|||
|
if (next !== undefined && !/^-/.test(next) && !get(flags.bools, key1) && !flags.allBools && (get(aliases, key1) ? !aliasIsBoolean(key1) : true)) {
|
|||
|
setArg(key1, next, arg);
|
|||
|
i++;
|
|||
|
} else if (/^(true|false)$/.test(next)) {
|
|||
|
setArg(key1, next === "true", arg);
|
|||
|
i++;
|
|||
|
} else {
|
|||
|
setArg(key1, get(flags.strings, key1) ? "" : true, arg);
|
|||
|
}
|
|||
|
} else if (/^-[^-]+/.test(arg)) {
|
|||
|
const letters = arg.slice(1, -1).split("");
|
|||
|
let broken = false;
|
|||
|
for(let j = 0; j < letters.length; j++){
|
|||
|
const next = arg.slice(j + 2);
|
|||
|
if (next === "-") {
|
|||
|
setArg(letters[j], next, arg);
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
|||
|
setArg(letters[j], next.split(/=(.+)/)[1], arg);
|
|||
|
broken = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
|||
|
setArg(letters[j], next, arg);
|
|||
|
broken = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
|||
|
setArg(letters[j], arg.slice(j + 2), arg);
|
|||
|
broken = true;
|
|||
|
break;
|
|||
|
} else {
|
|||
|
setArg(letters[j], get(flags.strings, letters[j]) ? "" : true, arg);
|
|||
|
}
|
|||
|
}
|
|||
|
const [key1] = arg.slice(-1);
|
|||
|
if (!broken && key1 !== "-") {
|
|||
|
if (args[i + 1] && !/^(-|--)[^-]/.test(args[i + 1]) && !get(flags.bools, key1) && (get(aliases, key1) ? !aliasIsBoolean(key1) : true)) {
|
|||
|
setArg(key1, args[i + 1], arg);
|
|||
|
i++;
|
|||
|
} else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
|
|||
|
setArg(key1, args[i + 1] === "true", arg);
|
|||
|
i++;
|
|||
|
} else {
|
|||
|
setArg(key1, get(flags.strings, key1) ? "" : true, arg);
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|||
|
argv._.push(flags.strings["_"] ?? !isNumber(arg) ? arg : Number(arg));
|
|||
|
}
|
|||
|
if (stopEarly) {
|
|||
|
argv._.push(...args.slice(i + 1));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
for (const key1 of Object.keys(defaults)){
|
|||
|
if (!hasKey(argv, key1.split("."))) {
|
|||
|
setKey(argv, key1.split("."), defaults[key1]);
|
|||
|
if (aliases[key1]) {
|
|||
|
for (const x of aliases[key1]){
|
|||
|
setKey(argv, x.split("."), defaults[key1]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (doubleDash) {
|
|||
|
argv["--"] = [];
|
|||
|
for (const key2 of notFlags){
|
|||
|
argv["--"].push(key2);
|
|||
|
}
|
|||
|
} else {
|
|||
|
for (const key2 of notFlags){
|
|||
|
argv._.push(key2);
|
|||
|
}
|
|||
|
}
|
|||
|
return argv;
|
|||
|
}
|
|||
|
const mod = function() {
|
|||
|
return {
|
|||
|
parse: parse
|
|||
|
};
|
|||
|
}();
|
|||
|
const CHAR_FORWARD_SLASH = 47;
|
|||
|
let NATIVE_OS = "linux";
|
|||
|
const navigator = globalThis.navigator;
|
|||
|
if (globalThis.Deno != null) {
|
|||
|
NATIVE_OS = Deno.build.os;
|
|||
|
} else if (navigator?.appVersion?.includes?.("Win") ?? false) {
|
|||
|
NATIVE_OS = "windows";
|
|||
|
}
|
|||
|
const isWindows = NATIVE_OS == "windows";
|
|||
|
const SEP = isWindows ? "\\" : "/";
|
|||
|
const SEP_PATTERN = isWindows ? /[\\/]+/ : /\/+/;
|
|||
|
function assertPath(path) {
|
|||
|
if (typeof path !== "string") {
|
|||
|
throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`);
|
|||
|
}
|
|||
|
}
|
|||
|
function isPosixPathSeparator(code) {
|
|||
|
return code === 47;
|
|||
|
}
|
|||
|
function isPathSeparator(code) {
|
|||
|
return isPosixPathSeparator(code) || code === 92;
|
|||
|
}
|
|||
|
function isWindowsDeviceRoot(code) {
|
|||
|
return code >= 97 && code <= 122 || code >= 65 && code <= 90;
|
|||
|
}
|
|||
|
function normalizeString(path, allowAboveRoot, separator, isPathSeparator1) {
|
|||
|
let res = "";
|
|||
|
let lastSegmentLength = 0;
|
|||
|
let lastSlash = -1;
|
|||
|
let dots = 0;
|
|||
|
let code;
|
|||
|
for(let i = 0, len = path.length; i <= len; ++i){
|
|||
|
if (i < len) code = path.charCodeAt(i);
|
|||
|
else if (isPathSeparator1(code)) break;
|
|||
|
else code = CHAR_FORWARD_SLASH;
|
|||
|
if (isPathSeparator1(code)) {
|
|||
|
if (lastSlash === i - 1 || dots === 1) {
|
|||
|
} else if (lastSlash !== i - 1 && dots === 2) {
|
|||
|
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
|
|||
|
if (res.length > 2) {
|
|||
|
const lastSlashIndex = res.lastIndexOf(separator);
|
|||
|
if (lastSlashIndex === -1) {
|
|||
|
res = "";
|
|||
|
lastSegmentLength = 0;
|
|||
|
} else {
|
|||
|
res = res.slice(0, lastSlashIndex);
|
|||
|
lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
|
|||
|
}
|
|||
|
lastSlash = i;
|
|||
|
dots = 0;
|
|||
|
continue;
|
|||
|
} else if (res.length === 2 || res.length === 1) {
|
|||
|
res = "";
|
|||
|
lastSegmentLength = 0;
|
|||
|
lastSlash = i;
|
|||
|
dots = 0;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
if (allowAboveRoot) {
|
|||
|
if (res.length > 0) res += `${separator}..`;
|
|||
|
else res = "..";
|
|||
|
lastSegmentLength = 2;
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
|
|||
|
else res = path.slice(lastSlash + 1, i);
|
|||
|
lastSegmentLength = i - lastSlash - 1;
|
|||
|
}
|
|||
|
lastSlash = i;
|
|||
|
dots = 0;
|
|||
|
} else if (code === 46 && dots !== -1) {
|
|||
|
++dots;
|
|||
|
} else {
|
|||
|
dots = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
function _format(sep, pathObject) {
|
|||
|
const dir = pathObject.dir || pathObject.root;
|
|||
|
const base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|||
|
if (!dir) return base;
|
|||
|
if (dir === pathObject.root) return dir + base;
|
|||
|
return dir + sep + base;
|
|||
|
}
|
|||
|
const sep = "\\";
|
|||
|
const delimiter = ";";
|
|||
|
function resolve(...pathSegments) {
|
|||
|
let resolvedDevice = "";
|
|||
|
let resolvedTail = "";
|
|||
|
let resolvedAbsolute = false;
|
|||
|
for(let i = pathSegments.length - 1; i >= -1; i--){
|
|||
|
let path;
|
|||
|
if (i >= 0) {
|
|||
|
path = pathSegments[i];
|
|||
|
} else if (!resolvedDevice) {
|
|||
|
if (globalThis.Deno == null) {
|
|||
|
throw new TypeError("Resolved a drive-letter-less path without a CWD.");
|
|||
|
}
|
|||
|
path = Deno.cwd();
|
|||
|
} else {
|
|||
|
if (globalThis.Deno == null) {
|
|||
|
throw new TypeError("Resolved a relative path without a CWD.");
|
|||
|
}
|
|||
|
path = Deno.env.get(`=${resolvedDevice}`) || Deno.cwd();
|
|||
|
if (path === undefined || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) {
|
|||
|
path = `${resolvedDevice}\\`;
|
|||
|
}
|
|||
|
}
|
|||
|
assertPath(path);
|
|||
|
const len = path.length;
|
|||
|
if (len === 0) continue;
|
|||
|
let rootEnd = 0;
|
|||
|
let device = "";
|
|||
|
let isAbsolute = false;
|
|||
|
const code = path.charCodeAt(0);
|
|||
|
if (len > 1) {
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
isAbsolute = true;
|
|||
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|||
|
let j = 2;
|
|||
|
let last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
const firstPart = path.slice(last, j);
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (!isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j === len) {
|
|||
|
device = `\\\\${firstPart}\\${path.slice(last)}`;
|
|||
|
rootEnd = j;
|
|||
|
} else if (j !== last) {
|
|||
|
device = `\\\\${firstPart}\\${path.slice(last, j)}`;
|
|||
|
rootEnd = j;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
rootEnd = 1;
|
|||
|
}
|
|||
|
} else if (isWindowsDeviceRoot(code)) {
|
|||
|
if (path.charCodeAt(1) === 58) {
|
|||
|
device = path.slice(0, 2);
|
|||
|
rootEnd = 2;
|
|||
|
if (len > 2) {
|
|||
|
if (isPathSeparator(path.charCodeAt(2))) {
|
|||
|
isAbsolute = true;
|
|||
|
rootEnd = 3;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isPathSeparator(code)) {
|
|||
|
rootEnd = 1;
|
|||
|
isAbsolute = true;
|
|||
|
}
|
|||
|
if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (resolvedDevice.length === 0 && device.length > 0) {
|
|||
|
resolvedDevice = device;
|
|||
|
}
|
|||
|
if (!resolvedAbsolute) {
|
|||
|
resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
|
|||
|
resolvedAbsolute = isAbsolute;
|
|||
|
}
|
|||
|
if (resolvedAbsolute && resolvedDevice.length > 0) break;
|
|||
|
}
|
|||
|
resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator);
|
|||
|
return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || ".";
|
|||
|
}
|
|||
|
function normalize(path) {
|
|||
|
assertPath(path);
|
|||
|
const len = path.length;
|
|||
|
if (len === 0) return ".";
|
|||
|
let rootEnd = 0;
|
|||
|
let device;
|
|||
|
let isAbsolute = false;
|
|||
|
const code = path.charCodeAt(0);
|
|||
|
if (len > 1) {
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
isAbsolute = true;
|
|||
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|||
|
let j = 2;
|
|||
|
let last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
const firstPart = path.slice(last, j);
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (!isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j === len) {
|
|||
|
return `\\\\${firstPart}\\${path.slice(last)}\\`;
|
|||
|
} else if (j !== last) {
|
|||
|
device = `\\\\${firstPart}\\${path.slice(last, j)}`;
|
|||
|
rootEnd = j;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
rootEnd = 1;
|
|||
|
}
|
|||
|
} else if (isWindowsDeviceRoot(code)) {
|
|||
|
if (path.charCodeAt(1) === 58) {
|
|||
|
device = path.slice(0, 2);
|
|||
|
rootEnd = 2;
|
|||
|
if (len > 2) {
|
|||
|
if (isPathSeparator(path.charCodeAt(2))) {
|
|||
|
isAbsolute = true;
|
|||
|
rootEnd = 3;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isPathSeparator(code)) {
|
|||
|
return "\\";
|
|||
|
}
|
|||
|
let tail;
|
|||
|
if (rootEnd < len) {
|
|||
|
tail = normalizeString(path.slice(rootEnd), !isAbsolute, "\\", isPathSeparator);
|
|||
|
} else {
|
|||
|
tail = "";
|
|||
|
}
|
|||
|
if (tail.length === 0 && !isAbsolute) tail = ".";
|
|||
|
if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) {
|
|||
|
tail += "\\";
|
|||
|
}
|
|||
|
if (device === undefined) {
|
|||
|
if (isAbsolute) {
|
|||
|
if (tail.length > 0) return `\\${tail}`;
|
|||
|
else return "\\";
|
|||
|
} else if (tail.length > 0) {
|
|||
|
return tail;
|
|||
|
} else {
|
|||
|
return "";
|
|||
|
}
|
|||
|
} else if (isAbsolute) {
|
|||
|
if (tail.length > 0) return `${device}\\${tail}`;
|
|||
|
else return `${device}\\`;
|
|||
|
} else if (tail.length > 0) {
|
|||
|
return device + tail;
|
|||
|
} else {
|
|||
|
return device;
|
|||
|
}
|
|||
|
}
|
|||
|
function isAbsolute(path) {
|
|||
|
assertPath(path);
|
|||
|
const len = path.length;
|
|||
|
if (len === 0) return false;
|
|||
|
const code = path.charCodeAt(0);
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
return true;
|
|||
|
} else if (isWindowsDeviceRoot(code)) {
|
|||
|
if (len > 2 && path.charCodeAt(1) === 58) {
|
|||
|
if (isPathSeparator(path.charCodeAt(2))) return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
function join(...paths) {
|
|||
|
const pathsCount = paths.length;
|
|||
|
if (pathsCount === 0) return ".";
|
|||
|
let joined;
|
|||
|
let firstPart = null;
|
|||
|
for(let i = 0; i < pathsCount; ++i){
|
|||
|
const path = paths[i];
|
|||
|
assertPath(path);
|
|||
|
if (path.length > 0) {
|
|||
|
if (joined === undefined) joined = firstPart = path;
|
|||
|
else joined += `\\${path}`;
|
|||
|
}
|
|||
|
}
|
|||
|
if (joined === undefined) return ".";
|
|||
|
let needsReplace = true;
|
|||
|
let slashCount = 0;
|
|||
|
assert(firstPart != null);
|
|||
|
if (isPathSeparator(firstPart.charCodeAt(0))) {
|
|||
|
++slashCount;
|
|||
|
const firstLen = firstPart.length;
|
|||
|
if (firstLen > 1) {
|
|||
|
if (isPathSeparator(firstPart.charCodeAt(1))) {
|
|||
|
++slashCount;
|
|||
|
if (firstLen > 2) {
|
|||
|
if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount;
|
|||
|
else {
|
|||
|
needsReplace = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (needsReplace) {
|
|||
|
for(; slashCount < joined.length; ++slashCount){
|
|||
|
if (!isPathSeparator(joined.charCodeAt(slashCount))) break;
|
|||
|
}
|
|||
|
if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`;
|
|||
|
}
|
|||
|
return normalize(joined);
|
|||
|
}
|
|||
|
function relative(from, to) {
|
|||
|
assertPath(from);
|
|||
|
assertPath(to);
|
|||
|
if (from === to) return "";
|
|||
|
const fromOrig = resolve(from);
|
|||
|
const toOrig = resolve(to);
|
|||
|
if (fromOrig === toOrig) return "";
|
|||
|
from = fromOrig.toLowerCase();
|
|||
|
to = toOrig.toLowerCase();
|
|||
|
if (from === to) return "";
|
|||
|
let fromStart = 0;
|
|||
|
let fromEnd = from.length;
|
|||
|
for(; fromStart < fromEnd; ++fromStart){
|
|||
|
if (from.charCodeAt(fromStart) !== 92) break;
|
|||
|
}
|
|||
|
for(; fromEnd - 1 > fromStart; --fromEnd){
|
|||
|
if (from.charCodeAt(fromEnd - 1) !== 92) break;
|
|||
|
}
|
|||
|
const fromLen = fromEnd - fromStart;
|
|||
|
let toStart = 0;
|
|||
|
let toEnd = to.length;
|
|||
|
for(; toStart < toEnd; ++toStart){
|
|||
|
if (to.charCodeAt(toStart) !== 92) break;
|
|||
|
}
|
|||
|
for(; toEnd - 1 > toStart; --toEnd){
|
|||
|
if (to.charCodeAt(toEnd - 1) !== 92) break;
|
|||
|
}
|
|||
|
const toLen = toEnd - toStart;
|
|||
|
const length = fromLen < toLen ? fromLen : toLen;
|
|||
|
let lastCommonSep = -1;
|
|||
|
let i = 0;
|
|||
|
for(; i <= length; ++i){
|
|||
|
if (i === length) {
|
|||
|
if (toLen > length) {
|
|||
|
if (to.charCodeAt(toStart + i) === 92) {
|
|||
|
return toOrig.slice(toStart + i + 1);
|
|||
|
} else if (i === 2) {
|
|||
|
return toOrig.slice(toStart + i);
|
|||
|
}
|
|||
|
}
|
|||
|
if (fromLen > length) {
|
|||
|
if (from.charCodeAt(fromStart + i) === 92) {
|
|||
|
lastCommonSep = i;
|
|||
|
} else if (i === 2) {
|
|||
|
lastCommonSep = 3;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
const fromCode = from.charCodeAt(fromStart + i);
|
|||
|
const toCode = to.charCodeAt(toStart + i);
|
|||
|
if (fromCode !== toCode) break;
|
|||
|
else if (fromCode === 92) lastCommonSep = i;
|
|||
|
}
|
|||
|
if (i !== length && lastCommonSep === -1) {
|
|||
|
return toOrig;
|
|||
|
}
|
|||
|
let out = "";
|
|||
|
if (lastCommonSep === -1) lastCommonSep = 0;
|
|||
|
for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){
|
|||
|
if (i === fromEnd || from.charCodeAt(i) === 92) {
|
|||
|
if (out.length === 0) out += "..";
|
|||
|
else out += "\\..";
|
|||
|
}
|
|||
|
}
|
|||
|
if (out.length > 0) {
|
|||
|
return out + toOrig.slice(toStart + lastCommonSep, toEnd);
|
|||
|
} else {
|
|||
|
toStart += lastCommonSep;
|
|||
|
if (toOrig.charCodeAt(toStart) === 92) ++toStart;
|
|||
|
return toOrig.slice(toStart, toEnd);
|
|||
|
}
|
|||
|
}
|
|||
|
function toNamespacedPath(path) {
|
|||
|
if (typeof path !== "string") return path;
|
|||
|
if (path.length === 0) return "";
|
|||
|
const resolvedPath = resolve(path);
|
|||
|
if (resolvedPath.length >= 3) {
|
|||
|
if (resolvedPath.charCodeAt(0) === 92) {
|
|||
|
if (resolvedPath.charCodeAt(1) === 92) {
|
|||
|
const code = resolvedPath.charCodeAt(2);
|
|||
|
if (code !== 63 && code !== 46) {
|
|||
|
return `\\\\?\\UNC\\${resolvedPath.slice(2)}`;
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0))) {
|
|||
|
if (resolvedPath.charCodeAt(1) === 58 && resolvedPath.charCodeAt(2) === 92) {
|
|||
|
return `\\\\?\\${resolvedPath}`;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return path;
|
|||
|
}
|
|||
|
function dirname(path) {
|
|||
|
assertPath(path);
|
|||
|
const len = path.length;
|
|||
|
if (len === 0) return ".";
|
|||
|
let rootEnd = -1;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let offset = 0;
|
|||
|
const code = path.charCodeAt(0);
|
|||
|
if (len > 1) {
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
rootEnd = offset = 1;
|
|||
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|||
|
let j = 2;
|
|||
|
let last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (!isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j === len) {
|
|||
|
return path;
|
|||
|
}
|
|||
|
if (j !== last) {
|
|||
|
rootEnd = offset = j + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isWindowsDeviceRoot(code)) {
|
|||
|
if (path.charCodeAt(1) === 58) {
|
|||
|
rootEnd = offset = 2;
|
|||
|
if (len > 2) {
|
|||
|
if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isPathSeparator(code)) {
|
|||
|
return path;
|
|||
|
}
|
|||
|
for(let i = len - 1; i >= offset; --i){
|
|||
|
if (isPathSeparator(path.charCodeAt(i))) {
|
|||
|
if (!matchedSlash) {
|
|||
|
end = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
matchedSlash = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (end === -1) {
|
|||
|
if (rootEnd === -1) return ".";
|
|||
|
else end = rootEnd;
|
|||
|
}
|
|||
|
return path.slice(0, end);
|
|||
|
}
|
|||
|
function basename(path, ext = "") {
|
|||
|
if (ext !== undefined && typeof ext !== "string") {
|
|||
|
throw new TypeError('"ext" argument must be a string');
|
|||
|
}
|
|||
|
assertPath(path);
|
|||
|
let start = 0;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let i;
|
|||
|
if (path.length >= 2) {
|
|||
|
const drive = path.charCodeAt(0);
|
|||
|
if (isWindowsDeviceRoot(drive)) {
|
|||
|
if (path.charCodeAt(1) === 58) start = 2;
|
|||
|
}
|
|||
|
}
|
|||
|
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|||
|
if (ext.length === path.length && ext === path) return "";
|
|||
|
let extIdx = ext.length - 1;
|
|||
|
let firstNonSlashEnd = -1;
|
|||
|
for(i = path.length - 1; i >= start; --i){
|
|||
|
const code = path.charCodeAt(i);
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
if (!matchedSlash) {
|
|||
|
start = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (firstNonSlashEnd === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
firstNonSlashEnd = i + 1;
|
|||
|
}
|
|||
|
if (extIdx >= 0) {
|
|||
|
if (code === ext.charCodeAt(extIdx)) {
|
|||
|
if ((--extIdx) === -1) {
|
|||
|
end = i;
|
|||
|
}
|
|||
|
} else {
|
|||
|
extIdx = -1;
|
|||
|
end = firstNonSlashEnd;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (start === end) end = firstNonSlashEnd;
|
|||
|
else if (end === -1) end = path.length;
|
|||
|
return path.slice(start, end);
|
|||
|
} else {
|
|||
|
for(i = path.length - 1; i >= start; --i){
|
|||
|
if (isPathSeparator(path.charCodeAt(i))) {
|
|||
|
if (!matchedSlash) {
|
|||
|
start = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (end === -1) return "";
|
|||
|
return path.slice(start, end);
|
|||
|
}
|
|||
|
}
|
|||
|
function extname(path) {
|
|||
|
assertPath(path);
|
|||
|
let start = 0;
|
|||
|
let startDot = -1;
|
|||
|
let startPart = 0;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let preDotState = 0;
|
|||
|
if (path.length >= 2 && path.charCodeAt(1) === 58 && isWindowsDeviceRoot(path.charCodeAt(0))) {
|
|||
|
start = startPart = 2;
|
|||
|
}
|
|||
|
for(let i = path.length - 1; i >= start; --i){
|
|||
|
const code = path.charCodeAt(i);
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
if (!matchedSlash) {
|
|||
|
startPart = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
if (code === 46) {
|
|||
|
if (startDot === -1) startDot = i;
|
|||
|
else if (preDotState !== 1) preDotState = 1;
|
|||
|
} else if (startDot !== -1) {
|
|||
|
preDotState = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
return path.slice(startDot, end);
|
|||
|
}
|
|||
|
function format4(pathObject) {
|
|||
|
if (pathObject === null || typeof pathObject !== "object") {
|
|||
|
throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`);
|
|||
|
}
|
|||
|
return _format("\\", pathObject);
|
|||
|
}
|
|||
|
function parse1(path) {
|
|||
|
assertPath(path);
|
|||
|
const ret = {
|
|||
|
root: "",
|
|||
|
dir: "",
|
|||
|
base: "",
|
|||
|
ext: "",
|
|||
|
name: ""
|
|||
|
};
|
|||
|
const len = path.length;
|
|||
|
if (len === 0) return ret;
|
|||
|
let rootEnd = 0;
|
|||
|
let code = path.charCodeAt(0);
|
|||
|
if (len > 1) {
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
rootEnd = 1;
|
|||
|
if (isPathSeparator(path.charCodeAt(1))) {
|
|||
|
let j = 2;
|
|||
|
let last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (!isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j < len && j !== last) {
|
|||
|
last = j;
|
|||
|
for(; j < len; ++j){
|
|||
|
if (isPathSeparator(path.charCodeAt(j))) break;
|
|||
|
}
|
|||
|
if (j === len) {
|
|||
|
rootEnd = j;
|
|||
|
} else if (j !== last) {
|
|||
|
rootEnd = j + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isWindowsDeviceRoot(code)) {
|
|||
|
if (path.charCodeAt(1) === 58) {
|
|||
|
rootEnd = 2;
|
|||
|
if (len > 2) {
|
|||
|
if (isPathSeparator(path.charCodeAt(2))) {
|
|||
|
if (len === 3) {
|
|||
|
ret.root = ret.dir = path;
|
|||
|
return ret;
|
|||
|
}
|
|||
|
rootEnd = 3;
|
|||
|
}
|
|||
|
} else {
|
|||
|
ret.root = ret.dir = path;
|
|||
|
return ret;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (isPathSeparator(code)) {
|
|||
|
ret.root = ret.dir = path;
|
|||
|
return ret;
|
|||
|
}
|
|||
|
if (rootEnd > 0) ret.root = path.slice(0, rootEnd);
|
|||
|
let startDot = -1;
|
|||
|
let startPart = rootEnd;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let i = path.length - 1;
|
|||
|
let preDotState = 0;
|
|||
|
for(; i >= rootEnd; --i){
|
|||
|
code = path.charCodeAt(i);
|
|||
|
if (isPathSeparator(code)) {
|
|||
|
if (!matchedSlash) {
|
|||
|
startPart = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
if (code === 46) {
|
|||
|
if (startDot === -1) startDot = i;
|
|||
|
else if (preDotState !== 1) preDotState = 1;
|
|||
|
} else if (startDot !== -1) {
|
|||
|
preDotState = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|||
|
if (end !== -1) {
|
|||
|
ret.base = ret.name = path.slice(startPart, end);
|
|||
|
}
|
|||
|
} else {
|
|||
|
ret.name = path.slice(startPart, startDot);
|
|||
|
ret.base = path.slice(startPart, end);
|
|||
|
ret.ext = path.slice(startDot, end);
|
|||
|
}
|
|||
|
if (startPart > 0 && startPart !== rootEnd) {
|
|||
|
ret.dir = path.slice(0, startPart - 1);
|
|||
|
} else ret.dir = ret.root;
|
|||
|
return ret;
|
|||
|
}
|
|||
|
function fromFileUrl(url) {
|
|||
|
url = url instanceof URL ? url : new URL(url);
|
|||
|
if (url.protocol != "file:") {
|
|||
|
throw new TypeError("Must be a file URL.");
|
|||
|
}
|
|||
|
let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
|
|||
|
if (url.hostname != "") {
|
|||
|
path = `\\\\${url.hostname}${path}`;
|
|||
|
}
|
|||
|
return path;
|
|||
|
}
|
|||
|
function toFileUrl(path) {
|
|||
|
if (!isAbsolute(path)) {
|
|||
|
throw new TypeError("Must be an absolute path.");
|
|||
|
}
|
|||
|
const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\][^/\\]))?(.*)/);
|
|||
|
const url = new URL("file:///");
|
|||
|
url.pathname = pathname.replace(/%/g, "%25");
|
|||
|
if (hostname != null) {
|
|||
|
url.hostname = hostname;
|
|||
|
if (!url.hostname) {
|
|||
|
throw new TypeError("Invalid hostname.");
|
|||
|
}
|
|||
|
}
|
|||
|
return url;
|
|||
|
}
|
|||
|
const mod1 = function() {
|
|||
|
return {
|
|||
|
sep: sep,
|
|||
|
delimiter: delimiter,
|
|||
|
resolve: resolve,
|
|||
|
normalize: normalize,
|
|||
|
isAbsolute: isAbsolute,
|
|||
|
join: join,
|
|||
|
relative: relative,
|
|||
|
toNamespacedPath: toNamespacedPath,
|
|||
|
dirname: dirname,
|
|||
|
basename: basename,
|
|||
|
extname: extname,
|
|||
|
format: format4,
|
|||
|
parse: parse1,
|
|||
|
fromFileUrl: fromFileUrl,
|
|||
|
toFileUrl: toFileUrl
|
|||
|
};
|
|||
|
}();
|
|||
|
const sep1 = "/";
|
|||
|
const delimiter1 = ":";
|
|||
|
function resolve1(...pathSegments) {
|
|||
|
let resolvedPath = "";
|
|||
|
let resolvedAbsolute = false;
|
|||
|
for(let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--){
|
|||
|
let path;
|
|||
|
if (i >= 0) path = pathSegments[i];
|
|||
|
else {
|
|||
|
if (globalThis.Deno == null) {
|
|||
|
throw new TypeError("Resolved a relative path without a CWD.");
|
|||
|
}
|
|||
|
path = Deno.cwd();
|
|||
|
}
|
|||
|
assertPath(path);
|
|||
|
if (path.length === 0) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
resolvedPath = `${path}/${resolvedPath}`;
|
|||
|
resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
|
|||
|
}
|
|||
|
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator);
|
|||
|
if (resolvedAbsolute) {
|
|||
|
if (resolvedPath.length > 0) return `/${resolvedPath}`;
|
|||
|
else return "/";
|
|||
|
} else if (resolvedPath.length > 0) return resolvedPath;
|
|||
|
else return ".";
|
|||
|
}
|
|||
|
function normalize1(path) {
|
|||
|
assertPath(path);
|
|||
|
if (path.length === 0) return ".";
|
|||
|
const isAbsolute1 = path.charCodeAt(0) === 47;
|
|||
|
const trailingSeparator = path.charCodeAt(path.length - 1) === 47;
|
|||
|
path = normalizeString(path, !isAbsolute1, "/", isPosixPathSeparator);
|
|||
|
if (path.length === 0 && !isAbsolute1) path = ".";
|
|||
|
if (path.length > 0 && trailingSeparator) path += "/";
|
|||
|
if (isAbsolute1) return `/${path}`;
|
|||
|
return path;
|
|||
|
}
|
|||
|
function isAbsolute1(path) {
|
|||
|
assertPath(path);
|
|||
|
return path.length > 0 && path.charCodeAt(0) === 47;
|
|||
|
}
|
|||
|
function join1(...paths) {
|
|||
|
if (paths.length === 0) return ".";
|
|||
|
let joined;
|
|||
|
for(let i = 0, len = paths.length; i < len; ++i){
|
|||
|
const path = paths[i];
|
|||
|
assertPath(path);
|
|||
|
if (path.length > 0) {
|
|||
|
if (!joined) joined = path;
|
|||
|
else joined += `/${path}`;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!joined) return ".";
|
|||
|
return normalize1(joined);
|
|||
|
}
|
|||
|
function relative1(from, to) {
|
|||
|
assertPath(from);
|
|||
|
assertPath(to);
|
|||
|
if (from === to) return "";
|
|||
|
from = resolve1(from);
|
|||
|
to = resolve1(to);
|
|||
|
if (from === to) return "";
|
|||
|
let fromStart = 1;
|
|||
|
const fromEnd = from.length;
|
|||
|
for(; fromStart < fromEnd; ++fromStart){
|
|||
|
if (from.charCodeAt(fromStart) !== 47) break;
|
|||
|
}
|
|||
|
const fromLen = fromEnd - fromStart;
|
|||
|
let toStart = 1;
|
|||
|
const toEnd = to.length;
|
|||
|
for(; toStart < toEnd; ++toStart){
|
|||
|
if (to.charCodeAt(toStart) !== 47) break;
|
|||
|
}
|
|||
|
const toLen = toEnd - toStart;
|
|||
|
const length = fromLen < toLen ? fromLen : toLen;
|
|||
|
let lastCommonSep = -1;
|
|||
|
let i = 0;
|
|||
|
for(; i <= length; ++i){
|
|||
|
if (i === length) {
|
|||
|
if (toLen > length) {
|
|||
|
if (to.charCodeAt(toStart + i) === 47) {
|
|||
|
return to.slice(toStart + i + 1);
|
|||
|
} else if (i === 0) {
|
|||
|
return to.slice(toStart + i);
|
|||
|
}
|
|||
|
} else if (fromLen > length) {
|
|||
|
if (from.charCodeAt(fromStart + i) === 47) {
|
|||
|
lastCommonSep = i;
|
|||
|
} else if (i === 0) {
|
|||
|
lastCommonSep = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
const fromCode = from.charCodeAt(fromStart + i);
|
|||
|
const toCode = to.charCodeAt(toStart + i);
|
|||
|
if (fromCode !== toCode) break;
|
|||
|
else if (fromCode === 47) lastCommonSep = i;
|
|||
|
}
|
|||
|
let out = "";
|
|||
|
for(i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i){
|
|||
|
if (i === fromEnd || from.charCodeAt(i) === 47) {
|
|||
|
if (out.length === 0) out += "..";
|
|||
|
else out += "/..";
|
|||
|
}
|
|||
|
}
|
|||
|
if (out.length > 0) return out + to.slice(toStart + lastCommonSep);
|
|||
|
else {
|
|||
|
toStart += lastCommonSep;
|
|||
|
if (to.charCodeAt(toStart) === 47) ++toStart;
|
|||
|
return to.slice(toStart);
|
|||
|
}
|
|||
|
}
|
|||
|
function toNamespacedPath1(path) {
|
|||
|
return path;
|
|||
|
}
|
|||
|
function dirname1(path) {
|
|||
|
assertPath(path);
|
|||
|
if (path.length === 0) return ".";
|
|||
|
const hasRoot = path.charCodeAt(0) === 47;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
for(let i = path.length - 1; i >= 1; --i){
|
|||
|
if (path.charCodeAt(i) === 47) {
|
|||
|
if (!matchedSlash) {
|
|||
|
end = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
matchedSlash = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (end === -1) return hasRoot ? "/" : ".";
|
|||
|
if (hasRoot && end === 1) return "//";
|
|||
|
return path.slice(0, end);
|
|||
|
}
|
|||
|
function basename1(path, ext = "") {
|
|||
|
if (ext !== undefined && typeof ext !== "string") {
|
|||
|
throw new TypeError('"ext" argument must be a string');
|
|||
|
}
|
|||
|
assertPath(path);
|
|||
|
let start = 0;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let i;
|
|||
|
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|||
|
if (ext.length === path.length && ext === path) return "";
|
|||
|
let extIdx = ext.length - 1;
|
|||
|
let firstNonSlashEnd = -1;
|
|||
|
for(i = path.length - 1; i >= 0; --i){
|
|||
|
const code = path.charCodeAt(i);
|
|||
|
if (code === 47) {
|
|||
|
if (!matchedSlash) {
|
|||
|
start = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (firstNonSlashEnd === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
firstNonSlashEnd = i + 1;
|
|||
|
}
|
|||
|
if (extIdx >= 0) {
|
|||
|
if (code === ext.charCodeAt(extIdx)) {
|
|||
|
if ((--extIdx) === -1) {
|
|||
|
end = i;
|
|||
|
}
|
|||
|
} else {
|
|||
|
extIdx = -1;
|
|||
|
end = firstNonSlashEnd;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (start === end) end = firstNonSlashEnd;
|
|||
|
else if (end === -1) end = path.length;
|
|||
|
return path.slice(start, end);
|
|||
|
} else {
|
|||
|
for(i = path.length - 1; i >= 0; --i){
|
|||
|
if (path.charCodeAt(i) === 47) {
|
|||
|
if (!matchedSlash) {
|
|||
|
start = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (end === -1) return "";
|
|||
|
return path.slice(start, end);
|
|||
|
}
|
|||
|
}
|
|||
|
function extname1(path) {
|
|||
|
assertPath(path);
|
|||
|
let startDot = -1;
|
|||
|
let startPart = 0;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let preDotState = 0;
|
|||
|
for(let i = path.length - 1; i >= 0; --i){
|
|||
|
const code = path.charCodeAt(i);
|
|||
|
if (code === 47) {
|
|||
|
if (!matchedSlash) {
|
|||
|
startPart = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
if (code === 46) {
|
|||
|
if (startDot === -1) startDot = i;
|
|||
|
else if (preDotState !== 1) preDotState = 1;
|
|||
|
} else if (startDot !== -1) {
|
|||
|
preDotState = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
return path.slice(startDot, end);
|
|||
|
}
|
|||
|
function format1(pathObject) {
|
|||
|
if (pathObject === null || typeof pathObject !== "object") {
|
|||
|
throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`);
|
|||
|
}
|
|||
|
return _format("/", pathObject);
|
|||
|
}
|
|||
|
function parse2(path) {
|
|||
|
assertPath(path);
|
|||
|
const ret = {
|
|||
|
root: "",
|
|||
|
dir: "",
|
|||
|
base: "",
|
|||
|
ext: "",
|
|||
|
name: ""
|
|||
|
};
|
|||
|
if (path.length === 0) return ret;
|
|||
|
const isAbsolute2 = path.charCodeAt(0) === 47;
|
|||
|
let start;
|
|||
|
if (isAbsolute2) {
|
|||
|
ret.root = "/";
|
|||
|
start = 1;
|
|||
|
} else {
|
|||
|
start = 0;
|
|||
|
}
|
|||
|
let startDot = -1;
|
|||
|
let startPart = 0;
|
|||
|
let end = -1;
|
|||
|
let matchedSlash = true;
|
|||
|
let i = path.length - 1;
|
|||
|
let preDotState = 0;
|
|||
|
for(; i >= start; --i){
|
|||
|
const code = path.charCodeAt(i);
|
|||
|
if (code === 47) {
|
|||
|
if (!matchedSlash) {
|
|||
|
startPart = i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (end === -1) {
|
|||
|
matchedSlash = false;
|
|||
|
end = i + 1;
|
|||
|
}
|
|||
|
if (code === 46) {
|
|||
|
if (startDot === -1) startDot = i;
|
|||
|
else if (preDotState !== 1) preDotState = 1;
|
|||
|
} else if (startDot !== -1) {
|
|||
|
preDotState = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|||
|
if (end !== -1) {
|
|||
|
if (startPart === 0 && isAbsolute2) {
|
|||
|
ret.base = ret.name = path.slice(1, end);
|
|||
|
} else {
|
|||
|
ret.base = ret.name = path.slice(startPart, end);
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (startPart === 0 && isAbsolute2) {
|
|||
|
ret.name = path.slice(1, startDot);
|
|||
|
ret.base = path.slice(1, end);
|
|||
|
} else {
|
|||
|
ret.name = path.slice(startPart, startDot);
|
|||
|
ret.base = path.slice(startPart, end);
|
|||
|
}
|
|||
|
ret.ext = path.slice(startDot, end);
|
|||
|
}
|
|||
|
if (startPart > 0) ret.dir = path.slice(0, startPart - 1);
|
|||
|
else if (isAbsolute2) ret.dir = "/";
|
|||
|
return ret;
|
|||
|
}
|
|||
|
function fromFileUrl1(url) {
|
|||
|
url = url instanceof URL ? url : new URL(url);
|
|||
|
if (url.protocol != "file:") {
|
|||
|
throw new TypeError("Must be a file URL.");
|
|||
|
}
|
|||
|
return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"));
|
|||
|
}
|
|||
|
function toFileUrl1(path) {
|
|||
|
if (!isAbsolute1(path)) {
|
|||
|
throw new TypeError("Must be an absolute path.");
|
|||
|
}
|
|||
|
const url = new URL("file:///");
|
|||
|
url.pathname = path.replace(/%/g, "%25").replace(/\\/g, "%5C");
|
|||
|
return url;
|
|||
|
}
|
|||
|
const mod2 = function() {
|
|||
|
return {
|
|||
|
sep: sep1,
|
|||
|
delimiter: delimiter1,
|
|||
|
resolve: resolve1,
|
|||
|
normalize: normalize1,
|
|||
|
isAbsolute: isAbsolute1,
|
|||
|
join: join1,
|
|||
|
relative: relative1,
|
|||
|
toNamespacedPath: toNamespacedPath1,
|
|||
|
dirname: dirname1,
|
|||
|
basename: basename1,
|
|||
|
extname: extname1,
|
|||
|
format: format1,
|
|||
|
parse: parse2,
|
|||
|
fromFileUrl: fromFileUrl1,
|
|||
|
toFileUrl: toFileUrl1
|
|||
|
};
|
|||
|
}();
|
|||
|
function common(paths, sep2 = SEP) {
|
|||
|
const [first = "", ...remaining] = paths;
|
|||
|
if (first === "" || remaining.length === 0) {
|
|||
|
return first.substring(0, first.lastIndexOf(sep2) + 1);
|
|||
|
}
|
|||
|
const parts = first.split(sep2);
|
|||
|
let endOfPrefix = parts.length;
|
|||
|
for (const path of remaining){
|
|||
|
const compare = path.split(sep2);
|
|||
|
for(let i = 0; i < endOfPrefix; i++){
|
|||
|
if (compare[i] !== parts[i]) {
|
|||
|
endOfPrefix = i;
|
|||
|
}
|
|||
|
}
|
|||
|
if (endOfPrefix === 0) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
}
|
|||
|
const prefix = parts.slice(0, endOfPrefix).join(sep2);
|
|||
|
return prefix.endsWith(sep2) ? prefix : `${prefix}${sep2}`;
|
|||
|
}
|
|||
|
const path1 = isWindows ? mod1 : mod2;
|
|||
|
const regExpEscapeChars = [
|
|||
|
"!",
|
|||
|
"$",
|
|||
|
"(",
|
|||
|
")",
|
|||
|
"*",
|
|||
|
"+",
|
|||
|
".",
|
|||
|
"=",
|
|||
|
"?",
|
|||
|
"[",
|
|||
|
"\\",
|
|||
|
"^",
|
|||
|
"{",
|
|||
|
"|"
|
|||
|
];
|
|||
|
const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join2 , normalize: normalize2 , parse: parse3 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 , } = path1;
|
|||
|
const rangeEscapeChars = [
|
|||
|
"-",
|
|||
|
"\\",
|
|||
|
"]"
|
|||
|
];
|
|||
|
function globToRegExp(glob, { extended =true , globstar: globstarOption = true , os =NATIVE_OS } = {
|
|||
|
}) {
|
|||
|
if (glob == "") {
|
|||
|
return /(?!)/;
|
|||
|
}
|
|||
|
const sep3 = os == "windows" ? "(?:\\\\|/)+" : "/+";
|
|||
|
const sepMaybe = os == "windows" ? "(?:\\\\|/)*" : "/*";
|
|||
|
const seps = os == "windows" ? [
|
|||
|
"\\",
|
|||
|
"/"
|
|||
|
] : [
|
|||
|
"/"
|
|||
|
];
|
|||
|
const globstar = os == "windows" ? "(?:[^\\\\/]*(?:\\\\|/|$)+)*" : "(?:[^/]*(?:/|$)+)*";
|
|||
|
const wildcard = os == "windows" ? "[^\\\\/]*" : "[^/]*";
|
|||
|
const escapePrefix = os == "windows" ? "`" : "\\";
|
|||
|
let newLength = glob.length;
|
|||
|
for(; newLength > 1 && seps.includes(glob[newLength - 1]); newLength--);
|
|||
|
glob = glob.slice(0, newLength);
|
|||
|
let regExpString = "";
|
|||
|
for(let j = 0; j < glob.length;){
|
|||
|
let segment = "";
|
|||
|
const groupStack = [];
|
|||
|
let inRange = false;
|
|||
|
let inEscape = false;
|
|||
|
let endsWithSep = false;
|
|||
|
let i = j;
|
|||
|
for(; i < glob.length && !seps.includes(glob[i]); i++){
|
|||
|
if (inEscape) {
|
|||
|
inEscape = false;
|
|||
|
const escapeChars = inRange ? rangeEscapeChars : regExpEscapeChars;
|
|||
|
segment += escapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == escapePrefix) {
|
|||
|
inEscape = true;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "[") {
|
|||
|
if (!inRange) {
|
|||
|
inRange = true;
|
|||
|
segment += "[";
|
|||
|
if (glob[i + 1] == "!") {
|
|||
|
i++;
|
|||
|
segment += "^";
|
|||
|
} else if (glob[i + 1] == "^") {
|
|||
|
i++;
|
|||
|
segment += "\\^";
|
|||
|
}
|
|||
|
continue;
|
|||
|
} else if (glob[i + 1] == ":") {
|
|||
|
let k = i + 1;
|
|||
|
let value = "";
|
|||
|
while(glob[k + 1] != null && glob[k + 1] != ":"){
|
|||
|
value += glob[k + 1];
|
|||
|
k++;
|
|||
|
}
|
|||
|
if (glob[k + 1] == ":" && glob[k + 2] == "]") {
|
|||
|
i = k + 2;
|
|||
|
if (value == "alnum") segment += "\\dA-Za-z";
|
|||
|
else if (value == "alpha") segment += "A-Za-z";
|
|||
|
else if (value == "ascii") segment += "\x00-\x7F";
|
|||
|
else if (value == "blank") segment += "\t ";
|
|||
|
else if (value == "cntrl") segment += "\x00-\x1F\x7F";
|
|||
|
else if (value == "digit") segment += "\\d";
|
|||
|
else if (value == "graph") segment += "\x21-\x7E";
|
|||
|
else if (value == "lower") segment += "a-z";
|
|||
|
else if (value == "print") segment += "\x20-\x7E";
|
|||
|
else if (value == "punct") {
|
|||
|
segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_‘{|}~";
|
|||
|
} else if (value == "space") segment += "\\s\v";
|
|||
|
else if (value == "upper") segment += "A-Z";
|
|||
|
else if (value == "word") segment += "\\w";
|
|||
|
else if (value == "xdigit") segment += "\\dA-Fa-f";
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (glob[i] == "]" && inRange) {
|
|||
|
inRange = false;
|
|||
|
segment += "]";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (inRange) {
|
|||
|
if (glob[i] == "\\") {
|
|||
|
segment += `\\\\`;
|
|||
|
} else {
|
|||
|
segment += glob[i];
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == ")" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") {
|
|||
|
segment += ")";
|
|||
|
const type = groupStack.pop();
|
|||
|
if (type == "!") {
|
|||
|
segment += wildcard;
|
|||
|
} else if (type != "@") {
|
|||
|
segment += type;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "|" && groupStack.length > 0 && groupStack[groupStack.length - 1] != "BRACE") {
|
|||
|
segment += "|";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "+" && extended && glob[i + 1] == "(") {
|
|||
|
i++;
|
|||
|
groupStack.push("+");
|
|||
|
segment += "(?:";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "@" && extended && glob[i + 1] == "(") {
|
|||
|
i++;
|
|||
|
groupStack.push("@");
|
|||
|
segment += "(?:";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "?") {
|
|||
|
if (extended && glob[i + 1] == "(") {
|
|||
|
i++;
|
|||
|
groupStack.push("?");
|
|||
|
segment += "(?:";
|
|||
|
} else {
|
|||
|
segment += ".";
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "!" && extended && glob[i + 1] == "(") {
|
|||
|
i++;
|
|||
|
groupStack.push("!");
|
|||
|
segment += "(?!";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "{") {
|
|||
|
groupStack.push("BRACE");
|
|||
|
segment += "(?:";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "}" && groupStack[groupStack.length - 1] == "BRACE") {
|
|||
|
groupStack.pop();
|
|||
|
segment += ")";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "," && groupStack[groupStack.length - 1] == "BRACE") {
|
|||
|
segment += "|";
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (glob[i] == "*") {
|
|||
|
if (extended && glob[i + 1] == "(") {
|
|||
|
i++;
|
|||
|
groupStack.push("*");
|
|||
|
segment += "(?:";
|
|||
|
} else {
|
|||
|
const prevChar = glob[i - 1];
|
|||
|
let numStars = 1;
|
|||
|
while(glob[i + 1] == "*"){
|
|||
|
i++;
|
|||
|
numStars++;
|
|||
|
}
|
|||
|
const nextChar = glob[i + 1];
|
|||
|
if (globstarOption && numStars == 2 && [
|
|||
|
...seps,
|
|||
|
undefined
|
|||
|
].includes(prevChar) && [
|
|||
|
...seps,
|
|||
|
undefined
|
|||
|
].includes(nextChar)) {
|
|||
|
segment += globstar;
|
|||
|
endsWithSep = true;
|
|||
|
} else {
|
|||
|
segment += wildcard;
|
|||
|
}
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
segment += regExpEscapeChars.includes(glob[i]) ? `\\${glob[i]}` : glob[i];
|
|||
|
}
|
|||
|
if (groupStack.length > 0 || inRange || inEscape) {
|
|||
|
segment = "";
|
|||
|
for (const c of glob.slice(j, i)){
|
|||
|
segment += regExpEscapeChars.includes(c) ? `\\${c}` : c;
|
|||
|
endsWithSep = false;
|
|||
|
}
|
|||
|
}
|
|||
|
regExpString += segment;
|
|||
|
if (!endsWithSep) {
|
|||
|
regExpString += i < glob.length ? sep3 : sepMaybe;
|
|||
|
endsWithSep = true;
|
|||
|
}
|
|||
|
while(seps.includes(glob[i]))i++;
|
|||
|
if (!(i > j)) {
|
|||
|
throw new Error("Assertion failure: i > j (potential infinite loop)");
|
|||
|
}
|
|||
|
j = i;
|
|||
|
}
|
|||
|
regExpString = `^${regExpString}$`;
|
|||
|
return new RegExp(regExpString);
|
|||
|
}
|
|||
|
function isGlob(str) {
|
|||
|
const chars = {
|
|||
|
"{": "}",
|
|||
|
"(": ")",
|
|||
|
"[": "]"
|
|||
|
};
|
|||
|
const regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
|
|||
|
if (str === "") {
|
|||
|
return false;
|
|||
|
}
|
|||
|
let match;
|
|||
|
while(match = regex.exec(str)){
|
|||
|
if (match[2]) return true;
|
|||
|
let idx = match.index + match[0].length;
|
|||
|
const open = match[1];
|
|||
|
const close = open ? chars[open] : null;
|
|||
|
if (open && close) {
|
|||
|
const n = str.indexOf(close, idx);
|
|||
|
if (n !== -1) {
|
|||
|
idx = n + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
str = str.slice(idx);
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
function normalizeGlob(glob, { globstar =false } = {
|
|||
|
}) {
|
|||
|
if (glob.match(/\0/g)) {
|
|||
|
throw new Error(`Glob contains invalid characters: "${glob}"`);
|
|||
|
}
|
|||
|
if (!globstar) {
|
|||
|
return normalize2(glob);
|
|||
|
}
|
|||
|
const s = SEP_PATTERN.source;
|
|||
|
const badParentPattern = new RegExp(`(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`, "g");
|
|||
|
return normalize2(glob.replace(badParentPattern, "\0")).replace(/\0/g, "..");
|
|||
|
}
|
|||
|
function joinGlobs(globs, { extended =false , globstar =false } = {
|
|||
|
}) {
|
|||
|
if (!globstar || globs.length == 0) {
|
|||
|
return join2(...globs);
|
|||
|
}
|
|||
|
if (globs.length === 0) return ".";
|
|||
|
let joined;
|
|||
|
for (const glob of globs){
|
|||
|
const path1 = glob;
|
|||
|
if (path1.length > 0) {
|
|||
|
if (!joined) joined = path1;
|
|||
|
else joined += `${SEP}${path1}`;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!joined) return ".";
|
|||
|
return normalizeGlob(joined, {
|
|||
|
extended,
|
|||
|
globstar
|
|||
|
});
|
|||
|
}
|
|||
|
const mod3 = function() {
|
|||
|
return {
|
|||
|
SEP: SEP,
|
|||
|
SEP_PATTERN: SEP_PATTERN,
|
|||
|
win32: mod1,
|
|||
|
posix: mod2,
|
|||
|
basename: basename2,
|
|||
|
delimiter: delimiter2,
|
|||
|
dirname: dirname2,
|
|||
|
extname: extname2,
|
|||
|
format: format2,
|
|||
|
fromFileUrl: fromFileUrl2,
|
|||
|
isAbsolute: isAbsolute2,
|
|||
|
join: join2,
|
|||
|
normalize: normalize2,
|
|||
|
parse: parse3,
|
|||
|
relative: relative2,
|
|||
|
resolve: resolve2,
|
|||
|
sep: sep2,
|
|||
|
toFileUrl: toFileUrl2,
|
|||
|
toNamespacedPath: toNamespacedPath2,
|
|||
|
globToRegExp,
|
|||
|
isGlob,
|
|||
|
normalizeGlob,
|
|||
|
joinGlobs,
|
|||
|
common
|
|||
|
};
|
|||
|
}();
|
|||
|
var LogLevels;
|
|||
|
(function(LogLevels1) {
|
|||
|
LogLevels1[LogLevels1["NOTSET"] = 0] = "NOTSET";
|
|||
|
LogLevels1[LogLevels1["DEBUG"] = 10] = "DEBUG";
|
|||
|
LogLevels1[LogLevels1["INFO"] = 20] = "INFO";
|
|||
|
LogLevels1[LogLevels1["WARNING"] = 30] = "WARNING";
|
|||
|
LogLevels1[LogLevels1["ERROR"] = 40] = "ERROR";
|
|||
|
LogLevels1[LogLevels1["CRITICAL"] = 50] = "CRITICAL";
|
|||
|
})(LogLevels || (LogLevels = {
|
|||
|
}));
|
|||
|
const byLevel = {
|
|||
|
[String(LogLevels.NOTSET)]: "NOTSET",
|
|||
|
[String(LogLevels.DEBUG)]: "DEBUG",
|
|||
|
[String(LogLevels.INFO)]: "INFO",
|
|||
|
[String(LogLevels.WARNING)]: "WARNING",
|
|||
|
[String(LogLevels.ERROR)]: "ERROR",
|
|||
|
[String(LogLevels.CRITICAL)]: "CRITICAL"
|
|||
|
};
|
|||
|
function getLevelByName(name) {
|
|||
|
switch(name){
|
|||
|
case "NOTSET":
|
|||
|
return LogLevels.NOTSET;
|
|||
|
case "DEBUG":
|
|||
|
return LogLevels.DEBUG;
|
|||
|
case "INFO":
|
|||
|
return LogLevels.INFO;
|
|||
|
case "WARNING":
|
|||
|
return LogLevels.WARNING;
|
|||
|
case "ERROR":
|
|||
|
return LogLevels.ERROR;
|
|||
|
case "CRITICAL":
|
|||
|
return LogLevels.CRITICAL;
|
|||
|
default:
|
|||
|
throw new Error(`no log level found for "${name}"`);
|
|||
|
}
|
|||
|
}
|
|||
|
function getLevelName(level) {
|
|||
|
const levelName = byLevel[level];
|
|||
|
if (levelName) {
|
|||
|
return levelName;
|
|||
|
}
|
|||
|
throw new Error(`no level name found for level: ${level}`);
|
|||
|
}
|
|||
|
class LogRecord {
|
|||
|
#args;
|
|||
|
#datetime;
|
|||
|
constructor(options){
|
|||
|
this.msg = options.msg;
|
|||
|
this.#args = [
|
|||
|
...options.args
|
|||
|
];
|
|||
|
this.level = options.level;
|
|||
|
this.loggerName = options.loggerName;
|
|||
|
this.#datetime = new Date();
|
|||
|
this.levelName = getLevelName(options.level);
|
|||
|
}
|
|||
|
get args() {
|
|||
|
return [
|
|||
|
...this.#args
|
|||
|
];
|
|||
|
}
|
|||
|
get datetime() {
|
|||
|
return new Date(this.#datetime.getTime());
|
|||
|
}
|
|||
|
}
|
|||
|
class Logger {
|
|||
|
#level;
|
|||
|
#handlers;
|
|||
|
#loggerName;
|
|||
|
constructor(loggerName, levelName1, options1 = {
|
|||
|
}){
|
|||
|
this.#loggerName = loggerName;
|
|||
|
this.#level = getLevelByName(levelName1);
|
|||
|
this.#handlers = options1.handlers || [];
|
|||
|
}
|
|||
|
get level() {
|
|||
|
return this.#level;
|
|||
|
}
|
|||
|
set level(level) {
|
|||
|
this.#level = level;
|
|||
|
}
|
|||
|
get levelName() {
|
|||
|
return getLevelName(this.#level);
|
|||
|
}
|
|||
|
set levelName(levelName) {
|
|||
|
this.#level = getLevelByName(levelName);
|
|||
|
}
|
|||
|
get loggerName() {
|
|||
|
return this.#loggerName;
|
|||
|
}
|
|||
|
set handlers(hndls) {
|
|||
|
this.#handlers = hndls;
|
|||
|
}
|
|||
|
get handlers() {
|
|||
|
return this.#handlers;
|
|||
|
}
|
|||
|
_log(level, msg, ...args) {
|
|||
|
if (this.level > level) {
|
|||
|
return msg instanceof Function ? undefined : msg;
|
|||
|
}
|
|||
|
let fnResult;
|
|||
|
let logMessage;
|
|||
|
if (msg instanceof Function) {
|
|||
|
fnResult = msg();
|
|||
|
logMessage = this.asString(fnResult);
|
|||
|
} else {
|
|||
|
logMessage = this.asString(msg);
|
|||
|
}
|
|||
|
const record = new LogRecord({
|
|||
|
msg: logMessage,
|
|||
|
args: args,
|
|||
|
level: level,
|
|||
|
loggerName: this.loggerName
|
|||
|
});
|
|||
|
this.#handlers.forEach((handler)=>{
|
|||
|
handler.handle(record);
|
|||
|
});
|
|||
|
return msg instanceof Function ? fnResult : msg;
|
|||
|
}
|
|||
|
asString(data) {
|
|||
|
if (typeof data === "string") {
|
|||
|
return data;
|
|||
|
} else if (data === null || typeof data === "number" || typeof data === "bigint" || typeof data === "boolean" || typeof data === "undefined" || typeof data === "symbol") {
|
|||
|
return String(data);
|
|||
|
} else if (typeof data === "object") {
|
|||
|
return JSON.stringify(data);
|
|||
|
}
|
|||
|
return "undefined";
|
|||
|
}
|
|||
|
debug(msg, ...args) {
|
|||
|
return this._log(LogLevels.DEBUG, msg, ...args);
|
|||
|
}
|
|||
|
info(msg, ...args) {
|
|||
|
return this._log(LogLevels.INFO, msg, ...args);
|
|||
|
}
|
|||
|
warning(msg, ...args) {
|
|||
|
return this._log(LogLevels.WARNING, msg, ...args);
|
|||
|
}
|
|||
|
error(msg, ...args) {
|
|||
|
return this._log(LogLevels.ERROR, msg, ...args);
|
|||
|
}
|
|||
|
critical(msg, ...args) {
|
|||
|
return this._log(LogLevels.CRITICAL, msg, ...args);
|
|||
|
}
|
|||
|
}
|
|||
|
const noColor = globalThis.Deno?.noColor ?? true;
|
|||
|
let enabled = !noColor;
|
|||
|
function code(open, close) {
|
|||
|
return {
|
|||
|
open: `\x1b[${open.join(";")}m`,
|
|||
|
close: `\x1b[${close}m`,
|
|||
|
regexp: new RegExp(`\\x1b\\[${close}m`, "g")
|
|||
|
};
|
|||
|
}
|
|||
|
function run(str, code1) {
|
|||
|
return enabled ? `${code1.open}${str.replace(code1.regexp, code1.open)}${code1.close}` : str;
|
|||
|
}
|
|||
|
function bold(str) {
|
|||
|
return run(str, code([
|
|||
|
1
|
|||
|
], 22));
|
|||
|
}
|
|||
|
function red(str) {
|
|||
|
return run(str, code([
|
|||
|
31
|
|||
|
], 39));
|
|||
|
}
|
|||
|
function yellow(str) {
|
|||
|
return run(str, code([
|
|||
|
33
|
|||
|
], 39));
|
|||
|
}
|
|||
|
function blue(str) {
|
|||
|
return run(str, code([
|
|||
|
34
|
|||
|
], 39));
|
|||
|
}
|
|||
|
const ANSI_PATTERN = new RegExp([
|
|||
|
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
|||
|
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
|
|||
|
].join("|"), "g");
|
|||
|
async function exists(filePath) {
|
|||
|
try {
|
|||
|
await Deno.lstat(filePath);
|
|||
|
return true;
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
function existsSync(filePath) {
|
|||
|
try {
|
|||
|
Deno.lstatSync(filePath);
|
|||
|
return true;
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
function copyBytes(src, dst, off = 0) {
|
|||
|
off = Math.max(0, Math.min(off, dst.byteLength));
|
|||
|
const dstBytesAvailable = dst.byteLength - off;
|
|||
|
if (src.byteLength > dstBytesAvailable) {
|
|||
|
src = src.subarray(0, dstBytesAvailable);
|
|||
|
}
|
|||
|
dst.set(src, off);
|
|||
|
return src.byteLength;
|
|||
|
}
|
|||
|
const DEFAULT_BUF_SIZE = 4096;
|
|||
|
const MIN_BUF_SIZE = 16;
|
|||
|
const CR = "\r".charCodeAt(0);
|
|||
|
const LF = "\n".charCodeAt(0);
|
|||
|
class BufferFullError extends Error {
|
|||
|
name = "BufferFullError";
|
|||
|
constructor(partial){
|
|||
|
super("Buffer full");
|
|||
|
this.partial = partial;
|
|||
|
}
|
|||
|
}
|
|||
|
class PartialReadError extends Deno.errors.UnexpectedEof {
|
|||
|
name = "PartialReadError";
|
|||
|
constructor(){
|
|||
|
super("Encountered UnexpectedEof, data only partially read");
|
|||
|
}
|
|||
|
}
|
|||
|
class BufReader {
|
|||
|
r = 0;
|
|||
|
w = 0;
|
|||
|
eof = false;
|
|||
|
static create(r, size = 4096) {
|
|||
|
return r instanceof BufReader ? r : new BufReader(r, size);
|
|||
|
}
|
|||
|
constructor(rd1, size1 = 4096){
|
|||
|
if (size1 < 16) {
|
|||
|
size1 = MIN_BUF_SIZE;
|
|||
|
}
|
|||
|
this._reset(new Uint8Array(size1), rd1);
|
|||
|
}
|
|||
|
size() {
|
|||
|
return this.buf.byteLength;
|
|||
|
}
|
|||
|
buffered() {
|
|||
|
return this.w - this.r;
|
|||
|
}
|
|||
|
async _fill() {
|
|||
|
if (this.r > 0) {
|
|||
|
this.buf.copyWithin(0, this.r, this.w);
|
|||
|
this.w -= this.r;
|
|||
|
this.r = 0;
|
|||
|
}
|
|||
|
if (this.w >= this.buf.byteLength) {
|
|||
|
throw Error("bufio: tried to fill full buffer");
|
|||
|
}
|
|||
|
for(let i = 100; i > 0; i--){
|
|||
|
const rr = await this.rd.read(this.buf.subarray(this.w));
|
|||
|
if (rr === null) {
|
|||
|
this.eof = true;
|
|||
|
return;
|
|||
|
}
|
|||
|
assert(rr >= 0, "negative read");
|
|||
|
this.w += rr;
|
|||
|
if (rr > 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
throw new Error(`No progress after ${100} read() calls`);
|
|||
|
}
|
|||
|
reset(r) {
|
|||
|
this._reset(this.buf, r);
|
|||
|
}
|
|||
|
_reset(buf, rd) {
|
|||
|
this.buf = buf;
|
|||
|
this.rd = rd;
|
|||
|
this.eof = false;
|
|||
|
}
|
|||
|
async read(p) {
|
|||
|
let rr = p.byteLength;
|
|||
|
if (p.byteLength === 0) return rr;
|
|||
|
if (this.r === this.w) {
|
|||
|
if (p.byteLength >= this.buf.byteLength) {
|
|||
|
const rr1 = await this.rd.read(p);
|
|||
|
const nread = rr1 ?? 0;
|
|||
|
assert(nread >= 0, "negative read");
|
|||
|
return rr1;
|
|||
|
}
|
|||
|
this.r = 0;
|
|||
|
this.w = 0;
|
|||
|
rr = await this.rd.read(this.buf);
|
|||
|
if (rr === 0 || rr === null) return rr;
|
|||
|
assert(rr >= 0, "negative read");
|
|||
|
this.w += rr;
|
|||
|
}
|
|||
|
const copied = copyBytes(this.buf.subarray(this.r, this.w), p, 0);
|
|||
|
this.r += copied;
|
|||
|
return copied;
|
|||
|
}
|
|||
|
async readFull(p) {
|
|||
|
let bytesRead = 0;
|
|||
|
while(bytesRead < p.length){
|
|||
|
try {
|
|||
|
const rr = await this.read(p.subarray(bytesRead));
|
|||
|
if (rr === null) {
|
|||
|
if (bytesRead === 0) {
|
|||
|
return null;
|
|||
|
} else {
|
|||
|
throw new PartialReadError();
|
|||
|
}
|
|||
|
}
|
|||
|
bytesRead += rr;
|
|||
|
} catch (err) {
|
|||
|
err.partial = p.subarray(0, bytesRead);
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
return p;
|
|||
|
}
|
|||
|
async readByte() {
|
|||
|
while(this.r === this.w){
|
|||
|
if (this.eof) return null;
|
|||
|
await this._fill();
|
|||
|
}
|
|||
|
const c = this.buf[this.r];
|
|||
|
this.r++;
|
|||
|
return c;
|
|||
|
}
|
|||
|
async readString(delim) {
|
|||
|
if (delim.length !== 1) {
|
|||
|
throw new Error("Delimiter should be a single character");
|
|||
|
}
|
|||
|
const buffer = await this.readSlice(delim.charCodeAt(0));
|
|||
|
if (buffer === null) return null;
|
|||
|
return new TextDecoder().decode(buffer);
|
|||
|
}
|
|||
|
async readLine() {
|
|||
|
let line;
|
|||
|
try {
|
|||
|
line = await this.readSlice(LF);
|
|||
|
} catch (err) {
|
|||
|
let { partial: partial1 } = err;
|
|||
|
assert(partial1 instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property");
|
|||
|
if (!(err instanceof BufferFullError)) {
|
|||
|
throw err;
|
|||
|
}
|
|||
|
if (!this.eof && partial1.byteLength > 0 && partial1[partial1.byteLength - 1] === CR) {
|
|||
|
assert(this.r > 0, "bufio: tried to rewind past start of buffer");
|
|||
|
this.r--;
|
|||
|
partial1 = partial1.subarray(0, partial1.byteLength - 1);
|
|||
|
}
|
|||
|
return {
|
|||
|
line: partial1,
|
|||
|
more: !this.eof
|
|||
|
};
|
|||
|
}
|
|||
|
if (line === null) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (line.byteLength === 0) {
|
|||
|
return {
|
|||
|
line,
|
|||
|
more: false
|
|||
|
};
|
|||
|
}
|
|||
|
if (line[line.byteLength - 1] == LF) {
|
|||
|
let drop = 1;
|
|||
|
if (line.byteLength > 1 && line[line.byteLength - 2] === CR) {
|
|||
|
drop = 2;
|
|||
|
}
|
|||
|
line = line.subarray(0, line.byteLength - drop);
|
|||
|
}
|
|||
|
return {
|
|||
|
line,
|
|||
|
more: false
|
|||
|
};
|
|||
|
}
|
|||
|
async readSlice(delim) {
|
|||
|
let s = 0;
|
|||
|
let slice;
|
|||
|
while(true){
|
|||
|
let i = this.buf.subarray(this.r + s, this.w).indexOf(delim);
|
|||
|
if (i >= 0) {
|
|||
|
i += s;
|
|||
|
slice = this.buf.subarray(this.r, this.r + i + 1);
|
|||
|
this.r += i + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (this.eof) {
|
|||
|
if (this.r === this.w) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
slice = this.buf.subarray(this.r, this.w);
|
|||
|
this.r = this.w;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (this.buffered() >= this.buf.byteLength) {
|
|||
|
this.r = this.w;
|
|||
|
const oldbuf = this.buf;
|
|||
|
const newbuf = this.buf.slice(0);
|
|||
|
this.buf = newbuf;
|
|||
|
throw new BufferFullError(oldbuf);
|
|||
|
}
|
|||
|
s = this.w - this.r;
|
|||
|
try {
|
|||
|
await this._fill();
|
|||
|
} catch (err) {
|
|||
|
err.partial = slice;
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
return slice;
|
|||
|
}
|
|||
|
async peek(n) {
|
|||
|
if (n < 0) {
|
|||
|
throw Error("negative count");
|
|||
|
}
|
|||
|
let avail = this.w - this.r;
|
|||
|
while(avail < n && avail < this.buf.byteLength && !this.eof){
|
|||
|
try {
|
|||
|
await this._fill();
|
|||
|
} catch (err) {
|
|||
|
err.partial = this.buf.subarray(this.r, this.w);
|
|||
|
throw err;
|
|||
|
}
|
|||
|
avail = this.w - this.r;
|
|||
|
}
|
|||
|
if (avail === 0 && this.eof) {
|
|||
|
return null;
|
|||
|
} else if (avail < n && this.eof) {
|
|||
|
return this.buf.subarray(this.r, this.r + avail);
|
|||
|
} else if (avail < n) {
|
|||
|
throw new BufferFullError(this.buf.subarray(this.r, this.w));
|
|||
|
}
|
|||
|
return this.buf.subarray(this.r, this.r + n);
|
|||
|
}
|
|||
|
}
|
|||
|
class AbstractBufBase {
|
|||
|
usedBufferBytes = 0;
|
|||
|
err = null;
|
|||
|
size() {
|
|||
|
return this.buf.byteLength;
|
|||
|
}
|
|||
|
available() {
|
|||
|
return this.buf.byteLength - this.usedBufferBytes;
|
|||
|
}
|
|||
|
buffered() {
|
|||
|
return this.usedBufferBytes;
|
|||
|
}
|
|||
|
}
|
|||
|
class BufWriter extends AbstractBufBase {
|
|||
|
static create(writer, size = 4096) {
|
|||
|
return writer instanceof BufWriter ? writer : new BufWriter(writer, size);
|
|||
|
}
|
|||
|
constructor(writer1, size2 = 4096){
|
|||
|
super();
|
|||
|
this.writer = writer1;
|
|||
|
if (size2 <= 0) {
|
|||
|
size2 = DEFAULT_BUF_SIZE;
|
|||
|
}
|
|||
|
this.buf = new Uint8Array(size2);
|
|||
|
}
|
|||
|
reset(w) {
|
|||
|
this.err = null;
|
|||
|
this.usedBufferBytes = 0;
|
|||
|
this.writer = w;
|
|||
|
}
|
|||
|
async flush() {
|
|||
|
if (this.err !== null) throw this.err;
|
|||
|
if (this.usedBufferBytes === 0) return;
|
|||
|
try {
|
|||
|
await Deno.writeAll(this.writer, this.buf.subarray(0, this.usedBufferBytes));
|
|||
|
} catch (e) {
|
|||
|
this.err = e;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
this.buf = new Uint8Array(this.buf.length);
|
|||
|
this.usedBufferBytes = 0;
|
|||
|
}
|
|||
|
async write(data) {
|
|||
|
if (this.err !== null) throw this.err;
|
|||
|
if (data.length === 0) return 0;
|
|||
|
let totalBytesWritten = 0;
|
|||
|
let numBytesWritten = 0;
|
|||
|
while(data.byteLength > this.available()){
|
|||
|
if (this.buffered() === 0) {
|
|||
|
try {
|
|||
|
numBytesWritten = await this.writer.write(data);
|
|||
|
} catch (e) {
|
|||
|
this.err = e;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
} else {
|
|||
|
numBytesWritten = copyBytes(data, this.buf, this.usedBufferBytes);
|
|||
|
this.usedBufferBytes += numBytesWritten;
|
|||
|
await this.flush();
|
|||
|
}
|
|||
|
totalBytesWritten += numBytesWritten;
|
|||
|
data = data.subarray(numBytesWritten);
|
|||
|
}
|
|||
|
numBytesWritten = copyBytes(data, this.buf, this.usedBufferBytes);
|
|||
|
this.usedBufferBytes += numBytesWritten;
|
|||
|
totalBytesWritten += numBytesWritten;
|
|||
|
return totalBytesWritten;
|
|||
|
}
|
|||
|
}
|
|||
|
class BufWriterSync extends AbstractBufBase {
|
|||
|
static create(writer, size = 4096) {
|
|||
|
return writer instanceof BufWriterSync ? writer : new BufWriterSync(writer, size);
|
|||
|
}
|
|||
|
constructor(writer2, size3 = 4096){
|
|||
|
super();
|
|||
|
this.writer = writer2;
|
|||
|
if (size3 <= 0) {
|
|||
|
size3 = DEFAULT_BUF_SIZE;
|
|||
|
}
|
|||
|
this.buf = new Uint8Array(size3);
|
|||
|
}
|
|||
|
reset(w) {
|
|||
|
this.err = null;
|
|||
|
this.usedBufferBytes = 0;
|
|||
|
this.writer = w;
|
|||
|
}
|
|||
|
flush() {
|
|||
|
if (this.err !== null) throw this.err;
|
|||
|
if (this.usedBufferBytes === 0) return;
|
|||
|
try {
|
|||
|
Deno.writeAllSync(this.writer, this.buf.subarray(0, this.usedBufferBytes));
|
|||
|
} catch (e) {
|
|||
|
this.err = e;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
this.buf = new Uint8Array(this.buf.length);
|
|||
|
this.usedBufferBytes = 0;
|
|||
|
}
|
|||
|
writeSync(data) {
|
|||
|
if (this.err !== null) throw this.err;
|
|||
|
if (data.length === 0) return 0;
|
|||
|
let totalBytesWritten = 0;
|
|||
|
let numBytesWritten = 0;
|
|||
|
while(data.byteLength > this.available()){
|
|||
|
if (this.buffered() === 0) {
|
|||
|
try {
|
|||
|
numBytesWritten = this.writer.writeSync(data);
|
|||
|
} catch (e) {
|
|||
|
this.err = e;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
} else {
|
|||
|
numBytesWritten = copyBytes(data, this.buf, this.usedBufferBytes);
|
|||
|
this.usedBufferBytes += numBytesWritten;
|
|||
|
this.flush();
|
|||
|
}
|
|||
|
totalBytesWritten += numBytesWritten;
|
|||
|
data = data.subarray(numBytesWritten);
|
|||
|
}
|
|||
|
numBytesWritten = copyBytes(data, this.buf, this.usedBufferBytes);
|
|||
|
this.usedBufferBytes += numBytesWritten;
|
|||
|
totalBytesWritten += numBytesWritten;
|
|||
|
return totalBytesWritten;
|
|||
|
}
|
|||
|
}
|
|||
|
const DEFAULT_FORMATTER = "{levelName} {msg}";
|
|||
|
class BaseHandler {
|
|||
|
constructor(levelName2, options2 = {
|
|||
|
}){
|
|||
|
this.level = getLevelByName(levelName2);
|
|||
|
this.levelName = levelName2;
|
|||
|
this.formatter = options2.formatter || DEFAULT_FORMATTER;
|
|||
|
}
|
|||
|
handle(logRecord) {
|
|||
|
if (this.level > logRecord.level) return;
|
|||
|
const msg = this.format(logRecord);
|
|||
|
return this.log(msg);
|
|||
|
}
|
|||
|
format(logRecord) {
|
|||
|
if (this.formatter instanceof Function) {
|
|||
|
return this.formatter(logRecord);
|
|||
|
}
|
|||
|
return this.formatter.replace(/{(\S+)}/g, (match, p1)=>{
|
|||
|
const value = logRecord[p1];
|
|||
|
if (value == null) {
|
|||
|
return match;
|
|||
|
}
|
|||
|
return String(value);
|
|||
|
});
|
|||
|
}
|
|||
|
log(_msg) {
|
|||
|
}
|
|||
|
async setup() {
|
|||
|
}
|
|||
|
async destroy() {
|
|||
|
}
|
|||
|
}
|
|||
|
class ConsoleHandler extends BaseHandler {
|
|||
|
format(logRecord) {
|
|||
|
let msg = super.format(logRecord);
|
|||
|
switch(logRecord.level){
|
|||
|
case LogLevels.INFO:
|
|||
|
msg = blue(msg);
|
|||
|
break;
|
|||
|
case LogLevels.WARNING:
|
|||
|
msg = yellow(msg);
|
|||
|
break;
|
|||
|
case LogLevels.ERROR:
|
|||
|
msg = red(msg);
|
|||
|
break;
|
|||
|
case LogLevels.CRITICAL:
|
|||
|
msg = bold(red(msg));
|
|||
|
break;
|
|||
|
default: break;
|
|||
|
}
|
|||
|
return msg;
|
|||
|
}
|
|||
|
log(msg) {
|
|||
|
console.log(msg);
|
|||
|
}
|
|||
|
}
|
|||
|
class WriterHandler extends BaseHandler {
|
|||
|
#encoder=new TextEncoder();
|
|||
|
}
|
|||
|
class FileHandler extends WriterHandler {
|
|||
|
_encoder = new TextEncoder();
|
|||
|
#unloadCallback=()=>this.destroy()
|
|||
|
;
|
|||
|
constructor(levelName3, options3){
|
|||
|
super(levelName3, options3);
|
|||
|
this._filename = options3.filename;
|
|||
|
this._mode = options3.mode ? options3.mode : "a";
|
|||
|
this._openOptions = {
|
|||
|
createNew: this._mode === "x",
|
|||
|
create: this._mode !== "x",
|
|||
|
append: this._mode === "a",
|
|||
|
truncate: this._mode !== "a",
|
|||
|
write: true
|
|||
|
};
|
|||
|
}
|
|||
|
async setup() {
|
|||
|
this._file = await Deno.open(this._filename, this._openOptions);
|
|||
|
this._writer = this._file;
|
|||
|
this._buf = new BufWriterSync(this._file);
|
|||
|
addEventListener("unload", this.#unloadCallback);
|
|||
|
}
|
|||
|
handle(logRecord) {
|
|||
|
super.handle(logRecord);
|
|||
|
if (logRecord.level > LogLevels.ERROR) {
|
|||
|
this.flush();
|
|||
|
}
|
|||
|
}
|
|||
|
log(msg) {
|
|||
|
this._buf.writeSync(this._encoder.encode(msg + "\n"));
|
|||
|
}
|
|||
|
flush() {
|
|||
|
if (this._buf?.buffered() > 0) {
|
|||
|
this._buf.flush();
|
|||
|
}
|
|||
|
}
|
|||
|
destroy() {
|
|||
|
this.flush();
|
|||
|
this._file?.close();
|
|||
|
this._file = undefined;
|
|||
|
removeEventListener("unload", this.#unloadCallback);
|
|||
|
return Promise.resolve();
|
|||
|
}
|
|||
|
}
|
|||
|
class RotatingFileHandler extends FileHandler {
|
|||
|
#maxBytes;
|
|||
|
#maxBackupCount;
|
|||
|
#currentFileSize=0;
|
|||
|
constructor(levelName4, options4){
|
|||
|
super(levelName4, options4);
|
|||
|
this.#maxBytes = options4.maxBytes;
|
|||
|
this.#maxBackupCount = options4.maxBackupCount;
|
|||
|
}
|
|||
|
async setup() {
|
|||
|
if (this.#maxBytes < 1) {
|
|||
|
this.destroy();
|
|||
|
throw new Error("maxBytes cannot be less than 1");
|
|||
|
}
|
|||
|
if (this.#maxBackupCount < 1) {
|
|||
|
this.destroy();
|
|||
|
throw new Error("maxBackupCount cannot be less than 1");
|
|||
|
}
|
|||
|
await super.setup();
|
|||
|
if (this._mode === "w") {
|
|||
|
for(let i = 1; i <= this.#maxBackupCount; i++){
|
|||
|
if (await exists(this._filename + "." + i)) {
|
|||
|
await Deno.remove(this._filename + "." + i);
|
|||
|
}
|
|||
|
}
|
|||
|
} else if (this._mode === "x") {
|
|||
|
for(let i = 1; i <= this.#maxBackupCount; i++){
|
|||
|
if (await exists(this._filename + "." + i)) {
|
|||
|
this.destroy();
|
|||
|
throw new Deno.errors.AlreadyExists("Backup log file " + this._filename + "." + i + " already exists");
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
this.#currentFileSize = (await Deno.stat(this._filename)).size;
|
|||
|
}
|
|||
|
}
|
|||
|
log(msg) {
|
|||
|
const msgByteLength = this._encoder.encode(msg).byteLength + 1;
|
|||
|
if (this.#currentFileSize + msgByteLength > this.#maxBytes) {
|
|||
|
this.rotateLogFiles();
|
|||
|
this.#currentFileSize = 0;
|
|||
|
}
|
|||
|
this._buf.writeSync(this._encoder.encode(msg + "\n"));
|
|||
|
this.#currentFileSize += msgByteLength;
|
|||
|
}
|
|||
|
rotateLogFiles() {
|
|||
|
this._buf.flush();
|
|||
|
Deno.close(this._file.rid);
|
|||
|
for(let i = this.#maxBackupCount - 1; i >= 0; i--){
|
|||
|
const source = this._filename + (i === 0 ? "" : "." + i);
|
|||
|
const dest = this._filename + "." + (i + 1);
|
|||
|
if (existsSync(source)) {
|
|||
|
Deno.renameSync(source, dest);
|
|||
|
}
|
|||
|
}
|
|||
|
this._file = Deno.openSync(this._filename, this._openOptions);
|
|||
|
this._writer = this._file;
|
|||
|
this._buf = new BufWriterSync(this._file);
|
|||
|
}
|
|||
|
}
|
|||
|
class LoggerConfig {
|
|||
|
}
|
|||
|
const DEFAULT_LEVEL = "INFO";
|
|||
|
const DEFAULT_CONFIG = {
|
|||
|
handlers: {
|
|||
|
default: new ConsoleHandler(DEFAULT_LEVEL)
|
|||
|
},
|
|||
|
loggers: {
|
|||
|
default: {
|
|||
|
level: DEFAULT_LEVEL,
|
|||
|
handlers: [
|
|||
|
"default"
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const state = {
|
|||
|
handlers: new Map(),
|
|||
|
loggers: new Map(),
|
|||
|
config: DEFAULT_CONFIG
|
|||
|
};
|
|||
|
const handlers = {
|
|||
|
BaseHandler,
|
|||
|
ConsoleHandler,
|
|||
|
WriterHandler,
|
|||
|
FileHandler,
|
|||
|
RotatingFileHandler
|
|||
|
};
|
|||
|
function getLogger(name) {
|
|||
|
if (!name) {
|
|||
|
const d = state.loggers.get("default");
|
|||
|
assert(d != null, `"default" logger must be set for getting logger without name`);
|
|||
|
return d;
|
|||
|
}
|
|||
|
const result = state.loggers.get(name);
|
|||
|
if (!result) {
|
|||
|
const logger = new Logger(name, "NOTSET", {
|
|||
|
handlers: []
|
|||
|
});
|
|||
|
state.loggers.set(name, logger);
|
|||
|
return logger;
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
function debug(msg, ...args) {
|
|||
|
if (msg instanceof Function) {
|
|||
|
return getLogger("default").debug(msg, ...args);
|
|||
|
}
|
|||
|
return getLogger("default").debug(msg, ...args);
|
|||
|
}
|
|||
|
function info(msg, ...args) {
|
|||
|
if (msg instanceof Function) {
|
|||
|
return getLogger("default").info(msg, ...args);
|
|||
|
}
|
|||
|
return getLogger("default").info(msg, ...args);
|
|||
|
}
|
|||
|
function warning(msg, ...args) {
|
|||
|
if (msg instanceof Function) {
|
|||
|
return getLogger("default").warning(msg, ...args);
|
|||
|
}
|
|||
|
return getLogger("default").warning(msg, ...args);
|
|||
|
}
|
|||
|
function error(msg, ...args) {
|
|||
|
if (msg instanceof Function) {
|
|||
|
return getLogger("default").error(msg, ...args);
|
|||
|
}
|
|||
|
return getLogger("default").error(msg, ...args);
|
|||
|
}
|
|||
|
function critical(msg, ...args) {
|
|||
|
if (msg instanceof Function) {
|
|||
|
return getLogger("default").critical(msg, ...args);
|
|||
|
}
|
|||
|
return getLogger("default").critical(msg, ...args);
|
|||
|
}
|
|||
|
async function setup(config) {
|
|||
|
state.config = {
|
|||
|
handlers: {
|
|||
|
...DEFAULT_CONFIG.handlers,
|
|||
|
...config.handlers
|
|||
|
},
|
|||
|
loggers: {
|
|||
|
...DEFAULT_CONFIG.loggers,
|
|||
|
...config.loggers
|
|||
|
}
|
|||
|
};
|
|||
|
state.handlers.forEach((handler)=>{
|
|||
|
handler.destroy();
|
|||
|
});
|
|||
|
state.handlers.clear();
|
|||
|
const handlers1 = state.config.handlers || {
|
|||
|
};
|
|||
|
for(const handlerName in handlers1){
|
|||
|
const handler = handlers1[handlerName];
|
|||
|
await handler.setup();
|
|||
|
state.handlers.set(handlerName, handler);
|
|||
|
}
|
|||
|
state.loggers.clear();
|
|||
|
const loggers = state.config.loggers || {
|
|||
|
};
|
|||
|
for(const loggerName1 in loggers){
|
|||
|
const loggerConfig = loggers[loggerName1];
|
|||
|
const handlerNames = loggerConfig.handlers || [];
|
|||
|
const handlers2 = [];
|
|||
|
handlerNames.forEach((handlerName1)=>{
|
|||
|
const handler = state.handlers.get(handlerName1);
|
|||
|
if (handler) {
|
|||
|
handlers2.push(handler);
|
|||
|
}
|
|||
|
});
|
|||
|
const levelName5 = loggerConfig.level || DEFAULT_LEVEL;
|
|||
|
const logger = new Logger(loggerName1, levelName5, {
|
|||
|
handlers: handlers2
|
|||
|
});
|
|||
|
state.loggers.set(loggerName1, logger);
|
|||
|
}
|
|||
|
}
|
|||
|
await setup(DEFAULT_CONFIG);
|
|||
|
const mod4 = await async function() {
|
|||
|
return {
|
|||
|
LogLevels: LogLevels,
|
|||
|
Logger: Logger,
|
|||
|
LoggerConfig: LoggerConfig,
|
|||
|
handlers: handlers,
|
|||
|
getLogger: getLogger,
|
|||
|
debug: debug,
|
|||
|
info: info,
|
|||
|
warning: warning,
|
|||
|
error: error,
|
|||
|
critical: critical,
|
|||
|
setup: setup
|
|||
|
};
|
|||
|
}();
|
|||
|
async function emptyDir(dir) {
|
|||
|
try {
|
|||
|
const items = [];
|
|||
|
for await (const dirEntry of Deno.readDir(dir)){
|
|||
|
items.push(dirEntry);
|
|||
|
}
|
|||
|
while(items.length){
|
|||
|
const item = items.shift();
|
|||
|
if (item && item.name) {
|
|||
|
const filepath = join2(dir, item.name);
|
|||
|
await Deno.remove(filepath, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (!(err instanceof Deno.errors.NotFound)) {
|
|||
|
throw err;
|
|||
|
}
|
|||
|
await Deno.mkdir(dir, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
function emptyDirSync(dir) {
|
|||
|
try {
|
|||
|
const items = [
|
|||
|
...Deno.readDirSync(dir)
|
|||
|
];
|
|||
|
while(items.length){
|
|||
|
const item = items.shift();
|
|||
|
if (item && item.name) {
|
|||
|
const filepath = join2(dir, item.name);
|
|||
|
Deno.removeSync(filepath, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (!(err instanceof Deno.errors.NotFound)) {
|
|||
|
throw err;
|
|||
|
}
|
|||
|
Deno.mkdirSync(dir, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
function isSubdir(src, dest, sep3 = sep2) {
|
|||
|
if (src === dest) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
const srcArray = src.split(sep3);
|
|||
|
const destArray = dest.split(sep3);
|
|||
|
return srcArray.every((current, i)=>destArray[i] === current
|
|||
|
);
|
|||
|
}
|
|||
|
function getFileInfoType(fileInfo) {
|
|||
|
return fileInfo.isFile ? "file" : fileInfo.isDirectory ? "dir" : fileInfo.isSymlink ? "symlink" : undefined;
|
|||
|
}
|
|||
|
async function ensureDir(dir) {
|
|||
|
try {
|
|||
|
const fileInfo = await Deno.lstat(dir);
|
|||
|
if (!fileInfo.isDirectory) {
|
|||
|
throw new Error(`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`);
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
await Deno.mkdir(dir, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
function ensureDirSync(dir) {
|
|||
|
try {
|
|||
|
const fileInfo = Deno.lstatSync(dir);
|
|||
|
if (!fileInfo.isDirectory) {
|
|||
|
throw new Error(`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`);
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
Deno.mkdirSync(dir, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
async function ensureFile(filePath) {
|
|||
|
try {
|
|||
|
const stat = await Deno.lstat(filePath);
|
|||
|
if (!stat.isFile) {
|
|||
|
throw new Error(`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`);
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
await ensureDir(dirname2(filePath));
|
|||
|
await Deno.writeFile(filePath, new Uint8Array());
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
function ensureFileSync(filePath) {
|
|||
|
try {
|
|||
|
const stat = Deno.lstatSync(filePath);
|
|||
|
if (!stat.isFile) {
|
|||
|
throw new Error(`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`);
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
ensureDirSync(dirname2(filePath));
|
|||
|
Deno.writeFileSync(filePath, new Uint8Array());
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
async function ensureLink(src, dest) {
|
|||
|
if (await exists(dest)) {
|
|||
|
const destStatInfo = await Deno.lstat(dest);
|
|||
|
const destFilePathType = getFileInfoType(destStatInfo);
|
|||
|
if (destFilePathType !== "file") {
|
|||
|
throw new Error(`Ensure path exists, expected 'file', got '${destFilePathType}'`);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
await ensureDir(dirname2(dest));
|
|||
|
await Deno.link(src, dest);
|
|||
|
}
|
|||
|
function ensureLinkSync(src, dest) {
|
|||
|
if (existsSync(dest)) {
|
|||
|
const destStatInfo = Deno.lstatSync(dest);
|
|||
|
const destFilePathType = getFileInfoType(destStatInfo);
|
|||
|
if (destFilePathType !== "file") {
|
|||
|
throw new Error(`Ensure path exists, expected 'file', got '${destFilePathType}'`);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
ensureDirSync(dirname2(dest));
|
|||
|
Deno.linkSync(src, dest);
|
|||
|
}
|
|||
|
async function ensureSymlink(src, dest) {
|
|||
|
const srcStatInfo = await Deno.lstat(src);
|
|||
|
const srcFilePathType = getFileInfoType(srcStatInfo);
|
|||
|
if (await exists(dest)) {
|
|||
|
const destStatInfo = await Deno.lstat(dest);
|
|||
|
const destFilePathType = getFileInfoType(destStatInfo);
|
|||
|
if (destFilePathType !== "symlink") {
|
|||
|
throw new Error(`Ensure path exists, expected 'symlink', got '${destFilePathType}'`);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
await ensureDir(dirname2(dest));
|
|||
|
if (Deno.build.os === "windows") {
|
|||
|
await Deno.symlink(src, dest, {
|
|||
|
type: srcFilePathType === "dir" ? "dir" : "file"
|
|||
|
});
|
|||
|
} else {
|
|||
|
await Deno.symlink(src, dest);
|
|||
|
}
|
|||
|
}
|
|||
|
function ensureSymlinkSync(src, dest) {
|
|||
|
const srcStatInfo = Deno.lstatSync(src);
|
|||
|
const srcFilePathType = getFileInfoType(srcStatInfo);
|
|||
|
if (existsSync(dest)) {
|
|||
|
const destStatInfo = Deno.lstatSync(dest);
|
|||
|
const destFilePathType = getFileInfoType(destStatInfo);
|
|||
|
if (destFilePathType !== "symlink") {
|
|||
|
throw new Error(`Ensure path exists, expected 'symlink', got '${destFilePathType}'`);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
ensureDirSync(dirname2(dest));
|
|||
|
if (Deno.build.os === "windows") {
|
|||
|
Deno.symlinkSync(src, dest, {
|
|||
|
type: srcFilePathType === "dir" ? "dir" : "file"
|
|||
|
});
|
|||
|
} else {
|
|||
|
Deno.symlinkSync(src, dest);
|
|||
|
}
|
|||
|
}
|
|||
|
function _createWalkEntrySync(path1) {
|
|||
|
path1 = normalize2(path1);
|
|||
|
const name = basename2(path1);
|
|||
|
const info1 = Deno.statSync(path1);
|
|||
|
return {
|
|||
|
path: path1,
|
|||
|
name,
|
|||
|
isFile: info1.isFile,
|
|||
|
isDirectory: info1.isDirectory,
|
|||
|
isSymlink: info1.isSymlink
|
|||
|
};
|
|||
|
}
|
|||
|
async function _createWalkEntry(path1) {
|
|||
|
path1 = normalize2(path1);
|
|||
|
const name = basename2(path1);
|
|||
|
const info1 = await Deno.stat(path1);
|
|||
|
return {
|
|||
|
path: path1,
|
|||
|
name,
|
|||
|
isFile: info1.isFile,
|
|||
|
isDirectory: info1.isDirectory,
|
|||
|
isSymlink: info1.isSymlink
|
|||
|
};
|
|||
|
}
|
|||
|
function include(path1, exts, match, skip) {
|
|||
|
if (exts && !exts.some((ext)=>path1.endsWith(ext)
|
|||
|
)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (match && !match.some((pattern)=>!!path1.match(pattern)
|
|||
|
)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (skip && skip.some((pattern)=>!!path1.match(pattern)
|
|||
|
)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
async function* walk(root, { maxDepth =Infinity , includeFiles =true , includeDirs =true , followSymlinks =false , exts =undefined , match =undefined , skip =undefined } = {
|
|||
|
}) {
|
|||
|
if (maxDepth < 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (includeDirs && include(root, exts, match, skip)) {
|
|||
|
yield await _createWalkEntry(root);
|
|||
|
}
|
|||
|
if (maxDepth < 1 || !include(root, undefined, undefined, skip)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
for await (const entry of Deno.readDir(root)){
|
|||
|
if (entry.isSymlink) {
|
|||
|
if (followSymlinks) {
|
|||
|
throw new Error("unimplemented");
|
|||
|
} else {
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
assert(entry.name != null);
|
|||
|
const path1 = join2(root, entry.name);
|
|||
|
if (entry.isFile) {
|
|||
|
if (includeFiles && include(path1, exts, match, skip)) {
|
|||
|
yield {
|
|||
|
path: path1,
|
|||
|
...entry
|
|||
|
};
|
|||
|
}
|
|||
|
} else {
|
|||
|
yield* walk(path1, {
|
|||
|
maxDepth: maxDepth - 1,
|
|||
|
includeFiles,
|
|||
|
includeDirs,
|
|||
|
followSymlinks,
|
|||
|
exts,
|
|||
|
match,
|
|||
|
skip
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
function* walkSync(root, { maxDepth =Infinity , includeFiles =true , includeDirs =true , followSymlinks =false , exts =undefined , match =undefined , skip =undefined } = {
|
|||
|
}) {
|
|||
|
if (maxDepth < 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (includeDirs && include(root, exts, match, skip)) {
|
|||
|
yield _createWalkEntrySync(root);
|
|||
|
}
|
|||
|
if (maxDepth < 1 || !include(root, undefined, undefined, skip)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
for (const entry of Deno.readDirSync(root)){
|
|||
|
if (entry.isSymlink) {
|
|||
|
if (followSymlinks) {
|
|||
|
throw new Error("unimplemented");
|
|||
|
} else {
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
assert(entry.name != null);
|
|||
|
const path1 = join2(root, entry.name);
|
|||
|
if (entry.isFile) {
|
|||
|
if (includeFiles && include(path1, exts, match, skip)) {
|
|||
|
yield {
|
|||
|
path: path1,
|
|||
|
...entry
|
|||
|
};
|
|||
|
}
|
|||
|
} else {
|
|||
|
yield* walkSync(path1, {
|
|||
|
maxDepth: maxDepth - 1,
|
|||
|
includeFiles,
|
|||
|
includeDirs,
|
|||
|
followSymlinks,
|
|||
|
exts,
|
|||
|
match,
|
|||
|
skip
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
const isWindows1 = Deno.build.os == "windows";
|
|||
|
function split(path1) {
|
|||
|
const s = SEP_PATTERN.source;
|
|||
|
const segments = path1.replace(new RegExp(`^${s}|${s}$`, "g"), "").split(SEP_PATTERN);
|
|||
|
const isAbsolute_ = isAbsolute2(path1);
|
|||
|
return {
|
|||
|
segments,
|
|||
|
isAbsolute: isAbsolute_,
|
|||
|
hasTrailingSep: !!path1.match(new RegExp(`${s}$`)),
|
|||
|
winRoot: isWindows1 && isAbsolute_ ? segments.shift() : undefined
|
|||
|
};
|
|||
|
}
|
|||
|
function throwUnlessNotFound(error1) {
|
|||
|
if (!(error1 instanceof Deno.errors.NotFound)) {
|
|||
|
throw error1;
|
|||
|
}
|
|||
|
}
|
|||
|
function comparePath(a, b) {
|
|||
|
if (a.path < b.path) return -1;
|
|||
|
if (a.path > b.path) return 1;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
async function* expandGlob(glob, { root =Deno.cwd() , exclude =[] , includeDirs =true , extended =false , globstar =false } = {
|
|||
|
}) {
|
|||
|
const globOptions = {
|
|||
|
extended,
|
|||
|
globstar
|
|||
|
};
|
|||
|
const absRoot = isAbsolute2(root) ? normalize2(root) : joinGlobs([
|
|||
|
Deno.cwd(),
|
|||
|
root
|
|||
|
], globOptions);
|
|||
|
const resolveFromRoot = (path1)=>isAbsolute2(path1) ? normalize2(path1) : joinGlobs([
|
|||
|
absRoot,
|
|||
|
path1
|
|||
|
], globOptions)
|
|||
|
;
|
|||
|
const excludePatterns = exclude.map(resolveFromRoot).map((s)=>globToRegExp(s, globOptions)
|
|||
|
);
|
|||
|
const shouldInclude = (path1)=>!excludePatterns.some((p)=>!!path1.match(p)
|
|||
|
)
|
|||
|
;
|
|||
|
const { segments , hasTrailingSep , winRoot } = split(resolveFromRoot(glob));
|
|||
|
let fixedRoot = winRoot != undefined ? winRoot : "/";
|
|||
|
while(segments.length > 0 && !isGlob(segments[0])){
|
|||
|
const seg = segments.shift();
|
|||
|
assert(seg != null);
|
|||
|
fixedRoot = joinGlobs([
|
|||
|
fixedRoot,
|
|||
|
seg
|
|||
|
], globOptions);
|
|||
|
}
|
|||
|
let fixedRootInfo;
|
|||
|
try {
|
|||
|
fixedRootInfo = await _createWalkEntry(fixedRoot);
|
|||
|
} catch (error1) {
|
|||
|
return throwUnlessNotFound(error1);
|
|||
|
}
|
|||
|
async function* advanceMatch(walkInfo, globSegment) {
|
|||
|
if (!walkInfo.isDirectory) {
|
|||
|
return;
|
|||
|
} else if (globSegment == "..") {
|
|||
|
const parentPath = joinGlobs([
|
|||
|
walkInfo.path,
|
|||
|
".."
|
|||
|
], globOptions);
|
|||
|
try {
|
|||
|
if (shouldInclude(parentPath)) {
|
|||
|
return yield await _createWalkEntry(parentPath);
|
|||
|
}
|
|||
|
} catch (error1) {
|
|||
|
throwUnlessNotFound(error1);
|
|||
|
}
|
|||
|
return;
|
|||
|
} else if (globSegment == "**") {
|
|||
|
return yield* walk(walkInfo.path, {
|
|||
|
includeFiles: false,
|
|||
|
skip: excludePatterns
|
|||
|
});
|
|||
|
}
|
|||
|
yield* walk(walkInfo.path, {
|
|||
|
maxDepth: 1,
|
|||
|
match: [
|
|||
|
globToRegExp(joinGlobs([
|
|||
|
walkInfo.path,
|
|||
|
globSegment
|
|||
|
], globOptions), globOptions),
|
|||
|
],
|
|||
|
skip: excludePatterns
|
|||
|
});
|
|||
|
}
|
|||
|
let currentMatches = [
|
|||
|
fixedRootInfo
|
|||
|
];
|
|||
|
for (const segment of segments){
|
|||
|
const nextMatchMap = new Map();
|
|||
|
for (const currentMatch of currentMatches){
|
|||
|
for await (const nextMatch of advanceMatch(currentMatch, segment)){
|
|||
|
nextMatchMap.set(nextMatch.path, nextMatch);
|
|||
|
}
|
|||
|
}
|
|||
|
currentMatches = [
|
|||
|
...nextMatchMap.values()
|
|||
|
].sort(comparePath);
|
|||
|
}
|
|||
|
if (hasTrailingSep) {
|
|||
|
currentMatches = currentMatches.filter((entry)=>entry.isDirectory
|
|||
|
);
|
|||
|
}
|
|||
|
if (!includeDirs) {
|
|||
|
currentMatches = currentMatches.filter((entry)=>!entry.isDirectory
|
|||
|
);
|
|||
|
}
|
|||
|
yield* currentMatches;
|
|||
|
}
|
|||
|
function* expandGlobSync(glob, { root =Deno.cwd() , exclude =[] , includeDirs =true , extended =false , globstar =false } = {
|
|||
|
}) {
|
|||
|
const globOptions = {
|
|||
|
extended,
|
|||
|
globstar
|
|||
|
};
|
|||
|
const absRoot = isAbsolute2(root) ? normalize2(root) : joinGlobs([
|
|||
|
Deno.cwd(),
|
|||
|
root
|
|||
|
], globOptions);
|
|||
|
const resolveFromRoot = (path1)=>isAbsolute2(path1) ? normalize2(path1) : joinGlobs([
|
|||
|
absRoot,
|
|||
|
path1
|
|||
|
], globOptions)
|
|||
|
;
|
|||
|
const excludePatterns = exclude.map(resolveFromRoot).map((s)=>globToRegExp(s, globOptions)
|
|||
|
);
|
|||
|
const shouldInclude = (path1)=>!excludePatterns.some((p)=>!!path1.match(p)
|
|||
|
)
|
|||
|
;
|
|||
|
const { segments , hasTrailingSep , winRoot } = split(resolveFromRoot(glob));
|
|||
|
let fixedRoot = winRoot != undefined ? winRoot : "/";
|
|||
|
while(segments.length > 0 && !isGlob(segments[0])){
|
|||
|
const seg = segments.shift();
|
|||
|
assert(seg != null);
|
|||
|
fixedRoot = joinGlobs([
|
|||
|
fixedRoot,
|
|||
|
seg
|
|||
|
], globOptions);
|
|||
|
}
|
|||
|
let fixedRootInfo;
|
|||
|
try {
|
|||
|
fixedRootInfo = _createWalkEntrySync(fixedRoot);
|
|||
|
} catch (error1) {
|
|||
|
return throwUnlessNotFound(error1);
|
|||
|
}
|
|||
|
function* advanceMatch(walkInfo, globSegment) {
|
|||
|
if (!walkInfo.isDirectory) {
|
|||
|
return;
|
|||
|
} else if (globSegment == "..") {
|
|||
|
const parentPath = joinGlobs([
|
|||
|
walkInfo.path,
|
|||
|
".."
|
|||
|
], globOptions);
|
|||
|
try {
|
|||
|
if (shouldInclude(parentPath)) {
|
|||
|
return yield _createWalkEntrySync(parentPath);
|
|||
|
}
|
|||
|
} catch (error1) {
|
|||
|
throwUnlessNotFound(error1);
|
|||
|
}
|
|||
|
return;
|
|||
|
} else if (globSegment == "**") {
|
|||
|
return yield* walkSync(walkInfo.path, {
|
|||
|
includeFiles: false,
|
|||
|
skip: excludePatterns
|
|||
|
});
|
|||
|
}
|
|||
|
yield* walkSync(walkInfo.path, {
|
|||
|
maxDepth: 1,
|
|||
|
match: [
|
|||
|
globToRegExp(joinGlobs([
|
|||
|
walkInfo.path,
|
|||
|
globSegment
|
|||
|
], globOptions), globOptions),
|
|||
|
],
|
|||
|
skip: excludePatterns
|
|||
|
});
|
|||
|
}
|
|||
|
let currentMatches = [
|
|||
|
fixedRootInfo
|
|||
|
];
|
|||
|
for (const segment of segments){
|
|||
|
const nextMatchMap = new Map();
|
|||
|
for (const currentMatch of currentMatches){
|
|||
|
for (const nextMatch of advanceMatch(currentMatch, segment)){
|
|||
|
nextMatchMap.set(nextMatch.path, nextMatch);
|
|||
|
}
|
|||
|
}
|
|||
|
currentMatches = [
|
|||
|
...nextMatchMap.values()
|
|||
|
].sort(comparePath);
|
|||
|
}
|
|||
|
if (hasTrailingSep) {
|
|||
|
currentMatches = currentMatches.filter((entry)=>entry.isDirectory
|
|||
|
);
|
|||
|
}
|
|||
|
if (!includeDirs) {
|
|||
|
currentMatches = currentMatches.filter((entry)=>!entry.isDirectory
|
|||
|
);
|
|||
|
}
|
|||
|
yield* currentMatches;
|
|||
|
}
|
|||
|
async function move(src, dest, { overwrite =false } = {
|
|||
|
}) {
|
|||
|
const srcStat = await Deno.stat(src);
|
|||
|
if (srcStat.isDirectory && isSubdir(src, dest)) {
|
|||
|
throw new Error(`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`);
|
|||
|
}
|
|||
|
if (overwrite) {
|
|||
|
if (await exists(dest)) {
|
|||
|
await Deno.remove(dest, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
}
|
|||
|
await Deno.rename(src, dest);
|
|||
|
} else {
|
|||
|
if (await exists(dest)) {
|
|||
|
throw new Error("dest already exists.");
|
|||
|
}
|
|||
|
await Deno.rename(src, dest);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
function moveSync(src, dest, { overwrite =false } = {
|
|||
|
}) {
|
|||
|
const srcStat = Deno.statSync(src);
|
|||
|
if (srcStat.isDirectory && isSubdir(src, dest)) {
|
|||
|
throw new Error(`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`);
|
|||
|
}
|
|||
|
if (overwrite) {
|
|||
|
if (existsSync(dest)) {
|
|||
|
Deno.removeSync(dest, {
|
|||
|
recursive: true
|
|||
|
});
|
|||
|
}
|
|||
|
Deno.renameSync(src, dest);
|
|||
|
} else {
|
|||
|
if (existsSync(dest)) {
|
|||
|
throw new Error("dest already exists.");
|
|||
|
}
|
|||
|
Deno.renameSync(src, dest);
|
|||
|
}
|
|||
|
}
|
|||
|
const isWindows2 = Deno.build.os === "windows";
|
|||
|
async function ensureValidCopy(src, dest, options5, isCopyFolder = false) {
|
|||
|
let destStat;
|
|||
|
try {
|
|||
|
destStat = await Deno.lstat(dest);
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
if (isCopyFolder && !destStat.isDirectory) {
|
|||
|
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`);
|
|||
|
}
|
|||
|
if (!options5.overwrite) {
|
|||
|
throw new Error(`'${dest}' already exists.`);
|
|||
|
}
|
|||
|
return destStat;
|
|||
|
}
|
|||
|
function ensureValidCopySync(src, dest, options5, isCopyFolder = false) {
|
|||
|
let destStat;
|
|||
|
try {
|
|||
|
destStat = Deno.lstatSync(dest);
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
return;
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
if (isCopyFolder && !destStat.isDirectory) {
|
|||
|
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`);
|
|||
|
}
|
|||
|
if (!options5.overwrite) {
|
|||
|
throw new Error(`'${dest}' already exists.`);
|
|||
|
}
|
|||
|
return destStat;
|
|||
|
}
|
|||
|
async function copyFile(src, dest, options5) {
|
|||
|
await ensureValidCopy(src, dest, options5);
|
|||
|
await Deno.copyFile(src, dest);
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const statInfo = await Deno.stat(src);
|
|||
|
assert(statInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(statInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
await Deno.utime(dest, statInfo.atime, statInfo.mtime);
|
|||
|
}
|
|||
|
}
|
|||
|
function copyFileSync(src, dest, options5) {
|
|||
|
ensureValidCopySync(src, dest, options5);
|
|||
|
Deno.copyFileSync(src, dest);
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const statInfo = Deno.statSync(src);
|
|||
|
assert(statInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(statInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
|
|||
|
}
|
|||
|
}
|
|||
|
async function copySymLink(src, dest, options5) {
|
|||
|
await ensureValidCopy(src, dest, options5);
|
|||
|
const originSrcFilePath = await Deno.readLink(src);
|
|||
|
const type = getFileInfoType(await Deno.lstat(src));
|
|||
|
if (isWindows2) {
|
|||
|
await Deno.symlink(originSrcFilePath, dest, {
|
|||
|
type: type === "dir" ? "dir" : "file"
|
|||
|
});
|
|||
|
} else {
|
|||
|
await Deno.symlink(originSrcFilePath, dest);
|
|||
|
}
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const statInfo = await Deno.lstat(src);
|
|||
|
assert(statInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(statInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
await Deno.utime(dest, statInfo.atime, statInfo.mtime);
|
|||
|
}
|
|||
|
}
|
|||
|
function copySymlinkSync(src, dest, options5) {
|
|||
|
ensureValidCopySync(src, dest, options5);
|
|||
|
const originSrcFilePath = Deno.readLinkSync(src);
|
|||
|
const type = getFileInfoType(Deno.lstatSync(src));
|
|||
|
if (isWindows2) {
|
|||
|
Deno.symlinkSync(originSrcFilePath, dest, {
|
|||
|
type: type === "dir" ? "dir" : "file"
|
|||
|
});
|
|||
|
} else {
|
|||
|
Deno.symlinkSync(originSrcFilePath, dest);
|
|||
|
}
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const statInfo = Deno.lstatSync(src);
|
|||
|
assert(statInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(statInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
|
|||
|
}
|
|||
|
}
|
|||
|
async function copyDir(src, dest, options5) {
|
|||
|
const destStat = await ensureValidCopy(src, dest, options5, true);
|
|||
|
if (!destStat) {
|
|||
|
await ensureDir(dest);
|
|||
|
}
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const srcStatInfo = await Deno.stat(src);
|
|||
|
assert(srcStatInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(srcStatInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
await Deno.utime(dest, srcStatInfo.atime, srcStatInfo.mtime);
|
|||
|
}
|
|||
|
for await (const entry of Deno.readDir(src)){
|
|||
|
const srcPath = join2(src, entry.name);
|
|||
|
const destPath = join2(dest, basename2(srcPath));
|
|||
|
if (entry.isSymlink) {
|
|||
|
await copySymLink(srcPath, destPath, options5);
|
|||
|
} else if (entry.isDirectory) {
|
|||
|
await copyDir(srcPath, destPath, options5);
|
|||
|
} else if (entry.isFile) {
|
|||
|
await copyFile(srcPath, destPath, options5);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
function copyDirSync(src, dest, options5) {
|
|||
|
const destStat = ensureValidCopySync(src, dest, options5, true);
|
|||
|
if (!destStat) {
|
|||
|
ensureDirSync(dest);
|
|||
|
}
|
|||
|
if (options5.preserveTimestamps) {
|
|||
|
const srcStatInfo = Deno.statSync(src);
|
|||
|
assert(srcStatInfo.atime instanceof Date, `statInfo.atime is unavailable`);
|
|||
|
assert(srcStatInfo.mtime instanceof Date, `statInfo.mtime is unavailable`);
|
|||
|
Deno.utimeSync(dest, srcStatInfo.atime, srcStatInfo.mtime);
|
|||
|
}
|
|||
|
for (const entry of Deno.readDirSync(src)){
|
|||
|
assert(entry.name != null, "file.name must be set");
|
|||
|
const srcPath = join2(src, entry.name);
|
|||
|
const destPath = join2(dest, basename2(srcPath));
|
|||
|
if (entry.isSymlink) {
|
|||
|
copySymlinkSync(srcPath, destPath, options5);
|
|||
|
} else if (entry.isDirectory) {
|
|||
|
copyDirSync(srcPath, destPath, options5);
|
|||
|
} else if (entry.isFile) {
|
|||
|
copyFileSync(srcPath, destPath, options5);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
async function copy(src, dest, options5 = {
|
|||
|
}) {
|
|||
|
src = resolve2(src);
|
|||
|
dest = resolve2(dest);
|
|||
|
if (src === dest) {
|
|||
|
throw new Error("Source and destination cannot be the same.");
|
|||
|
}
|
|||
|
const srcStat = await Deno.lstat(src);
|
|||
|
if (srcStat.isDirectory && isSubdir(src, dest)) {
|
|||
|
throw new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`);
|
|||
|
}
|
|||
|
if (srcStat.isSymlink) {
|
|||
|
await copySymLink(src, dest, options5);
|
|||
|
} else if (srcStat.isDirectory) {
|
|||
|
await copyDir(src, dest, options5);
|
|||
|
} else if (srcStat.isFile) {
|
|||
|
await copyFile(src, dest, options5);
|
|||
|
}
|
|||
|
}
|
|||
|
function copySync(src, dest, options5 = {
|
|||
|
}) {
|
|||
|
src = resolve2(src);
|
|||
|
dest = resolve2(dest);
|
|||
|
if (src === dest) {
|
|||
|
throw new Error("Source and destination cannot be the same.");
|
|||
|
}
|
|||
|
const srcStat = Deno.lstatSync(src);
|
|||
|
if (srcStat.isDirectory && isSubdir(src, dest)) {
|
|||
|
throw new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`);
|
|||
|
}
|
|||
|
if (srcStat.isSymlink) {
|
|||
|
copySymlinkSync(src, dest, options5);
|
|||
|
} else if (srcStat.isDirectory) {
|
|||
|
copyDirSync(src, dest, options5);
|
|||
|
} else if (srcStat.isFile) {
|
|||
|
copyFileSync(src, dest, options5);
|
|||
|
}
|
|||
|
}
|
|||
|
var EOL;
|
|||
|
(function(EOL1) {
|
|||
|
EOL1["LF"] = "\n";
|
|||
|
EOL1["CRLF"] = "\r\n";
|
|||
|
})(EOL || (EOL = {
|
|||
|
}));
|
|||
|
const regDetect = /(?:\r?\n)/g;
|
|||
|
function detect(content) {
|
|||
|
const d = content.match(regDetect);
|
|||
|
if (!d || d.length === 0) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const crlf = d.filter((x)=>x === EOL.CRLF
|
|||
|
);
|
|||
|
if (crlf.length > 0) {
|
|||
|
return EOL.CRLF;
|
|||
|
} else {
|
|||
|
return EOL.LF;
|
|||
|
}
|
|||
|
}
|
|||
|
function format3(content, eol) {
|
|||
|
return content.replace(regDetect, eol);
|
|||
|
}
|
|||
|
const mod5 = function() {
|
|||
|
return {
|
|||
|
exists,
|
|||
|
existsSync,
|
|||
|
emptyDir,
|
|||
|
emptyDirSync,
|
|||
|
ensureDir,
|
|||
|
ensureDirSync,
|
|||
|
ensureFile,
|
|||
|
ensureFileSync,
|
|||
|
ensureLink,
|
|||
|
ensureLinkSync,
|
|||
|
ensureSymlink,
|
|||
|
ensureSymlinkSync,
|
|||
|
expandGlob,
|
|||
|
expandGlobSync,
|
|||
|
move,
|
|||
|
moveSync,
|
|||
|
copy,
|
|||
|
copySync,
|
|||
|
_createWalkEntrySync,
|
|||
|
_createWalkEntry,
|
|||
|
walk,
|
|||
|
walkSync,
|
|||
|
EOL,
|
|||
|
detect,
|
|||
|
format: format3
|
|||
|
};
|
|||
|
}();
|
|||
|
const base64abc = [
|
|||
|
"A",
|
|||
|
"B",
|
|||
|
"C",
|
|||
|
"D",
|
|||
|
"E",
|
|||
|
"F",
|
|||
|
"G",
|
|||
|
"H",
|
|||
|
"I",
|
|||
|
"J",
|
|||
|
"K",
|
|||
|
"L",
|
|||
|
"M",
|
|||
|
"N",
|
|||
|
"O",
|
|||
|
"P",
|
|||
|
"Q",
|
|||
|
"R",
|
|||
|
"S",
|
|||
|
"T",
|
|||
|
"U",
|
|||
|
"V",
|
|||
|
"W",
|
|||
|
"X",
|
|||
|
"Y",
|
|||
|
"Z",
|
|||
|
"a",
|
|||
|
"b",
|
|||
|
"c",
|
|||
|
"d",
|
|||
|
"e",
|
|||
|
"f",
|
|||
|
"g",
|
|||
|
"h",
|
|||
|
"i",
|
|||
|
"j",
|
|||
|
"k",
|
|||
|
"l",
|
|||
|
"m",
|
|||
|
"n",
|
|||
|
"o",
|
|||
|
"p",
|
|||
|
"q",
|
|||
|
"r",
|
|||
|
"s",
|
|||
|
"t",
|
|||
|
"u",
|
|||
|
"v",
|
|||
|
"w",
|
|||
|
"x",
|
|||
|
"y",
|
|||
|
"z",
|
|||
|
"0",
|
|||
|
"1",
|
|||
|
"2",
|
|||
|
"3",
|
|||
|
"4",
|
|||
|
"5",
|
|||
|
"6",
|
|||
|
"7",
|
|||
|
"8",
|
|||
|
"9",
|
|||
|
"+",
|
|||
|
"/"
|
|||
|
];
|
|||
|
function encode(data) {
|
|||
|
const uint8 = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data);
|
|||
|
let result = "", i;
|
|||
|
const l = uint8.length;
|
|||
|
for(i = 2; i < l; i += 3){
|
|||
|
result += base64abc[uint8[i - 2] >> 2];
|
|||
|
result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
|
|||
|
result += base64abc[(uint8[i - 1] & 15) << 2 | uint8[i] >> 6];
|
|||
|
result += base64abc[uint8[i] & 63];
|
|||
|
}
|
|||
|
if (i === l + 1) {
|
|||
|
result += base64abc[uint8[i - 2] >> 2];
|
|||
|
result += base64abc[(uint8[i - 2] & 3) << 4];
|
|||
|
result += "==";
|
|||
|
}
|
|||
|
if (i === l) {
|
|||
|
result += base64abc[uint8[i - 2] >> 2];
|
|||
|
result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4];
|
|||
|
result += base64abc[(uint8[i - 1] & 15) << 2];
|
|||
|
result += "=";
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
function decode(b64) {
|
|||
|
const binString = atob(b64);
|
|||
|
const size4 = binString.length;
|
|||
|
const bytes = new Uint8Array(size4);
|
|||
|
for(let i = 0; i < size4; i++){
|
|||
|
bytes[i] = binString.charCodeAt(i);
|
|||
|
}
|
|||
|
return bytes;
|
|||
|
}
|
|||
|
const importMeta = {
|
|||
|
url: "<https://deno.land/std@0.77.0/hash/_wasm/wasm.js>",
|
|||
|
main: false
|
|||
|
};
|
|||
|
const source = decode("AGFzbQEAAAABSQxgAn9/AGACf38Bf2ADf39/AGADf39/AX9gAX8AYAF/AX9gAABgBH9/f38Bf2AFf39/f38AYAV/f39/fwF/YAJ+fwF/YAF/AX4CTQMDd2JnFV9fd2JpbmRnZW5fc3RyaW5nX25ldwABA3diZxBfX3diaW5kZ2VuX3Rocm93AAADd2JnEl9fd2JpbmRnZW5fcmV0aHJvdwAEA6sBqQEAAgEAAAIFAAACAAQABAADAAAAAQcJAAAAAAAAAAAAAAAAAAAAAAICAgIAAAAAAAAAAAAAAAAAAAACAgICBAAAAgAAAQAAAAAAAAAAAAAAAAAECgEEAQIAAAAAAgIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAgICAAEGAAMEAgcEAgQEAwMFBAQAAwQDAQEBAQQABwYBBgYBAAELBQUFBQUFBQAEBAUBcAFpaQUDAQARBgkBfwFBgIDAAAsHoQEJBm1lbW9yeQIAE19fd2JnX2Rlbm9oYXNoX2ZyZWUAhAELY3JlYXRlX2hhc2gABQt1cGRhdGVfaGFzaACFAQtkaWdlc3RfaGFzaACCARFfX3diaW5kZ2VuX21hbGxvYwCNARJfX3diaW5kZ2VuX3JlYWxsb2MAkwETX193YmluZGdlbl9leHBvcnRfMgMAD19fd2JpbmRnZW5fZnJlZQCZAQmPAQEAQQELaJcBqgGcAZYBnwFYqwFDDy5XowE3PEFIkgGjAWA/QkliPi9EjgGlAVI9GSiHAaQBR2EwRY8BU18nOooBqAFQIS2JAakBUVkTHnunAUsVJnqmAUoqNjiYAagBcSkyNJgBqQF1LBocmAGnAXQrIiSYAaYBdzU5cDEzeBsddiMlc4wBVoABlQGiAZQBCsixBqkBjEwBVn4gACABKQN4IgIgASkDSCIaIAEpAwAiFyABKQMIIgtCOIkgC0IHiIUgC0I/iYV8fCABKQNwIgNCA4kgA0IGiIUgA0ItiYV8IgRCOIkgBEIHiIUgBEI/iYV8IAEpA1AiPiABKQMQIglCOIkgCUIHiIUgCUI/iYUgC3x8IAJCBoggAkIDiYUgAkItiYV8IgcgASkDQCITIBpCB4ggGkI4iYUgGkI/iYV8fCABKQMwIhQgASkDOCJCQjiJIEJCB4iFIEJCP4mFfCACfCABKQNoIkQgASkDICIVIAEpAygiQ0I4iSBDQgeIhSBDQj+JhXx8IAEpA1giPyABKQMYIgpCOIkgCkIHiIUgCkI/iYUgCXx8IARCBoggBEIDiYUgBEItiYV8IgZCA4kgBkIGiIUgBkItiYV8IgVCA4kgBUIGiIUgBUItiYV8IghCA4kgCEIGiIUgCEItiYV8Igx8IANCB4ggA0I4iYUgA0I/iYUgRHwgCHwgASkDYCJAQjiJIEBCB4iFIEBCP4mFID98IAV8ID5CB4ggPkI4iYUgPkI/iYUgGnwgBnwgE0IHiCATQjiJhSATQj+JhSBCfCAEfCAUQgeIIBRCOImFIBRCP4mFIEN8IAN8IBVCB4ggFUI4iYUgFUI/iYUgCnwgQHwgB0IGiCAHQgOJhSAHQi2JhXwiDUIDiSANQgaIhSANQi2JhXwiDkIDiSAOQgaIhSAOQi2JhXwiEEIDiSAQQgaIhSAQQi2JhXwiEUIDiSARQgaIhSARQi2JhXwiFkIDiSAWQgaIhSAWQi2JhXwiGEIDiSAYQgaIhSAYQi2JhXwiGUI4iSAZQgeIhSAZQj+JhSACQgeIIAJCOImFIAJCP4mFIAN8IBB8IERCB4ggREI4iYUgREI/iYUgQHwgDnwgP0IHiCA/QjiJhSA/Qj+JhSA+fCANfCAMQgaIIAxCA4mFIAxCLYmFfCIbQgOJIBtCBoiFIBtCLYmFfCIcQgOJIBxCBoiFIBxCLYmFfCIdfCAHQgeIIAdCOImFIAdCP4mFIAR8IBF8IB1CBoggHUIDiYUgHUItiYV8Ih4gDEIHiCAMQjiJhSAMQj+JhSAQfHwgCEIHiCAIQjiJhSAIQj+JhSAOfCAdfCAFQgeIIAVCOImFIAVCP4mFIA18IBx8IAZCB4ggBkI4iYUgBkI/iYUgB3wgG3wgGUIGiCAZQgOJhSAZQi2JhXwiH0IDiSAfQgaIhSAfQi2JhXwiIEIDiSAgQgaIhSAgQi2JhXwiIUIDiSAhQgaIhSAhQi2JhXwiInwgGEIHiCAYQjiJhSAYQj+JhSAcfCAhfCAWQgeIIBZCOImFIBZCP4mFIBt8ICB8IBFCB4ggEUI4iYUgEUI/iYUgDHwgH3wgEEIHiCAQQjiJhSAQQj+JhSAIfCAZfCAOQgeIIA5COImFIA5CP4mFIAV8IBh8IA1CB4ggDUI4iYUgDUI/iYUgBnwgFnwgHkIGiCAeQgOJhSAeQi2JhXwiI0IDiSAjQgaIhSAjQi2JhXwiJEIDiSAkQgaIhSAkQi2JhXwiJUIDiSAlQgaIhSAlQi2JhXwiJkIDiSAmQgaIhSAmQi2JhXwiJ0IDiSAnQgaIhSAnQi2JhXwiKEIDiSAoQgaIhSAoQi2JhXwiKUI4iSApQgeIhSApQj+JhSAdQgeIIB1COImFIB1CP4mFIBh8ICV8IBxCB4ggHEI4iYUgHEI/iYUgFnwgJHwgG0IHiCAbQjiJhSAbQj+JhSARfCAjfCAiQgaIICJCA4mFICJCLYmFfCIqQgOJICpCBoiFICpCLYmFfCIrQgOJICtCBoiFICtCLYmFfCIsfCAeQgeIIB5COImFIB5CP4mFIBl8ICZ8ICxCBoggLEIDiYUgLEItiYV8Ii0gIkIHiCAiQjiJhSAiQj+JhSAlfHwgIUIHiCAhQjiJhSAhQj+JhSAkfCAsfCAgQgeIICBCOImFICBCP4mFICN8ICt8IB9CB4ggH0I4iYUgH0I/iYUgHnwgKnwgKUIGiCApQgOJhSApQi2JhXwiLkIDiSAuQgaIhSAuQi2JhXwiL0IDiSAvQgaIhSAvQi2JhXwiMEIDiSAwQgaIhSAwQi2JhXwiMXwgKEIHiCAoQjiJhSAoQj+JhSArfCAwfCAnQgeIICdCOImFICdCP4mFICp8IC98ICZCB4ggJkI4iYUgJkI/iYUgInwgLnwgJUIHiCAlQjiJhSAlQj+JhSAhfCApfCAkQgeIICRCOImFICRCP4mFICB8ICh8ICNCB4ggI0I4iYUgI0I/iYUgH3wgJ3wgLUIGiCAtQgOJhSAtQi2JhXwiMkIDiSAyQgaIhSAyQi2JhXwiM0IDiSAzQgaIhSAzQi2JhXwiNEIDiSA0QgaIhSA0Qi2JhXwiNUIDiSA1QgaIhSA1Qi2JhXwiNkIDiSA2QgaIhSA2Qi2JhXwiN0IDiSA3QgaIhSA3Qi2JhXwiOEI4iSA4QgeIhSA4Qj+JhSAsQgeIICxCOImFICxCP4mFICh8IDR8ICtCB4ggK0I4iYUgK0I/iYUgJ3wgM3wgKkIHiCAqQjiJhSAqQj+JhSAmfCAyfCAxQgaIIDFCA4mFIDFCLYmFfCI5QgOJIDlCBoiFIDlCLYmFfCI6QgOJIDpCBoiFIDpCLYmFfCI7fCAtQgeIIC1COImFIC1CP4mFICl8IDV8IDtCBoggO0IDiYUgO0ItiYV8IjwgMUIHiCAxQjiJhSAxQj+JhSA0fHwgMEIHiCAwQjiJhSAwQj+JhSAzfCA7fCAvQgeIIC9COImFIC9CP4mFIDJ8IDp8IC5CB4ggLkI4iYUgLkI/iYUgLXwgOXwgOEIGiCA4QgOJhSA4Qi2JhXwiPUIDiSA9QgaIhSA9Qi2JhXwiRkIDiSBGQgaIhSBGQi2JhXwiR0IDiSBHQgaIhSBHQi2JhXwiSHwgN0IHiCA3QjiJhSA3Qj+JhSA6fCBHfCA2QgeIIDZCOImFIDZCP4mFIDl8IEZ8IDVCB4ggNUI4iYUgNUI/iYUgMXwgPXwgNEIHiCA0QjiJhSA0Qj+JhSAwfCA4fCAzQgeIIDNCOImFIDNCP4mFIC98IDd8IDJCB4ggMkI4iYUgMkI/iYUgLnwgNnwgPEIGiCA8QgOJhSA8Qi2JhXwiQUIDiSBBQgaIhSBBQi2JhXwiSUID
|
|||
|
let wasm;
|
|||
|
let cachedTextDecoder = new TextDecoder('utf-8', {
|
|||
|
ignoreBOM: true,
|
|||
|
fatal: true
|
|||
|
});
|
|||
|
cachedTextDecoder.decode();
|
|||
|
let cachegetUint8Memory0 = null;
|
|||
|
function getUint8Memory0() {
|
|||
|
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
|||
|
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
|||
|
}
|
|||
|
return cachegetUint8Memory0;
|
|||
|
}
|
|||
|
function getStringFromWasm0(ptr, len) {
|
|||
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
|||
|
}
|
|||
|
const heap = new Array(32).fill(undefined);
|
|||
|
heap.push(undefined, null, true, false);
|
|||
|
let heap_next = heap.length;
|
|||
|
function addHeapObject(obj) {
|
|||
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|||
|
const idx = heap_next;
|
|||
|
heap_next = heap[idx];
|
|||
|
heap[idx] = obj;
|
|||
|
return idx;
|
|||
|
}
|
|||
|
function getObject(idx) {
|
|||
|
return heap[idx];
|
|||
|
}
|
|||
|
function dropObject(idx) {
|
|||
|
if (idx < 36) return;
|
|||
|
heap[idx] = heap_next;
|
|||
|
heap_next = idx;
|
|||
|
}
|
|||
|
function takeObject(idx) {
|
|||
|
const ret = getObject(idx);
|
|||
|
dropObject(idx);
|
|||
|
return ret;
|
|||
|
}
|
|||
|
let WASM_VECTOR_LEN = 0;
|
|||
|
let cachedTextEncoder = new TextEncoder('utf-8');
|
|||
|
const encodeString = typeof cachedTextEncoder.encodeInto === 'function' ? function(arg, view) {
|
|||
|
return cachedTextEncoder.encodeInto(arg, view);
|
|||
|
} : function(arg, view) {
|
|||
|
const buf = cachedTextEncoder.encode(arg);
|
|||
|
view.set(buf);
|
|||
|
return {
|
|||
|
read: arg.length,
|
|||
|
written: buf.length
|
|||
|
};
|
|||
|
};
|
|||
|
function passStringToWasm0(arg, malloc, realloc) {
|
|||
|
if (realloc === undefined) {
|
|||
|
const buf = cachedTextEncoder.encode(arg);
|
|||
|
const ptr = malloc(buf.length);
|
|||
|
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
|
|||
|
WASM_VECTOR_LEN = buf.length;
|
|||
|
return ptr;
|
|||
|
}
|
|||
|
let len = arg.length;
|
|||
|
let ptr = malloc(len);
|
|||
|
const mem = getUint8Memory0();
|
|||
|
let offset = 0;
|
|||
|
for(; offset < len; offset++){
|
|||
|
const code1 = arg.charCodeAt(offset);
|
|||
|
if (code1 > 127) break;
|
|||
|
mem[ptr + offset] = code1;
|
|||
|
}
|
|||
|
if (offset !== len) {
|
|||
|
if (offset !== 0) {
|
|||
|
arg = arg.slice(offset);
|
|||
|
}
|
|||
|
ptr = realloc(ptr, len, len = offset + arg.length * 3);
|
|||
|
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
|||
|
const ret = encodeString(arg, view);
|
|||
|
offset += ret.written;
|
|||
|
}
|
|||
|
WASM_VECTOR_LEN = offset;
|
|||
|
return ptr;
|
|||
|
}
|
|||
|
function create_hash(algorithm) {
|
|||
|
var ptr0 = passStringToWasm0(algorithm, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|||
|
var len0 = WASM_VECTOR_LEN;
|
|||
|
var ret = wasm.create_hash(ptr0, len0);
|
|||
|
return DenoHash.__wrap(ret);
|
|||
|
}
|
|||
|
function _assertClass(instance, klass) {
|
|||
|
if (!(instance instanceof klass)) {
|
|||
|
throw new Error(`expected instance of ${klass.name}`);
|
|||
|
}
|
|||
|
return instance.ptr;
|
|||
|
}
|
|||
|
function passArray8ToWasm0(arg, malloc) {
|
|||
|
const ptr = malloc(arg.length * 1);
|
|||
|
getUint8Memory0().set(arg, ptr / 1);
|
|||
|
WASM_VECTOR_LEN = arg.length;
|
|||
|
return ptr;
|
|||
|
}
|
|||
|
function update_hash(hash, data) {
|
|||
|
_assertClass(hash, DenoHash);
|
|||
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|||
|
var len0 = WASM_VECTOR_LEN;
|
|||
|
wasm.update_hash(hash.ptr, ptr0, len0);
|
|||
|
}
|
|||
|
let cachegetInt32Memory0 = null;
|
|||
|
function getInt32Memory0() {
|
|||
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
|||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
|||
|
}
|
|||
|
return cachegetInt32Memory0;
|
|||
|
}
|
|||
|
function getArrayU8FromWasm0(ptr, len) {
|
|||
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
|||
|
}
|
|||
|
function digest_hash(hash) {
|
|||
|
try {
|
|||
|
const retptr = wasm.__wbindgen_export_2.value - 16;
|
|||
|
wasm.__wbindgen_export_2.value = retptr;
|
|||
|
_assertClass(hash, DenoHash);
|
|||
|
wasm.digest_hash(retptr, hash.ptr);
|
|||
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
|||
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
|||
|
var v0 = getArrayU8FromWasm0(r0, r1).slice();
|
|||
|
wasm.__wbindgen_free(r0, r1 * 1);
|
|||
|
return v0;
|
|||
|
} finally{
|
|||
|
wasm.__wbindgen_export_2.value += 16;
|
|||
|
}
|
|||
|
}
|
|||
|
class DenoHash {
|
|||
|
static __wrap(ptr) {
|
|||
|
const obj = Object.create(DenoHash.prototype);
|
|||
|
obj.ptr = ptr;
|
|||
|
return obj;
|
|||
|
}
|
|||
|
free() {
|
|||
|
const ptr = this.ptr;
|
|||
|
this.ptr = 0;
|
|||
|
wasm.__wbg_denohash_free(ptr);
|
|||
|
}
|
|||
|
}
|
|||
|
async function load(module, imports) {
|
|||
|
if (typeof Response === 'function' && module instanceof Response) {
|
|||
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
|||
|
try {
|
|||
|
return await WebAssembly.instantiateStreaming(module, imports);
|
|||
|
} catch (e) {
|
|||
|
if (module.headers.get('Content-Type') != 'application/wasm') {
|
|||
|
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
|||
|
} else {
|
|||
|
throw e;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
const bytes = await module.arrayBuffer();
|
|||
|
return await WebAssembly.instantiate(bytes, imports);
|
|||
|
} else {
|
|||
|
const instance = await WebAssembly.instantiate(module, imports);
|
|||
|
if (instance instanceof WebAssembly.Instance) {
|
|||
|
return {
|
|||
|
instance,
|
|||
|
module
|
|||
|
};
|
|||
|
} else {
|
|||
|
return instance;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
async function init(input) {
|
|||
|
if (typeof input === 'undefined') {
|
|||
|
input = importMeta.url.replace(/\.js$/, '_bg.wasm');
|
|||
|
}
|
|||
|
const imports = {
|
|||
|
};
|
|||
|
imports.wbg = {
|
|||
|
};
|
|||
|
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
|||
|
var ret = getStringFromWasm0(arg0, arg1);
|
|||
|
return addHeapObject(ret);
|
|||
|
};
|
|||
|
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
|||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
|||
|
};
|
|||
|
imports.wbg.__wbindgen_rethrow = function(arg0) {
|
|||
|
throw takeObject(arg0);
|
|||
|
};
|
|||
|
if (typeof input === 'string' || typeof Request === 'function' && input instanceof Request || typeof URL === 'function' && input instanceof URL) {
|
|||
|
input = fetch(input);
|
|||
|
}
|
|||
|
const { instance , module } = await load(await input, imports);
|
|||
|
wasm = instance.exports;
|
|||
|
init.__wbindgen_wasm_module = module;
|
|||
|
return wasm;
|
|||
|
}
|
|||
|
const hextable = new TextEncoder().encode("0123456789abcdef");
|
|||
|
function encodedLen(n) {
|
|||
|
return n * 2;
|
|||
|
}
|
|||
|
function encode1(src) {
|
|||
|
const dst = new Uint8Array(encodedLen(src.length));
|
|||
|
for(let i = 0; i < dst.length; i++){
|
|||
|
const v = src[i];
|
|||
|
dst[i * 2] = hextable[v >> 4];
|
|||
|
dst[i * 2 + 1] = hextable[v & 15];
|
|||
|
}
|
|||
|
return dst;
|
|||
|
}
|
|||
|
function encodeToString(src) {
|
|||
|
return new TextDecoder().decode(encode1(src));
|
|||
|
}
|
|||
|
await init(source);
|
|||
|
const TYPE_ERROR_MSG = "hash: `data` is invalid type";
|
|||
|
class Hash {
|
|||
|
#hash;
|
|||
|
#digested;
|
|||
|
constructor(algorithm){
|
|||
|
this.#hash = create_hash(algorithm);
|
|||
|
this.#digested = false;
|
|||
|
}
|
|||
|
update(data) {
|
|||
|
let msg;
|
|||
|
if (typeof data === "string") {
|
|||
|
msg = new TextEncoder().encode(data);
|
|||
|
} else if (typeof data === "object") {
|
|||
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|||
|
msg = new Uint8Array(data);
|
|||
|
} else {
|
|||
|
throw new Error(TYPE_ERROR_MSG);
|
|||
|
}
|
|||
|
} else {
|
|||
|
throw new Error(TYPE_ERROR_MSG);
|
|||
|
}
|
|||
|
update_hash(this.#hash, msg);
|
|||
|
return this;
|
|||
|
}
|
|||
|
digest() {
|
|||
|
if (this.#digested) throw new Error("hash: already digested");
|
|||
|
this.#digested = true;
|
|||
|
return digest_hash(this.#hash);
|
|||
|
}
|
|||
|
toString(format = "hex") {
|
|||
|
const finalized = new Uint8Array(this.digest());
|
|||
|
switch(format){
|
|||
|
case "hex":
|
|||
|
return encodeToString(finalized);
|
|||
|
case "base64":
|
|||
|
return encode(finalized);
|
|||
|
default:
|
|||
|
throw new Error("hash: invalid format");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
function createHash(algorithm1) {
|
|||
|
return new Hash(algorithm1);
|
|||
|
}
|
|||
|
const mod6 = function() {
|
|||
|
return {
|
|||
|
createHash: createHash
|
|||
|
};
|
|||
|
}();
|
|||
|
const SEMVER_SPEC_VERSION = "2.0.0";
|
|||
|
const MAX_SAFE_COMPONENT_LENGTH = 16;
|
|||
|
const re = [];
|
|||
|
const src = [];
|
|||
|
let R = 0;
|
|||
|
const NUMERICIDENTIFIER = R++;
|
|||
|
src[NUMERICIDENTIFIER] = "0|[1-9]\\d*";
|
|||
|
const NUMERICIDENTIFIERLOOSE = R++;
|
|||
|
src[NUMERICIDENTIFIERLOOSE] = "[0-9]+";
|
|||
|
const NONNUMERICIDENTIFIER = R++;
|
|||
|
src[NONNUMERICIDENTIFIER] = "\\d*[a-zA-Z-][a-zA-Z0-9-]*";
|
|||
|
const MAINVERSION = R++;
|
|||
|
const nid = src[NUMERICIDENTIFIER];
|
|||
|
src[MAINVERSION] = `(${nid})\\.(${nid})\\.(${nid})`;
|
|||
|
const MAINVERSIONLOOSE = R++;
|
|||
|
const nidl = src[NUMERICIDENTIFIERLOOSE];
|
|||
|
src[MAINVERSIONLOOSE] = `(${nidl})\\.(${nidl})\\.(${nidl})`;
|
|||
|
const PRERELEASEIDENTIFIER = R++;
|
|||
|
src[PRERELEASEIDENTIFIER] = "(?:" + src[NUMERICIDENTIFIER] + "|" + src[NONNUMERICIDENTIFIER] + ")";
|
|||
|
const PRERELEASEIDENTIFIERLOOSE = R++;
|
|||
|
src[PRERELEASEIDENTIFIERLOOSE] = "(?:" + src[NUMERICIDENTIFIERLOOSE] + "|" + src[NONNUMERICIDENTIFIER] + ")";
|
|||
|
const PRERELEASE = R++;
|
|||
|
src[PRERELEASE] = "(?:-(" + src[PRERELEASEIDENTIFIER] + "(?:\\." + src[PRERELEASEIDENTIFIER] + ")*))";
|
|||
|
const PRERELEASELOOSE = R++;
|
|||
|
src[PRERELEASELOOSE] = "(?:-?(" + src[PRERELEASEIDENTIFIERLOOSE] + "(?:\\." + src[PRERELEASEIDENTIFIERLOOSE] + ")*))";
|
|||
|
const BUILDIDENTIFIER = R++;
|
|||
|
src[BUILDIDENTIFIER] = "[0-9A-Za-z-]+";
|
|||
|
const BUILD = R++;
|
|||
|
src[BUILD] = "(?:\\+(" + src[BUILDIDENTIFIER] + "(?:\\." + src[BUILDIDENTIFIER] + ")*))";
|
|||
|
const FULL = R++;
|
|||
|
const FULLPLAIN = "v?" + src[MAINVERSION] + src[PRERELEASE] + "?" + src[BUILD] + "?";
|
|||
|
src[FULL] = "^" + FULLPLAIN + "$";
|
|||
|
const LOOSEPLAIN = "[v=\\s]*" + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + "?" + src[BUILD] + "?";
|
|||
|
const LOOSE = R++;
|
|||
|
src[LOOSE] = "^" + LOOSEPLAIN + "$";
|
|||
|
const GTLT = R++;
|
|||
|
src[GTLT] = "((?:<|>)?=?)";
|
|||
|
const XRANGEIDENTIFIERLOOSE = R++;
|
|||
|
src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + "|x|X|\\*";
|
|||
|
const XRANGEIDENTIFIER = R++;
|
|||
|
src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + "|x|X|\\*";
|
|||
|
const XRANGEPLAIN = R++;
|
|||
|
src[XRANGEPLAIN] = "[v=\\s]*(" + src[XRANGEIDENTIFIER] + ")" + "(?:\\.(" + src[XRANGEIDENTIFIER] + ")" + "(?:\\.(" + src[XRANGEIDENTIFIER] + ")" + "(?:" + src[PRERELEASE] + ")?" + src[BUILD] + "?" + ")?)?";
|
|||
|
const XRANGEPLAINLOOSE = R++;
|
|||
|
src[XRANGEPLAINLOOSE] = "[v=\\s]*(" + src[XRANGEIDENTIFIERLOOSE] + ")" + "(?:\\.(" + src[XRANGEIDENTIFIERLOOSE] + ")" + "(?:\\.(" + src[XRANGEIDENTIFIERLOOSE] + ")" + "(?:" + src[PRERELEASELOOSE] + ")?" + src[BUILD] + "?" + ")?)?";
|
|||
|
const XRANGE = R++;
|
|||
|
src[XRANGE] = "^" + src[GTLT] + "\\s*" + src[XRANGEPLAIN] + "$";
|
|||
|
const XRANGELOOSE = R++;
|
|||
|
src[XRANGELOOSE] = "^" + src[GTLT] + "\\s*" + src[XRANGEPLAINLOOSE] + "$";
|
|||
|
const COERCE = R++;
|
|||
|
src[COERCE] = "(?:^|[^\\d])" + "(\\d{1," + MAX_SAFE_COMPONENT_LENGTH + "})" + "(?:\\.(\\d{1," + MAX_SAFE_COMPONENT_LENGTH + "}))?" + "(?:\\.(\\d{1," + MAX_SAFE_COMPONENT_LENGTH + "}))?" + "(?:$|[^\\d])";
|
|||
|
const LONETILDE = R++;
|
|||
|
src[LONETILDE] = "(?:~>?)";
|
|||
|
const TILDETRIM = R++;
|
|||
|
src[TILDETRIM] = "(\\s*)" + src[LONETILDE] + "\\s+";
|
|||
|
re[TILDETRIM] = new RegExp(src[TILDETRIM], "g");
|
|||
|
const tildeTrimReplace = "$1~";
|
|||
|
const TILDE = R++;
|
|||
|
src[TILDE] = "^" + src[LONETILDE] + src[XRANGEPLAIN] + "$";
|
|||
|
const TILDELOOSE = R++;
|
|||
|
src[TILDELOOSE] = "^" + src[LONETILDE] + src[XRANGEPLAINLOOSE] + "$";
|
|||
|
const LONECARET = R++;
|
|||
|
src[LONECARET] = "(?:\\^)";
|
|||
|
const CARETTRIM = R++;
|
|||
|
src[CARETTRIM] = "(\\s*)" + src[LONECARET] + "\\s+";
|
|||
|
re[CARETTRIM] = new RegExp(src[CARETTRIM], "g");
|
|||
|
const caretTrimReplace = "$1^";
|
|||
|
const CARET = R++;
|
|||
|
src[CARET] = "^" + src[LONECARET] + src[XRANGEPLAIN] + "$";
|
|||
|
const CARETLOOSE = R++;
|
|||
|
src[CARETLOOSE] = "^" + src[LONECARET] + src[XRANGEPLAINLOOSE] + "$";
|
|||
|
const COMPARATORLOOSE = R++;
|
|||
|
src[COMPARATORLOOSE] = "^" + src[GTLT] + "\\s*(" + LOOSEPLAIN + ")$|^$";
|
|||
|
const COMPARATOR = R++;
|
|||
|
src[COMPARATOR] = "^" + src[GTLT] + "\\s*(" + FULLPLAIN + ")$|^$";
|
|||
|
const COMPARATORTRIM = R++;
|
|||
|
src[COMPARATORTRIM] = "(\\s*)" + src[GTLT] + "\\s*(" + LOOSEPLAIN + "|" + src[XRANGEPLAIN] + ")";
|
|||
|
re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], "g");
|
|||
|
const comparatorTrimReplace = "$1$2$3";
|
|||
|
const HYPHENRANGE = R++;
|
|||
|
src[HYPHENRANGE] = "^\\s*(" + src[XRANGEPLAIN] + ")" + "\\s+-\\s+" + "(" + src[XRANGEPLAIN] + ")" + "\\s*$";
|
|||
|
const HYPHENRANGELOOSE = R++;
|
|||
|
src[HYPHENRANGELOOSE] = "^\\s*(" + src[XRANGEPLAINLOOSE] + ")" + "\\s+-\\s+" + "(" + src[XRANGEPLAINLOOSE] + ")" + "\\s*$";
|
|||
|
const STAR = R++;
|
|||
|
src[STAR] = "(<|>)?=?\\s*\\*";
|
|||
|
for(let i = 0; i < R; i++){
|
|||
|
if (!re[i]) {
|
|||
|
re[i] = new RegExp(src[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
function parse4(version, optionsOrLoose) {
|
|||
|
if (!optionsOrLoose || typeof optionsOrLoose !== "object") {
|
|||
|
optionsOrLoose = {
|
|||
|
loose: !!optionsOrLoose,
|
|||
|
includePrerelease: false
|
|||
|
};
|
|||
|
}
|
|||
|
if (version instanceof SemVer) {
|
|||
|
return version;
|
|||
|
}
|
|||
|
if (typeof version !== "string") {
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (version.length > 256) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const r = optionsOrLoose.loose ? re[LOOSE] : re[FULL];
|
|||
|
if (!r.test(version)) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
try {
|
|||
|
return new SemVer(version, optionsOrLoose);
|
|||
|
} catch (er) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
function valid(version, optionsOrLoose) {
|
|||
|
if (version === null) return null;
|
|||
|
const v = parse4(version, optionsOrLoose);
|
|||
|
return v ? v.version : null;
|
|||
|
}
|
|||
|
function clean(version, optionsOrLoose) {
|
|||
|
const s = parse4(version.trim().replace(/^[=v]+/, ""), optionsOrLoose);
|
|||
|
return s ? s.version : null;
|
|||
|
}
|
|||
|
class SemVer {
|
|||
|
constructor(version1, optionsOrLoose2){
|
|||
|
if (!optionsOrLoose2 || typeof optionsOrLoose2 !== "object") {
|
|||
|
optionsOrLoose2 = {
|
|||
|
loose: !!optionsOrLoose2,
|
|||
|
includePrerelease: false
|
|||
|
};
|
|||
|
}
|
|||
|
if (version1 instanceof SemVer) {
|
|||
|
if (version1.loose === optionsOrLoose2.loose) {
|
|||
|
return version1;
|
|||
|
} else {
|
|||
|
version1 = version1.version;
|
|||
|
}
|
|||
|
} else if (typeof version1 !== "string") {
|
|||
|
throw new TypeError("Invalid Version: " + version1);
|
|||
|
}
|
|||
|
if (version1.length > 256) {
|
|||
|
throw new TypeError("version is longer than " + 256 + " characters");
|
|||
|
}
|
|||
|
if (!(this instanceof SemVer)) {
|
|||
|
return new SemVer(version1, optionsOrLoose2);
|
|||
|
}
|
|||
|
this.options = optionsOrLoose2;
|
|||
|
this.loose = !!optionsOrLoose2.loose;
|
|||
|
const m = version1.trim().match(optionsOrLoose2.loose ? re[LOOSE] : re[FULL]);
|
|||
|
if (!m) {
|
|||
|
throw new TypeError("Invalid Version: " + version1);
|
|||
|
}
|
|||
|
this.raw = version1;
|
|||
|
this.major = +m[1];
|
|||
|
this.minor = +m[2];
|
|||
|
this.patch = +m[3];
|
|||
|
if (this.major > Number.MAX_SAFE_INTEGER || this.major < 0) {
|
|||
|
throw new TypeError("Invalid major version");
|
|||
|
}
|
|||
|
if (this.minor > Number.MAX_SAFE_INTEGER || this.minor < 0) {
|
|||
|
throw new TypeError("Invalid minor version");
|
|||
|
}
|
|||
|
if (this.patch > Number.MAX_SAFE_INTEGER || this.patch < 0) {
|
|||
|
throw new TypeError("Invalid patch version");
|
|||
|
}
|
|||
|
if (!m[4]) {
|
|||
|
this.prerelease = [];
|
|||
|
} else {
|
|||
|
this.prerelease = m[4].split(".").map((id)=>{
|
|||
|
if (/^[0-9]+$/.test(id)) {
|
|||
|
const num = +id;
|
|||
|
if (num >= 0 && num < Number.MAX_SAFE_INTEGER) {
|
|||
|
return num;
|
|||
|
}
|
|||
|
}
|
|||
|
return id;
|
|||
|
});
|
|||
|
}
|
|||
|
this.build = m[5] ? m[5].split(".") : [];
|
|||
|
this.format();
|
|||
|
}
|
|||
|
format() {
|
|||
|
this.version = this.major + "." + this.minor + "." + this.patch;
|
|||
|
if (this.prerelease.length) {
|
|||
|
this.version += "-" + this.prerelease.join(".");
|
|||
|
}
|
|||
|
return this.version;
|
|||
|
}
|
|||
|
compare(other) {
|
|||
|
if (!(other instanceof SemVer)) {
|
|||
|
other = new SemVer(other, this.options);
|
|||
|
}
|
|||
|
return this.compareMain(other) || this.comparePre(other);
|
|||
|
}
|
|||
|
compareMain(other) {
|
|||
|
if (!(other instanceof SemVer)) {
|
|||
|
other = new SemVer(other, this.options);
|
|||
|
}
|
|||
|
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
|
|||
|
}
|
|||
|
comparePre(other) {
|
|||
|
if (!(other instanceof SemVer)) {
|
|||
|
other = new SemVer(other, this.options);
|
|||
|
}
|
|||
|
if (this.prerelease.length && !other.prerelease.length) {
|
|||
|
return -1;
|
|||
|
} else if (!this.prerelease.length && other.prerelease.length) {
|
|||
|
return 1;
|
|||
|
} else if (!this.prerelease.length && !other.prerelease.length) {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
let i1 = 0;
|
|||
|
do {
|
|||
|
const a = this.prerelease[i1];
|
|||
|
const b = other.prerelease[i1];
|
|||
|
if (a === undefined && b === undefined) {
|
|||
|
return 0;
|
|||
|
} else if (b === undefined) {
|
|||
|
return 1;
|
|||
|
} else if (a === undefined) {
|
|||
|
return -1;
|
|||
|
} else if (a === b) {
|
|||
|
continue;
|
|||
|
} else {
|
|||
|
return compareIdentifiers(a, b);
|
|||
|
}
|
|||
|
}while (++i1)
|
|||
|
return 1;
|
|||
|
}
|
|||
|
compareBuild(other) {
|
|||
|
if (!(other instanceof SemVer)) {
|
|||
|
other = new SemVer(other, this.options);
|
|||
|
}
|
|||
|
let i1 = 0;
|
|||
|
do {
|
|||
|
const a = this.build[i1];
|
|||
|
const b = other.build[i1];
|
|||
|
if (a === undefined && b === undefined) {
|
|||
|
return 0;
|
|||
|
} else if (b === undefined) {
|
|||
|
return 1;
|
|||
|
} else if (a === undefined) {
|
|||
|
return -1;
|
|||
|
} else if (a === b) {
|
|||
|
continue;
|
|||
|
} else {
|
|||
|
return compareIdentifiers(a, b);
|
|||
|
}
|
|||
|
}while (++i1)
|
|||
|
return 1;
|
|||
|
}
|
|||
|
inc(release, identifier) {
|
|||
|
switch(release){
|
|||
|
case "premajor":
|
|||
|
this.prerelease.length = 0;
|
|||
|
this.patch = 0;
|
|||
|
this.minor = 0;
|
|||
|
this.major++;
|
|||
|
this.inc("pre", identifier);
|
|||
|
break;
|
|||
|
case "preminor":
|
|||
|
this.prerelease.length = 0;
|
|||
|
this.patch = 0;
|
|||
|
this.minor++;
|
|||
|
this.inc("pre", identifier);
|
|||
|
break;
|
|||
|
case "prepatch":
|
|||
|
this.prerelease.length = 0;
|
|||
|
this.inc("patch", identifier);
|
|||
|
this.inc("pre", identifier);
|
|||
|
break;
|
|||
|
case "prerelease":
|
|||
|
if (this.prerelease.length === 0) {
|
|||
|
this.inc("patch", identifier);
|
|||
|
}
|
|||
|
this.inc("pre", identifier);
|
|||
|
break;
|
|||
|
case "major":
|
|||
|
if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) {
|
|||
|
this.major++;
|
|||
|
}
|
|||
|
this.minor = 0;
|
|||
|
this.patch = 0;
|
|||
|
this.prerelease = [];
|
|||
|
break;
|
|||
|
case "minor":
|
|||
|
if (this.patch !== 0 || this.prerelease.length === 0) {
|
|||
|
this.minor++;
|
|||
|
}
|
|||
|
this.patch = 0;
|
|||
|
this.prerelease = [];
|
|||
|
break;
|
|||
|
case "patch":
|
|||
|
if (this.prerelease.length === 0) {
|
|||
|
this.patch++;
|
|||
|
}
|
|||
|
this.prerelease = [];
|
|||
|
break;
|
|||
|
case "pre":
|
|||
|
if (this.prerelease.length === 0) {
|
|||
|
this.prerelease = [
|
|||
|
0
|
|||
|
];
|
|||
|
} else {
|
|||
|
let i1 = this.prerelease.length;
|
|||
|
while((--i1) >= 0){
|
|||
|
if (typeof this.prerelease[i1] === "number") {
|
|||
|
this.prerelease[i1]++;
|
|||
|
i1 = -2;
|
|||
|
}
|
|||
|
}
|
|||
|
if (i1 === -1) {
|
|||
|
this.prerelease.push(0);
|
|||
|
}
|
|||
|
}
|
|||
|
if (identifier) {
|
|||
|
if (this.prerelease[0] === identifier) {
|
|||
|
if (isNaN(this.prerelease[1])) {
|
|||
|
this.prerelease = [
|
|||
|
identifier,
|
|||
|
0
|
|||
|
];
|
|||
|
}
|
|||
|
} else {
|
|||
|
this.prerelease = [
|
|||
|
identifier,
|
|||
|
0
|
|||
|
];
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
throw new Error("invalid increment argument: " + release);
|
|||
|
}
|
|||
|
this.format();
|
|||
|
this.raw = this.version;
|
|||
|
return this;
|
|||
|
}
|
|||
|
toString() {
|
|||
|
return this.version;
|
|||
|
}
|
|||
|
}
|
|||
|
function inc(version1, release, optionsOrLoose1, identifier) {
|
|||
|
if (typeof optionsOrLoose1 === "string") {
|
|||
|
identifier = optionsOrLoose1;
|
|||
|
optionsOrLoose1 = undefined;
|
|||
|
}
|
|||
|
try {
|
|||
|
return new SemVer(version1, optionsOrLoose1).inc(release, identifier).version;
|
|||
|
} catch (er) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
function diff(version1, version2, optionsOrLoose1) {
|
|||
|
if (eq(version1, version2, optionsOrLoose1)) {
|
|||
|
return null;
|
|||
|
} else {
|
|||
|
const v1 = parse4(version1);
|
|||
|
const v2 = parse4(version2);
|
|||
|
let prefix = "";
|
|||
|
let defaultResult = null;
|
|||
|
if (v1 && v2) {
|
|||
|
if (v1.prerelease.length || v2.prerelease.length) {
|
|||
|
prefix = "pre";
|
|||
|
defaultResult = "prerelease";
|
|||
|
}
|
|||
|
for(const key in v1){
|
|||
|
if (key === "major" || key === "minor" || key === "patch") {
|
|||
|
if (v1[key] !== v2[key]) {
|
|||
|
return prefix + key;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return defaultResult;
|
|||
|
}
|
|||
|
}
|
|||
|
const numeric = /^[0-9]+$/;
|
|||
|
function compareIdentifiers(a, b) {
|
|||
|
const anum = numeric.test(a);
|
|||
|
const bnum = numeric.test(b);
|
|||
|
if (a === null || b === null) throw "Comparison against null invalid";
|
|||
|
if (anum && bnum) {
|
|||
|
a = +a;
|
|||
|
b = +b;
|
|||
|
}
|
|||
|
return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1;
|
|||
|
}
|
|||
|
function rcompareIdentifiers(a, b) {
|
|||
|
return compareIdentifiers(b, a);
|
|||
|
}
|
|||
|
function major(v, optionsOrLoose1) {
|
|||
|
return new SemVer(v, optionsOrLoose1).major;
|
|||
|
}
|
|||
|
function minor(v, optionsOrLoose1) {
|
|||
|
return new SemVer(v, optionsOrLoose1).minor;
|
|||
|
}
|
|||
|
function patch(v, optionsOrLoose1) {
|
|||
|
return new SemVer(v, optionsOrLoose1).patch;
|
|||
|
}
|
|||
|
function compare(v1, v2, optionsOrLoose1) {
|
|||
|
return new SemVer(v1, optionsOrLoose1).compare(new SemVer(v2, optionsOrLoose1));
|
|||
|
}
|
|||
|
function compareLoose(a, b) {
|
|||
|
return compare(a, b, true);
|
|||
|
}
|
|||
|
function compareBuild(a, b, loose) {
|
|||
|
var versionA = new SemVer(a, loose);
|
|||
|
var versionB = new SemVer(b, loose);
|
|||
|
return versionA.compare(versionB) || versionA.compareBuild(versionB);
|
|||
|
}
|
|||
|
function rcompare(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v2, v1, optionsOrLoose1);
|
|||
|
}
|
|||
|
function sort(list, optionsOrLoose1) {
|
|||
|
return list.sort((a, b)=>{
|
|||
|
return compareBuild(a, b, optionsOrLoose1);
|
|||
|
});
|
|||
|
}
|
|||
|
function rsort(list, optionsOrLoose1) {
|
|||
|
return list.sort((a, b)=>{
|
|||
|
return compareBuild(b, a, optionsOrLoose1);
|
|||
|
});
|
|||
|
}
|
|||
|
function gt(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) > 0;
|
|||
|
}
|
|||
|
function lt(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) < 0;
|
|||
|
}
|
|||
|
function eq(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) === 0;
|
|||
|
}
|
|||
|
function neq(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) !== 0;
|
|||
|
}
|
|||
|
function gte(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) >= 0;
|
|||
|
}
|
|||
|
function lte(v1, v2, optionsOrLoose1) {
|
|||
|
return compare(v1, v2, optionsOrLoose1) <= 0;
|
|||
|
}
|
|||
|
function cmp(v1, operator, v2, optionsOrLoose1) {
|
|||
|
switch(operator){
|
|||
|
case "===":
|
|||
|
if (typeof v1 === "object") v1 = v1.version;
|
|||
|
if (typeof v2 === "object") v2 = v2.version;
|
|||
|
return v1 === v2;
|
|||
|
case "!==":
|
|||
|
if (typeof v1 === "object") v1 = v1.version;
|
|||
|
if (typeof v2 === "object") v2 = v2.version;
|
|||
|
return v1 !== v2;
|
|||
|
case "":
|
|||
|
case "=":
|
|||
|
case "==":
|
|||
|
return eq(v1, v2, optionsOrLoose1);
|
|||
|
case "!=":
|
|||
|
return neq(v1, v2, optionsOrLoose1);
|
|||
|
case ">":
|
|||
|
return gt(v1, v2, optionsOrLoose1);
|
|||
|
case ">=":
|
|||
|
return gte(v1, v2, optionsOrLoose1);
|
|||
|
case "<":
|
|||
|
return lt(v1, v2, optionsOrLoose1);
|
|||
|
case "<=":
|
|||
|
return lte(v1, v2, optionsOrLoose1);
|
|||
|
default:
|
|||
|
throw new TypeError("Invalid operator: " + operator);
|
|||
|
}
|
|||
|
}
|
|||
|
const ANY = {
|
|||
|
};
|
|||
|
class Comparator {
|
|||
|
constructor(comp1, optionsOrLoose1){
|
|||
|
if (!optionsOrLoose1 || typeof optionsOrLoose1 !== "object") {
|
|||
|
optionsOrLoose1 = {
|
|||
|
loose: !!optionsOrLoose1,
|
|||
|
includePrerelease: false
|
|||
|
};
|
|||
|
}
|
|||
|
if (comp1 instanceof Comparator) {
|
|||
|
if (comp1.loose === !!optionsOrLoose1.loose) {
|
|||
|
return comp1;
|
|||
|
} else {
|
|||
|
comp1 = comp1.value;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!(this instanceof Comparator)) {
|
|||
|
return new Comparator(comp1, optionsOrLoose1);
|
|||
|
}
|
|||
|
this.options = optionsOrLoose1;
|
|||
|
this.loose = !!optionsOrLoose1.loose;
|
|||
|
this.parse(comp1);
|
|||
|
if (this.semver === ANY) {
|
|||
|
this.value = "";
|
|||
|
} else {
|
|||
|
this.value = this.operator + this.semver.version;
|
|||
|
}
|
|||
|
}
|
|||
|
parse(comp) {
|
|||
|
const r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
|
|||
|
const m1 = comp.match(r);
|
|||
|
if (!m1) {
|
|||
|
throw new TypeError("Invalid comparator: " + comp);
|
|||
|
}
|
|||
|
const m11 = m1[1];
|
|||
|
this.operator = m11 !== undefined ? m11 : "";
|
|||
|
if (this.operator === "=") {
|
|||
|
this.operator = "";
|
|||
|
}
|
|||
|
if (!m1[2]) {
|
|||
|
this.semver = ANY;
|
|||
|
} else {
|
|||
|
this.semver = new SemVer(m1[2], this.options.loose);
|
|||
|
}
|
|||
|
}
|
|||
|
test(version) {
|
|||
|
if (this.semver === ANY || version === ANY) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
if (typeof version === "string") {
|
|||
|
version = new SemVer(version, this.options);
|
|||
|
}
|
|||
|
return cmp(version, this.operator, this.semver, this.options);
|
|||
|
}
|
|||
|
intersects(comp, optionsOrLoose) {
|
|||
|
if (!(comp instanceof Comparator)) {
|
|||
|
throw new TypeError("a Comparator is required");
|
|||
|
}
|
|||
|
if (!optionsOrLoose || typeof optionsOrLoose !== "object") {
|
|||
|
optionsOrLoose = {
|
|||
|
loose: !!optionsOrLoose,
|
|||
|
includePrerelease: false
|
|||
|
};
|
|||
|
}
|
|||
|
let rangeTmp;
|
|||
|
if (this.operator === "") {
|
|||
|
if (this.value === "") {
|
|||
|
return true;
|
|||
|
}
|
|||
|
rangeTmp = new Range1(comp.value, optionsOrLoose);
|
|||
|
return satisfies(this.value, rangeTmp, optionsOrLoose);
|
|||
|
} else if (comp.operator === "") {
|
|||
|
if (comp.value === "") {
|
|||
|
return true;
|
|||
|
}
|
|||
|
rangeTmp = new Range1(this.value, optionsOrLoose);
|
|||
|
return satisfies(comp.semver, rangeTmp, optionsOrLoose);
|
|||
|
}
|
|||
|
const sameDirectionIncreasing = (this.operator === ">=" || this.operator === ">") && (comp.operator === ">=" || comp.operator === ">");
|
|||
|
const sameDirectionDecreasing = (this.operator === "<=" || this.operator === "<") && (comp.operator === "<=" || comp.operator === "<");
|
|||
|
const sameSemVer = this.semver.version === comp.semver.version;
|
|||
|
const differentDirectionsInclusive = (this.operator === ">=" || this.operator === "<=") && (comp.operator === ">=" || comp.operator === "<=");
|
|||
|
const oppositeDirectionsLessThan = cmp(this.semver, "<", comp.semver, optionsOrLoose) && (this.operator === ">=" || this.operator === ">") && (comp.operator === "<=" || comp.operator === "<");
|
|||
|
const oppositeDirectionsGreaterThan = cmp(this.semver, ">", comp.semver, optionsOrLoose) && (this.operator === "<=" || this.operator === "<") && (comp.operator === ">=" || comp.operator === ">");
|
|||
|
return sameDirectionIncreasing || sameDirectionDecreasing || sameSemVer && differentDirectionsInclusive || oppositeDirectionsLessThan || oppositeDirectionsGreaterThan;
|
|||
|
}
|
|||
|
toString() {
|
|||
|
return this.value;
|
|||
|
}
|
|||
|
}
|
|||
|
class Range1 {
|
|||
|
constructor(range1, optionsOrLoose3){
|
|||
|
if (!optionsOrLoose3 || typeof optionsOrLoose3 !== "object") {
|
|||
|
optionsOrLoose3 = {
|
|||
|
loose: !!optionsOrLoose3,
|
|||
|
includePrerelease: false
|
|||
|
};
|
|||
|
}
|
|||
|
if (range1 instanceof Range1) {
|
|||
|
if (range1.loose === !!optionsOrLoose3.loose && range1.includePrerelease === !!optionsOrLoose3.includePrerelease) {
|
|||
|
return range1;
|
|||
|
} else {
|
|||
|
return new Range1(range1.raw, optionsOrLoose3);
|
|||
|
}
|
|||
|
}
|
|||
|
if (range1 instanceof Comparator) {
|
|||
|
return new Range1(range1.value, optionsOrLoose3);
|
|||
|
}
|
|||
|
if (!(this instanceof Range1)) {
|
|||
|
return new Range1(range1, optionsOrLoose3);
|
|||
|
}
|
|||
|
this.options = optionsOrLoose3;
|
|||
|
this.loose = !!optionsOrLoose3.loose;
|
|||
|
this.includePrerelease = !!optionsOrLoose3.includePrerelease;
|
|||
|
this.raw = range1;
|
|||
|
this.set = range1.split(/\s*\|\|\s*/).map((range1)=>this.parseRange(range1.trim())
|
|||
|
).filter((c)=>{
|
|||
|
return c.length;
|
|||
|
});
|
|||
|
if (!this.set.length) {
|
|||
|
throw new TypeError("Invalid SemVer Range: " + range1);
|
|||
|
}
|
|||
|
this.format();
|
|||
|
}
|
|||
|
format() {
|
|||
|
this.range = this.set.map((comps)=>comps.join(" ").trim()
|
|||
|
).join("||").trim();
|
|||
|
return this.range;
|
|||
|
}
|
|||
|
parseRange(range) {
|
|||
|
const loose = this.options.loose;
|
|||
|
range = range.trim();
|
|||
|
const hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
|
|||
|
range = range.replace(hr, hyphenReplace);
|
|||
|
range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
|
|||
|
range = range.replace(re[TILDETRIM], tildeTrimReplace);
|
|||
|
range = range.replace(re[CARETTRIM], caretTrimReplace);
|
|||
|
range = range.split(/\s+/).join(" ");
|
|||
|
const compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
|
|||
|
let set = range.split(" ").map((comp2)=>parseComparator(comp2, this.options)
|
|||
|
).join(" ").split(/\s+/);
|
|||
|
if (this.options.loose) {
|
|||
|
set = set.filter((comp2)=>{
|
|||
|
return !!comp2.match(compRe);
|
|||
|
});
|
|||
|
}
|
|||
|
return set.map((comp2)=>new Comparator(comp2, this.options)
|
|||
|
);
|
|||
|
}
|
|||
|
test(version) {
|
|||
|
if (typeof version === "string") {
|
|||
|
version = new SemVer(version, this.options);
|
|||
|
}
|
|||
|
for(var i1 = 0; i1 < this.set.length; i1++){
|
|||
|
if (testSet(this.set[i1], version, this.options)) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
intersects(range, optionsOrLoose) {
|
|||
|
if (!(range instanceof Range1)) {
|
|||
|
throw new TypeError("a Range is required");
|
|||
|
}
|
|||
|
return this.set.some((thisComparators)=>{
|
|||
|
return isSatisfiable(thisComparators, optionsOrLoose) && range.set.some((rangeComparators)=>{
|
|||
|
return isSatisfiable(rangeComparators, optionsOrLoose) && thisComparators.every((thisComparator)=>{
|
|||
|
return rangeComparators.every((rangeComparator)=>{
|
|||
|
return thisComparator.intersects(rangeComparator, optionsOrLoose);
|
|||
|
});
|
|||
|
});
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
toString() {
|
|||
|
return this.range;
|
|||
|
}
|
|||
|
}
|
|||
|
function testSet(set, version2, options5) {
|
|||
|
for(let i2 = 0; i2 < set.length; i2++){
|
|||
|
if (!set[i2].test(version2)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (version2.prerelease.length && !options5.includePrerelease) {
|
|||
|
for(let i3 = 0; i3 < set.length; i3++){
|
|||
|
if (set[i3].semver === ANY) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (set[i3].semver.prerelease.length > 0) {
|
|||
|
const allowed = set[i3].semver;
|
|||
|
if (allowed.major === version2.major && allowed.minor === version2.minor && allowed.patch === version2.patch) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
function isSatisfiable(comparators, options5) {
|
|||
|
let result = true;
|
|||
|
const remainingComparators = comparators.slice();
|
|||
|
let testComparator = remainingComparators.pop();
|
|||
|
while(result && remainingComparators.length){
|
|||
|
result = remainingComparators.every((otherComparator)=>{
|
|||
|
return testComparator?.intersects(otherComparator, options5);
|
|||
|
});
|
|||
|
testComparator = remainingComparators.pop();
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
function toComparators(range2, optionsOrLoose4) {
|
|||
|
return new Range1(range2, optionsOrLoose4).set.map((comp2)=>{
|
|||
|
return comp2.map((c)=>c.value
|
|||
|
).join(" ").trim().split(" ");
|
|||
|
});
|
|||
|
}
|
|||
|
function parseComparator(comp2, options5) {
|
|||
|
comp2 = replaceCarets(comp2, options5);
|
|||
|
comp2 = replaceTildes(comp2, options5);
|
|||
|
comp2 = replaceXRanges(comp2, options5);
|
|||
|
comp2 = replaceStars(comp2, options5);
|
|||
|
return comp2;
|
|||
|
}
|
|||
|
function isX(id) {
|
|||
|
return !id || id.toLowerCase() === "x" || id === "*";
|
|||
|
}
|
|||
|
function replaceTildes(comp2, options5) {
|
|||
|
return comp2.trim().split(/\s+/).map((comp3)=>replaceTilde(comp3, options5)
|
|||
|
).join(" ");
|
|||
|
}
|
|||
|
function replaceTilde(comp2, options5) {
|
|||
|
const r = options5.loose ? re[TILDELOOSE] : re[TILDE];
|
|||
|
return comp2.replace(r, (_, M, m1, p, pr)=>{
|
|||
|
let ret;
|
|||
|
if (isX(M)) {
|
|||
|
ret = "";
|
|||
|
} else if (isX(m1)) {
|
|||
|
ret = ">=" + M + ".0.0 <" + (+M + 1) + ".0.0";
|
|||
|
} else if (isX(p)) {
|
|||
|
ret = ">=" + M + "." + m1 + ".0 <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
} else if (pr) {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + "-" + pr + " <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + " <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
}
|
|||
|
return ret;
|
|||
|
});
|
|||
|
}
|
|||
|
function replaceCarets(comp2, options5) {
|
|||
|
return comp2.trim().split(/\s+/).map((comp3)=>replaceCaret(comp3, options5)
|
|||
|
).join(" ");
|
|||
|
}
|
|||
|
function replaceCaret(comp2, options5) {
|
|||
|
const r = options5.loose ? re[CARETLOOSE] : re[CARET];
|
|||
|
return comp2.replace(r, (_, M, m1, p, pr)=>{
|
|||
|
let ret;
|
|||
|
if (isX(M)) {
|
|||
|
ret = "";
|
|||
|
} else if (isX(m1)) {
|
|||
|
ret = ">=" + M + ".0.0 <" + (+M + 1) + ".0.0";
|
|||
|
} else if (isX(p)) {
|
|||
|
if (M === "0") {
|
|||
|
ret = ">=" + M + "." + m1 + ".0 <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + ".0 <" + (+M + 1) + ".0.0";
|
|||
|
}
|
|||
|
} else if (pr) {
|
|||
|
if (M === "0") {
|
|||
|
if (m1 === "0") {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + "-" + pr + " <" + M + "." + m1 + "." + (+p + 1);
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + "-" + pr + " <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
}
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (M === "0") {
|
|||
|
if (m1 === "0") {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + " <" + M + "." + m1 + "." + (+p + 1);
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + " <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
}
|
|||
|
} else {
|
|||
|
ret = ">=" + M + "." + m1 + "." + p + " <" + (+M + 1) + ".0.0";
|
|||
|
}
|
|||
|
}
|
|||
|
return ret;
|
|||
|
});
|
|||
|
}
|
|||
|
function replaceXRanges(comp2, options5) {
|
|||
|
return comp2.split(/\s+/).map((comp3)=>replaceXRange(comp3, options5)
|
|||
|
).join(" ");
|
|||
|
}
|
|||
|
function replaceXRange(comp2, options5) {
|
|||
|
comp2 = comp2.trim();
|
|||
|
const r = options5.loose ? re[XRANGELOOSE] : re[XRANGE];
|
|||
|
return comp2.replace(r, (ret, gtlt, M, m1, p, pr)=>{
|
|||
|
const xM = isX(M);
|
|||
|
const xm = xM || isX(m1);
|
|||
|
const xp = xm || isX(p);
|
|||
|
const anyX = xp;
|
|||
|
if (gtlt === "=" && anyX) {
|
|||
|
gtlt = "";
|
|||
|
}
|
|||
|
if (xM) {
|
|||
|
if (gtlt === ">" || gtlt === "<") {
|
|||
|
ret = "<0.0.0";
|
|||
|
} else {
|
|||
|
ret = "*";
|
|||
|
}
|
|||
|
} else if (gtlt && anyX) {
|
|||
|
if (xm) {
|
|||
|
m1 = 0;
|
|||
|
}
|
|||
|
p = 0;
|
|||
|
if (gtlt === ">") {
|
|||
|
gtlt = ">=";
|
|||
|
if (xm) {
|
|||
|
M = +M + 1;
|
|||
|
m1 = 0;
|
|||
|
p = 0;
|
|||
|
} else {
|
|||
|
m1 = +m1 + 1;
|
|||
|
p = 0;
|
|||
|
}
|
|||
|
} else if (gtlt === "<=") {
|
|||
|
gtlt = "<";
|
|||
|
if (xm) {
|
|||
|
M = +M + 1;
|
|||
|
} else {
|
|||
|
m1 = +m1 + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
ret = gtlt + M + "." + m1 + "." + p;
|
|||
|
} else if (xm) {
|
|||
|
ret = ">=" + M + ".0.0 <" + (+M + 1) + ".0.0";
|
|||
|
} else if (xp) {
|
|||
|
ret = ">=" + M + "." + m1 + ".0 <" + M + "." + (+m1 + 1) + ".0";
|
|||
|
}
|
|||
|
return ret;
|
|||
|
});
|
|||
|
}
|
|||
|
function replaceStars(comp2, options5) {
|
|||
|
return comp2.trim().replace(re[STAR], "");
|
|||
|
}
|
|||
|
function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
|
|||
|
if (isX(fM)) {
|
|||
|
from = "";
|
|||
|
} else if (isX(fm)) {
|
|||
|
from = ">=" + fM + ".0.0";
|
|||
|
} else if (isX(fp)) {
|
|||
|
from = ">=" + fM + "." + fm + ".0";
|
|||
|
} else {
|
|||
|
from = ">=" + from;
|
|||
|
}
|
|||
|
if (isX(tM)) {
|
|||
|
to = "";
|
|||
|
} else if (isX(tm)) {
|
|||
|
to = "<" + (+tM + 1) + ".0.0";
|
|||
|
} else if (isX(tp)) {
|
|||
|
to = "<" + tM + "." + (+tm + 1) + ".0";
|
|||
|
} else if (tpr) {
|
|||
|
to = "<=" + tM + "." + tm + "." + tp + "-" + tpr;
|
|||
|
} else {
|
|||
|
to = "<=" + to;
|
|||
|
}
|
|||
|
return (from + " " + to).trim();
|
|||
|
}
|
|||
|
function satisfies(version2, range2, optionsOrLoose4) {
|
|||
|
try {
|
|||
|
range2 = new Range1(range2, optionsOrLoose4);
|
|||
|
} catch (er) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
return range2.test(version2);
|
|||
|
}
|
|||
|
function maxSatisfying(versions, range2, optionsOrLoose4) {
|
|||
|
var max = null;
|
|||
|
var maxSV = null;
|
|||
|
try {
|
|||
|
var rangeObj = new Range1(range2, optionsOrLoose4);
|
|||
|
} catch (er) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
versions.forEach((v)=>{
|
|||
|
if (rangeObj.test(v)) {
|
|||
|
if (!max || maxSV && maxSV.compare(v) === -1) {
|
|||
|
max = v;
|
|||
|
maxSV = new SemVer(max, optionsOrLoose4);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return max;
|
|||
|
}
|
|||
|
function minSatisfying(versions, range2, optionsOrLoose4) {
|
|||
|
var min = null;
|
|||
|
var minSV = null;
|
|||
|
try {
|
|||
|
var rangeObj = new Range1(range2, optionsOrLoose4);
|
|||
|
} catch (er) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
versions.forEach((v)=>{
|
|||
|
if (rangeObj.test(v)) {
|
|||
|
if (!min || minSV.compare(v) === 1) {
|
|||
|
min = v;
|
|||
|
minSV = new SemVer(min, optionsOrLoose4);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return min;
|
|||
|
}
|
|||
|
function minVersion(range2, optionsOrLoose4) {
|
|||
|
range2 = new Range1(range2, optionsOrLoose4);
|
|||
|
var minver = new SemVer("0.0.0");
|
|||
|
if (range2.test(minver)) {
|
|||
|
return minver;
|
|||
|
}
|
|||
|
minver = new SemVer("0.0.0-0");
|
|||
|
if (range2.test(minver)) {
|
|||
|
return minver;
|
|||
|
}
|
|||
|
minver = null;
|
|||
|
for(var i2 = 0; i2 < range2.set.length; ++i2){
|
|||
|
var comparators = range2.set[i2];
|
|||
|
comparators.forEach((comparator)=>{
|
|||
|
var compver = new SemVer(comparator.semver.version);
|
|||
|
switch(comparator.operator){
|
|||
|
case ">":
|
|||
|
if (compver.prerelease.length === 0) {
|
|||
|
compver.patch++;
|
|||
|
} else {
|
|||
|
compver.prerelease.push(0);
|
|||
|
}
|
|||
|
compver.raw = compver.format();
|
|||
|
case "":
|
|||
|
case ">=":
|
|||
|
if (!minver || gt(minver, compver)) {
|
|||
|
minver = compver;
|
|||
|
}
|
|||
|
break;
|
|||
|
case "<":
|
|||
|
case "<=": break;
|
|||
|
default:
|
|||
|
throw new Error("Unexpected operation: " + comparator.operator);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
if (minver && range2.test(minver)) {
|
|||
|
return minver;
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
function validRange(range2, optionsOrLoose4) {
|
|||
|
try {
|
|||
|
if (range2 === null) return null;
|
|||
|
return new Range1(range2, optionsOrLoose4).range || "*";
|
|||
|
} catch (er) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
function ltr(version2, range2, optionsOrLoose4) {
|
|||
|
return outside(version2, range2, "<", optionsOrLoose4);
|
|||
|
}
|
|||
|
function gtr(version2, range2, optionsOrLoose4) {
|
|||
|
return outside(version2, range2, ">", optionsOrLoose4);
|
|||
|
}
|
|||
|
function outside(version2, range2, hilo, optionsOrLoose4) {
|
|||
|
version2 = new SemVer(version2, optionsOrLoose4);
|
|||
|
range2 = new Range1(range2, optionsOrLoose4);
|
|||
|
let gtfn;
|
|||
|
let ltefn;
|
|||
|
let ltfn;
|
|||
|
let comp2;
|
|||
|
let ecomp;
|
|||
|
switch(hilo){
|
|||
|
case ">":
|
|||
|
gtfn = gt;
|
|||
|
ltefn = lte;
|
|||
|
ltfn = lt;
|
|||
|
comp2 = ">";
|
|||
|
ecomp = ">=";
|
|||
|
break;
|
|||
|
case "<":
|
|||
|
gtfn = lt;
|
|||
|
ltefn = gte;
|
|||
|
ltfn = gt;
|
|||
|
comp2 = "<";
|
|||
|
ecomp = "<=";
|
|||
|
break;
|
|||
|
default:
|
|||
|
throw new TypeError('Must provide a hilo val of "<" or ">"');
|
|||
|
}
|
|||
|
if (satisfies(version2, range2, optionsOrLoose4)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
for(let i2 = 0; i2 < range2.set.length; ++i2){
|
|||
|
const comparators = range2.set[i2];
|
|||
|
let high = null;
|
|||
|
let low = null;
|
|||
|
comparators.forEach((comparator)=>{
|
|||
|
if (comparator.semver === ANY) {
|
|||
|
comparator = new Comparator(">=0.0.0");
|
|||
|
}
|
|||
|
high = high || comparator;
|
|||
|
low = low || comparator;
|
|||
|
if (gtfn(comparator.semver, high.semver, optionsOrLoose4)) {
|
|||
|
high = comparator;
|
|||
|
} else if (ltfn(comparator.semver, low.semver, optionsOrLoose4)) {
|
|||
|
low = comparator;
|
|||
|
}
|
|||
|
});
|
|||
|
if (high === null || low === null) return true;
|
|||
|
if (high.operator === comp2 || high.operator === ecomp) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if ((!low.operator || low.operator === comp2) && ltefn(version2, low.semver)) {
|
|||
|
return false;
|
|||
|
} else if (low.operator === ecomp && ltfn(version2, low.semver)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
function prerelease(version2, optionsOrLoose4) {
|
|||
|
var parsed = parse4(version2, optionsOrLoose4);
|
|||
|
return parsed && parsed.prerelease.length ? parsed.prerelease : null;
|
|||
|
}
|
|||
|
function intersects(range11, range2, optionsOrLoose4) {
|
|||
|
range11 = new Range1(range11, optionsOrLoose4);
|
|||
|
range2 = new Range1(range2, optionsOrLoose4);
|
|||
|
return range11.intersects(range2);
|
|||
|
}
|
|||
|
function coerce(version2, optionsOrLoose4) {
|
|||
|
if (version2 instanceof SemVer) {
|
|||
|
return version2;
|
|||
|
}
|
|||
|
if (typeof version2 !== "string") {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const match = version2.match(re[COERCE]);
|
|||
|
if (match == null) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return parse4(match[1] + "." + (match[2] || "0") + "." + (match[3] || "0"), optionsOrLoose4);
|
|||
|
}
|
|||
|
const mod7 = function() {
|
|||
|
return {
|
|||
|
SEMVER_SPEC_VERSION: SEMVER_SPEC_VERSION,
|
|||
|
parse: parse4,
|
|||
|
valid: valid,
|
|||
|
clean: clean,
|
|||
|
SemVer: SemVer,
|
|||
|
inc: inc,
|
|||
|
diff: diff,
|
|||
|
compareIdentifiers: compareIdentifiers,
|
|||
|
rcompareIdentifiers: rcompareIdentifiers,
|
|||
|
major: major,
|
|||
|
minor: minor,
|
|||
|
patch: patch,
|
|||
|
compare: compare,
|
|||
|
compareLoose: compareLoose,
|
|||
|
compareBuild: compareBuild,
|
|||
|
rcompare: rcompare,
|
|||
|
sort: sort,
|
|||
|
rsort: rsort,
|
|||
|
gt: gt,
|
|||
|
lt: lt,
|
|||
|
eq: eq,
|
|||
|
neq: neq,
|
|||
|
gte: gte,
|
|||
|
lte: lte,
|
|||
|
cmp: cmp,
|
|||
|
Comparator: Comparator,
|
|||
|
Range: Range1,
|
|||
|
toComparators: toComparators,
|
|||
|
satisfies: satisfies,
|
|||
|
maxSatisfying: maxSatisfying,
|
|||
|
minSatisfying: minSatisfying,
|
|||
|
minVersion: minVersion,
|
|||
|
validRange: validRange,
|
|||
|
ltr: ltr,
|
|||
|
gtr: gtr,
|
|||
|
outside: outside,
|
|||
|
prerelease: prerelease,
|
|||
|
intersects: intersects,
|
|||
|
coerce: coerce,
|
|||
|
default: SemVer
|
|||
|
};
|
|||
|
}();
|
|||
|
const version2 = "1.11.0";
|
|||
|
const TaskName_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "String"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "TaskName",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const TrackedFileName_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "String"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "TrackedFileName",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const TrackedFileHash_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "String"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "TrackedFileHash",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Timestamp_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "String"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Timestamp",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const TaskData_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "struct_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "lastExecution",
|
|||
|
"default": {
|
|||
|
"kind": "just",
|
|||
|
"value": null
|
|||
|
},
|
|||
|
"name": "lastExecution",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "Nullable"
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "Timestamp"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "trackedFiles",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "trackedFiles",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"name": "Map"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "TrackedFileName"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
},
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "TrackedFileData"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "TaskData",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const TrackedFileData_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "struct_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "hash",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "hash",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "TrackedFileHash"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "timestamp",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "timestamp",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "Timestamp"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "TrackedFileData",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Manifest_AST = {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "struct_",
|
|||
|
"value": {
|
|||
|
"typeParams": [],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "tasks",
|
|||
|
"default": {
|
|||
|
"kind": "just",
|
|||
|
"value": []
|
|||
|
},
|
|||
|
"name": "tasks",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"name": "Map"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "TaskName"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
},
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "dnit.manifest",
|
|||
|
"name": "TaskData"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Manifest",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const snManifest = {
|
|||
|
moduleName: "dnit.manifest",
|
|||
|
name: "Manifest"
|
|||
|
};
|
|||
|
function texprManifest() {
|
|||
|
return {
|
|||
|
value: {
|
|||
|
typeRef: {
|
|||
|
kind: "reference",
|
|||
|
value: snManifest
|
|||
|
},
|
|||
|
parameters: []
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
const _AST_MAP = {
|
|||
|
"dnit.manifest.TaskName": TaskName_AST,
|
|||
|
"dnit.manifest.TrackedFileName": TrackedFileName_AST,
|
|||
|
"dnit.manifest.TrackedFileHash": TrackedFileHash_AST,
|
|||
|
"dnit.manifest.Timestamp": Timestamp_AST,
|
|||
|
"dnit.manifest.TaskData": TaskData_AST,
|
|||
|
"dnit.manifest.TrackedFileData": TrackedFileData_AST,
|
|||
|
"dnit.manifest.Manifest": Manifest_AST
|
|||
|
};
|
|||
|
function isEnum(union) {
|
|||
|
for (let field of union.fields){
|
|||
|
if (!isVoid(field.typeExpr)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
function isVoid(texpr) {
|
|||
|
if (texpr.typeRef.kind === "primitive") {
|
|||
|
return texpr.typeRef.value === "Void";
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
function asJsonObject(jv) {
|
|||
|
if (jv instanceof Object && !(jv instanceof Array)) {
|
|||
|
return jv;
|
|||
|
}
|
|||
|
return undefined;
|
|||
|
}
|
|||
|
function asJsonArray(jv) {
|
|||
|
if (jv instanceof Array) {
|
|||
|
return jv;
|
|||
|
}
|
|||
|
return undefined;
|
|||
|
}
|
|||
|
function createJsonBinding(dresolver, texpr) {
|
|||
|
const jb0 = buildJsonBinding(dresolver, texpr.value, {
|
|||
|
});
|
|||
|
function fromJsonE(json) {
|
|||
|
try {
|
|||
|
return jb0.fromJson(json);
|
|||
|
} catch (e) {
|
|||
|
throw mapJsonException(e);
|
|||
|
}
|
|||
|
}
|
|||
|
return {
|
|||
|
typeExpr: texpr.value,
|
|||
|
toJson: jb0.toJson,
|
|||
|
fromJson: jb0.fromJson,
|
|||
|
fromJsonE
|
|||
|
};
|
|||
|
}
|
|||
|
function mapJsonException(exception) {
|
|||
|
if (exception && exception['kind'] == "JsonParseException") {
|
|||
|
const jserr = exception;
|
|||
|
return new Error(jserr.getMessage());
|
|||
|
} else {
|
|||
|
return exception;
|
|||
|
}
|
|||
|
}
|
|||
|
function jsonParseException(message1) {
|
|||
|
const context = [];
|
|||
|
let createContextString = ()=>{
|
|||
|
const rcontext = context.slice(0);
|
|||
|
rcontext.push('$');
|
|||
|
rcontext.reverse();
|
|||
|
return rcontext.join('.');
|
|||
|
};
|
|||
|
return {
|
|||
|
kind: 'JsonParseException',
|
|||
|
getMessage () {
|
|||
|
return message1 + ' at ' + createContextString();
|
|||
|
},
|
|||
|
pushField (fieldName) {
|
|||
|
context.push(fieldName);
|
|||
|
},
|
|||
|
pushIndex (index) {
|
|||
|
context.push('[' + index + ']');
|
|||
|
},
|
|||
|
toString () {
|
|||
|
return this.getMessage();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
function isJsonParseException(exception) {
|
|||
|
return exception.kind === 'JsonParseException';
|
|||
|
}
|
|||
|
function buildJsonBinding(dresolver, texpr, boundTypeParams) {
|
|||
|
if (texpr.typeRef.kind === "primitive") {
|
|||
|
return primitiveJsonBinding(dresolver, texpr.typeRef.value, texpr.parameters, boundTypeParams);
|
|||
|
} else if (texpr.typeRef.kind === "reference") {
|
|||
|
const ast = dresolver(texpr.typeRef.value);
|
|||
|
if (ast.decl.type_.kind === "struct_") {
|
|||
|
return structJsonBinding(dresolver, ast.decl.type_.value, texpr.parameters, boundTypeParams);
|
|||
|
} else if (ast.decl.type_.kind === "union_") {
|
|||
|
const union = ast.decl.type_.value;
|
|||
|
if (isEnum(union)) {
|
|||
|
return enumJsonBinding(dresolver, union, texpr.parameters, boundTypeParams);
|
|||
|
} else {
|
|||
|
return unionJsonBinding(dresolver, union, texpr.parameters, boundTypeParams);
|
|||
|
}
|
|||
|
} else if (ast.decl.type_.kind === "newtype_") {
|
|||
|
return newtypeJsonBinding(dresolver, ast.decl.type_.value, texpr.parameters, boundTypeParams);
|
|||
|
} else if (ast.decl.type_.kind === "type_") {
|
|||
|
return typedefJsonBinding(dresolver, ast.decl.type_.value, texpr.parameters, boundTypeParams);
|
|||
|
}
|
|||
|
} else if (texpr.typeRef.kind === "typeParam") {
|
|||
|
return boundTypeParams[texpr.typeRef.value];
|
|||
|
}
|
|||
|
throw new Error("buildJsonBinding : unimplemented ADL type");
|
|||
|
}
|
|||
|
function primitiveJsonBinding(dresolver, ptype, params, boundTypeParams) {
|
|||
|
if (ptype === "String") {
|
|||
|
return identityJsonBinding("a string", (v)=>typeof v === 'string'
|
|||
|
);
|
|||
|
} else if (ptype === "Int8") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Void") {
|
|||
|
return identityJsonBinding("a null", (v)=>v === null
|
|||
|
);
|
|||
|
} else if (ptype === "Bool") {
|
|||
|
return identityJsonBinding("a bool", (v)=>typeof v === 'boolean'
|
|||
|
);
|
|||
|
} else if (ptype === "Int8") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Int16") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Int32") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Int64") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Word8") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Word16") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Word32") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Word64") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Float") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Double") {
|
|||
|
return identityJsonBinding("a number", (v)=>typeof v === 'number'
|
|||
|
);
|
|||
|
} else if (ptype === "Json") {
|
|||
|
return identityJsonBinding("a json value", (_v)=>true
|
|||
|
);
|
|||
|
} else if (ptype === "Bytes") {
|
|||
|
return bytesJsonBinding();
|
|||
|
} else if (ptype === "Vector") {
|
|||
|
return vectorJsonBinding(dresolver, params[0], boundTypeParams);
|
|||
|
} else if (ptype === "StringMap") {
|
|||
|
return stringMapJsonBinding(dresolver, params[0], boundTypeParams);
|
|||
|
} else if (ptype === "Nullable") {
|
|||
|
return nullableJsonBinding(dresolver, params[0], boundTypeParams);
|
|||
|
} else throw new Error("Unimplemented json binding for primitive " + ptype);
|
|||
|
}
|
|||
|
function identityJsonBinding(expected, predicate) {
|
|||
|
function toJson(v) {
|
|||
|
return v;
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
if (!predicate(json)) {
|
|||
|
throw jsonParseException("expected " + expected);
|
|||
|
}
|
|||
|
return json;
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function bytesJsonBinding() {
|
|||
|
function toJson(v) {
|
|||
|
throw new Error("bytesJsonBinding not implemented");
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
if (typeof json != 'string') {
|
|||
|
throw jsonParseException('expected a string');
|
|||
|
}
|
|||
|
throw new Error("bytesJsonBinding not implemented");
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function vectorJsonBinding(dresolver, texpr, boundTypeParams) {
|
|||
|
const elementBinding = once(()=>buildJsonBinding(dresolver, texpr, boundTypeParams)
|
|||
|
);
|
|||
|
function toJson(v) {
|
|||
|
return v.map(elementBinding().toJson);
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
const jarr = asJsonArray(json);
|
|||
|
if (jarr == undefined) {
|
|||
|
throw jsonParseException('expected an array');
|
|||
|
}
|
|||
|
let result = [];
|
|||
|
jarr.forEach((eljson, i2)=>{
|
|||
|
try {
|
|||
|
result.push(elementBinding().fromJson(eljson));
|
|||
|
} catch (e) {
|
|||
|
if (isJsonParseException(e)) {
|
|||
|
e.pushIndex(i2);
|
|||
|
}
|
|||
|
throw e;
|
|||
|
}
|
|||
|
});
|
|||
|
return result;
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function stringMapJsonBinding(dresolver, texpr, boundTypeParams) {
|
|||
|
const elementBinding = once(()=>buildJsonBinding(dresolver, texpr, boundTypeParams)
|
|||
|
);
|
|||
|
function toJson(v) {
|
|||
|
const result = {
|
|||
|
};
|
|||
|
for(let k in v){
|
|||
|
result[k] = elementBinding().toJson(v[k]);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
const jobj = asJsonObject(json);
|
|||
|
if (!jobj) {
|
|||
|
throw jsonParseException('expected an object');
|
|||
|
}
|
|||
|
let result = {
|
|||
|
};
|
|||
|
for(let k in jobj){
|
|||
|
try {
|
|||
|
result[k] = elementBinding().fromJson(jobj[k]);
|
|||
|
} catch (e) {
|
|||
|
if (isJsonParseException(e)) {
|
|||
|
e.pushField(k);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function nullableJsonBinding(dresolver, texpr, boundTypeParams) {
|
|||
|
const elementBinding = once(()=>buildJsonBinding(dresolver, texpr, boundTypeParams)
|
|||
|
);
|
|||
|
function toJson(v) {
|
|||
|
if (v === null) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return elementBinding().toJson(v);
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
if (json === null) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return elementBinding().fromJson(json);
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function structJsonBinding(dresolver, struct, params, boundTypeParams) {
|
|||
|
const newBoundTypeParams = createBoundTypeParams(dresolver, struct.typeParams, params, boundTypeParams);
|
|||
|
const fieldDetails = [];
|
|||
|
struct.fields.forEach((field)=>{
|
|||
|
let buildDefault = once(()=>{
|
|||
|
if (field.default.kind === "just") {
|
|||
|
const json = field.default.value;
|
|||
|
return {
|
|||
|
'value': buildJsonBinding(dresolver, field.typeExpr, newBoundTypeParams).fromJson(json)
|
|||
|
};
|
|||
|
} else {
|
|||
|
return null;
|
|||
|
}
|
|||
|
});
|
|||
|
fieldDetails.push({
|
|||
|
field: field,
|
|||
|
jsonBinding: once(()=>buildJsonBinding(dresolver, field.typeExpr, newBoundTypeParams)
|
|||
|
),
|
|||
|
buildDefault: buildDefault
|
|||
|
});
|
|||
|
});
|
|||
|
function toJson(v0) {
|
|||
|
const v = v0;
|
|||
|
const json = {
|
|||
|
};
|
|||
|
fieldDetails.forEach((fd)=>{
|
|||
|
json[fd.field.serializedName] = fd.jsonBinding().toJson(v && v[fd.field.name]);
|
|||
|
});
|
|||
|
return json;
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
const jobj = asJsonObject(json);
|
|||
|
if (!jobj) {
|
|||
|
throw jsonParseException("expected an object");
|
|||
|
}
|
|||
|
const v = {
|
|||
|
};
|
|||
|
fieldDetails.forEach((fd)=>{
|
|||
|
if (jobj[fd.field.serializedName] === undefined) {
|
|||
|
const defaultv = fd.buildDefault();
|
|||
|
if (defaultv === null) {
|
|||
|
throw jsonParseException("missing struct field " + fd.field.serializedName);
|
|||
|
} else {
|
|||
|
v[fd.field.name] = defaultv.value;
|
|||
|
}
|
|||
|
} else {
|
|||
|
try {
|
|||
|
v[fd.field.name] = fd.jsonBinding().fromJson(jobj[fd.field.serializedName]);
|
|||
|
} catch (e) {
|
|||
|
if (isJsonParseException(e)) {
|
|||
|
e.pushField(fd.field.serializedName);
|
|||
|
}
|
|||
|
throw e;
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return v;
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function enumJsonBinding(_dresolver, union, _params, _boundTypeParams) {
|
|||
|
const fieldSerializedNames = [];
|
|||
|
const fieldNumbers = {
|
|||
|
};
|
|||
|
union.fields.forEach((field, i2)=>{
|
|||
|
fieldSerializedNames.push(field.serializedName);
|
|||
|
fieldNumbers[field.serializedName] = i2;
|
|||
|
});
|
|||
|
function toJson(v) {
|
|||
|
return fieldSerializedNames[v];
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
if (typeof json !== 'string') {
|
|||
|
throw jsonParseException("expected a string for enum");
|
|||
|
}
|
|||
|
const result = fieldNumbers[json];
|
|||
|
if (result === undefined) {
|
|||
|
throw jsonParseException("invalid string for enum: " + json);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function unionJsonBinding(dresolver, union, params, boundTypeParams) {
|
|||
|
const newBoundTypeParams = createBoundTypeParams(dresolver, union.typeParams, params, boundTypeParams);
|
|||
|
const detailsByName = {
|
|||
|
};
|
|||
|
const detailsBySerializedName = {
|
|||
|
};
|
|||
|
union.fields.forEach((field)=>{
|
|||
|
const details = {
|
|||
|
field: field,
|
|||
|
isVoid: isVoid(field.typeExpr),
|
|||
|
jsonBinding: once(()=>buildJsonBinding(dresolver, field.typeExpr, newBoundTypeParams)
|
|||
|
)
|
|||
|
};
|
|||
|
detailsByName[field.name] = details;
|
|||
|
detailsBySerializedName[field.serializedName] = details;
|
|||
|
});
|
|||
|
function toJson(v0) {
|
|||
|
const v = v0;
|
|||
|
const details = detailsByName[v.kind];
|
|||
|
if (details.isVoid) {
|
|||
|
return details.field.serializedName;
|
|||
|
} else {
|
|||
|
const result = {
|
|||
|
};
|
|||
|
result[details.field.serializedName] = details.jsonBinding().toJson(v.value);
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
function lookupDetails(serializedName) {
|
|||
|
let details = detailsBySerializedName[serializedName];
|
|||
|
if (details === undefined) {
|
|||
|
throw jsonParseException("invalid union field " + serializedName);
|
|||
|
}
|
|||
|
return details;
|
|||
|
}
|
|||
|
function fromJson(json) {
|
|||
|
if (typeof json === "string") {
|
|||
|
let details = lookupDetails(json);
|
|||
|
if (!details.isVoid) {
|
|||
|
throw jsonParseException("union field " + json + "needs an associated value");
|
|||
|
}
|
|||
|
return {
|
|||
|
kind: details.field.name
|
|||
|
};
|
|||
|
}
|
|||
|
const jobj = asJsonObject(json);
|
|||
|
if (jobj) {
|
|||
|
for(let k in jobj){
|
|||
|
let details = lookupDetails(k);
|
|||
|
try {
|
|||
|
return {
|
|||
|
kind: details.field.name,
|
|||
|
value: details.jsonBinding().fromJson(jobj[k])
|
|||
|
};
|
|||
|
} catch (e) {
|
|||
|
if (isJsonParseException(e)) {
|
|||
|
e.pushField(k);
|
|||
|
}
|
|||
|
throw e;
|
|||
|
}
|
|||
|
}
|
|||
|
throw jsonParseException("union without a property");
|
|||
|
} else {
|
|||
|
throw jsonParseException("expected an object or string");
|
|||
|
}
|
|||
|
}
|
|||
|
return {
|
|||
|
toJson,
|
|||
|
fromJson
|
|||
|
};
|
|||
|
}
|
|||
|
function newtypeJsonBinding(dresolver, newtype, params, boundTypeParams) {
|
|||
|
const newBoundTypeParams = createBoundTypeParams(dresolver, newtype.typeParams, params, boundTypeParams);
|
|||
|
return buildJsonBinding(dresolver, newtype.typeExpr, newBoundTypeParams);
|
|||
|
}
|
|||
|
function typedefJsonBinding(dresolver, typedef, params, boundTypeParams) {
|
|||
|
const newBoundTypeParams = createBoundTypeParams(dresolver, typedef.typeParams, params, boundTypeParams);
|
|||
|
return buildJsonBinding(dresolver, typedef.typeExpr, newBoundTypeParams);
|
|||
|
}
|
|||
|
function createBoundTypeParams(dresolver, paramNames, paramTypes, boundTypeParams) {
|
|||
|
let result = {
|
|||
|
};
|
|||
|
paramNames.forEach((paramName, i2)=>{
|
|||
|
result[paramName] = buildJsonBinding(dresolver, paramTypes[i2], boundTypeParams);
|
|||
|
});
|
|||
|
return result;
|
|||
|
}
|
|||
|
function once(run1) {
|
|||
|
let result = null;
|
|||
|
return ()=>{
|
|||
|
if (result === null) {
|
|||
|
result = run1();
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
}
|
|||
|
function declResolver(...astMaps) {
|
|||
|
const astMap = {
|
|||
|
};
|
|||
|
for (let map of astMaps){
|
|||
|
for(let scopedName in map){
|
|||
|
astMap[scopedName] = map[scopedName];
|
|||
|
}
|
|||
|
}
|
|||
|
function resolver(scopedName) {
|
|||
|
const scopedNameStr = scopedName.moduleName + "." + scopedName.name;
|
|||
|
const result = astMap[scopedNameStr];
|
|||
|
if (result === undefined) {
|
|||
|
throw new Error("Unable to resolve ADL type " + scopedNameStr);
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
return resolver;
|
|||
|
}
|
|||
|
const Pair_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "struct_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"T1",
|
|||
|
"T2"
|
|||
|
],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "v1",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "v1",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T1"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "v2",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "v2",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T2"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Pair",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Either_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "union_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"T1",
|
|||
|
"T2"
|
|||
|
],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "left",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "left",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T1"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "right",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "right",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T2"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Either",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Maybe_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "union_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"T"
|
|||
|
],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "nothing",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "nothing",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "Void"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "just",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "just",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Maybe",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Error_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "union_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"T"
|
|||
|
],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "value",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "value",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "error",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "error",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "String"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Error",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const MapEntry_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "struct_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"K",
|
|||
|
"V"
|
|||
|
],
|
|||
|
"fields": [
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "k",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "key",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "K"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
},
|
|||
|
{
|
|||
|
"annotations": [],
|
|||
|
"serializedName": "v",
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"name": "value",
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "V"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "MapEntry",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Map_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"K",
|
|||
|
"V"
|
|||
|
],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "Vector"
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "reference",
|
|||
|
"value": {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"name": "Pair"
|
|||
|
}
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "K"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
},
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "V"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Map",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const Set_AST = {
|
|||
|
"moduleName": "sys.types",
|
|||
|
"decl": {
|
|||
|
"annotations": [],
|
|||
|
"type_": {
|
|||
|
"kind": "newtype_",
|
|||
|
"value": {
|
|||
|
"typeParams": [
|
|||
|
"T"
|
|||
|
],
|
|||
|
"default": {
|
|||
|
"kind": "nothing"
|
|||
|
},
|
|||
|
"typeExpr": {
|
|||
|
"typeRef": {
|
|||
|
"kind": "primitive",
|
|||
|
"value": "Vector"
|
|||
|
},
|
|||
|
"parameters": [
|
|||
|
{
|
|||
|
"typeRef": {
|
|||
|
"kind": "typeParam",
|
|||
|
"value": "T"
|
|||
|
},
|
|||
|
"parameters": []
|
|||
|
}
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
"name": "Set",
|
|||
|
"version": {
|
|||
|
"kind": "nothing"
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
const _AST_MAP1 = {
|
|||
|
"sys.types.Pair": Pair_AST,
|
|||
|
"sys.types.Either": Either_AST,
|
|||
|
"sys.types.Maybe": Maybe_AST,
|
|||
|
"sys.types.Error": Error_AST,
|
|||
|
"sys.types.MapEntry": MapEntry_AST,
|
|||
|
"sys.types.Map": Map_AST,
|
|||
|
"sys.types.Set": Set_AST
|
|||
|
};
|
|||
|
const ADL = {
|
|||
|
..._AST_MAP,
|
|||
|
..._AST_MAP1
|
|||
|
};
|
|||
|
const RESOLVER = declResolver(ADL);
|
|||
|
class ADLMap {
|
|||
|
constructor(data, isEqual){
|
|||
|
this.data = data;
|
|||
|
this.isEqual = isEqual;
|
|||
|
}
|
|||
|
has(k) {
|
|||
|
return this.findIndex(k) !== -1;
|
|||
|
}
|
|||
|
get(k) {
|
|||
|
const ind = this.findIndex(k);
|
|||
|
if (ind === -1) {
|
|||
|
return undefined;
|
|||
|
}
|
|||
|
return this.data[ind].v2;
|
|||
|
}
|
|||
|
getOrInsert(k, v) {
|
|||
|
const existing = this.get(k);
|
|||
|
if (existing === undefined) {
|
|||
|
this.set(k, v);
|
|||
|
return v;
|
|||
|
}
|
|||
|
return existing;
|
|||
|
}
|
|||
|
set(k, v) {
|
|||
|
const ind = this.findIndex(k);
|
|||
|
if (ind === -1) {
|
|||
|
this.data.push({
|
|||
|
v1: k,
|
|||
|
v2: v
|
|||
|
});
|
|||
|
}
|
|||
|
this.data[ind] = {
|
|||
|
v1: k,
|
|||
|
v2: v
|
|||
|
};
|
|||
|
return this;
|
|||
|
}
|
|||
|
keys() {
|
|||
|
return this.data.map((p)=>p.v1
|
|||
|
);
|
|||
|
}
|
|||
|
values() {
|
|||
|
return this.data.map((p)=>p.v2
|
|||
|
);
|
|||
|
}
|
|||
|
entries() {
|
|||
|
return this.data.map((p)=>[
|
|||
|
p.v1,
|
|||
|
p.v2
|
|||
|
]
|
|||
|
);
|
|||
|
}
|
|||
|
toData() {
|
|||
|
return this.data;
|
|||
|
}
|
|||
|
findIndex(k) {
|
|||
|
return this.data.findIndex((p)=>this.isEqual(p.v1, k)
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
class Manifest {
|
|||
|
jsonBinding = createJsonBinding(RESOLVER, texprManifest());
|
|||
|
tasks = new ADLMap([], (k1, k2)=>k1 === k2
|
|||
|
);
|
|||
|
constructor(dir, filename = ".manifest.json"){
|
|||
|
this.filename = mod3.join(dir, filename);
|
|||
|
}
|
|||
|
async load() {
|
|||
|
if (await mod5.exists(this.filename)) {
|
|||
|
const json = JSON.parse(await Deno.readTextFile(this.filename));
|
|||
|
const mdata = this.jsonBinding.fromJson(json);
|
|||
|
for (const p of mdata.tasks){
|
|||
|
const taskName = p.v1;
|
|||
|
const taskData = p.v2;
|
|||
|
this.tasks.set(taskName, new TaskManifest(taskData));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
async save() {
|
|||
|
if (!await mod5.exists(mod3.dirname(this.filename))) {
|
|||
|
}
|
|||
|
const mdata = {
|
|||
|
tasks: this.tasks.entries().map((p)=>({
|
|||
|
v1: p[0],
|
|||
|
v2: p[1].toData()
|
|||
|
})
|
|||
|
)
|
|||
|
};
|
|||
|
const jsonval = this.jsonBinding.toJson(mdata);
|
|||
|
await Deno.writeTextFile(this.filename, JSON.stringify(jsonval, null, 2));
|
|||
|
}
|
|||
|
}
|
|||
|
class TaskManifest {
|
|||
|
lastExecution = null;
|
|||
|
trackedFiles = new ADLMap([], (k1, k2)=>k1 === k2
|
|||
|
);
|
|||
|
constructor(data1){
|
|||
|
this.trackedFiles = new ADLMap(data1.trackedFiles, (k1, k2)=>k1 === k2
|
|||
|
);
|
|||
|
this.lastExecution = data1.lastExecution;
|
|||
|
}
|
|||
|
getFileData(fn) {
|
|||
|
return this.trackedFiles.get(fn);
|
|||
|
}
|
|||
|
setFileData(fn, d) {
|
|||
|
this.trackedFiles.set(fn, d);
|
|||
|
}
|
|||
|
setExecutionTimestamp() {
|
|||
|
this.lastExecution = new Date().toISOString();
|
|||
|
}
|
|||
|
toData() {
|
|||
|
return {
|
|||
|
lastExecution: this.lastExecution,
|
|||
|
trackedFiles: this.trackedFiles.toData()
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
class AsyncQueue {
|
|||
|
inProgress = 0;
|
|||
|
queue = [];
|
|||
|
constructor(concurrency){
|
|||
|
this.concurrency = concurrency;
|
|||
|
}
|
|||
|
async schedule(t) {
|
|||
|
return new Promise((resolve3, reject)=>{
|
|||
|
this.queue.push({
|
|||
|
action: t,
|
|||
|
resolve: resolve3,
|
|||
|
reject
|
|||
|
});
|
|||
|
this.startQueuedItem();
|
|||
|
});
|
|||
|
}
|
|||
|
startQueuedItem() {
|
|||
|
if (this.inProgress >= this.concurrency) {
|
|||
|
return;
|
|||
|
}
|
|||
|
const item = this.queue.shift();
|
|||
|
if (item === undefined) {
|
|||
|
return;
|
|||
|
}
|
|||
|
this.inProgress += 1;
|
|||
|
item.action().then((val)=>{
|
|||
|
item.resolve(val);
|
|||
|
}).catch((err)=>{
|
|||
|
item.reject(err);
|
|||
|
}).finally(()=>{
|
|||
|
this.inProgress -= 1;
|
|||
|
this.startQueuedItem();
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
class ExecContext {
|
|||
|
taskRegister = new Map();
|
|||
|
targetRegister = new Map();
|
|||
|
doneTasks = new Set();
|
|||
|
inprogressTasks = new Set();
|
|||
|
internalLogger = mod4.getLogger("internal");
|
|||
|
taskLogger = mod4.getLogger("task");
|
|||
|
userLogger = mod4.getLogger("user");
|
|||
|
constructor(manifest, args){
|
|||
|
this.manifest = manifest;
|
|||
|
this.args = args;
|
|||
|
if (args["verbose"] !== undefined) {
|
|||
|
this.internalLogger.levelName = "INFO";
|
|||
|
}
|
|||
|
const concurrency1 = args["concurrency"] || 4;
|
|||
|
this.asyncQueue = new AsyncQueue(concurrency1);
|
|||
|
this.internalLogger.info(`Starting ExecContext version: ${version2}`);
|
|||
|
}
|
|||
|
getTaskByName(name) {
|
|||
|
return this.taskRegister.get(name);
|
|||
|
}
|
|||
|
}
|
|||
|
function taskContext(ctx, task) {
|
|||
|
return {
|
|||
|
logger: ctx.taskLogger,
|
|||
|
task,
|
|||
|
args: ctx.args
|
|||
|
};
|
|||
|
}
|
|||
|
function isTask(dep) {
|
|||
|
return dep instanceof Task;
|
|||
|
}
|
|||
|
function isTrackedFile(dep) {
|
|||
|
return dep instanceof TrackedFile;
|
|||
|
}
|
|||
|
function isTrackedFileAsync(dep) {
|
|||
|
return dep instanceof TrackedFilesAsync;
|
|||
|
}
|
|||
|
async function statPath(path1) {
|
|||
|
try {
|
|||
|
const fileInfo = await Deno.stat(path1);
|
|||
|
return {
|
|||
|
kind: 'fileInfo',
|
|||
|
fileInfo
|
|||
|
};
|
|||
|
} catch (err) {
|
|||
|
if (err instanceof Deno.errors.NotFound) {
|
|||
|
return {
|
|||
|
kind: 'nonExistent'
|
|||
|
};
|
|||
|
}
|
|||
|
throw err;
|
|||
|
}
|
|||
|
}
|
|||
|
class Task {
|
|||
|
taskManifest = null;
|
|||
|
constructor(taskParams){
|
|||
|
this.name = taskParams.name;
|
|||
|
this.action = taskParams.action;
|
|||
|
this.description = taskParams.description;
|
|||
|
this.task_deps = new Set(this.getTaskDeps(taskParams.deps || []));
|
|||
|
this.file_deps = new Set(this.getTrackedFiles(taskParams.deps || []));
|
|||
|
this.async_files_deps = new Set(this.getTrackedFilesAsync(taskParams.deps || []));
|
|||
|
this.targets = new Set(taskParams.targets || []);
|
|||
|
this.uptodate = taskParams.uptodate;
|
|||
|
for (const f of this.targets){
|
|||
|
f.setTask(this);
|
|||
|
}
|
|||
|
}
|
|||
|
getTaskDeps(deps) {
|
|||
|
return deps.filter(isTask);
|
|||
|
}
|
|||
|
getTrackedFiles(deps) {
|
|||
|
return deps.filter(isTrackedFile);
|
|||
|
}
|
|||
|
getTrackedFilesAsync(deps) {
|
|||
|
return deps.filter(isTrackedFileAsync);
|
|||
|
}
|
|||
|
async setup(ctx) {
|
|||
|
if (this.taskManifest === null) {
|
|||
|
for (const t of this.targets){
|
|||
|
ctx.targetRegister.set(t.path, this);
|
|||
|
}
|
|||
|
this.taskManifest = ctx.manifest.tasks.getOrInsert(this.name, new TaskManifest({
|
|||
|
lastExecution: null,
|
|||
|
trackedFiles: []
|
|||
|
}));
|
|||
|
for (const taskDep of this.task_deps){
|
|||
|
await taskDep.setup(ctx);
|
|||
|
}
|
|||
|
for (const fDep of this.file_deps){
|
|||
|
const fDepTask = fDep.getTask();
|
|||
|
if (fDepTask !== null) {
|
|||
|
await fDepTask.setup(ctx);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
async exec(ctx) {
|
|||
|
if (ctx.doneTasks.has(this)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
if (ctx.inprogressTasks.has(this)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
ctx.inprogressTasks.add(this);
|
|||
|
for (const afd of this.async_files_deps){
|
|||
|
const file_deps = await afd.getTrackedFiles();
|
|||
|
for (const fd of file_deps){
|
|||
|
this.file_deps.add(fd);
|
|||
|
}
|
|||
|
}
|
|||
|
for (const fd of this.file_deps){
|
|||
|
const t = ctx.targetRegister.get(fd.path);
|
|||
|
if (t !== undefined) {
|
|||
|
this.task_deps.add(t);
|
|||
|
}
|
|||
|
}
|
|||
|
await this.execDependencies(ctx);
|
|||
|
let actualUpToDate = true;
|
|||
|
actualUpToDate = actualUpToDate && await this.checkFileDeps(ctx);
|
|||
|
ctx.internalLogger.info(`${this.name} checkFileDeps ${actualUpToDate}`);
|
|||
|
actualUpToDate = actualUpToDate && await this.targetsExist(ctx);
|
|||
|
ctx.internalLogger.info(`${this.name} targetsExist ${actualUpToDate}`);
|
|||
|
if (this.uptodate !== undefined) {
|
|||
|
actualUpToDate = actualUpToDate && await this.uptodate(taskContext(ctx, this));
|
|||
|
}
|
|||
|
ctx.internalLogger.info(`${this.name} uptodate ${actualUpToDate}`);
|
|||
|
if (actualUpToDate) {
|
|||
|
ctx.taskLogger.info(`--- ${this.name}`);
|
|||
|
} else {
|
|||
|
ctx.taskLogger.info(`... ${this.name}`);
|
|||
|
await this.action(taskContext(ctx, this));
|
|||
|
ctx.taskLogger.info(`=== ${this.name}`);
|
|||
|
{
|
|||
|
this.taskManifest?.setExecutionTimestamp();
|
|||
|
let promisesInProgress = [];
|
|||
|
for (const fdep of this.file_deps){
|
|||
|
promisesInProgress.push(ctx.asyncQueue.schedule(async ()=>{
|
|||
|
const trackedFileData = await fdep.getFileData(ctx);
|
|||
|
this.taskManifest?.setFileData(fdep.path, trackedFileData);
|
|||
|
}));
|
|||
|
}
|
|||
|
await Promise.all(promisesInProgress);
|
|||
|
}
|
|||
|
}
|
|||
|
ctx.doneTasks.add(this);
|
|||
|
ctx.inprogressTasks.delete(this);
|
|||
|
}
|
|||
|
async targetsExist(ctx) {
|
|||
|
const tex = await Promise.all(Array.from(this.targets).map(async (tf)=>ctx.asyncQueue.schedule(()=>tf.exists()
|
|||
|
)
|
|||
|
));
|
|||
|
return !tex.some((t)=>!t
|
|||
|
);
|
|||
|
}
|
|||
|
async checkFileDeps(ctx) {
|
|||
|
let fileDepsUpToDate = true;
|
|||
|
let promisesInProgress = [];
|
|||
|
const taskManifest = this.taskManifest;
|
|||
|
if (taskManifest === null) {
|
|||
|
throw new Error(`Invalid null taskManifest on ${this.name}`);
|
|||
|
}
|
|||
|
for (const fdep of this.file_deps){
|
|||
|
promisesInProgress.push(ctx.asyncQueue.schedule(async ()=>{
|
|||
|
const r = await fdep.getFileDataOrCached(ctx, taskManifest.getFileData(fdep.path));
|
|||
|
taskManifest.setFileData(fdep.path, r.tData);
|
|||
|
fileDepsUpToDate = fileDepsUpToDate && r.upToDate;
|
|||
|
}));
|
|||
|
}
|
|||
|
await Promise.all(promisesInProgress);
|
|||
|
promisesInProgress = [];
|
|||
|
return fileDepsUpToDate;
|
|||
|
}
|
|||
|
async execDependencies(ctx) {
|
|||
|
for (const dep of this.task_deps){
|
|||
|
if (!ctx.doneTasks.has(dep) && !ctx.inprogressTasks.has(dep)) {
|
|||
|
await dep.exec(ctx);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
class TrackedFile {
|
|||
|
path = "";
|
|||
|
#getHash;
|
|||
|
#getTimestamp;
|
|||
|
fromTask = null;
|
|||
|
constructor(fileParams){
|
|||
|
this.path = mod3.posix.resolve(fileParams.path);
|
|||
|
this.#getHash = fileParams.getHash || getFileSha1Sum;
|
|||
|
this.#getTimestamp = fileParams.getTimestamp || getFileTimestamp;
|
|||
|
}
|
|||
|
async stat() {
|
|||
|
mod4.getLogger('internal').info(`checking file ${this.path}`);
|
|||
|
return await statPath(this.path);
|
|||
|
}
|
|||
|
async exists(statInput) {
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
return statResult.kind === 'fileInfo';
|
|||
|
}
|
|||
|
async getHash(statInput) {
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
if (statResult.kind !== 'fileInfo') {
|
|||
|
return "";
|
|||
|
}
|
|||
|
mod4.getLogger('internal').info(`checking hash on ${this.path}`);
|
|||
|
return this.#getHash(this.path, statResult.fileInfo);
|
|||
|
}
|
|||
|
async getTimestamp(statInput) {
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
if (statResult.kind !== 'fileInfo') {
|
|||
|
return "";
|
|||
|
}
|
|||
|
return this.#getTimestamp(this.path, statResult.fileInfo);
|
|||
|
}
|
|||
|
async isUpToDate(ctx, tData, statInput) {
|
|||
|
if (tData === undefined) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
const mtime = await this.getTimestamp(statResult);
|
|||
|
if (mtime === tData.timestamp) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
const hash = await this.getHash(statResult);
|
|||
|
return hash === tData.hash;
|
|||
|
}
|
|||
|
async getFileData(ctx, statInput) {
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
return {
|
|||
|
hash: await this.getHash(statResult),
|
|||
|
timestamp: await this.getTimestamp(statResult)
|
|||
|
};
|
|||
|
}
|
|||
|
async getFileDataOrCached(ctx, tData, statInput) {
|
|||
|
let statResult = statInput;
|
|||
|
if (statResult === undefined) {
|
|||
|
statResult = await this.stat();
|
|||
|
}
|
|||
|
if (tData !== undefined && await this.isUpToDate(ctx, tData, statResult)) {
|
|||
|
return {
|
|||
|
tData,
|
|||
|
upToDate: true
|
|||
|
};
|
|||
|
}
|
|||
|
return {
|
|||
|
tData: await this.getFileData(ctx, statResult),
|
|||
|
upToDate: false
|
|||
|
};
|
|||
|
}
|
|||
|
setTask(t) {
|
|||
|
if (this.fromTask === null) {
|
|||
|
this.fromTask = t;
|
|||
|
} else {
|
|||
|
throw new Error("Duplicate tasks generating TrackedFile as target - " + this.path);
|
|||
|
}
|
|||
|
}
|
|||
|
getTask() {
|
|||
|
return this.fromTask;
|
|||
|
}
|
|||
|
}
|
|||
|
class TrackedFilesAsync {
|
|||
|
kind = 'trackedfilesasync';
|
|||
|
constructor(gen){
|
|||
|
this.gen = gen;
|
|||
|
}
|
|||
|
async getTrackedFiles() {
|
|||
|
return this.gen();
|
|||
|
}
|
|||
|
}
|
|||
|
async function getFileSha1Sum(filename1) {
|
|||
|
const data2 = await Deno.readFile(filename1);
|
|||
|
const hashsha1 = mod6.createHash("sha1");
|
|||
|
hashsha1.update(data2);
|
|||
|
const hashInHex = hashsha1.toString();
|
|||
|
return hashInHex;
|
|||
|
}
|
|||
|
async function getFileTimestamp(filename1, stat) {
|
|||
|
const mtime = stat.mtime;
|
|||
|
return mtime?.toISOString() || "";
|
|||
|
}
|
|||
|
class StdErrPlainHandler extends mod4.handlers.BaseHandler {
|
|||
|
constructor(levelName5){
|
|||
|
super(levelName5, {
|
|||
|
formatter: "{msg}"
|
|||
|
});
|
|||
|
}
|
|||
|
log(msg) {
|
|||
|
Deno.stderr.writeSync(new TextEncoder().encode(msg + "\n"));
|
|||
|
}
|
|||
|
}
|
|||
|
class StdErrHandler extends mod4.handlers.ConsoleHandler {
|
|||
|
log(msg) {
|
|||
|
Deno.stderr.writeSync(new TextEncoder().encode(msg + "\n"));
|
|||
|
}
|
|||
|
}
|
|||
|
async function setupLogging() {
|
|||
|
await mod4.setup({
|
|||
|
handlers: {
|
|||
|
stderr: new StdErrHandler("DEBUG"),
|
|||
|
stderrPlain: new StdErrPlainHandler("DEBUG")
|
|||
|
},
|
|||
|
loggers: {
|
|||
|
internal: {
|
|||
|
level: "WARNING",
|
|||
|
handlers: [
|
|||
|
"stderrPlain"
|
|||
|
]
|
|||
|
},
|
|||
|
task: {
|
|||
|
level: "INFO",
|
|||
|
handlers: [
|
|||
|
"stderrPlain"
|
|||
|
]
|
|||
|
},
|
|||
|
user: {
|
|||
|
level: "INFO",
|
|||
|
handlers: [
|
|||
|
"stderrPlain"
|
|||
|
]
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
function findUserSourceContext(dir1) {
|
|||
|
const pathParts = dir1.split(mod3.SEP);
|
|||
|
return {
|
|||
|
path: dir1,
|
|||
|
stat: Deno.lstatSync(dir1)
|
|||
|
};
|
|||
|
}
|
|||
|
function findUserSource(dir1, startCtxArg) {
|
|||
|
const startCtx = startCtxArg === null ? findUserSourceContext(dir1) : startCtxArg;
|
|||
|
const dirStat = Deno.lstatSync(dir1);
|
|||
|
if (dirStat.dev !== startCtx.stat.dev) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
if (mod3.resolve(mod3.join(dir1, "..")) === dir1) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
const subdirs = [
|
|||
|
"dnit"
|
|||
|
];
|
|||
|
const defaultSources = [
|
|||
|
"main.ts",
|
|||
|
"dnit.ts",
|
|||
|
];
|
|||
|
const importmaps = [
|
|||
|
"import_map.json",
|
|||
|
".import_map.json"
|
|||
|
];
|
|||
|
for (const subdir of subdirs){
|
|||
|
for (const sourceName of defaultSources){
|
|||
|
const res = {
|
|||
|
baseDir: mod3.resolve(dir1),
|
|||
|
dnitDir: mod3.resolve(mod3.join(dir1, subdir)),
|
|||
|
mainSrc: mod3.resolve(mod3.join(dir1, subdir, sourceName))
|
|||
|
};
|
|||
|
if (mod5.existsSync(res.mainSrc)) {
|
|||
|
for (const importMapFile of importmaps){
|
|||
|
const importmap = mod3.resolve(mod3.join(dir1, subdir, importMapFile));
|
|||
|
if (mod5.existsSync(importmap)) {
|
|||
|
return {
|
|||
|
...res,
|
|||
|
importmap
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
return {
|
|||
|
...res,
|
|||
|
importmap: null
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return findUserSource(mod3.join(dir1, ".."), startCtx);
|
|||
|
}
|
|||
|
async function parseDotDenoVersionFile(fname) {
|
|||
|
const denoReqSemverRange = await Deno.readTextFile(fname);
|
|||
|
return denoReqSemverRange;
|
|||
|
}
|
|||
|
async function getDenoVersion() {
|
|||
|
const proc = Deno.run({
|
|||
|
cmd: [
|
|||
|
"deno",
|
|||
|
"--version"
|
|||
|
],
|
|||
|
stdout: 'piped'
|
|||
|
});
|
|||
|
const [status, output] = await Promise.all([
|
|||
|
proc.status(),
|
|||
|
proc.output()
|
|||
|
]);
|
|||
|
const decoder = new TextDecoder();
|
|||
|
const denoVersionStr = decoder.decode(output);
|
|||
|
const regmatch = denoVersionStr.match(/deno[ ]+([0-9.]+)/);
|
|||
|
if (regmatch) {
|
|||
|
return regmatch[1];
|
|||
|
}
|
|||
|
throw new Error("Invalid parse of deno version output");
|
|||
|
}
|
|||
|
function checkValidDenoVersion(denoVersion, denoReqSemverRange) {
|
|||
|
return mod7.satisfies(denoVersion, denoReqSemverRange);
|
|||
|
}
|
|||
|
async function launch(logger) {
|
|||
|
const userSource = findUserSource(Deno.cwd(), null);
|
|||
|
if (userSource !== null) {
|
|||
|
logger.info("running source:" + userSource.mainSrc);
|
|||
|
logger.info("running wd:" + userSource.baseDir);
|
|||
|
logger.info("running importmap:" + userSource.importmap);
|
|||
|
logger.info("running dnitDir:" + userSource.dnitDir);
|
|||
|
const denoVersion = await getDenoVersion();
|
|||
|
logger.info("deno version:" + denoVersion);
|
|||
|
const dotDenoVersionFile = mod3.join(userSource.dnitDir, '.denoversion');
|
|||
|
if (mod5.existsSync(dotDenoVersionFile)) {
|
|||
|
const reqDenoVerStr = await parseDotDenoVersionFile(dotDenoVersionFile);
|
|||
|
const validDenoVer = checkValidDenoVersion(denoVersion, reqDenoVerStr);
|
|||
|
if (!validDenoVer) {
|
|||
|
throw new Error("Requires deno version " + reqDenoVerStr);
|
|||
|
}
|
|||
|
logger.info("deno version ok:" + denoVersion + " for " + reqDenoVerStr);
|
|||
|
}
|
|||
|
Deno.chdir(userSource.baseDir);
|
|||
|
const permissions = [
|
|||
|
"--allow-read",
|
|||
|
"--allow-write",
|
|||
|
"--allow-run",
|
|||
|
"--allow-env",
|
|||
|
"--allow-net",
|
|||
|
];
|
|||
|
const flags = [
|
|||
|
"--quiet",
|
|||
|
"--unstable",
|
|||
|
];
|
|||
|
const importmap = userSource.importmap ? [
|
|||
|
"--importmap",
|
|||
|
userSource.importmap,
|
|||
|
] : [];
|
|||
|
const proc = Deno.run({
|
|||
|
cmd: [
|
|||
|
"deno",
|
|||
|
"run"
|
|||
|
].concat(flags).concat(permissions).concat(importmap).concat([
|
|||
|
userSource.mainSrc
|
|||
|
]).concat([
|
|||
|
"--dnitDir",
|
|||
|
userSource.dnitDir
|
|||
|
]).concat(Deno.args)
|
|||
|
});
|
|||
|
const status = await proc.status();
|
|||
|
return status;
|
|||
|
} else {
|
|||
|
logger.error("No dnit.ts or dnit directory found");
|
|||
|
return {
|
|||
|
success: false,
|
|||
|
code: 1
|
|||
|
};
|
|||
|
}
|
|||
|
}
|
|||
|
async function main1() {
|
|||
|
const args1 = mod.parse(Deno.args);
|
|||
|
if (args1["version"] === true) {
|
|||
|
console.log(`dnit ${version2}`);
|
|||
|
Deno.exit(0);
|
|||
|
}
|
|||
|
await setupLogging();
|
|||
|
const internalLogger = mod4.getLogger("internal");
|
|||
|
if (args1["verbose"] !== undefined) {
|
|||
|
internalLogger.levelName = "INFO";
|
|||
|
}
|
|||
|
internalLogger.info(`starting dnit launch using version: ${version2}`);
|
|||
|
launch(internalLogger).then((st)=>{
|
|||
|
Deno.exit(st.code);
|
|||
|
});
|
|||
|
}
|
|||
|
main1();
|
|||
|
export { main1 as main };
|