Fix bin/publish: copy docs.dist from project root

Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-10-21 02:08:33 +00:00
commit f6fac6c4bc
79758 changed files with 10547827 additions and 0 deletions

47
vendor/spatie/ignition/node_modules/uvu/assert/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,47 @@
type Types = 'string' | 'number' | 'boolean' | 'object' | 'undefined' | 'function';
export type Message = string | Error;
export function ok(actual: any, msg?: Message): asserts actual;
export function is(actual: any, expects: any, msg?: Message): void;
export function equal(actual: any, expects: any, msg?: Message): void;
export function type(actual: any, expects: Types, msg?: Message): void;
export function instance(actual: any, expects: any, msg?: Message): void;
export function snapshot(actual: string, expects: string, msg?: Message): void;
export function fixture(actual: string, expects: string, msg?: Message): void;
export function match(actual: string, expects: string | RegExp, msg?: Message): void;
export function throws(fn: Function, expects?: Message | RegExp | Function, msg?: Message): void;
export function not(actual: any, msg?: Message): void;
export function unreachable(msg?: Message): void;
export namespace is {
function not(actual: any, expects: any, msg?: Message): void;
}
export namespace not {
function ok(actual: any, msg?: Message): void;
function equal(actual: any, expects: any, msg?: Message): void;
function type(actual: any, expects: Types, msg?: Message): void;
function instance(actual: any, expects: any, msg?: Message): void;
function snapshot(actual: string, expects: string, msg?: Message): void;
function fixture(actual: string, expects: string, msg?: Message): void;
function match(actual: string, expects: string | RegExp, msg?: Message): void;
function throws(fn: Function, expects?: Message | RegExp | Function, msg?: Message): void;
}
export class Assertion extends Error {
name: 'Assertion';
code: 'ERR_ASSERTION';
details: false | string;
generated: boolean;
operator: string;
expects: any;
actual: any;
constructor(options?: {
message: string;
details?: string;
generated?: boolean;
operator: string;
expects: any;
actual: any;
});
}

173
vendor/spatie/ignition/node_modules/uvu/assert/index.js generated vendored Executable file
View File

@@ -0,0 +1,173 @@
const { dequal } = require('dequal');
const { compare, lines } = require('uvu/diff');
function dedent(str) {
str = str.replace(/\r?\n/g, '\n');
let arr = str.match(/^[ \t]*(?=\S)/gm);
let i = 0, min = 1/0, len = (arr||[]).length;
for (; i < len; i++) min = Math.min(min, arr[i].length);
return len && min ? str.replace(new RegExp(`^[ \\t]{${min}}`, 'gm'), '') : str;
}
class Assertion extends Error {
constructor(opts={}) {
super(opts.message);
this.name = 'Assertion';
this.code = 'ERR_ASSERTION';
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.details = opts.details || false;
this.generated = !!opts.generated;
this.operator = opts.operator;
this.expects = opts.expects;
this.actual = opts.actual;
}
}
function assert(bool, actual, expects, operator, detailer, backup, msg) {
if (bool) return;
let message = msg || backup;
if (msg instanceof Error) throw msg;
let details = detailer && detailer(actual, expects);
throw new Assertion({ actual, expects, operator, message, details, generated: !msg });
}
function ok(val, msg) {
assert(!!val, false, true, 'ok', false, 'Expected value to be truthy', msg);
}
function is(val, exp, msg) {
assert(val === exp, val, exp, 'is', compare, 'Expected values to be strictly equal:', msg);
}
function equal(val, exp, msg) {
assert(dequal(val, exp), val, exp, 'equal', compare, 'Expected values to be deeply equal:', msg);
}
function unreachable(msg) {
assert(false, true, false, 'unreachable', false, 'Expected not to be reached!', msg);
}
function type(val, exp, msg) {
let tmp = typeof val;
assert(tmp === exp, tmp, exp, 'type', false, `Expected "${tmp}" to be "${exp}"`, msg);
}
function instance(val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(val instanceof exp, val, exp, 'instance', false, `Expected value to be an instance of ${name}`, msg);
}
function match(val, exp, msg) {
if (typeof exp === 'string') {
assert(val.includes(exp), val, exp, 'match', false, `Expected value to include "${exp}" substring`, msg);
} else {
assert(exp.test(val), val, exp, 'match', false, `Expected value to match \`${String(exp)}\` pattern`, msg);
}
}
function snapshot(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'snapshot', lines, 'Expected value to match snapshot:', msg);
}
const lineNums = (x, y) => lines(x, y, 1);
function fixture(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'fixture', lineNums, 'Expected value to match fixture:', msg);
}
function throws(blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
assert(false, false, true, 'throws', false, 'Expected function to throw', msg);
} catch (err) {
if (err instanceof Assertion) throw err;
if (typeof exp === 'function') {
assert(exp(err), false, true, 'throws', false, 'Expected function to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(exp.test(err.message), false, true, 'throws', false, `Expected function to throw exception matching \`${String(exp)}\` pattern`, msg);
}
}
}
// ---
function not(val, msg) {
assert(!val, true, false, 'not', false, 'Expected value to be falsey', msg);
}
not.ok = not;
is.not = function (val, exp, msg) {
assert(val !== exp, val, exp, 'is.not', false, 'Expected values not to be strictly equal', msg);
}
not.equal = function (val, exp, msg) {
assert(!dequal(val, exp), val, exp, 'not.equal', false, 'Expected values not to be deeply equal', msg);
}
not.type = function (val, exp, msg) {
let tmp = typeof val;
assert(tmp !== exp, tmp, exp, 'not.type', false, `Expected "${tmp}" not to be "${exp}"`, msg);
}
not.instance = function (val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(!(val instanceof exp), val, exp, 'not.instance', false, `Expected value not to be an instance of ${name}`, msg);
}
not.snapshot = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.snapshot', false, 'Expected value not to match snapshot', msg);
}
not.fixture = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.fixture', false, 'Expected value not to match fixture', msg);
}
not.match = function (val, exp, msg) {
if (typeof exp === 'string') {
assert(!val.includes(exp), val, exp, 'not.match', false, `Expected value not to include "${exp}" substring`, msg);
} else {
assert(!exp.test(val), val, exp, 'not.match', false, `Expected value not to match \`${String(exp)}\` pattern`, msg);
}
}
not.throws = function (blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
} catch (err) {
if (typeof exp === 'function') {
assert(!exp(err), true, false, 'not.throws', false, 'Expected function not to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(!exp.test(err.message), true, false, 'not.throws', false, `Expected function not to throw exception matching \`${String(exp)}\` pattern`, msg);
} else if (!exp) {
assert(false, true, false, 'not.throws', false, 'Expected function not to throw', msg);
}
}
}
exports.Assertion = Assertion;
exports.equal = equal;
exports.fixture = fixture;
exports.instance = instance;
exports.is = is;
exports.match = match;
exports.not = not;
exports.ok = ok;
exports.snapshot = snapshot;
exports.throws = throws;
exports.type = type;
exports.unreachable = unreachable;

160
vendor/spatie/ignition/node_modules/uvu/assert/index.mjs generated vendored Executable file
View File

@@ -0,0 +1,160 @@
import { dequal } from 'dequal';
import { compare, lines } from 'uvu/diff';
function dedent(str) {
str = str.replace(/\r?\n/g, '\n');
let arr = str.match(/^[ \t]*(?=\S)/gm);
let i = 0, min = 1/0, len = (arr||[]).length;
for (; i < len; i++) min = Math.min(min, arr[i].length);
return len && min ? str.replace(new RegExp(`^[ \\t]{${min}}`, 'gm'), '') : str;
}
export class Assertion extends Error {
constructor(opts={}) {
super(opts.message);
this.name = 'Assertion';
this.code = 'ERR_ASSERTION';
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.details = opts.details || false;
this.generated = !!opts.generated;
this.operator = opts.operator;
this.expects = opts.expects;
this.actual = opts.actual;
}
}
function assert(bool, actual, expects, operator, detailer, backup, msg) {
if (bool) return;
let message = msg || backup;
if (msg instanceof Error) throw msg;
let details = detailer && detailer(actual, expects);
throw new Assertion({ actual, expects, operator, message, details, generated: !msg });
}
export function ok(val, msg) {
assert(!!val, false, true, 'ok', false, 'Expected value to be truthy', msg);
}
export function is(val, exp, msg) {
assert(val === exp, val, exp, 'is', compare, 'Expected values to be strictly equal:', msg);
}
export function equal(val, exp, msg) {
assert(dequal(val, exp), val, exp, 'equal', compare, 'Expected values to be deeply equal:', msg);
}
export function unreachable(msg) {
assert(false, true, false, 'unreachable', false, 'Expected not to be reached!', msg);
}
export function type(val, exp, msg) {
let tmp = typeof val;
assert(tmp === exp, tmp, exp, 'type', false, `Expected "${tmp}" to be "${exp}"`, msg);
}
export function instance(val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(val instanceof exp, val, exp, 'instance', false, `Expected value to be an instance of ${name}`, msg);
}
export function match(val, exp, msg) {
if (typeof exp === 'string') {
assert(val.includes(exp), val, exp, 'match', false, `Expected value to include "${exp}" substring`, msg);
} else {
assert(exp.test(val), val, exp, 'match', false, `Expected value to match \`${String(exp)}\` pattern`, msg);
}
}
export function snapshot(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'snapshot', lines, 'Expected value to match snapshot:', msg);
}
const lineNums = (x, y) => lines(x, y, 1);
export function fixture(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'fixture', lineNums, 'Expected value to match fixture:', msg);
}
export function throws(blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
assert(false, false, true, 'throws', false, 'Expected function to throw', msg);
} catch (err) {
if (err instanceof Assertion) throw err;
if (typeof exp === 'function') {
assert(exp(err), false, true, 'throws', false, 'Expected function to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(exp.test(err.message), false, true, 'throws', false, `Expected function to throw exception matching \`${String(exp)}\` pattern`, msg);
}
}
}
// ---
export function not(val, msg) {
assert(!val, true, false, 'not', false, 'Expected value to be falsey', msg);
}
not.ok = not;
is.not = function (val, exp, msg) {
assert(val !== exp, val, exp, 'is.not', false, 'Expected values not to be strictly equal', msg);
}
not.equal = function (val, exp, msg) {
assert(!dequal(val, exp), val, exp, 'not.equal', false, 'Expected values not to be deeply equal', msg);
}
not.type = function (val, exp, msg) {
let tmp = typeof val;
assert(tmp !== exp, tmp, exp, 'not.type', false, `Expected "${tmp}" not to be "${exp}"`, msg);
}
not.instance = function (val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(!(val instanceof exp), val, exp, 'not.instance', false, `Expected value not to be an instance of ${name}`, msg);
}
not.snapshot = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.snapshot', false, 'Expected value not to match snapshot', msg);
}
not.fixture = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.fixture', false, 'Expected value not to match fixture', msg);
}
not.match = function (val, exp, msg) {
if (typeof exp === 'string') {
assert(!val.includes(exp), val, exp, 'not.match', false, `Expected value not to include "${exp}" substring`, msg);
} else {
assert(!exp.test(val), val, exp, 'not.match', false, `Expected value not to match \`${String(exp)}\` pattern`, msg);
}
}
not.throws = function (blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
} catch (err) {
if (typeof exp === 'function') {
assert(!exp(err), true, false, 'not.throws', false, 'Expected function not to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(!exp.test(err.message), true, false, 'not.throws', false, `Expected function not to throw exception matching \`${String(exp)}\` pattern`, msg);
} else if (!exp) {
assert(false, true, false, 'not.throws', false, 'Expected function not to throw', msg);
}
}
}

35
vendor/spatie/ignition/node_modules/uvu/bin.js generated vendored Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env node
const sade = require('sade');
const pkg = require('./package');
const { parse } = require('./parse');
const dimport = x => new Function(`return import(${ JSON.stringify(x) })`).call(0);
const hasImport = (() => {
try { new Function('import').call(0) }
catch (err) { return !/unexpected/i.test(err.message) }
})();
sade('uvu [dir] [pattern]')
.version(pkg.version)
.option('-b, --bail', 'Exit on first failure')
.option('-i, --ignore', 'Any file patterns to ignore')
.option('-r, --require', 'Additional module(s) to preload')
.option('-C, --cwd', 'The current directory to resolve from', '.')
.option('-c, --color', 'Print colorized output', true)
.action(async (dir, pattern, opts) => {
try {
if (opts.color) process.env.FORCE_COLOR = '1';
let ctx = await parse(dir, pattern, opts);
if (!ctx.requires && hasImport) {
await dimport('uvu/run').then(m => m.run(ctx.suites, opts));
} else {
await require('uvu/run').run(ctx.suites, opts);
}
} catch (err) {
console.error(err.stack || err.message);
process.exit(1);
}
})
.parse(process.argv);

5
vendor/spatie/ignition/node_modules/uvu/diff/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,5 @@
export function chars(input: any, expects: any): string;
export function lines(input: any, expects: any, linenum?: number): string;
export function direct(input: any, expects: any, lenA?: number, lenB?: number): string;
export function compare(input: any, expects: any): string;
export function arrays(input: any, expects: any): string;

228
vendor/spatie/ignition/node_modules/uvu/diff/index.js generated vendored Executable file
View File

@@ -0,0 +1,228 @@
const kleur = require('kleur');
const diff = require('diff');
const colors = {
'--': kleur.red,
'··': kleur.grey,
'++': kleur.green,
};
const TITLE = kleur.dim().italic;
const TAB=kleur.dim('→'), SPACE=kleur.dim('·'), NL=kleur.dim('↵');
const LOG = (sym, str) => colors[sym](sym + PRETTY(str)) + '\n';
const LINE = (num, x) => kleur.dim('L' + String(num).padStart(x, '0') + ' ');
const PRETTY = str => str.replace(/[ ]/g, SPACE).replace(/\t/g, TAB).replace(/(\r?\n)/g, NL);
function line(obj, prev, pad) {
let char = obj.removed ? '--' : obj.added ? '++' : '··';
let arr = obj.value.replace(/\r?\n$/, '').split('\n');
let i=0, tmp, out='';
if (obj.added) out += colors[char]().underline(TITLE('Expected:')) + '\n';
else if (obj.removed) out += colors[char]().underline(TITLE('Actual:')) + '\n';
for (; i < arr.length; i++) {
tmp = arr[i];
if (tmp != null) {
if (prev) out += LINE(prev + i, pad);
out += LOG(char, tmp || '\n');
}
}
return out;
}
// TODO: want better diffing
//~> complex items bail outright
function arrays(input, expect) {
let arr = diff.diffArrays(input, expect);
let i=0, j=0, k=0, tmp, val, char, isObj, str;
let out = LOG('··', '[');
for (; i < arr.length; i++) {
char = (tmp = arr[i]).removed ? '--' : tmp.added ? '++' : '··';
if (tmp.added) {
out += colors[char]().underline(TITLE('Expected:')) + '\n';
} else if (tmp.removed) {
out += colors[char]().underline(TITLE('Actual:')) + '\n';
}
for (j=0; j < tmp.value.length; j++) {
isObj = (tmp.value[j] && typeof tmp.value[j] === 'object');
val = stringify(tmp.value[j]).split(/\r?\n/g);
for (k=0; k < val.length;) {
str = ' ' + val[k++] + (isObj ? '' : ',');
if (isObj && k === val.length && (j + 1) < tmp.value.length) str += ',';
out += LOG(char, str);
}
}
}
return out + LOG('··', ']');
}
function lines(input, expect, linenum = 0) {
let i=0, tmp, output='';
let arr = diff.diffLines(input, expect);
let pad = String(expect.split(/\r?\n/g).length - linenum).length;
for (; i < arr.length; i++) {
output += line(tmp = arr[i], linenum, pad);
if (linenum && !tmp.removed) linenum += tmp.count;
}
return output;
}
function chars(input, expect) {
let arr = diff.diffChars(input, expect);
let i=0, output='', tmp;
let l1 = input.length;
let l2 = expect.length;
let p1 = PRETTY(input);
let p2 = PRETTY(expect);
tmp = arr[i];
if (l1 === l2) {
// no length offsets
} else if (tmp.removed && arr[i + 1]) {
let del = tmp.count - arr[i + 1].count;
if (del == 0) {
// wash~
} else if (del > 0) {
expect = ' '.repeat(del) + expect;
p2 = ' '.repeat(del) + p2;
l2 += del;
} else if (del < 0) {
input = ' '.repeat(-del) + input;
p1 = ' '.repeat(-del) + p1;
l1 += -del;
}
}
output += direct(p1, p2, l1, l2);
if (l1 === l2) {
for (tmp=' '; i < l1; i++) {
tmp += input[i] === expect[i] ? ' ' : '^';
}
} else {
for (tmp=' '; i < arr.length; i++) {
tmp += ((arr[i].added || arr[i].removed) ? '^' : ' ').repeat(Math.max(arr[i].count, 0));
if (i + 1 < arr.length && ((arr[i].added && arr[i+1].removed) || (arr[i].removed && arr[i+1].added))) {
arr[i + 1].count -= arr[i].count;
}
}
}
return output + kleur.red(tmp);
}
function direct(input, expect, lenA = String(input).length, lenB = String(expect).length) {
let gutter = 4;
let lenC = Math.max(lenA, lenB);
let typeA=typeof input, typeB=typeof expect;
if (typeA !== typeB) {
gutter = 2;
let delA = gutter + lenC - lenA;
let delB = gutter + lenC - lenB;
input += ' '.repeat(delA) + kleur.dim(`[${typeA}]`);
expect += ' '.repeat(delB) + kleur.dim(`[${typeB}]`);
lenA += delA + typeA.length + 2;
lenB += delB + typeB.length + 2;
lenC = Math.max(lenA, lenB);
}
let output = colors['++']('++' + expect + ' '.repeat(gutter + lenC - lenB) + TITLE('(Expected)')) + '\n';
return output + colors['--']('--' + input + ' '.repeat(gutter + lenC - lenA) + TITLE('(Actual)')) + '\n';
}
function sort(input, expect) {
var k, i=0, tmp, isArr = Array.isArray(input);
var keys=[], out=isArr ? Array(input.length) : {};
if (isArr) {
for (i=0; i < out.length; i++) {
tmp = input[i];
if (!tmp || typeof tmp !== 'object') out[i] = tmp;
else out[i] = sort(tmp, expect[i]); // might not be right
}
} else {
for (k in expect)
keys.push(k);
for (; i < keys.length; i++) {
if (Object.prototype.hasOwnProperty.call(input, k = keys[i])) {
if (!(tmp = input[k]) || typeof tmp !== 'object') out[k] = tmp;
else out[k] = sort(tmp, expect[k]);
}
}
for (k in input) {
if (!out.hasOwnProperty(k)) {
out[k] = input[k]; // expect didnt have
}
}
}
return out;
}
function circular() {
var cache = new Set;
return function print(key, val) {
if (val === void 0) return '[__VOID__]';
if (typeof val === 'number' && val !== val) return '[__NAN__]';
if (typeof val === 'bigint') return val.toString();
if (!val || typeof val !== 'object') return val;
if (cache.has(val)) return '[Circular]';
cache.add(val); return val;
}
}
function stringify(input) {
return JSON.stringify(input, circular(), 2).replace(/"\[__NAN__\]"/g, 'NaN').replace(/"\[__VOID__\]"/g, 'undefined');
}
function compare(input, expect) {
if (Array.isArray(expect) && Array.isArray(input)) return arrays(input, expect);
if (expect instanceof RegExp) return chars(''+input, ''+expect);
let isA = input && typeof input == 'object';
let isB = expect && typeof expect == 'object';
if (isA && isB) input = sort(input, expect);
if (isB) expect = stringify(expect);
if (isA) input = stringify(input);
if (expect && typeof expect == 'object') {
input = stringify(sort(input, expect));
expect = stringify(expect);
}
isA = typeof input == 'string';
isB = typeof expect == 'string';
if (isA && /\r?\n/.test(input)) return lines(input, ''+expect);
if (isB && /\r?\n/.test(expect)) return lines(''+input, expect);
if (isA && isB) return chars(input, expect);
return direct(input, expect);
}
exports.arrays = arrays;
exports.chars = chars;
exports.circular = circular;
exports.compare = compare;
exports.direct = direct;
exports.lines = lines;
exports.sort = sort;
exports.stringify = stringify;

219
vendor/spatie/ignition/node_modules/uvu/diff/index.mjs generated vendored Executable file
View File

@@ -0,0 +1,219 @@
import kleur from 'kleur';
import * as diff from 'diff';
const colors = {
'--': kleur.red,
'··': kleur.grey,
'++': kleur.green,
};
const TITLE = kleur.dim().italic;
const TAB=kleur.dim('→'), SPACE=kleur.dim('·'), NL=kleur.dim('↵');
const LOG = (sym, str) => colors[sym](sym + PRETTY(str)) + '\n';
const LINE = (num, x) => kleur.dim('L' + String(num).padStart(x, '0') + ' ');
const PRETTY = str => str.replace(/[ ]/g, SPACE).replace(/\t/g, TAB).replace(/(\r?\n)/g, NL);
function line(obj, prev, pad) {
let char = obj.removed ? '--' : obj.added ? '++' : '··';
let arr = obj.value.replace(/\r?\n$/, '').split('\n');
let i=0, tmp, out='';
if (obj.added) out += colors[char]().underline(TITLE('Expected:')) + '\n';
else if (obj.removed) out += colors[char]().underline(TITLE('Actual:')) + '\n';
for (; i < arr.length; i++) {
tmp = arr[i];
if (tmp != null) {
if (prev) out += LINE(prev + i, pad);
out += LOG(char, tmp || '\n');
}
}
return out;
}
// TODO: want better diffing
//~> complex items bail outright
export function arrays(input, expect) {
let arr = diff.diffArrays(input, expect);
let i=0, j=0, k=0, tmp, val, char, isObj, str;
let out = LOG('··', '[');
for (; i < arr.length; i++) {
char = (tmp = arr[i]).removed ? '--' : tmp.added ? '++' : '··';
if (tmp.added) {
out += colors[char]().underline(TITLE('Expected:')) + '\n';
} else if (tmp.removed) {
out += colors[char]().underline(TITLE('Actual:')) + '\n';
}
for (j=0; j < tmp.value.length; j++) {
isObj = (tmp.value[j] && typeof tmp.value[j] === 'object');
val = stringify(tmp.value[j]).split(/\r?\n/g);
for (k=0; k < val.length;) {
str = ' ' + val[k++] + (isObj ? '' : ',');
if (isObj && k === val.length && (j + 1) < tmp.value.length) str += ',';
out += LOG(char, str);
}
}
}
return out + LOG('··', ']');
}
export function lines(input, expect, linenum = 0) {
let i=0, tmp, output='';
let arr = diff.diffLines(input, expect);
let pad = String(expect.split(/\r?\n/g).length - linenum).length;
for (; i < arr.length; i++) {
output += line(tmp = arr[i], linenum, pad);
if (linenum && !tmp.removed) linenum += tmp.count;
}
return output;
}
export function chars(input, expect) {
let arr = diff.diffChars(input, expect);
let i=0, output='', tmp;
let l1 = input.length;
let l2 = expect.length;
let p1 = PRETTY(input);
let p2 = PRETTY(expect);
tmp = arr[i];
if (l1 === l2) {
// no length offsets
} else if (tmp.removed && arr[i + 1]) {
let del = tmp.count - arr[i + 1].count;
if (del == 0) {
// wash~
} else if (del > 0) {
expect = ' '.repeat(del) + expect;
p2 = ' '.repeat(del) + p2;
l2 += del;
} else if (del < 0) {
input = ' '.repeat(-del) + input;
p1 = ' '.repeat(-del) + p1;
l1 += -del;
}
}
output += direct(p1, p2, l1, l2);
if (l1 === l2) {
for (tmp=' '; i < l1; i++) {
tmp += input[i] === expect[i] ? ' ' : '^';
}
} else {
for (tmp=' '; i < arr.length; i++) {
tmp += ((arr[i].added || arr[i].removed) ? '^' : ' ').repeat(Math.max(arr[i].count, 0));
if (i + 1 < arr.length && ((arr[i].added && arr[i+1].removed) || (arr[i].removed && arr[i+1].added))) {
arr[i + 1].count -= arr[i].count;
}
}
}
return output + kleur.red(tmp);
}
export function direct(input, expect, lenA = String(input).length, lenB = String(expect).length) {
let gutter = 4;
let lenC = Math.max(lenA, lenB);
let typeA=typeof input, typeB=typeof expect;
if (typeA !== typeB) {
gutter = 2;
let delA = gutter + lenC - lenA;
let delB = gutter + lenC - lenB;
input += ' '.repeat(delA) + kleur.dim(`[${typeA}]`);
expect += ' '.repeat(delB) + kleur.dim(`[${typeB}]`);
lenA += delA + typeA.length + 2;
lenB += delB + typeB.length + 2;
lenC = Math.max(lenA, lenB);
}
let output = colors['++']('++' + expect + ' '.repeat(gutter + lenC - lenB) + TITLE('(Expected)')) + '\n';
return output + colors['--']('--' + input + ' '.repeat(gutter + lenC - lenA) + TITLE('(Actual)')) + '\n';
}
export function sort(input, expect) {
var k, i=0, tmp, isArr = Array.isArray(input);
var keys=[], out=isArr ? Array(input.length) : {};
if (isArr) {
for (i=0; i < out.length; i++) {
tmp = input[i];
if (!tmp || typeof tmp !== 'object') out[i] = tmp;
else out[i] = sort(tmp, expect[i]); // might not be right
}
} else {
for (k in expect)
keys.push(k);
for (; i < keys.length; i++) {
if (Object.prototype.hasOwnProperty.call(input, k = keys[i])) {
if (!(tmp = input[k]) || typeof tmp !== 'object') out[k] = tmp;
else out[k] = sort(tmp, expect[k]);
}
}
for (k in input) {
if (!out.hasOwnProperty(k)) {
out[k] = input[k]; // expect didnt have
}
}
}
return out;
}
export function circular() {
var cache = new Set;
return function print(key, val) {
if (val === void 0) return '[__VOID__]';
if (typeof val === 'number' && val !== val) return '[__NAN__]';
if (typeof val === 'bigint') return val.toString();
if (!val || typeof val !== 'object') return val;
if (cache.has(val)) return '[Circular]';
cache.add(val); return val;
}
}
export function stringify(input) {
return JSON.stringify(input, circular(), 2).replace(/"\[__NAN__\]"/g, 'NaN').replace(/"\[__VOID__\]"/g, 'undefined');
}
export function compare(input, expect) {
if (Array.isArray(expect) && Array.isArray(input)) return arrays(input, expect);
if (expect instanceof RegExp) return chars(''+input, ''+expect);
let isA = input && typeof input == 'object';
let isB = expect && typeof expect == 'object';
if (isA && isB) input = sort(input, expect);
if (isB) expect = stringify(expect);
if (isA) input = stringify(input);
if (expect && typeof expect == 'object') {
input = stringify(sort(input, expect));
expect = stringify(expect);
}
isA = typeof input == 'string';
isB = typeof expect == 'string';
if (isA && /\r?\n/.test(input)) return lines(input, ''+expect);
if (isB && /\r?\n/.test(expect)) return lines(''+input, expect);
if (isA && isB) return chars(input, expect);
return direct(input, expect);
}

167
vendor/spatie/ignition/node_modules/uvu/dist/index.js generated vendored Executable file
View File

@@ -0,0 +1,167 @@
const kleur = require('kleur');
const { compare } = require('uvu/diff');
let isCLI = false, isNode = false;
let hrtime = (now = Date.now()) => () => (Date.now() - now).toFixed(2) + 'ms';
let write = console.log;
const into = (ctx, key) => (name, handler) => ctx[key].push({ name, handler });
const context = (state) => ({ tests:[], before:[], after:[], bEach:[], aEach:[], only:[], skips:0, state });
const milli = arr => (arr[0]*1e3 + arr[1]/1e6).toFixed(2) + 'ms';
const hook = (ctx, key) => handler => ctx[key].push(handler);
if (isNode = typeof process < 'u' && typeof process.stdout < 'u') {
// globalThis polyfill; Node < 12
if (typeof globalThis !== 'object') {
Object.defineProperty(global, 'globalThis', {
get: function () { return this }
});
}
let rgx = /(\.bin[\\+\/]uvu$|uvu[\\+\/]bin\.js)/i;
isCLI = process.argv.some(x => rgx.test(x));
// attach node-specific utils
write = x => process.stdout.write(x);
hrtime = (now = process.hrtime()) => () => milli(process.hrtime(now));
} else if (typeof performance < 'u') {
hrtime = (now = performance.now()) => () => (performance.now() - now).toFixed(2) + 'ms';
}
globalThis.UVU_QUEUE = globalThis.UVU_QUEUE || [];
isCLI = isCLI || !!globalThis.UVU_DEFER;
isCLI || UVU_QUEUE.push([null]);
const QUOTE = kleur.dim('"'), GUTTER = '\n ';
const FAIL = kleur.red('✘ '), PASS = kleur.gray('• ');
const IGNORE = /^\s*at.*(?:\(|\s)(?:node|(internal\/[\w/]*))/;
const FAILURE = kleur.bold().bgRed(' FAIL ');
const FILE = kleur.bold().underline().white;
const SUITE = kleur.bgWhite().bold;
function stack(stack, idx) {
let i=0, line, out='';
let arr = stack.substring(idx).replace(/\\/g, '/').split('\n');
for (; i < arr.length; i++) {
line = arr[i].trim();
if (line.length && !IGNORE.test(line)) {
out += '\n ' + line;
}
}
return kleur.grey(out) + '\n';
}
function format(name, err, suite = '') {
let { details, operator='' } = err;
let idx = err.stack && err.stack.indexOf('\n');
if (err.name.startsWith('AssertionError') && !operator.includes('not')) details = compare(err.actual, err.expected); // TODO?
let str = ' ' + FAILURE + (suite ? kleur.red(SUITE(` ${suite} `)) : '') + ' ' + QUOTE + kleur.red().bold(name) + QUOTE;
str += '\n ' + err.message + (operator ? kleur.italic().dim(` (${operator})`) : '') + '\n';
if (details) str += GUTTER + details.split('\n').join(GUTTER);
if (!!~idx) str += stack(err.stack, idx);
return str + '\n';
}
async function runner(ctx, name) {
let { only, tests, before, after, bEach, aEach, state } = ctx;
let hook, test, arr = only.length ? only : tests;
let num=0, errors='', total=arr.length;
try {
if (name) write(SUITE(kleur.black(` ${name} `)) + ' ');
for (hook of before) await hook(state);
for (test of arr) {
state.__test__ = test.name;
try {
for (hook of bEach) await hook(state);
await test.handler(state);
for (hook of aEach) await hook(state);
write(PASS);
num++;
} catch (err) {
for (hook of aEach) await hook(state);
if (errors.length) errors += '\n';
errors += format(test.name, err, name);
write(FAIL);
}
}
} finally {
state.__test__ = '';
for (hook of after) await hook(state);
let msg = ` (${num} / ${total})\n`;
let skipped = (only.length ? tests.length : 0) + ctx.skips;
write(errors.length ? kleur.red(msg) : kleur.green(msg));
return [errors || true, num, skipped, total];
}
}
let timer;
function defer() {
clearTimeout(timer);
timer = setTimeout(exec);
}
function setup(ctx, name = '') {
ctx.state.__test__ = '';
ctx.state.__suite__ = name;
const test = into(ctx, 'tests');
test.before = hook(ctx, 'before');
test.before.each = hook(ctx, 'bEach');
test.after = hook(ctx, 'after');
test.after.each = hook(ctx, 'aEach');
test.only = into(ctx, 'only');
test.skip = () => { ctx.skips++ };
test.run = () => {
let copy = { ...ctx };
let run = runner.bind(0, copy, name);
Object.assign(ctx, context(copy.state));
UVU_QUEUE[globalThis.UVU_INDEX || 0].push(run);
isCLI || defer();
};
return test;
}
const suite = (name = '', state = {}) => setup(context(state), name);
const test = suite();
let isRunning = false;
async function exec(bail) {
let timer = hrtime();
let done=0, total=0, skips=0, code=0;
isRunning = true;
for (let group of UVU_QUEUE) {
if (total) write('\n');
let name = group.shift();
if (name != null) write(FILE(name) + '\n');
for (let test of group) {
let [errs, ran, skip, max] = await test();
total += max; done += ran; skips += skip;
if (errs.length) {
write('\n' + errs + '\n'); code=1;
if (bail) return isNode && process.exit(1);
}
}
}
isRunning = false;
write('\n Total: ' + total);
write((code ? kleur.red : kleur.green)('\n Passed: ' + done));
write('\n Skipped: ' + (skips ? kleur.yellow(skips) : skips));
write('\n Duration: ' + timer() + '\n\n');
if (isNode) process.exitCode = code;
}
if (isNode) process.on('exit', () => {
if (!isRunning) return; // okay to exit
process.exitCode = process.exitCode || 1;
console.error('Exiting early before testing is finished.');
});
exports.exec = exec;
exports.suite = suite;
exports.test = test;

163
vendor/spatie/ignition/node_modules/uvu/dist/index.mjs generated vendored Executable file
View File

@@ -0,0 +1,163 @@
import kleur from 'kleur';
import { compare } from 'uvu/diff';
let isCLI = false, isNode = false;
let hrtime = (now = Date.now()) => () => (Date.now() - now).toFixed(2) + 'ms';
let write = console.log;
const into = (ctx, key) => (name, handler) => ctx[key].push({ name, handler });
const context = (state) => ({ tests:[], before:[], after:[], bEach:[], aEach:[], only:[], skips:0, state });
const milli = arr => (arr[0]*1e3 + arr[1]/1e6).toFixed(2) + 'ms';
const hook = (ctx, key) => handler => ctx[key].push(handler);
if (isNode = typeof process < 'u' && typeof process.stdout < 'u') {
// globalThis polyfill; Node < 12
if (typeof globalThis !== 'object') {
Object.defineProperty(global, 'globalThis', {
get: function () { return this }
});
}
let rgx = /(\.bin[\\+\/]uvu$|uvu[\\+\/]bin\.js)/i;
isCLI = process.argv.some(x => rgx.test(x));
// attach node-specific utils
write = x => process.stdout.write(x);
hrtime = (now = process.hrtime()) => () => milli(process.hrtime(now));
} else if (typeof performance < 'u') {
hrtime = (now = performance.now()) => () => (performance.now() - now).toFixed(2) + 'ms';
}
globalThis.UVU_QUEUE = globalThis.UVU_QUEUE || [];
isCLI = isCLI || !!globalThis.UVU_DEFER;
isCLI || UVU_QUEUE.push([null]);
const QUOTE = kleur.dim('"'), GUTTER = '\n ';
const FAIL = kleur.red('✘ '), PASS = kleur.gray('• ');
const IGNORE = /^\s*at.*(?:\(|\s)(?:node|(internal\/[\w/]*))/;
const FAILURE = kleur.bold().bgRed(' FAIL ');
const FILE = kleur.bold().underline().white;
const SUITE = kleur.bgWhite().bold;
function stack(stack, idx) {
let i=0, line, out='';
let arr = stack.substring(idx).replace(/\\/g, '/').split('\n');
for (; i < arr.length; i++) {
line = arr[i].trim();
if (line.length && !IGNORE.test(line)) {
out += '\n ' + line;
}
}
return kleur.grey(out) + '\n';
}
function format(name, err, suite = '') {
let { details, operator='' } = err;
let idx = err.stack && err.stack.indexOf('\n');
if (err.name.startsWith('AssertionError') && !operator.includes('not')) details = compare(err.actual, err.expected); // TODO?
let str = ' ' + FAILURE + (suite ? kleur.red(SUITE(` ${suite} `)) : '') + ' ' + QUOTE + kleur.red().bold(name) + QUOTE;
str += '\n ' + err.message + (operator ? kleur.italic().dim(` (${operator})`) : '') + '\n';
if (details) str += GUTTER + details.split('\n').join(GUTTER);
if (!!~idx) str += stack(err.stack, idx);
return str + '\n';
}
async function runner(ctx, name) {
let { only, tests, before, after, bEach, aEach, state } = ctx;
let hook, test, arr = only.length ? only : tests;
let num=0, errors='', total=arr.length;
try {
if (name) write(SUITE(kleur.black(` ${name} `)) + ' ');
for (hook of before) await hook(state);
for (test of arr) {
state.__test__ = test.name;
try {
for (hook of bEach) await hook(state);
await test.handler(state);
for (hook of aEach) await hook(state);
write(PASS);
num++;
} catch (err) {
for (hook of aEach) await hook(state);
if (errors.length) errors += '\n';
errors += format(test.name, err, name);
write(FAIL);
}
}
} finally {
state.__test__ = '';
for (hook of after) await hook(state);
let msg = ` (${num} / ${total})\n`;
let skipped = (only.length ? tests.length : 0) + ctx.skips;
write(errors.length ? kleur.red(msg) : kleur.green(msg));
return [errors || true, num, skipped, total];
}
}
let timer;
function defer() {
clearTimeout(timer);
timer = setTimeout(exec);
}
function setup(ctx, name = '') {
ctx.state.__test__ = '';
ctx.state.__suite__ = name;
const test = into(ctx, 'tests');
test.before = hook(ctx, 'before');
test.before.each = hook(ctx, 'bEach');
test.after = hook(ctx, 'after');
test.after.each = hook(ctx, 'aEach');
test.only = into(ctx, 'only');
test.skip = () => { ctx.skips++ };
test.run = () => {
let copy = { ...ctx };
let run = runner.bind(0, copy, name);
Object.assign(ctx, context(copy.state));
UVU_QUEUE[globalThis.UVU_INDEX || 0].push(run);
isCLI || defer();
};
return test;
}
export const suite = (name = '', state = {}) => setup(context(state), name);
export const test = suite();
let isRunning = false;
export async function exec(bail) {
let timer = hrtime();
let done=0, total=0, skips=0, code=0;
isRunning = true;
for (let group of UVU_QUEUE) {
if (total) write('\n');
let name = group.shift();
if (name != null) write(FILE(name) + '\n');
for (let test of group) {
let [errs, ran, skip, max] = await test();
total += max; done += ran; skips += skip;
if (errs.length) {
write('\n' + errs + '\n'); code=1;
if (bail) return isNode && process.exit(1);
}
}
}
isRunning = false;
write('\n Total: ' + total);
write((code ? kleur.red : kleur.green)('\n Passed: ' + done));
write('\n Skipped: ' + (skips ? kleur.yellow(skips) : skips));
write('\n Duration: ' + timer() + '\n\n');
if (isNode) process.exitCode = code;
}
if (isNode) process.on('exit', () => {
if (!isRunning) return; // okay to exit
process.exitCode = process.exitCode || 1;
console.error('Exiting early before testing is finished.');
});

27
vendor/spatie/ignition/node_modules/uvu/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,27 @@
declare namespace uvu {
type Crumbs = { __suite__: string; __test__: string };
type Callback<T> = (context: T & Crumbs) => Promise<void> | void;
interface Hook<T> {
(hook: Callback<T>): void;
each(hook: Callback<T>): void;
}
interface Test<T> {
(name: string, test: Callback<T>): void;
only(name: string, test: Callback<T>): void;
skip(name?: string, test?: Callback<T>): void;
before: Hook<T>;
after: Hook<T>
run(): void;
}
}
type Context = Record<string, any>;
export type Test<T=Context> = uvu.Test<T>;
export type Callback<T=Context> = uvu.Callback<T>;
export const test: uvu.Test<Context>;
export function suite<T=Context>(title?: string, context?: T): uvu.Test<T>;
export function exec(bail?: boolean): Promise<void>;

21
vendor/spatie/ignition/node_modules/uvu/license generated vendored Executable file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,38 @@
declare function print(input: string | boolean | number): string;
declare function print(input: undefined | void): undefined;
declare function print(input: null): null;
type Colorize = typeof print;
export declare const $: { enabled: boolean };
// Colors
export declare const black: Colorize;
export declare const red: Colorize;
export declare const green: Colorize;
export declare const yellow: Colorize;
export declare const blue: Colorize;
export declare const magenta: Colorize;
export declare const cyan: Colorize;
export declare const white: Colorize;
export declare const gray: Colorize;
export declare const grey: Colorize;
// Backgrounds
export declare const bgBlack: Colorize;
export declare const bgRed: Colorize;
export declare const bgGreen: Colorize;
export declare const bgYellow: Colorize;
export declare const bgBlue: Colorize;
export declare const bgMagenta: Colorize;
export declare const bgCyan: Colorize;
export declare const bgWhite: Colorize;
// Modifiers
export declare const reset: Colorize;
export declare const bold: Colorize;
export declare const dim: Colorize;
export declare const italic: Colorize;
export declare const underline: Colorize;
export declare const inverse: Colorize;
export declare const hidden: Colorize;
export declare const strikethrough: Colorize;

View File

@@ -0,0 +1,53 @@
let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
if (typeof process !== 'undefined') {
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
isTTY = process.stdout && process.stdout.isTTY;
}
const $ = exports.$ = {
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (
FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY
)
}
function init(x, y) {
let rgx = new RegExp(`\\x1b\\[${y}m`, 'g');
let open = `\x1b[${x}m`, close = `\x1b[${y}m`;
return function (txt) {
if (!$.enabled || txt == null) return txt;
return open + (!!~(''+txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
};
}
// modifiers
exports.reset = init(0, 0);
exports.bold = init(1, 22);
exports.dim = init(2, 22);
exports.italic = init(3, 23);
exports.underline = init(4, 24);
exports.inverse = init(7, 27);
exports.hidden = init(8, 28);
exports.strikethrough = init(9, 29);
// colors
exports.black = init(30, 39);
exports.red = init(31, 39);
exports.green = init(32, 39);
exports.yellow = init(33, 39);
exports.blue = init(34, 39);
exports.magenta = init(35, 39);
exports.cyan = init(36, 39);
exports.white = init(37, 39);
exports.gray = init(90, 39);
exports.grey = init(90, 39);
// background colors
exports.bgBlack = init(40, 49);
exports.bgRed = init(41, 49);
exports.bgGreen = init(42, 49);
exports.bgYellow = init(43, 49);
exports.bgBlue = init(44, 49);
exports.bgMagenta = init(45, 49);
exports.bgCyan = init(46, 49);
exports.bgWhite = init(47, 49);

View File

@@ -0,0 +1,53 @@
let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
if (typeof process !== 'undefined') {
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
isTTY = process.stdout && process.stdout.isTTY;
}
export const $ = {
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (
FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY
)
}
function init(x, y) {
let rgx = new RegExp(`\\x1b\\[${y}m`, 'g');
let open = `\x1b[${x}m`, close = `\x1b[${y}m`;
return function (txt) {
if (!$.enabled || txt == null) return txt;
return open + (!!~(''+txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
};
}
// modifiers
export const reset = init(0, 0);
export const bold = init(1, 22);
export const dim = init(2, 22);
export const italic = init(3, 23);
export const underline = init(4, 24);
export const inverse = init(7, 27);
export const hidden = init(8, 28);
export const strikethrough = init(9, 29);
// colors
export const black = init(30, 39);
export const red = init(31, 39);
export const green = init(32, 39);
export const yellow = init(33, 39);
export const blue = init(34, 39);
export const magenta = init(35, 39);
export const cyan = init(36, 39);
export const white = init(37, 39);
export const gray = init(90, 39);
export const grey = init(90, 39);
// background colors
export const bgBlack = init(40, 49);
export const bgRed = init(41, 49);
export const bgGreen = init(42, 49);
export const bgYellow = init(43, 49);
export const bgBlue = init(44, 49);
export const bgMagenta = init(45, 49);
export const bgCyan = init(46, 49);
export const bgWhite = init(47, 49);

View File

@@ -0,0 +1,45 @@
// Originally by: Rogier Schouten <https://github.com/rogierschouten>
// Adapted by: Madhav Varshney <https://github.com/madhavarshney>
declare namespace kleur {
interface Color {
(x: string | number): string;
(): Kleur;
}
interface Kleur {
// Colors
black: Color;
red: Color;
green: Color;
yellow: Color;
blue: Color;
magenta: Color;
cyan: Color;
white: Color;
gray: Color;
grey: Color;
// Backgrounds
bgBlack: Color;
bgRed: Color;
bgGreen: Color;
bgYellow: Color;
bgBlue: Color;
bgMagenta: Color;
bgCyan: Color;
bgWhite: Color;
// Modifiers
reset: Color;
bold: Color;
dim: Color;
italic: Color;
underline: Color;
inverse: Color;
hidden: Color;
strikethrough: Color;
}
}
declare let kleur: kleur.Kleur & { enabled: boolean };
export = kleur;

View File

@@ -0,0 +1,110 @@
'use strict';
let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
if (typeof process !== 'undefined') {
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
isTTY = process.stdout && process.stdout.isTTY;
}
const $ = {
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (
FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY
),
// modifiers
reset: init(0, 0),
bold: init(1, 22),
dim: init(2, 22),
italic: init(3, 23),
underline: init(4, 24),
inverse: init(7, 27),
hidden: init(8, 28),
strikethrough: init(9, 29),
// colors
black: init(30, 39),
red: init(31, 39),
green: init(32, 39),
yellow: init(33, 39),
blue: init(34, 39),
magenta: init(35, 39),
cyan: init(36, 39),
white: init(37, 39),
gray: init(90, 39),
grey: init(90, 39),
// background colors
bgBlack: init(40, 49),
bgRed: init(41, 49),
bgGreen: init(42, 49),
bgYellow: init(43, 49),
bgBlue: init(44, 49),
bgMagenta: init(45, 49),
bgCyan: init(46, 49),
bgWhite: init(47, 49)
};
function run(arr, str) {
let i=0, tmp, beg='', end='';
for (; i < arr.length; i++) {
tmp = arr[i];
beg += tmp.open;
end += tmp.close;
if (!!~str.indexOf(tmp.close)) {
str = str.replace(tmp.rgx, tmp.close + tmp.open);
}
}
return beg + str + end;
}
function chain(has, keys) {
let ctx = { has, keys };
ctx.reset = $.reset.bind(ctx);
ctx.bold = $.bold.bind(ctx);
ctx.dim = $.dim.bind(ctx);
ctx.italic = $.italic.bind(ctx);
ctx.underline = $.underline.bind(ctx);
ctx.inverse = $.inverse.bind(ctx);
ctx.hidden = $.hidden.bind(ctx);
ctx.strikethrough = $.strikethrough.bind(ctx);
ctx.black = $.black.bind(ctx);
ctx.red = $.red.bind(ctx);
ctx.green = $.green.bind(ctx);
ctx.yellow = $.yellow.bind(ctx);
ctx.blue = $.blue.bind(ctx);
ctx.magenta = $.magenta.bind(ctx);
ctx.cyan = $.cyan.bind(ctx);
ctx.white = $.white.bind(ctx);
ctx.gray = $.gray.bind(ctx);
ctx.grey = $.grey.bind(ctx);
ctx.bgBlack = $.bgBlack.bind(ctx);
ctx.bgRed = $.bgRed.bind(ctx);
ctx.bgGreen = $.bgGreen.bind(ctx);
ctx.bgYellow = $.bgYellow.bind(ctx);
ctx.bgBlue = $.bgBlue.bind(ctx);
ctx.bgMagenta = $.bgMagenta.bind(ctx);
ctx.bgCyan = $.bgCyan.bind(ctx);
ctx.bgWhite = $.bgWhite.bind(ctx);
return ctx;
}
function init(open, close) {
let blk = {
open: `\x1b[${open}m`,
close: `\x1b[${close}m`,
rgx: new RegExp(`\\x1b\\[${close}m`, 'g')
};
return function (txt) {
if (this !== void 0 && this.has !== void 0) {
!!~this.has.indexOf(open) || (this.has.push(open),this.keys.push(blk));
return txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+'';
}
return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+'';
};
}
module.exports = $;

View File

@@ -0,0 +1,110 @@
'use strict';
let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;
if (typeof process !== 'undefined') {
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
isTTY = process.stdout && process.stdout.isTTY;
}
const $ = {
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (
FORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY
),
// modifiers
reset: init(0, 0),
bold: init(1, 22),
dim: init(2, 22),
italic: init(3, 23),
underline: init(4, 24),
inverse: init(7, 27),
hidden: init(8, 28),
strikethrough: init(9, 29),
// colors
black: init(30, 39),
red: init(31, 39),
green: init(32, 39),
yellow: init(33, 39),
blue: init(34, 39),
magenta: init(35, 39),
cyan: init(36, 39),
white: init(37, 39),
gray: init(90, 39),
grey: init(90, 39),
// background colors
bgBlack: init(40, 49),
bgRed: init(41, 49),
bgGreen: init(42, 49),
bgYellow: init(43, 49),
bgBlue: init(44, 49),
bgMagenta: init(45, 49),
bgCyan: init(46, 49),
bgWhite: init(47, 49)
};
function run(arr, str) {
let i=0, tmp, beg='', end='';
for (; i < arr.length; i++) {
tmp = arr[i];
beg += tmp.open;
end += tmp.close;
if (!!~str.indexOf(tmp.close)) {
str = str.replace(tmp.rgx, tmp.close + tmp.open);
}
}
return beg + str + end;
}
function chain(has, keys) {
let ctx = { has, keys };
ctx.reset = $.reset.bind(ctx);
ctx.bold = $.bold.bind(ctx);
ctx.dim = $.dim.bind(ctx);
ctx.italic = $.italic.bind(ctx);
ctx.underline = $.underline.bind(ctx);
ctx.inverse = $.inverse.bind(ctx);
ctx.hidden = $.hidden.bind(ctx);
ctx.strikethrough = $.strikethrough.bind(ctx);
ctx.black = $.black.bind(ctx);
ctx.red = $.red.bind(ctx);
ctx.green = $.green.bind(ctx);
ctx.yellow = $.yellow.bind(ctx);
ctx.blue = $.blue.bind(ctx);
ctx.magenta = $.magenta.bind(ctx);
ctx.cyan = $.cyan.bind(ctx);
ctx.white = $.white.bind(ctx);
ctx.gray = $.gray.bind(ctx);
ctx.grey = $.grey.bind(ctx);
ctx.bgBlack = $.bgBlack.bind(ctx);
ctx.bgRed = $.bgRed.bind(ctx);
ctx.bgGreen = $.bgGreen.bind(ctx);
ctx.bgYellow = $.bgYellow.bind(ctx);
ctx.bgBlue = $.bgBlue.bind(ctx);
ctx.bgMagenta = $.bgMagenta.bind(ctx);
ctx.bgCyan = $.bgCyan.bind(ctx);
ctx.bgWhite = $.bgWhite.bind(ctx);
return ctx;
}
function init(open, close) {
let blk = {
open: `\x1b[${open}m`,
close: `\x1b[${close}m`,
rgx: new RegExp(`\\x1b\\[${close}m`, 'g')
};
return function (txt) {
if (this !== void 0 && this.has !== void 0) {
!!~this.has.indexOf(open) || (this.has.push(open),this.keys.push(blk));
return txt === void 0 ? this : $.enabled ? run(this.keys, txt+'') : txt+'';
}
return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt+'') : txt+'';
};
}
export default $;

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,232 @@
<div align="center">
<img src="shots/logo.png" alt="kleur" height="120" />
</div>
<div align="center">
<a href="https://npmjs.org/package/kleur">
<img src="https://badgen.now.sh/npm/v/kleur" alt="version" />
</a>
<a href="https://github.com/lukeed/kleur/actions?query=workflow%3ACI">
<img src="https://github.com/lukeed/kleur/workflows/CI/badge.svg?event=push" alt="CI" />
</a>
<a href="https://npmjs.org/package/kleur">
<img src="https://badgen.now.sh/npm/dm/kleur" alt="downloads" />
</a>
<a href="https://packagephobia.now.sh/result?p=kleur">
<img src="https://packagephobia.now.sh/badge?p=kleur" alt="install size" />
</a>
</div>
<div align="center">The fastest Node.js library for formatting terminal text with ANSI colors~!</div>
## Features
* No dependencies
* Super [lightweight](#load-time) & [performant](#performance)
* Supports [nested](#nested-methods) & [chained](#chained-methods) colors
* No `String.prototype` modifications
* Conditional [color support](#conditional-support)
* [Fully treeshakable](#individual-colors)
* Familiar [API](#api)
---
As of `v3.0` the Chalk-style syntax (magical getter) is no longer used.<br>Please visit [History](#history) for migration paths supporting that syntax.
---
## Install
```
$ npm install --save kleur
```
## Usage
```js
import kleur from 'kleur';
// basic usage
kleur.red('red text');
// chained methods
kleur.blue().bold().underline('howdy partner');
// nested methods
kleur.bold(`${ white().bgRed('[ERROR]') } ${ kleur.red().italic('Something happened')}`);
```
### Chained Methods
```js
const { bold, green } = require('kleur');
console.log(bold().red('this is a bold red message'));
console.log(bold().italic('this is a bold italicized message'));
console.log(bold().yellow().bgRed().italic('this is a bold yellow italicized message'));
console.log(green().bold().underline('this is a bold green underlined message'));
```
<img src="shots/1.png" width="300" />
### Nested Methods
```js
const { yellow, red, cyan } = require('kleur');
console.log(yellow(`foo ${red().bold('red')} bar ${cyan('cyan')} baz`));
console.log(yellow('foo ' + red().bold('red') + ' bar ' + cyan('cyan') + ' baz'));
```
<img src="shots/2.png" width="300" />
### Conditional Support
Toggle color support as needed; `kleur` includes simple auto-detection which may not cover all cases.
> **Note:** Both `kleur` and `kleur/colors` share the same detection logic.
```js
import kleur from 'kleur';
// manually disable
kleur.enabled = false;
// or use another library to detect support
kleur.enabled = require('color-support').level > 0;
console.log(kleur.red('I will only be colored red if the terminal supports colors'));
```
> **Important:** <br>Colors will be disabled automatically in non [TTY contexts](https://nodejs.org/api/process.html#process_a_note_on_process_i_o). For example, spawning another process or piping output into another process will disable colorization automatically. To force colors in your piped output, you may do so with the `FORCE_COLOR=1` environment variable:
```sh
$ node app.js #=> COLORS
$ node app.js > log.txt #=> NO COLORS
$ FORCE_COLOR=1 node app.js > log.txt #=> COLORS
$ FORCE_COLOR=0 node app.js > log.txt #=> NO COLORS
```
## API
Any `kleur` method returns a `String` when invoked with input; otherwise chaining is expected.
> It's up to the developer to pass the output to destinations like `console.log`, `process.stdout.write`, etc.
The methods below are grouped by type for legibility purposes only. They each can be [chained](#chained-methods) or [nested](#nested-methods) with one another.
***Colors:***
> black &mdash; red &mdash; green &mdash; yellow &mdash; blue &mdash; magenta &mdash; cyan &mdash; white &mdash; gray &mdash; grey
***Backgrounds:***
> bgBlack &mdash; bgRed &mdash; bgGreen &mdash; bgYellow &mdash; bgBlue &mdash; bgMagenta &mdash; bgCyan &mdash; bgWhite
***Modifiers:***
> reset &mdash; bold &mdash; dim &mdash; italic* &mdash; underline &mdash; inverse &mdash; hidden &mdash; strikethrough*
<sup>* <em>Not widely supported</em></sup>
## Individual Colors
When you only need a few colors, it doesn't make sense to import _all_ of `kleur` because, as small as it is, `kleur` is not treeshakeable, and so most of its code will be doing nothing. In order to fix this, you can import from the `kleur/colors` submodule which _fully_ supports tree-shaking.
The caveat with this approach is that color functions **are not** chainable~!<br>Each function receives and colorizes its input. You may combine colors, backgrounds, and modifiers by nesting function calls within other functions.
```js
// or: import * as kleur from 'kleur/colors';
import { red, underline, bgWhite } from 'kleur/colors';
red('red text');
//~> kleur.red('red text');
underline(red('red underlined text'));
//~> kleur.underline().red('red underlined text');
bgWhite(underline(red('red underlined text w/ white background')));
//~> kleur.bgWhite().underline().red('red underlined text w/ white background');
```
> **Note:** All the same [colors, backgrounds, and modifiers](#api) are available.
***Conditional Support***
The `kleur/colors` submodule also allows you to toggle color support, as needed.<br>
It includes the same initial assumptions as `kleur`, in an attempt to have colors enabled by default.
Unlike `kleur`, this setting exists as `kleur.$.enabled` instead of `kleur.enabled`:
```js
import * as kleur from 'kleur/colors';
// or: import { $, red } from 'kleur/colors';
// manually disabled
kleur.$.enabled = false;
// or use another library to detect support
kleur.$.enabled = require('color-support').level > 0;
console.log(red('I will only be colored red if the terminal supports colors'));
```
## Benchmarks
> Using Node v10.13.0
### Load time
```
chalk :: 5.303ms
kleur :: 0.488ms
kleur/colors :: 0.369ms
ansi-colors :: 1.504ms
```
### Performance
```
# All Colors
ansi-colors x 177,625 ops/sec ±1.47% (92 runs sampled)
chalk x 611,907 ops/sec ±0.20% (92 runs sampled)
kleur x 742,509 ops/sec ±1.47% (93 runs sampled)
kleur/colors x 881,742 ops/sec ±0.19% (98 runs sampled)
# Stacked colors
ansi-colors x 23,331 ops/sec ±1.81% (94 runs sampled)
chalk x 337,178 ops/sec ±0.20% (98 runs sampled)
kleur x 78,299 ops/sec ±1.01% (97 runs sampled)
kleur/colors x 104,431 ops/sec ±0.22% (97 runs sampled)
# Nested colors
ansi-colors x 67,181 ops/sec ±1.15% (92 runs sampled)
chalk x 116,361 ops/sec ±0.63% (94 runs sampled)
kleur x 139,514 ops/sec ±0.76% (95 runs sampled)
kleur/colors x 145,716 ops/sec ±0.97% (97 runs sampled)
```
## History
This project originally forked [`ansi-colors`](https://github.com/doowb/ansi-colors).
Beginning with `kleur@3.0`, the Chalk-style syntax (magical getter) has been replaced with function calls per key:
```js
// Old:
c.red.bold.underline('old');
// New:
c.red().bold().underline('new');
```
> <sup><em>As I work more with Rust, the newer syntax feels so much better & more natural!</em></sup>
If you prefer the old syntax, you may migrate to `ansi-colors` or newer `chalk` releases.<br>Versions below `kleur@3.0` have been officially deprecated.
## License
MIT © [Luke Edwards](https://lukeed.com)

View File

@@ -0,0 +1,37 @@
import type * as mri from 'mri';
type Arrayable<T> = T | T[];
declare function sade(usage: string, isSingle?: boolean): sade.Sade;
declare namespace sade {
export type Handler = (...args: any[]) => any;
export type Value = number | string | boolean | null;
export interface LazyOutput {
name: string;
handler: Handler;
args: string[];
}
export interface Sade {
command(usage: string, description?: string, options?: {
alias?: Arrayable<string>;
default?: boolean;
}): Sade;
option(flag: string, description?: string, value?: Value): Sade;
action(handler: Handler): Sade;
describe(text: Arrayable<string>): Sade;
alias(...names: string[]): Sade;
example(usage: string): Sade;
parse(arr: string[], opts: { lazy: true } & mri.Options): LazyOutput;
parse(arr: string[], opts?: { lazy?: boolean } & mri.Options): void;
version(value: string): Sade;
help(cmd?: string): void;
}
}
export = sade;

View File

@@ -0,0 +1 @@
const e=require("mri"),t="__all__",i="__default__",s="\n";function r(e){if(!e.length)return"";let t=function(e){let t=0,i=0,s=0,r=e.length;if(r)for(;r--;)i=e[r].length,i>t&&(s=r,t=i);return e[s].length}(e.map(e=>e[0]))+4;return e.map(e=>e[0]+" ".repeat(t-e[0].length)+e[1]+(null==e[2]?"":` (default ${e[2]})`))}function n(e){return e}function l(e,t,i){if(!t||!t.length)return"";let r=0,n="";for(n+="\n "+e;r<t.length;r++)n+="\n "+i(t[r]);return n+s}function a(e,t,i=1){let s=l("ERROR",[t],n);s+=`\n Run \`$ ${e} --help\` for more info.\n`,console.error(s),process.exit(i)}class o{constructor(e,s){let[r,...n]=e.split(/\s+/);s=s||n.length>0,this.bin=r,this.ver="0.0.0",this.default="",this.tree={},this.command(t),this.command([i].concat(s?n:"<command>").join(" ")),this.single=s,this.curr=""}command(e,t,i={}){if(this.single)throw new Error('Disable "single" mode to add commands');let s=[],r=[],n=/(\[|<)/;if(e.split(/\s+/).forEach(e=>{(n.test(e.charAt(0))?r:s).push(e)}),s=s.join(" "),s in this.tree)throw new Error("Command already exists: "+s);return s.includes("__")||r.unshift(s),r=r.join(" "),this.curr=s,i.default&&(this.default=s),this.tree[s]={usage:r,alibi:[],options:[],alias:{},default:{},examples:[]},i.alias&&this.alias(i.alias),t&&this.describe(t),this}describe(e){return this.tree[this.curr||i].describe=Array.isArray(e)?e:function(e){return(e||"").replace(/([.?!])\s*(?=[A-Z])/g,"$1|").split("|")}(e),this}alias(...e){if(this.single)throw new Error('Cannot call `alias()` in "single" mode');if(!this.curr)throw new Error("Cannot call `alias()` before defining a command");return(this.tree[this.curr].alibi=this.tree[this.curr].alibi.concat(...e)).forEach(e=>this.tree[e]=this.curr),this}option(e,i,s){let r=this.tree[this.curr||t],[n,l]=function(e){return(e||"").split(/^-{1,2}|,|\s+-{1,2}|\s+/).filter(Boolean)}(e);if(l&&l.length>1&&([n,l]=[l,n]),e="--"+n,l&&l.length>0){e=`-${l}, ${e}`;let t=r.alias[l];r.alias[l]=(t||[]).concat(n)}let a=[e,i||""];return void 0!==s?(a.push(s),r.default[n]=s):l||(r.default[n]=void 0),r.options.push(a),this}action(e){return this.tree[this.curr||i].handler=e,this}example(e){return this.tree[this.curr||i].examples.push(e),this}version(e){return this.ver=e,this}parse(s,r={}){s=s.slice();let n,l,o,h,u=2,c=e(s.slice(u),{alias:{h:"help",v:"version"}}),f=this.single,p=this.bin,d="";if(f)h=this.tree[i];else{let e,t=1,i=c._.length+1;for(;t<i;t++)if(n=c._.slice(0,t).join(" "),e=this.tree[n],"string"==typeof e)l=(d=e).split(" "),s.splice(s.indexOf(c._[0]),t,...l),t+=l.length-t;else if(e)d=n;else if(d)break;if(h=this.tree[d],o=void 0===h,o)if(this.default)d=this.default,h=this.tree[d],s.unshift(d),u++;else if(n)return a(p,"Invalid command: "+n)}if(c.help)return this.help(!f&&!o&&d);if(c.version)return this._version();if(!f&&void 0===h)return a(p,"No command specified.");let g=this.tree[t];r.alias=Object.assign(g.alias,h.alias,r.alias),r.default=Object.assign(g.default,h.default,r.default),n=d.split(" "),l=s.indexOf(n[0],2),~l&&s.splice(l,n.length);let m=e(s.slice(u),r);if(!m||"string"==typeof m)return a(p,m||"Parsed unknown option flag(s)!");let b=h.usage.split(/\s+/),_=b.filter(e=>"<"===e.charAt(0)),v=m._.splice(0,_.length);if(v.length<_.length)return d&&(p+=" "+d),a(p,"Insufficient arguments!");b.filter(e=>"["===e.charAt(0)).forEach(e=>{v.push(m._.shift())}),v.push(m);let $=h.handler;return r.lazy?{args:v,name:d,handler:$}:$.apply(null,v)}help(e){console.log(function(e,a,o,h){let u="",c=a[o],f="$ "+e,p=a[t],d=e=>`${f} ${e}`.replace(/\s+/g," "),g=[["-h, --help","Displays this message"]];if(o===i&&g.unshift(["-v, --version","Displays current version"]),c.options=(c.options||[]).concat(p.options,g),c.options.length>0&&(c.usage+=" [options]"),u+=l("Description",c.describe,n),u+=l("Usage",[c.usage],d),h||o!==i)h||o===i||(u+=l("Aliases",c.alibi,d));else{let e,t=/^__/,i="",o=[];for(e in a)"string"==typeof a[e]||t.test(e)||o.push([e,(a[e].describe||[""])[0]])<3&&(i+=`\n ${f} ${e} --help`);u+=l("Available Commands",r(o),n),u+="\n For more info, run any command with the `--help` flag"+i+s}return u+=l("Options",r(c.options),n),u+=l("Examples",c.examples.map(d),n),u}(this.bin,this.tree,e||i,this.single))}_version(){console.log(`${this.bin}, ${this.ver}`)}}module.exports=(e,t)=>new o(e,t);

View File

@@ -0,0 +1 @@
import e from"mri";const t="__all__",i="__default__",s="\n";function r(e){if(!e.length)return"";let t=function(e){let t=0,i=0,s=0,r=e.length;if(r)for(;r--;)i=e[r].length,i>t&&(s=r,t=i);return e[s].length}(e.map(e=>e[0]))+4;return e.map(e=>e[0]+" ".repeat(t-e[0].length)+e[1]+(null==e[2]?"":` (default ${e[2]})`))}function n(e){return e}function l(e,t,i){if(!t||!t.length)return"";let r=0,n="";for(n+="\n "+e;r<t.length;r++)n+="\n "+i(t[r]);return n+s}function a(e,t,i=1){let s=l("ERROR",[t],n);s+=`\n Run \`$ ${e} --help\` for more info.\n`,console.error(s),process.exit(i)}class o{constructor(e,s){let[r,...n]=e.split(/\s+/);s=s||n.length>0,this.bin=r,this.ver="0.0.0",this.default="",this.tree={},this.command(t),this.command([i].concat(s?n:"<command>").join(" ")),this.single=s,this.curr=""}command(e,t,i={}){if(this.single)throw new Error('Disable "single" mode to add commands');let s=[],r=[],n=/(\[|<)/;if(e.split(/\s+/).forEach(e=>{(n.test(e.charAt(0))?r:s).push(e)}),s=s.join(" "),s in this.tree)throw new Error("Command already exists: "+s);return s.includes("__")||r.unshift(s),r=r.join(" "),this.curr=s,i.default&&(this.default=s),this.tree[s]={usage:r,alibi:[],options:[],alias:{},default:{},examples:[]},i.alias&&this.alias(i.alias),t&&this.describe(t),this}describe(e){return this.tree[this.curr||i].describe=Array.isArray(e)?e:function(e){return(e||"").replace(/([.?!])\s*(?=[A-Z])/g,"$1|").split("|")}(e),this}alias(...e){if(this.single)throw new Error('Cannot call `alias()` in "single" mode');if(!this.curr)throw new Error("Cannot call `alias()` before defining a command");return(this.tree[this.curr].alibi=this.tree[this.curr].alibi.concat(...e)).forEach(e=>this.tree[e]=this.curr),this}option(e,i,s){let r=this.tree[this.curr||t],[n,l]=function(e){return(e||"").split(/^-{1,2}|,|\s+-{1,2}|\s+/).filter(Boolean)}(e);if(l&&l.length>1&&([n,l]=[l,n]),e="--"+n,l&&l.length>0){e=`-${l}, ${e}`;let t=r.alias[l];r.alias[l]=(t||[]).concat(n)}let a=[e,i||""];return void 0!==s?(a.push(s),r.default[n]=s):l||(r.default[n]=void 0),r.options.push(a),this}action(e){return this.tree[this.curr||i].handler=e,this}example(e){return this.tree[this.curr||i].examples.push(e),this}version(e){return this.ver=e,this}parse(s,r={}){s=s.slice();let n,l,o,h,u=2,f=e(s.slice(u),{alias:{h:"help",v:"version"}}),c=this.single,p=this.bin,d="";if(c)h=this.tree[i];else{let e,t=1,i=f._.length+1;for(;t<i;t++)if(n=f._.slice(0,t).join(" "),e=this.tree[n],"string"==typeof e)l=(d=e).split(" "),s.splice(s.indexOf(f._[0]),t,...l),t+=l.length-t;else if(e)d=n;else if(d)break;if(h=this.tree[d],o=void 0===h,o)if(this.default)d=this.default,h=this.tree[d],s.unshift(d),u++;else if(n)return a(p,"Invalid command: "+n)}if(f.help)return this.help(!c&&!o&&d);if(f.version)return this._version();if(!c&&void 0===h)return a(p,"No command specified.");let g=this.tree[t];r.alias=Object.assign(g.alias,h.alias,r.alias),r.default=Object.assign(g.default,h.default,r.default),n=d.split(" "),l=s.indexOf(n[0],2),~l&&s.splice(l,n.length);let m=e(s.slice(u),r);if(!m||"string"==typeof m)return a(p,m||"Parsed unknown option flag(s)!");let b=h.usage.split(/\s+/),_=b.filter(e=>"<"===e.charAt(0)),v=m._.splice(0,_.length);if(v.length<_.length)return d&&(p+=" "+d),a(p,"Insufficient arguments!");b.filter(e=>"["===e.charAt(0)).forEach(e=>{v.push(m._.shift())}),v.push(m);let $=h.handler;return r.lazy?{args:v,name:d,handler:$}:$.apply(null,v)}help(e){console.log(function(e,a,o,h){let u="",f=a[o],c="$ "+e,p=a[t],d=e=>`${c} ${e}`.replace(/\s+/g," "),g=[["-h, --help","Displays this message"]];if(o===i&&g.unshift(["-v, --version","Displays current version"]),f.options=(f.options||[]).concat(p.options,g),f.options.length>0&&(f.usage+=" [options]"),u+=l("Description",f.describe,n),u+=l("Usage",[f.usage],d),h||o!==i)h||o===i||(u+=l("Aliases",f.alibi,d));else{let e,t=/^__/,i="",o=[];for(e in a)"string"==typeof a[e]||t.test(e)||o.push([e,(a[e].describe||[""])[0]])<3&&(i+=`\n ${c} ${e} --help`);u+=l("Available Commands",r(o),n),u+="\n For more info, run any command with the `--help` flag"+i+s}return u+=l("Options",r(f.options),n),u+=l("Examples",f.examples.map(d),n),u}(this.bin,this.tree,e||i,this.single))}_version(){console.log(`${this.bin}, ${this.ver}`)}}export default(e,t)=>new o(e,t);

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (https://lukeed.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,672 @@
# sade [![Build Status](https://travis-ci.org/lukeed/sade.svg?branch=master)](https://travis-ci.org/lukeed/sade)
> Smooth (CLI) Operator 🎶
Sade is a small but powerful tool for building command-line interface (CLI) applications for Node.js that are fast, responsive, and helpful!
It enables default commands, git-like subcommands, option flags with aliases, default option values with type-casting, required-vs-optional argument handling, command validation, and automated help text generation!
Your app's UX will be as smooth as butter... just like [Sade's voice](https://www.youtube.com/watch?v=4TYv2PhG89A). 😉
## Install
```
$ npm install --save sade
```
## Usage
***Input:***
```js
#!/usr/bin/env node
const sade = require('sade');
const prog = sade('my-cli');
prog
.version('1.0.5')
.option('--global, -g', 'An example global flag')
.option('-c, --config', 'Provide path to custom config', 'foo.config.js');
prog
.command('build <src> <dest>')
.describe('Build the source directory. Expects an `index.js` entry file.')
.option('-o, --output', 'Change the name of the output file', 'bundle.js')
.example('build src build --global --config my-conf.js')
.example('build app public -o main.js')
.action((src, dest, opts) => {
console.log(`> building from ${src} to ${dest}`);
console.log('> these are extra opts', opts);
});
prog.parse(process.argv);
```
***Output:***
```a
$ my-cli --help
Usage
$ my-cli <command> [options]
Available Commands
build Build the source directory.
For more info, run any command with the `--help` flag
$ my-cli build --help
Options
-v, --version Displays current version
-g, --global An example global flag
-c, --config Provide path to custom config (default foo.config.js)
-h, --help Displays this message
$ my-cli build --help
Description
Build the source directory.
Expects an `index.js` entry file.
Usage
$ my-cli build <src> [options]
Options
-o, --output Change the name of the output file (default bundle.js)
-g, --global An example global flag
-c, --config Provide path to custom config (default foo.config.js)
-h, --help Displays this message
Examples
$ my-cli build src build --global --config my-conf.js
$ my-cli build app public -o main.js
```
## Tips
- **Define your global/program-wide version, options, description, and/or examples first.**<br>
_Once you define a Command, you can't access the global-scope again._
- **Define all commands & options in the order that you want them to appear.**<br>
_Sade will not mutate or sort your CLI for you. Global options print before local options._
- **Required arguments without values will error & exit**<br>
_An `Insufficient arguments!` error will be displayed along with a help prompt._
- **Don't worry about manually displaying help~!**<br>
_Your help text is displayed automatically... including command-specific help text!_
- **Automatic default/basic patterns**<br>
_Usage text will always append `[options]` & `--help` and `--version` are done for you._
- **Only define what you want to display!**<br>
_Help text sections (example, options, etc) will only display if you provide values._
## Subcommands
Subcommands are defined & parsed like any other command! When defining their [`usage`](#usage-1), everything up until the first argument (`[foo]` or `<foo>`) is interpreted as the command string.
They should be defined in the order that you want them to appear in your general `--help` output.
Lastly, it is _not_ necessary to define the subcommand's "base" as an additional command. However, if you choose to do so, it's recommended that you define it first for better visibility.
```js
const prog = sade('git');
// Not necessary for subcommands to work, but it's here anyway!
prog
.command('remote')
.describe('Manage set of tracked repositories')
.action(opts => {
console.log('~> Print current remotes...');
});
prog
.command('remote add <name> <url>', 'Demo...')
.action((name, url, opts) => {
console.log(`~> Adding a new remote (${name}) to ${url}`);
});
prog
.command('remote rename <old> <new>', 'Demo...')
.action((old, nxt, opts) => {
console.log(`~> Renaming from ${old} to ${nxt}~!`);
});
```
## Single Command Mode
In certain circumstances, you may only need `sade` for a single-command CLI application.
> **Note:** Until `v1.6.0`, this made for an awkward pairing.
To enable this, you may make use of the [`isSingle`](#issingle) argument. Doing so allows you to pass the program's entire [`usage` text](#usage-1) into the `name` argument.
With "Single Command Mode" enabled, your entire binary operates as one command. This means that any [`prog.command`](#progcommandusage-desc-opts) calls are disallowed & will instead throw an Error. Of course, you may still define a program version, a description, an example or two, and declare options. You are customizing the program's attributes as a whole.<sup>*</sup>
> <sup>*</sup> This is true for multi-command applications, too, up until your first `prog.command()` call!
***Example***
Let's reconstruct [`sirv-cli`](https://github.com/lukeed/sirv), which is a single-command application that (optionally) accepts a directory from which to serve files. It also offers a slew of option flags:
```js
sade('sirv [dir]', true)
.version('1.0.0')
.describe('Run a static file server')
.example('public -qeim 31536000')
.example('--port 8080 --etag')
.example('my-app --dev')
.option('-D, --dev', 'Enable "dev" mode')
.option('-e, --etag', 'Enable "Etag" header')
// There are a lot...
.option('-H, --host', 'Hostname to bind', 'localhost')
.option('-p, --port', 'Port to bind', 5000)
.action((dir, opts) => {
// Program handler
})
.parse(process.argv);
```
When `sirv --help` is run, the generated help text is trimmed, fully aware that there's only one command in this program:
```
Description
Run a static file server
Usage
$ sirv [dir] [options]
Options
-D, --dev Enable "dev" mode
-e, --etag Enable "Etag" header
-H, --host Hostname to bind (default localhost)
-p, --port Port to bind (default 5000)
-v, --version Displays current version
-h, --help Displays this message
Examples
$ sirv public -qeim 31536000
$ sirv --port 8080 --etag
$ sirv my-app --dev
```
## Command Aliases
Command aliases are alternative names (aliases) for a command. They are often used as shortcuts or as typo relief!
The aliased names do not appear in the general help text.<br>
Instead, they only appear within the Command-specific help text under an "Aliases" section.
***Limitations***
* You cannot assign aliases while in [Single Command Mode](#single-command-mode)
* You cannot call [`prog.alias()`](#progaliasnames) before defining any Commands (via `prog.commmand()`)
* You, the developer, must keep track of which aliases have already been used and/or exist as Command names
***Example***
Let's reconstruct the `npm install` command as a Sade program:
```js
sade('npm')
// ...
.command('install [package]', 'Install a package', {
alias: ['i', 'add', 'isntall']
})
.option('-P, --save-prod', 'Package will appear in your dependencies.')
.option('-D, --save-dev', 'Package will appear in your devDependencies.')
.option('-O, --save-optional', 'Package will appear in your optionalDependencies')
.option('-E, --save-exact', 'Save exact versions instead of using a semver range operator')
// ...
```
When we run `npm --help` we'll see this general help text:
```
Usage
$ npm <command> [options]
Available Commands
install Install a package
For more info, run any command with the `--help` flag
$ npm install --help
Options
-v, --version Displays current version
-h, --help Displays this message
```
When we run `npm install --help` &mdash; ***or*** the help flag with any of `install`'s aliases &mdash; we'll see this command-specific help text:
```
Description
Install a package
Usage
$ npm install [package] [options]
Aliases
$ npm i
$ npm add
$ npm isntall
Options
-P, --save-prod Package will appear in your dependencies.
-D, --save-dev Package will appear in your devDependencies.
-O, --save-optional Package will appear in your optionalDependencies
-E, --save-exact Save exact versions instead of using a semver range operator
-h, --help Displays this message
```
## API
### sade(name, isSingle)
Returns: `Program`
Returns your chainable Sade instance, aka your `Program`.
#### name
Type: `String`<br>
Required: `true`
The name of your `Program` / binary application.
#### isSingle
Type: `Boolean`<br>
Default: `name.includes(' ');`
If your `Program` is meant to have ***only one command***.<br>
When `true`, this simplifies your generated `--help` output such that:
* the "root-level help" is your _only_ help text
* the "root-level help" does not display an `Available Commands` section
* the "root-level help" does not inject `$ name <command>` into the `Usage` section
* the "root-level help" does not display `For more info, run any command with the `--help` flag` text
You may customize the `Usage` of your command by modifying the `name` argument directly.<br>
Please read [Single Command Mode](#single-command-mode) for an example and more information.
> **Important:** Whenever `name` includes a custom usage, then `isSingle` is automatically assumed and enforced!
### prog.command(usage, desc, opts)
Create a new Command for your Program. This changes the current state of your Program.
All configuration methods (`prog.describe`, `prog.action`, etc) will apply to this Command until another Command has been created!
#### usage
Type: `String`
The usage pattern for your current Command. This will be included in the general or command-specific `--help` output.
_Required_ arguments are wrapped with `<` and `>` characters; for example, `<foo>` and `<bar>`.
_Optional_ arguments are wrapped with `[` and `]` characters; for example, `[foo]` and `[bar]`.
All arguments are ***positionally important***, which means they are passed to your current Command's [`handler`](#handler) function in the order that they were defined.
When optional arguments are defined but don't receive a value, their positionally-equivalent function parameter will be `undefined`.
> **Important:** You **must** define & expect required arguments _before_ optional arguments!
```js
sade('foo')
.command('greet <adjective> <noun>')
.action((adjective, noun, opts) => {
console.log(`Hello, ${adjective} ${noun}!`);
})
.command('drive <vehicle> [color] [speed]')
.action((vehicle, color, speed, opts) => {
let arr = ['Driving my'];
arr.push(color ? `${color} ${vehicle}` : vehicle);
speed && arr.push(`at ${speed}`);
opts.yolo && arr.push('...YOLO!!');
let str = arr.join(' ');
console.log(str);
});
```
```sh
$ foo greet beautiful person
# //=> Hello, beautiful person!
$ foo drive car
# //=> Driving my car
$ foo drive car red
# //=> Driving my red card
$ foo drive car blue 100mph --yolo
# //=> Driving my blue car at 100mph ...YOLO!!
```
#### desc
Type: `String`<br>
Default: `''`
The Command's description. The value is passed directly to [`prog.describe`](#progdescribetext).
#### opts
Type: `Object`<br>
Default: `{}`
##### opts.alias
Type: `String|Array`
Optionally define one or more aliases for the current Command.<br>
When declared, the `opts.alias` value is passed _directly_ to the [`prog.alias`](#progaliasnames) method.
```js
// Program A is equivalent to Program B
// ---
const A = sade('bin')
.command('build', 'My build command', { alias: 'b' })
.command('watch', 'My watch command', { alias: ['w', 'dev'] });
const B = sade('bin')
.command('build', 'My build command').alias('b')
.command('watch', 'My watch command').alias('w', 'dev');
```
##### opts.default
Type: `Boolean`
Manually set/force the current Command to be the Program's default command. This ensures that the current Command will run if no command was specified.
> **Important:** If you run your Program without a Command _and_ without specifying a default command, your Program will exit with a `No command specified` error.
```js
const prog = sade('greet');
prog.command('hello');
//=> only runs if :: `$ greet hello`
// $ greet
//=> error: No command specified.
prog.command('howdy', '', { default:true });
//=> runs as `$ greet` OR `$ greet howdy`
// $ greet
//=> runs 'howdy' handler
// $ greet foobar
//=> error: Invalid command
```
### prog.describe(text)
Add a description to the current Command.
#### text
Type: `String|Array`
The description text for the current Command. This will be included in the general or command-specific `--help` output.
Internally, your description will be separated into an `Array` of sentences.
For general `--help` output, ***only*** the first sentence will be displayed. However, **all sentences** will be printed for command-specific `--help` text.
> **Note:** Pass an `Array` if you don't want internal assumptions. However, the first item is _always_ displayed in general help, so it's recommended to keep it short.
### prog.alias(...names)
Define one or more aliases for the current Command.
> **Important:** An error will be thrown if:<br>1) the program is in [Single Command Mode](#single-command-mode); or<br>2) `prog.alias` is called before any `prog.command`.
#### names
Type: `String`
The list of alternative names (aliases) for the current Command.<br>
For example, you may want to define shortcuts and/or common typos for the Command's full name.
> **Important:** Sade _does not_ check if the incoming `names` are already in use by other Commands or their aliases.<br>During conflicts, the Command with the same `name` is given priority, otherwise the first Command (according to Program order) with `name` as an alias is chosen.
The `prog.alias()` is append-only, so calling it multiple times within a Command context will _keep_ all aliases, including those initially passed via [`opts.alias`](#optsdefault).
```js
sade('bin')
.command('hello <name>', 'Greet someone by their name', {
alias: ['hey', 'yo']
})
.alias('hi', 'howdy')
.alias('hola', 'oi');
//=> hello aliases: hey, yo, hi, howdy, hola, oi
```
### prog.action(handler)
Attach a callback to the current Command.
#### handler
Type: `Function`
The function to run when the current Command is executed.
Its parameters are based (positionally) on your Command's [`usage`](#usage-1) definition.
All options, flags, and extra/unknown values are included as the last parameter.
> **Note:** Optional arguments are also passed as parameters & may be `undefined`!
```js
sade('foo')
.command('cp <src> <dest>')
.option('-f, --force', 'Overwrite without confirmation')
.option('-c, --clone-dir', 'Copy files to additional directory')
.option('-v, --verbose', 'Enable verbose output')
.action((src, dest, opts) => {
console.log(`Copying files from ${src} --> ${dest}`);
opts.c && console.log(`ALSO copying files from ${src} --> ${opts['clone-dir']}`);
console.log('My options:', opts);
})
// $ foo cp original my-copy -v
//=> Copying files from original --> my-copy
//=> My options: { _:[], v:true, verbose:true }
// $ foo cp original my-copy --clone-dir my-backup
//=> Copying files from original --> my-copy
//=> ALSO copying files from original --> my-backup
//=> My options: { _:[], c:'my-backup', 'clone-dir':'my-backup' }
```
### prog.example(str)
Add an example for the current Command.
#### str
Type: `String`
The example string to add. This will be included in the general or command-specific `--help` output.
> **Note:** Your example's `str` will be prefixed with your Program's [`name`](#sadename).
### prog.option(flags, desc, value)
Add an Option to the current Command.
#### flags
Type: `String`
The Option's flags, which may optionally include an alias.
You may use a comma (`,`) or a space (` `) to separate the flags.
> **Note:** The short & long flags can be declared in any order. However, the alias will always be displayed first.
> **Important:** If using hyphenated flag names, they will be accessible **as declared** within your [`action()`](#progactionhandler) handler!
```js
prog.option('--global'); // no alias
prog.option('-g, --global'); // alias first, comma
prog.option('--global -g'); // alias last, space
// etc...
```
#### desc
Type: `String`
The description for the Option.
#### value
Type: `String`
The **default** value for the Option.
Flags and aliases, if parsed, are `true` by default. See [`mri`](https://github.com/lukeed/mri#minimist) for more info.
> **Note:** You probably only want to define a default `value` if you're expecting a `String` or `Number` value type.
If you _do_ pass a `String` or `Number` value type, your flag value will be casted to the same type. See [`mri#options.default`](https://github.com/lukeed/mri#optionsdefault) for info~!
### prog.version(str)
The `--version` and `-v` flags will automatically output the Program version.
#### str
Type: `String`<br>
Default: `0.0.0`
The new version number for your Program.
> **Note:** Your Program `version` is `0.0.0` until you change it.
### prog.parse(arr, opts)
Parse a set of CLI arguments.
#### arr
Type: `Array`
Your Program's `process.argv` input.
> **Important:** Do not `.slice(2)`! Doing so will break parsing~!
#### opts
Type: `Object`<br>
Default: `{}`
Additional `process.argv` parsing config. See [`mri`'s options](https://github.com/lukeed/mri#mriargs-options) for details.
> **Important:** These values _override_ any internal values!
```js
prog
.command('hello')
.option('-f, --force', 'My flag');
//=> currently has alias pair: f <--> force
prog.parse(process.argv, {
alias: {
f: ['foo', 'fizz']
},
default: {
abc: 123
}
});
//=> ADDS alias pair: f <--> foo
//=> REMOVES alias pair: f <--> force
//=> ADDS alias pair: f <--> fizz
//=> ADDS default: abc -> 123 (number)
```
#### opts.unknown
Type: `Function`<br>
Default: `undefined`
Callback to run when an unspecified option flag has been found. This is [passed directly to `mri`](https://github.com/lukeed/mri#optionsunknown).
Your handler will receive the unknown flag (string) as its only argument.<br>
You may return a string, which will be used as a custom error message. Otherwise, a default message is displayed.
```js
sade('sirv')
.command('start [dir]')
.parse(process.argv, {
unknown: arg => `Custom error message: ${arg}`
});
/*
$ sirv start --foobar
ERROR
Custom error message: --foobar
Run `$ sirv --help` for more info.
*/
```
#### opts.lazy
Type: `Boolean`<br>
Default: `false`
If true, Sade will not immediately execute the `action` handler. Instead, `parse()` will return an object of `{ name, args, handler }` shape, wherein the `name` is the command name, `args` is all arguments that _would be_ passed to the action handler, and `handler` is the function itself.
From this, you may choose when to run the `handler` function. You also have the option to further modify the `args` for any reason, if needed.
```js
let { name, args, handler } = prog.parse(process.argv, { lazy:true });
console.log('> Received command: ', name);
// later on...
handler.apply(null, args);
```
### prog.help(cmd)
Manually display the help text for a given command. If no command name is provided, the general/global help is printed.
Your general and command-specific help text is automatically attached to the `--help` and `-h` flags.
> **Note:** You don't have to call this directly! It's automatically run when you `bin --help`
#### cmd
Type: `String`<br>
Default: `null`
The name of the command for which to display help. Otherwise displays the general help.
## License
MIT © [Luke Edwards](https://lukeed.com)

22
vendor/spatie/ignition/node_modules/uvu/parse/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,22 @@
type Arrayable<T> = T[] | T;
export interface Suite {
/** The relative file path */
name: string;
/** The absolute file path */
file: string;
}
export interface Options {
cwd: string;
require: Arrayable<string>;
ignore: Arrayable<string | RegExp>;
}
export interface Argv {
dir: string;
suites: Suite[];
requires: boolean;
}
export function parse(dir?: string, pattern?: string|RegExp, opts?: Partial<Options>): Promise<Argv>;

50
vendor/spatie/ignition/node_modules/uvu/parse/index.js generated vendored Executable file
View File

@@ -0,0 +1,50 @@
// @ts-check
const { readdir, stat } = require('fs');
const { resolve, join } = require('path');
const { promisify } = require('util');
const ls = promisify(readdir);
const toStat = promisify(stat);
const toRegex = x => new RegExp(x, 'i');
async function parse(dir, pattern, opts = {}) {
if (pattern) pattern = toRegex(pattern);
else if (dir) pattern = /(((?:[^\/]*(?:\/|$))*)[\\\/])?\w+\.([mc]js|[jt]sx?)$/;
else pattern = /((\/|^)(tests?|__tests?__)\/.*|\.(tests?|spec)|^\/?tests?)\.([mc]js|[jt]sx?)$/i;
dir = resolve(opts.cwd || '.', dir || '.');
let suites = [];
let requires = [].concat(opts.require || []).filter(Boolean);
let ignores = ['^.git', 'node_modules'].concat(opts.ignore || []).map(toRegex);
requires.forEach(name => {
try { return require(name) }
catch (e) { throw new Error(`Cannot find module "${name}"`) }
});
// NOTE: Node 8.x support
// @modified lukeed/totalist
await (async function collect(d, p) {
await ls(d).then(files => {
return Promise.all(
files.map(async str => {
let name = join(p, str);
for (let i = ignores.length; i--;) {
if (ignores[i].test(name)) return;
}
let file = join(d, str);
let stats = await toStat(file);
if (stats.isDirectory()) return collect(file, name);
else if (pattern.test(name)) suites.push({ name, file });
})
);
});
})(dir, '');
suites.sort((a, b) => a.name.localeCompare(b.name));
return { dir, suites, requires: requires.length > 0 };
}
exports.parse = parse;

51
vendor/spatie/ignition/node_modules/uvu/parse/index.mjs generated vendored Executable file
View File

@@ -0,0 +1,51 @@
import { readdir, stat } from 'fs';
import { createRequire } from 'module';
import { resolve, join } from 'path';
import { promisify } from 'util';
const ls = promisify(readdir);
const toStat = promisify(stat);
const toRegex = x => new RegExp(x, 'i');
export async function parse(dir, pattern, opts = {}) {
if (pattern) pattern = toRegex(pattern);
else if (dir) pattern = /(((?:[^\/]*(?:\/|$))*)[\\\/])?\w+\.([mc]js|[jt]sx?)$/;
else pattern = /((\/|^)(tests?|__tests?__)\/.*|\.(tests?|spec)|^\/?tests?)\.([mc]js|[jt]sx?)$/i;
dir = resolve(opts.cwd || '.', dir || '.');
let suites = [];
let requires = [].concat(opts.require || []).filter(Boolean);
let ignores = ['^.git', 'node_modules'].concat(opts.ignore || []).map(toRegex);
if (requires.length) {
let $require = createRequire(import.meta.url);
requires.forEach(name => {
try { return $require(name) }
catch (e) { throw new Error(`Cannot find module "${name}"`) }
});
}
// NOTE: Node 8.x support
// @modified lukeed/totalist
await (async function collect(d, p) {
await ls(d).then(files => {
return Promise.all(
files.map(async str => {
let name = join(p, str);
for (let i = ignores.length; i--;) {
if (ignores[i].test(name)) return;
}
let file = join(d, str);
let stats = await toStat(file);
if (stats.isDirectory()) return collect(file, name);
else if (pattern.test(name)) suites.push({ name, file });
})
);
});
})(dir, '');
suites.sort((a, b) => a.name.localeCompare(b.name));
return { dir, suites, requires: requires.length > 0 };
}

137
vendor/spatie/ignition/node_modules/uvu/readme.md generated vendored Executable file
View File

@@ -0,0 +1,137 @@
<div align="center">
<img src="shots/uvu.jpg" alt="uvu" height="120" />
</div>
<div align="center">
<a href="https://npmjs.org/package/uvu">
<img src="https://badgen.now.sh/npm/v/uvu" alt="version" />
</a>
<a href="https://github.com/lukeed/uvu/actions">
<img src="https://github.com/lukeed/uvu/workflows/CI/badge.svg" alt="CI" />
</a>
<a href="https://npmjs.org/package/uvu">
<img src="https://badgen.now.sh/npm/dm/uvu" alt="downloads" />
</a>
<a href="https://packagephobia.now.sh/result?p=uvu">
<img src="https://packagephobia.now.sh/badge?p=uvu" alt="install size" />
</a>
</div>
<div align="center">
<b>uvu</b> is an extremely fast and lightweight test runner for Node.js and the browser<br>
<b>U</b>ltimate <b>V</b>elocity, <b>U</b>nleashed<br><br>
<img width="380" alt="example with suites" src="shots/suites.gif"/>
</div>
## Features
* Super [lightweight](https://npm.anvaka.com/#/view/2d/uvu)
* Extremely [performant](#benchmarks)
* Individually executable test files
* Supports `async`/`await` tests
* Supports native ES Modules
* Browser-Compatible
* Familiar API
## Install
```
$ npm install --save-dev uvu
```
## Usage
> Check out [`/examples`](/examples) for a list of working demos!
```js
// tests/demo.js
import { test } from 'uvu';
import * as assert from 'uvu/assert';
test('Math.sqrt()', () => {
assert.is(Math.sqrt(4), 2);
assert.is(Math.sqrt(144), 12);
assert.is(Math.sqrt(2), Math.SQRT2);
});
test('JSON', () => {
const input = {
foo: 'hello',
bar: 'world'
};
const output = JSON.stringify(input);
assert.snapshot(output, `{"foo":"hello","bar":"world"}`);
assert.equal(JSON.parse(output), input, 'matches original');
});
test.run();
```
Then execute this test file:
```sh
# via `uvu` cli, for all `/tests/**` files
$ uvu -r esm tests
# via `node` directly, for file isolation
$ node -r esm tests/demo.js
```
> **Note:** The `-r esm` is for legacy Node.js versions. [Learn More](/docs/esm.md)
> [View the `uvu` CLI documentation](/docs/cli.md)
## Assertions
The [`uvu/assert`](/docs/api.assert.md) module is _completely_ optional.
In fact, you may use any assertion library, including Node's native [`assert`](https://nodejs.org/api/assert.html) module! This works because `uvu` relies on thrown Errors to detect failures. Implicitly, this also means that any uncaught exceptions and/or unhandled `Promise` rejections will result in a failure, which is what you want!
## API
### Module: `uvu`
> [View `uvu` API documentation](/docs/api.uvu.md)
The main entry from which you will import the `test` or `suite` methods.
### Module: `uvu/assert`
> [View `uvu/assert` API documentation](/docs/api.assert.md)
A collection of assertion methods to use within your tests. Please note that:
* these are browser compatible
* these are _completely_ optional
## Benchmarks
> via the [`/bench`](/bench) directory with Node v10.21.0
Below you'll find each test runner with two timing values:
* the `took ___` value is the total process execution time from startup to termination
* the parenthesis value (`(___)`) is the self-reported execution time, if known
Each test runner's `stdout` is printed to the console to verify all assertions pass.<br>Said output is excluded below for brevity.
```
~> "ava" took 594ms ( ??? )
~> "jest" took 962ms (356 ms)
~> "mocha" took 209ms ( 4 ms)
~> "tape" took 122ms ( ??? )
~> "uvu" took 72ms ( 1.3ms)
```
## License
MIT © [Luke Edwards](https://lukeed.com)

2
vendor/spatie/ignition/node_modules/uvu/run/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,2 @@
import type { Suite } from 'uvu/parse';
export function run(suites: Suite[], options?: { bail: boolean }): Promise<void>;

12
vendor/spatie/ignition/node_modules/uvu/run/index.js generated vendored Executable file
View File

@@ -0,0 +1,12 @@
exports.run = async function (suites, opts={}) {
globalThis.UVU_DEFER = 1;
const uvu = require('uvu');
suites.forEach((suite, idx) => {
globalThis.UVU_QUEUE.push([suite.name]);
globalThis.UVU_INDEX = idx;
require(suite.file);
});
await uvu.exec(opts.bail);
}

13
vendor/spatie/ignition/node_modules/uvu/run/index.mjs generated vendored Executable file
View File

@@ -0,0 +1,13 @@
export async function run(suites, opts={}) {
globalThis.UVU_DEFER = 1;
const uvu = await import('uvu');
let suite, idx=0;
for (suite of suites) {
globalThis.UVU_INDEX = idx++;
globalThis.UVU_QUEUE.push([suite.name]);
await import('file:///' + suite.file);
}
await uvu.exec(opts.bail);
}