WIP: bootstrap and partial real Solana watcher implementation

This commit is contained in:
2026-08-16 09:17:45 +00:00
commit dc23412c3f
7232 changed files with 1687637 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
{
"main": "../../cjs/_write_only_error.cjs",
"module": "../../esm/_write_only_error.js"
}

View File

@@ -0,0 +1,94 @@
import type { ParserServices, TSESTree } from '../ts-estree';
import type { ParserOptions } from './ParserOptions';
import type { Scope } from './Scope';
export declare namespace Parser {
interface ParserMeta {
/**
* The unique name of the parser.
*/
name: string;
/**
* The a string identifying the version of the parser.
*/
version?: string;
}
/**
* A loose definition of the ParserModule type for use with configs
* This type intended to relax validation of configs so that parsers that have
* different AST types or scope managers can still be passed to configs
*
* @see {@link LooseRuleDefinition}, {@link LooseProcessorModule}
*/
type LooseParserModule = {
/**
* Information about the parser to uniquely identify it when serializing.
*/
meta?: {
[K in keyof ParserMeta]?: ParserMeta[K] | undefined;
};
/**
* Parses the given text into an AST
*/
parseForESLint(text: string, options?: unknown): {
[k in keyof ParseResult]: unknown;
};
} | {
/**
* Information about the parser to uniquely identify it when serializing.
*/
meta?: {
[K in keyof ParserMeta]?: ParserMeta[K] | undefined;
};
/**
* Parses the given text into an ESTree AST
*/
parse(text: string, options?: unknown): unknown;
};
type ParserModule = {
/**
* Information about the parser to uniquely identify it when serializing.
*/
meta?: ParserMeta;
/**
* Parses the given text into an AST
*/
parseForESLint(text: string, options?: ParserOptions): ParseResult;
} | {
/**
* Information about the parser to uniquely identify it when serializing.
*/
meta?: ParserMeta;
/**
* Parses the given text into an ESTree AST
*/
parse(text: string, options?: ParserOptions): TSESTree.Program;
};
interface ParseResult {
/**
* The ESTree AST
*/
ast: TSESTree.Program;
/**
* A `ScopeManager` object.
* Custom parsers can use customized scope analysis for experimental/enhancement syntaxes.
* The default is the `ScopeManager` object which is created by `eslint-scope`.
*/
scopeManager?: Scope.ScopeManager;
/**
* Any parser-dependent services (such as type checkers for nodes).
* The value of the services property is available to rules as `context.sourceCode.parserServices`.
* The default is an empty object.
*/
services?: ParserServices;
/**
* An object to customize AST traversal.
* The keys of the object are the type of AST nodes.
* Each value is an array of the property names which should be traversed.
* The default is `KEYS` of `eslint-visitor-keys`.
*/
visitorKeys?: VisitorKeys;
}
interface VisitorKeys {
[nodeType: string]: readonly string[];
}
}

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'no-dynamic-delete',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow using the `delete` operator on computed key expressions',
recommended: 'strict',
},
messages: {
dynamicDelete: 'Do not delete dynamically computed property keys.',
},
schema: [],
},
defaultOptions: [],
create(context) {
return {
'UnaryExpression[operator=delete]'(node) {
if (node.argument.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
!node.argument.computed ||
isAcceptableIndexExpression(node.argument.property)) {
return;
}
context.report({
node: node.argument.property,
messageId: 'dynamicDelete',
});
},
};
},
});
function isAcceptableIndexExpression(property) {
return ((property.type === utils_1.AST_NODE_TYPES.Literal &&
['number', 'string'].includes(typeof property.value)) ||
(property.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
property.operator === '-' &&
property.argument.type === utils_1.AST_NODE_TYPES.Literal &&
typeof property.argument.value === 'number'));
}

View File

@@ -0,0 +1,236 @@
import _typeof from "./typeof.js";
import setFunctionName from "./setFunctionName.js";
import toPropertyKey from "./toPropertyKey.js";
function old_createMetadataMethodsForProperty(e, t, a, r) {
return {
getMetadata: function getMetadata(o) {
old_assertNotFinished(r, "getMetadata"), old_assertMetadataKey(o);
var i = e[o];
if (void 0 !== i) if (1 === t) {
var n = i["public"];
if (void 0 !== n) return n[a];
} else if (2 === t) {
var l = i["private"];
if (void 0 !== l) return l.get(a);
} else if (Object.hasOwnProperty.call(i, "constructor")) return i.constructor;
},
setMetadata: function setMetadata(o, i) {
old_assertNotFinished(r, "setMetadata"), old_assertMetadataKey(o);
var n = e[o];
if (void 0 === n && (n = e[o] = {}), 1 === t) {
var l = n["public"];
void 0 === l && (l = n["public"] = {}), l[a] = i;
} else if (2 === t) {
var s = n.priv;
void 0 === s && (s = n["private"] = new Map()), s.set(a, i);
} else n.constructor = i;
}
};
}
function old_convertMetadataMapToFinal(e, t) {
var a = e[Symbol.metadata || Symbol["for"]("Symbol.metadata")],
r = Object.getOwnPropertySymbols(t);
if (0 !== r.length) {
for (var o = 0; o < r.length; o++) {
var i = r[o],
n = t[i],
l = a ? a[i] : null,
s = n["public"],
c = l ? l["public"] : null;
s && c && Object.setPrototypeOf(s, c);
var d = n["private"];
if (d) {
var u = Array.from(d.values()),
f = l ? l["private"] : null;
f && (u = u.concat(f)), n["private"] = u;
}
l && Object.setPrototypeOf(n, l);
}
a && Object.setPrototypeOf(t, a), e[Symbol.metadata || Symbol["for"]("Symbol.metadata")] = t;
}
}
function old_createAddInitializerMethod(e, t) {
return function (a) {
old_assertNotFinished(t, "addInitializer"), old_assertCallable(a, "An initializer"), e.push(a);
};
}
function old_memberDec(e, t, a, r, o, i, n, l, s) {
var c;
switch (i) {
case 1:
c = "accessor";
break;
case 2:
c = "method";
break;
case 3:
c = "getter";
break;
case 4:
c = "setter";
break;
default:
c = "field";
}
var d,
u,
f = {
kind: c,
name: l ? "#" + t : toPropertyKey(t),
isStatic: n,
isPrivate: l
},
p = {
v: !1
};
if (0 !== i && (f.addInitializer = old_createAddInitializerMethod(o, p)), l) {
d = 2, u = Symbol(t);
var v = {};
0 === i ? (v.get = a.get, v.set = a.set) : 2 === i ? v.get = function () {
return a.value;
} : (1 !== i && 3 !== i || (v.get = function () {
return a.get.call(this);
}), 1 !== i && 4 !== i || (v.set = function (e) {
a.set.call(this, e);
})), f.access = v;
} else d = 1, u = t;
try {
return e(s, Object.assign(f, old_createMetadataMethodsForProperty(r, d, u, p)));
} finally {
p.v = !0;
}
}
function old_assertNotFinished(e, t) {
if (e.v) throw Error("attempted to call " + t + " after decoration was finished");
}
function old_assertMetadataKey(e) {
if ("symbol" != _typeof(e)) throw new TypeError("Metadata keys must be symbols, received: " + e);
}
function old_assertCallable(e, t) {
if ("function" != typeof e) throw new TypeError(t + " must be a function");
}
function old_assertValidReturnValue(e, t) {
var a = _typeof(t);
if (1 === e) {
if ("object" !== a || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
void 0 !== t.get && old_assertCallable(t.get, "accessor.get"), void 0 !== t.set && old_assertCallable(t.set, "accessor.set"), void 0 !== t.init && old_assertCallable(t.init, "accessor.init"), void 0 !== t.initializer && old_assertCallable(t.initializer, "accessor.initializer");
} else if ("function" !== a) throw new TypeError((0 === e ? "field" : 10 === e ? "class" : "method") + " decorators must return a function or void 0");
}
function old_getInit(e) {
var t;
return null == (t = e.init) && (t = e.initializer) && void 0 !== console && console.warn(".initializer has been renamed to .init as of March 2022"), t;
}
function old_applyMemberDec(e, t, a, r, o, i, n, l, s) {
var c,
d,
u,
f,
p,
v,
y,
h = a[0];
if (n ? (0 === o || 1 === o ? (c = {
get: a[3],
set: a[4]
}, u = "get") : 3 === o ? (c = {
get: a[3]
}, u = "get") : 4 === o ? (c = {
set: a[3]
}, u = "set") : c = {
value: a[3]
}, 0 !== o && (1 === o && setFunctionName(a[4], "#" + r, "set"), setFunctionName(a[3], "#" + r, u))) : 0 !== o && (c = Object.getOwnPropertyDescriptor(t, r)), 1 === o ? f = {
get: c.get,
set: c.set
} : 2 === o ? f = c.value : 3 === o ? f = c.get : 4 === o && (f = c.set), "function" == typeof h) void 0 !== (p = old_memberDec(h, r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? d = p : 1 === o ? (d = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = {
get: v,
set: y
}) : f = p);else for (var m = h.length - 1; m >= 0; m--) {
var b;
void 0 !== (p = old_memberDec(h[m], r, c, l, s, o, i, n, f)) && (old_assertValidReturnValue(o, p), 0 === o ? b = p : 1 === o ? (b = old_getInit(p), v = p.get || f.get, y = p.set || f.set, f = {
get: v,
set: y
}) : f = p, void 0 !== b && (void 0 === d ? d = b : "function" == typeof d ? d = [d, b] : d.push(b)));
}
if (0 === o || 1 === o) {
if (void 0 === d) d = function d(e, t) {
return t;
};else if ("function" != typeof d) {
var g = d;
d = function d(e, t) {
for (var a = t, r = 0; r < g.length; r++) a = g[r].call(e, a);
return a;
};
} else {
var _ = d;
d = function d(e, t) {
return _.call(e, t);
};
}
e.push(d);
}
0 !== o && (1 === o ? (c.get = f.get, c.set = f.set) : 2 === o ? c.value = f : 3 === o ? c.get = f : 4 === o && (c.set = f), n ? 1 === o ? (e.push(function (e, t) {
return f.get.call(e, t);
}), e.push(function (e, t) {
return f.set.call(e, t);
})) : 2 === o ? e.push(f) : e.push(function (e, t) {
return f.call(e, t);
}) : Object.defineProperty(t, r, c));
}
function old_applyMemberDecs(e, t, a, r, o) {
for (var i, n, l = new Map(), s = new Map(), c = 0; c < o.length; c++) {
var d = o[c];
if (Array.isArray(d)) {
var u,
f,
p,
v = d[1],
y = d[2],
h = d.length > 3,
m = v >= 5;
if (m ? (u = t, f = r, 0 != (v -= 5) && (p = n = n || [])) : (u = t.prototype, f = a, 0 !== v && (p = i = i || [])), 0 !== v && !h) {
var b = m ? s : l,
g = b.get(y) || 0;
if (!0 === g || 3 === g && 4 !== v || 4 === g && 3 !== v) throw Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + y);
!g && v > 2 ? b.set(y, v) : b.set(y, !0);
}
old_applyMemberDec(e, u, d, y, v, m, h, f, p);
}
}
old_pushInitializers(e, i), old_pushInitializers(e, n);
}
function old_pushInitializers(e, t) {
t && e.push(function (e) {
for (var a = 0; a < t.length; a++) t[a].call(e);
return e;
});
}
function old_applyClassDecs(e, t, a, r) {
if (r.length > 0) {
for (var o = [], i = t, n = t.name, l = r.length - 1; l >= 0; l--) {
var s = {
v: !1
};
try {
var c = Object.assign({
kind: "class",
name: n,
addInitializer: old_createAddInitializerMethod(o, s)
}, old_createMetadataMethodsForProperty(a, 0, n, s)),
d = r[l](i, c);
} finally {
s.v = !0;
}
void 0 !== d && (old_assertValidReturnValue(10, d), i = d);
}
e.push(i, function () {
for (var e = 0; e < o.length; e++) o[e].call(i);
});
}
}
function applyDecs(e, t, a) {
var r = [],
o = {},
i = {};
return old_applyMemberDecs(r, e, i, o, t), old_convertMetadataMapToFinal(e.prototype, i), old_applyClassDecs(r, e, o, a), old_convertMetadataMapToFinal(e, o), r;
}
export { applyDecs as default };

View File

@@ -0,0 +1,323 @@
///////////////////////////////////////////////////
//////////////// TYPES ///////////////////
///////////////////////////////////////////////////
export interface $ZSF {
$zsf: { version: number };
type: string;
// default value if not defined
default: unknown;
// fallback value if validation fails
fallback: unknown;
}
export interface $ZSFString extends $ZSF {
type: "string";
min_length?: number;
max_length?: number;
pattern?: string;
}
export type NumberTypes = "float32" | "int32" | "uint32" | "float64" | "int64" | "uint64" | "bigint" | "bigdecimal";
export interface $ZSFNumber extends $ZSF {
type: "number";
format?: NumberTypes;
minimum?: number;
maximum?: number;
multiple_of?: number;
}
export interface $ZSFBoolean extends $ZSF {
type: "boolean";
}
export interface $ZSFNull extends $ZSF {
type: "null";
}
export interface $ZSFUndefined extends $ZSF {
type: "undefined";
}
export interface $ZSFOptional<T extends $ZSF = $ZSF> extends $ZSF {
type: "optional";
inner: T;
}
export interface $ZSFNever extends $ZSF {
type: "never";
}
export interface $ZSFAny extends $ZSF {
type: "any";
}
/** Supports */
export interface $ZSFEnum<Elements extends { [k: string]: $ZSFLiteral } = { [k: string]: $ZSFLiteral }> extends $ZSF {
type: "enum";
elements: Elements;
}
export interface $ZSFArray<PrefixItems extends $ZSF[] = $ZSF[], Items extends $ZSF = $ZSF> extends $ZSF {
type: "array";
prefixItems: PrefixItems;
items: Items;
}
// type $ZSFObjectProperties = { [k: string]: $ZSF };
type $ZSFObjectProperties = Array<{
key: string;
value: $ZSF;
format?: "literal" | "pattern";
ordering?: number;
}>;
export interface $ZSFObject<Properties extends $ZSFObjectProperties = $ZSFObjectProperties> extends $ZSF {
type: "object";
properties: Properties;
}
// export interface $ZSFTuple<
// Items extends $ZSF[] = $ZSF[],
// Rest extends $ZSF = $ZSF,
// > extends $ZSF {
// type: "array";
// items: Items;
// rest: Rest;
// }
/** Supports arbitrary literal values */
export interface $ZSFLiteral<T extends $ZSF = $ZSF> extends $ZSF {
type: "literal";
schema: T;
value: unknown;
}
export interface $ZSFUnion<Elements extends $ZSF[] = $ZSF[]> extends $ZSF {
type: "union";
elements: Elements;
}
export interface $ZSFIntersection extends $ZSF {
type: "intersection";
elements: $ZSF[];
}
export interface $ZSFMap<K extends $ZSF = $ZSF, V extends $ZSF = $ZSF> extends $ZSF {
type: "map";
keys: K;
values: V;
}
export interface $ZSFConditional<If extends $ZSF, Then extends $ZSF, Else extends $ZSF> extends $ZSF {
type: "conditional";
if: If;
then: Then;
else: Else;
}
/////////////////////////////////////////////////
//////////////// CHECKS ////////////////
/////////////////////////////////////////////////
// export interface $ZSFCheckRegex {
// check: "regex";
// pattern: string;
// }
// export interface $ZSFCheckEmail {
// check: "email";
// }
// export interface $ZSFCheckURL {
// check: "url";
// }
// export interface $ZSFCheckEmoji {
// check: "emoji";
// }
// export interface $ZSFCheckUUID {
// check: "uuid";
// }
// export interface $ZSFCheckUUIDv4 {
// check: "uuidv4";
// }
// export interface $ZSFCheckUUIDv6 {
// check: "uuidv6";
// }
// export interface $ZSFCheckNanoid {
// check: "nanoid";
// }
// export interface $ZSFCheckGUID {
// check: "guid";
// }
// export interface $ZSFCheckCUID {
// check: "cuid";
// }
// export interface $ZSFCheckCUID2 {
// check: "cuid2";
// }
// export interface $ZSFCheckULID {
// check: "ulid";
// }
// export interface $ZSFCheckXID {
// check: "xid";
// }
// export interface $ZSFCheckKSUID {
// check: "ksuid";
// }
// export interface $ZSFCheckISODateTime {
// check: "datetime";
// precision?: number;
// local?: boolean;
// }
// export interface $ZSFCheckISODate {
// check: "date";
// }
// export interface $ZSFCheckISOTime {
// check: "time";
// precision?: number;
// local?: boolean;
// }
// export interface $ZSFCheckDuration {
// check: "duration";
// }
// export interface $ZSFCheckIP {
// check: "ip";
// }
// export interface $ZSFCheckIPv4 {
// check: "ipv4";
// }
// export interface $ZSFCheckIPv6 {
// check: "ipv6";
// }
// export interface $ZSFCheckBase64 {
// check: "base64";
// }
// export interface $ZSFCheckJWT {
// check: "jwt";
// }
// export interface $ZSFCheckJSONString {
// check: "json_string";
// }
// export interface $ZSFCheckPrefix {
// check: "prefix";
// prefix: string;
// }
// export interface $ZSFCheckSuffix {
// check: "suffix";
// suffix: string;
// }
// export interface $ZSFCheckIncludes {
// check: "includes";
// includes: string;
// }
// export interface $ZSFCheckMinSize {
// check: "min_size";
// minimum: number;
// }
// export interface $ZSFCheckMaxSize {
// check: "max_size";
// maximum: number;
// }
// export interface $ZSFCheckSizeEquals {
// check: "size_equals";
// size: number;
// }
// export interface $ZSFCheckLessThan {
// check: "less_than";
// maximum: number | bigint | Date;
// }
// export interface $ZSFCheckLessThanOrEqual {
// check: "less_than_or_equal";
// maximum: number | bigint | Date;
// }
// export interface $ZSFCheckGreaterThan {
// check: "greater_than";
// minimum: number | bigint | Date;
// }
// export interface $ZSFCheckGreaterThanOrEqual {
// check: "greater_than_or_equal";
// minimum: number | bigint | Date;
// }
// export interface $ZSFCheckEquals {
// check: "equals";
// value: number | bigint | Date;
// }
// export interface $ZSFCheckMultipleOf {
// check: "multiple_of";
// multipleOf: number;
// }
// export type $ZSFStringFormatChecks =
// | $ZSFCheckRegex
// | $ZSFCheckEmail
// | $ZSFCheckURL
// | $ZSFCheckEmoji
// | $ZSFCheckUUID
// | $ZSFCheckUUIDv4
// | $ZSFCheckUUIDv6
// | $ZSFCheckNanoid
// | $ZSFCheckGUID
// | $ZSFCheckCUID
// | $ZSFCheckCUID2
// | $ZSFCheckULID
// | $ZSFCheckXID
// | $ZSFCheckKSUID
// | $ZSFCheckISODateTime
// | $ZSFCheckISODate
// | $ZSFCheckISOTime
// | $ZSFCheckDuration
// | $ZSFCheckIP
// | $ZSFCheckIPv4
// | $ZSFCheckIPv6
// | $ZSFCheckBase64
// | $ZSFCheckJWT
// | $ZSFCheckJSONString
// | $ZSFCheckPrefix
// | $ZSFCheckSuffix
// | $ZSFCheckIncludes;
// export type $ZSFCheck =
// | $ZSFStringFormatChecks
// | $ZSFCheckMinSize
// | $ZSFCheckMaxSize
// | $ZSFCheckSizeEquals
// | $ZSFCheckLessThan
// | $ZSFCheckLessThanOrEqual
// | $ZSFCheckGreaterThan
// | $ZSFCheckGreaterThanOrEqual
// | $ZSFCheckEquals
// | $ZSFCheckMultipleOf;

View File

@@ -0,0 +1,83 @@
const { getStream, getSecureStream } = getStreamFuncs()
module.exports = {
/**
* Get a socket stream compatible with the current runtime environment.
* @returns {Duplex}
*/
getStream,
/**
* Get a TLS secured socket, compatible with the current environment,
* using the socket and other settings given in `options`.
* @returns {Duplex}
*/
getSecureStream,
}
/**
* The stream functions that work in Node.js
*/
function getNodejsStreamFuncs() {
function getStream(ssl) {
const net = require('net')
return new net.Socket()
}
function getSecureStream(options) {
const tls = require('tls')
return tls.connect(options)
}
return {
getStream,
getSecureStream,
}
}
/**
* The stream functions that work in Cloudflare Workers
*/
function getCloudflareStreamFuncs() {
function getStream(ssl) {
const { CloudflareSocket } = require('pg-cloudflare')
return new CloudflareSocket(ssl)
}
function getSecureStream(options) {
options.socket.startTls(options)
return options.socket
}
return {
getStream,
getSecureStream,
}
}
/**
* Are we running in a Cloudflare Worker?
*
* @returns true if the code is currently running inside a Cloudflare Worker.
*/
function isCloudflareRuntime() {
// Since 2022-03-21 the `global_navigator` compatibility flag is on for Cloudflare Workers
// which means that `navigator.userAgent` will be defined.
// eslint-disable-next-line no-undef
if (typeof navigator === 'object' && navigator !== null && typeof navigator.userAgent === 'string') {
// eslint-disable-next-line no-undef
return navigator.userAgent === 'Cloudflare-Workers'
}
// In case `navigator` or `navigator.userAgent` is not defined then try a more sneaky approach
if (typeof Response === 'function') {
const resp = new Response(null, { cf: { thing: true } })
if (typeof resp.cf === 'object' && resp.cf !== null && resp.cf.thing) {
return true
}
}
return false
}
function getStreamFuncs() {
if (isCloudflareRuntime()) {
return getCloudflareStreamFuncs()
}
return getNodejsStreamFuncs()
}

View File

@@ -0,0 +1,91 @@
{
"types": {
"problem": [],
"suggestion": [],
"layout": []
},
"deprecated": [],
"removed": [
{
"removed": "generator-star",
"replacedBy": [{ "rule": { "name": "generator-star-spacing" } }]
},
{
"removed": "global-strict",
"replacedBy": [{ "rule": { "name": "strict" } }]
},
{
"removed": "no-arrow-condition",
"replacedBy": [
{ "rule": { "name": "no-confusing-arrow" } },
{ "rule": { "name": "no-constant-condition" } }
]
},
{
"removed": "no-comma-dangle",
"replacedBy": [{ "rule": { "name": "comma-dangle" } }]
},
{
"removed": "no-empty-class",
"replacedBy": [{ "rule": { "name": "no-empty-character-class" } }]
},
{
"removed": "no-empty-label",
"replacedBy": [{ "rule": { "name": "no-labels" } }]
},
{
"removed": "no-extra-strict",
"replacedBy": [{ "rule": { "name": "strict" } }]
},
{
"removed": "no-reserved-keys",
"replacedBy": [{ "rule": { "name": "quote-props" } }]
},
{
"removed": "no-space-before-semi",
"replacedBy": [{ "rule": { "name": "semi-spacing" } }]
},
{
"removed": "no-wrap-func",
"replacedBy": [{ "rule": { "name": "no-extra-parens" } }]
},
{
"removed": "space-after-function-name",
"replacedBy": [{ "rule": { "name": "space-before-function-paren" } }]
},
{
"removed": "space-after-keywords",
"replacedBy": [{ "rule": { "name": "keyword-spacing" } }]
},
{
"removed": "space-before-function-parentheses",
"replacedBy": [{ "rule": { "name": "space-before-function-paren" } }]
},
{
"removed": "space-before-keywords",
"replacedBy": [{ "rule": { "name": "keyword-spacing" } }]
},
{
"removed": "space-in-brackets",
"replacedBy": [
{ "rule": { "name": "object-curly-spacing" } },
{ "rule": { "name": "array-bracket-spacing" } },
{ "rule": { "name": "computed-property-spacing" } }
]
},
{
"removed": "space-return-throw-case",
"replacedBy": [{ "rule": { "name": "keyword-spacing" } }]
},
{
"removed": "space-unary-word-ops",
"replacedBy": [{ "rule": { "name": "space-unary-ops" } }]
},
{
"removed": "spaced-line-comment",
"replacedBy": [{ "rule": { "name": "spaced-comment" } }]
},
{ "removed": "valid-jsdoc", "replacedBy": [] },
{ "removed": "require-jsdoc", "replacedBy": [] }
]
}

View File

@@ -0,0 +1,14 @@
"use strict";
var _set_prototype_of = require("./_set_prototype_of.cjs");
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });
if (superClass) _set_prototype_of._(subClass, superClass);
}
exports._ = _inherits;

View File

@@ -0,0 +1,22 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABILITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference lib="es2021" />
/// <reference lib="dom" />
/// <reference lib="webworker.importscripts" />
/// <reference lib="scripthost" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />

View File

@@ -0,0 +1,110 @@
'use strict'
const { test, describe } = require('node:test')
const prettifyErrorLog = require('./prettify-error-log')
const colors = require('../colors')
const {
ERROR_LIKE_KEYS,
MESSAGE_KEY
} = require('../constants')
const context = {
EOL: '\n',
IDENT: ' ',
customPrettifiers: {},
errorLikeObjectKeys: ERROR_LIKE_KEYS,
errorProps: [],
messageKey: MESSAGE_KEY,
objectColorizer: colors()
}
test('returns string with default settings', t => {
const err = Error('Something went wrong')
const str = prettifyErrorLog({ log: err, context })
t.assert.ok(str.startsWith(' Error: Something went wrong'))
})
test('returns string with custom ident', t => {
const err = Error('Something went wrong')
const str = prettifyErrorLog({
log: err,
context: {
...context,
IDENT: ' '
}
})
t.assert.ok(str.startsWith(' Error: Something went wrong'))
})
test('returns string with custom eol', t => {
const err = Error('Something went wrong')
const str = prettifyErrorLog({
log: err,
context: {
...context,
EOL: '\r\n'
}
})
t.assert.ok(str.startsWith(' Error: Something went wrong\r\n'))
})
describe('errorProperties', () => {
test('excludes all for wildcard', t => {
const err = Error('boom')
err.foo = 'foo'
const str = prettifyErrorLog({
log: err,
context: {
...context,
errorProps: ['*']
}
})
t.assert.ok(str.startsWith(' Error: boom'))
t.assert.strictEqual(str.includes('foo: "foo"'), false)
})
test('excludes only selected properties', t => {
const err = Error('boom')
err.foo = 'foo'
const str = prettifyErrorLog({
log: err,
context: {
...context,
errorProps: ['foo']
}
})
t.assert.ok(str.startsWith(' Error: boom'))
t.assert.strictEqual(str.includes('foo: foo'), true)
})
test('ignores specified properties if not present', t => {
const err = Error('boom')
err.foo = 'foo'
const str = prettifyErrorLog({
log: err,
context: {
...context,
errorProps: ['foo', 'bar']
}
})
t.assert.ok(str.startsWith(' Error: boom'))
t.assert.strictEqual(str.includes('foo: foo'), true)
t.assert.strictEqual(str.includes('bar'), false)
})
test('processes nested objects', t => {
const err = Error('boom')
err.foo = { bar: 'bar', message: 'included' }
const str = prettifyErrorLog({
log: err,
context: {
...context,
errorProps: ['foo']
}
})
t.assert.ok(str.startsWith(' Error: boom'))
t.assert.strictEqual(str.includes('foo: {'), true)
t.assert.strictEqual(str.includes('bar: "bar"'), true)
t.assert.strictEqual(str.includes('message: "included"'), true)
})
})

View File

@@ -0,0 +1,6 @@
"use strict";
function _array_with_holes(arr) {
if (Array.isArray(arr)) return arr;
}
exports._ = _array_with_holes;

View File

@@ -0,0 +1,5 @@
import assertClassBrand from "./assertClassBrand.js";
function _classPrivateSetter(s, r, a, t) {
return r(assertClassBrand(s, a), t), t;
}
export { _classPrivateSetter as default };

View File

@@ -0,0 +1,18 @@
import * as fs from 'node:fs'
import { once } from 'node:events'
import { Transform } from 'node:stream'
async function run (opts: { destination?: fs.PathLike }): Promise<Transform> {
if (!opts.destination) throw new Error('kaboom')
const stream = fs.createWriteStream(opts.destination)
await once(stream, 'open')
const t = new Transform({
transform (chunk, enc, cb) {
setImmediate(cb, null, chunk.toString().toUpperCase())
}
})
t.pipe(stream)
return t
}
export default run

View File

@@ -0,0 +1 @@
export { _ as default } from "../esm/_class_private_field_loose_base.js";

View File

@@ -0,0 +1,4 @@
{
"main": "../../cjs/_create_class.cjs",
"module": "../../esm/_create_class.js"
}

View File

@@ -0,0 +1,2 @@
declare const equal: (a: any, b: any) => boolean;
export = equal;

View File

@@ -0,0 +1 @@
export { _ as default } from "../esm/_create_for_of_iterator_helper_loose.js";

View File

@@ -0,0 +1,92 @@
// Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import gulp from 'gulp';
import mocha from 'gulp-mocha';
import eslint from 'gulp-eslint';
import minimist from 'minimist';
import git from 'gulp-git';
import bump from 'gulp-bump';
import filter from 'gulp-filter';
import tagVersion from 'gulp-tag-version';
import 'babel-register';
const SOURCE = [
'*.js'
];
let ESLINT_OPTION = {
parser: 'babel-eslint',
parserOptions: {
'sourceType': 'module'
},
rules: {
'quotes': 0,
'eqeqeq': 0,
'no-use-before-define': 0,
'no-shadow': 0,
'no-new': 0,
'no-underscore-dangle': 0,
'no-multi-spaces': 0,
'no-native-reassign': 0,
'no-loop-func': 0
},
env: {
'node': true
}
};
gulp.task('test', function() {
let options = minimist(process.argv.slice(2), {
string: 'test',
default: {
test: 'test/*.js'
}
}
);
return gulp.src(options.test).pipe(mocha({reporter: 'spec'}));
});
gulp.task('lint', () =>
gulp.src(SOURCE)
.pipe(eslint(ESLINT_OPTION))
.pipe(eslint.formatEach('stylish', process.stderr))
.pipe(eslint.failOnError())
);
let inc = importance =>
gulp.src(['./package.json'])
.pipe(bump({type: importance}))
.pipe(gulp.dest('./'))
.pipe(git.commit('Bumps package version'))
.pipe(filter('package.json'))
.pipe(tagVersion({
prefix: ''
}))
;
gulp.task('travis', [ 'lint', 'test' ]);
gulp.task('default', [ 'travis' ]);
gulp.task('patch', [ ], () => inc('patch'));
gulp.task('minor', [ ], () => inc('minor'));
gulp.task('major', [ ], () => inc('major'));

View File

@@ -0,0 +1,76 @@
'use strict'
let Container = require('./container')
let LazyResult, Processor
class Root extends Container {
constructor(defaults) {
super(defaults)
this.type = 'root'
if (!this.nodes) this.nodes = []
}
normalize(child, sample, type) {
let keepBefore = new Set()
for (let node of Array.isArray(child) ? child : [child]) {
if (
node &&
typeof node === 'object' &&
!node.parent &&
node.raws &&
typeof node.raws.before !== 'undefined'
) {
keepBefore.add(node.raws)
}
}
let nodes = super.normalize(child)
if (sample) {
if (type === 'prepend') {
if (this.nodes.length > 1) {
sample.raws.before = this.nodes[1].raws.before
} else {
delete sample.raws.before
}
} else if (this.first !== sample) {
for (let node of nodes) {
if (!keepBefore.has(node.raws)) {
node.raws.before = sample.raws.before
}
}
}
}
return nodes
}
removeChild(child, ignore) {
let index = this.index(child)
if (!ignore && index === 0 && this.nodes.length > 1) {
this.nodes[1].raws.before = this.nodes[index].raws.before
}
return super.removeChild(child)
}
toResult(opts = {}) {
let lazy = new LazyResult(new Processor(), this, opts)
return lazy.stringify()
}
}
Root.registerLazyResult = dependant => {
LazyResult = dependant
}
Root.registerProcessor = dependant => {
Processor = dependant
}
module.exports = Root
Root.default = Root
Container.registerRoot(Root)

View File

@@ -0,0 +1 @@
export { _ as default } from "../esm/_class_apply_descriptor_update.js";

View File

@@ -0,0 +1,10 @@
"use strict";
var _class_apply_descriptor_update = require("./_class_apply_descriptor_update.cjs");
var _class_extract_field_descriptor = require("./_class_extract_field_descriptor.cjs");
function _class_private_field_update(receiver, privateMap) {
var descriptor = _class_extract_field_descriptor._(receiver, privateMap, "update");
return _class_apply_descriptor_update._(receiver, descriptor);
}
exports._ = _class_private_field_update;

View File

@@ -0,0 +1,39 @@
/**
* @typedef { import('estree').Node} Node
* @typedef {{
* skip: () => void;
* remove: () => void;
* replace: (node: Node) => void;
* }} WalkerContext
*/
export class WalkerBase {
/** @type {boolean} */
should_skip: boolean;
/** @type {boolean} */
should_remove: boolean;
/** @type {Node | null} */
replacement: Node | null;
/** @type {WalkerContext} */
context: WalkerContext;
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
* @param {Node} node
*/
replace<Parent extends import("estree").Node>(parent: Parent | null | undefined, prop: keyof Parent | null | undefined, index: number | null | undefined, node: Node): void;
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
*/
remove<Parent_1 extends import("estree").Node>(parent: Parent_1 | null | undefined, prop: keyof Parent_1 | null | undefined, index: number | null | undefined): void;
}
export type Node = import('estree').Node;
export type WalkerContext = {
skip: () => void;
remove: () => void;
replace: (node: Node) => void;
};

View File

@@ -0,0 +1 @@
{"version":3,"file":"_assert.js","sourceRoot":"","sources":["src/_assert.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,yCAMoB;AACpB,8DAA8D;AACjD,QAAA,MAAM,GAAc,iBAAE,CAAC;AACpC,8DAA8D;AACjD,QAAA,OAAO,GAAc,kBAAE,CAAC;AACrC,8DAA8D;AACjD,QAAA,OAAO,GAAc,kBAAE,CAAC;AACrC,8DAA8D;AACjD,QAAA,OAAO,GAAc,kBAAE,CAAC"}

View File

@@ -0,0 +1,65 @@
/**
* @fileoverview Define the cursor which iterates tokens and comments.
* @author Toru Nagashima
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const Cursor = require("./cursor");
const { getFirstIndex, search } = require("./utils");
//------------------------------------------------------------------------------
// Exports
//------------------------------------------------------------------------------
/**
* The cursor which iterates tokens and comments.
*/
module.exports = class ForwardTokenCommentCursor extends Cursor {
/**
* Initializes this cursor.
* @param {Token[]} tokens The array of tokens.
* @param {Comment[]} comments The array of comments.
* @param {Object} indexMap The map from locations to indices in `tokens`.
* @param {number} startLoc The start location of the iteration range.
* @param {number} endLoc The end location of the iteration range.
*/
constructor(tokens, comments, indexMap, startLoc, endLoc) {
super();
this.tokens = tokens;
this.comments = comments;
this.tokenIndex = getFirstIndex(tokens, indexMap, startLoc);
this.commentIndex = search(comments, startLoc);
this.border = endLoc;
}
/** @inheritdoc */
moveNext() {
const token =
this.tokenIndex < this.tokens.length
? this.tokens[this.tokenIndex]
: null;
const comment =
this.commentIndex < this.comments.length
? this.comments[this.commentIndex]
: null;
if (token && (!comment || token.range[0] < comment.range[0])) {
this.current = token;
this.tokenIndex += 1;
} else if (comment) {
this.current = comment;
this.commentIndex += 1;
} else {
this.current = null;
}
return (
Boolean(this.current) &&
(this.border === -1 || this.current.range[1] <= this.border)
);
}
};

View File

@@ -0,0 +1,73 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `pnpm run generate-configs`
module.exports = {
parserOptions: { program: null, project: false, projectService: false },
rules: {
'@typescript-eslint/await-thenable': 'off',
'@typescript-eslint/consistent-return': 'off',
'@typescript-eslint/consistent-type-exports': 'off',
'@typescript-eslint/dot-notation': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/no-array-delete': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/no-confusing-void-expression': 'off',
'@typescript-eslint/no-deprecated': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-for-in-array': 'off',
'@typescript-eslint/no-implied-eval': 'off',
'@typescript-eslint/no-meaningless-void-operator': 'off',
'@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/no-misused-spread': 'off',
'@typescript-eslint/no-mixed-enums': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off',
'@typescript-eslint/no-unnecessary-qualifier': 'off',
'@typescript-eslint/no-unnecessary-template-expression': 'off',
'@typescript-eslint/no-unnecessary-type-arguments': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unnecessary-type-conversion': 'off',
'@typescript-eslint/no-unnecessary-type-parameters': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-type-assertion': 'off',
'@typescript-eslint/no-unsafe-unary-minus': 'off',
'@typescript-eslint/no-useless-default-assignment': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/only-throw-error': 'off',
'@typescript-eslint/prefer-destructuring': 'off',
'@typescript-eslint/prefer-find': 'off',
'@typescript-eslint/prefer-includes': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-readonly': 'off',
'@typescript-eslint/prefer-readonly-parameter-types': 'off',
'@typescript-eslint/prefer-reduce-type-parameter': 'off',
'@typescript-eslint/prefer-regexp-exec': 'off',
'@typescript-eslint/prefer-return-this-type': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/promise-function-async': 'off',
'@typescript-eslint/related-getter-setter-pairs': 'off',
'@typescript-eslint/require-array-sort-compare': 'off',
'@typescript-eslint/require-await': 'off',
'@typescript-eslint/restrict-plus-operands': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/return-await': 'off',
'@typescript-eslint/strict-boolean-expressions': 'off',
'@typescript-eslint/strict-void-return': 'off',
'@typescript-eslint/switch-exhaustiveness-check': 'off',
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
},
};

View File

@@ -0,0 +1,350 @@
# @pinojs/redact
> Smart object redaction for JavaScript applications - safe AND fast!
Redact JS objects with the same API as [fast-redact](https://github.com/davidmarkclements/fast-redact), but uses innovative **selective cloning** instead of mutating the original. This provides immutability guarantees with **performance competitive** to fast-redact for real-world usage patterns.
## Install
```bash
npm install @pinojs/redact
```
## Usage
```js
const slowRedact = require('@pinojs/redact')
const redact = slowRedact({
paths: ['headers.cookie', 'headers.authorization', 'user.password']
})
const obj = {
headers: {
cookie: 'secret-session-token',
authorization: 'Bearer abc123',
'x-forwarded-for': '192.168.1.1'
},
user: {
name: 'john',
password: 'secret123'
}
}
console.log(redact(obj))
// Output: {"headers":{"cookie":"[REDACTED]","authorization":"[REDACTED]","x-forwarded-for":"192.168.1.1"},"user":{"name":"john","password":"[REDACTED]"}}
// Original object is completely unchanged:
console.log(obj.headers.cookie) // 'secret-session-token'
```
## API
### slowRedact(options) → Function
Creates a redaction function with the specified options.
#### Options
- **paths** `string[]` (required): An array of strings describing the nested location of a key in an object
- **censor** `any` (optional, default: `'[REDACTED]'`): The value to replace sensitive data with. Can be a static value or function.
- **serialize** `Function|boolean` (optional, default: `JSON.stringify`): Serialization function. Set to `false` to return the redacted object.
- **remove** `boolean` (optional, default: `false`): Remove redacted keys from serialized output
- **strict** `boolean` (optional, default: `true`): Throw on non-object values or pass through primitives
#### Path Syntax
Supports the same path syntax as fast-redact:
- **Dot notation**: `'user.name'`, `'headers.cookie'`
- **Bracket notation**: `'user["password"]'`, `'headers["X-Forwarded-For"]'`
- **Array indices**: `'users[0].password'`, `'items[1].secret'`
- **Wildcards**:
- Terminal: `'users.*.password'` (redacts password for all users)
- Intermediate: `'*.password'` (redacts password at any level)
- Array wildcard: `'items.*'` (redacts all array elements)
#### Examples
**Custom censor value:**
```js
const redact = slowRedact({
paths: ['password'],
censor: '***HIDDEN***'
})
```
**Dynamic censor function:**
```js
const redact = slowRedact({
paths: ['password'],
censor: (value, path) => `REDACTED:${path}`
})
```
**Return object instead of JSON string:**
```js
const redact = slowRedact({
paths: ['secret'],
serialize: false
})
const result = redact({ secret: 'hidden', public: 'data' })
console.log(result.secret) // '[REDACTED]'
console.log(result.public) // 'data'
// Restore original values
const restored = result.restore()
console.log(restored.secret) // 'hidden'
```
**Custom serialization:**
```js
const redact = slowRedact({
paths: ['password'],
serialize: obj => JSON.stringify(obj, null, 2)
})
```
**Remove keys instead of redacting:**
```js
const redact = slowRedact({
paths: ['password', 'user.secret'],
remove: true
})
const obj = { username: 'john', password: 'secret123', user: { name: 'Jane', secret: 'hidden' } }
console.log(redact(obj))
// Output: {"username":"john","user":{"name":"Jane"}}
// Note: 'password' and 'user.secret' are completely absent, not redacted
```
**Wildcard patterns:**
```js
// Redact all properties in secrets object
const redact1 = slowRedact({ paths: ['secrets.*'] })
// Redact password for any user
const redact2 = slowRedact({ paths: ['users.*.password'] })
// Redact all items in an array
const redact3 = slowRedact({ paths: ['items.*'] })
// Remove all secrets instead of redacting them
const redact4 = slowRedact({ paths: ['secrets.*'], remove: true })
```
## Key Differences from fast-redact
### Safety First
- **No mutation**: Original objects are never modified
- **Selective cloning**: Only clones paths that need redaction, shares references for everything else
- **Restore capability**: Can restore original values when `serialize: false`
### Feature Compatibility
- **Remove option**: Full compatibility with fast-redact's `remove: true` option to completely omit keys from output
- **All path patterns**: Supports same syntax including wildcards, bracket notation, and array indices
- **Censor functions**: Dynamic censoring with path information passed as arrays
- **Serialization**: Custom serializers and `serialize: false` mode
### Smart Performance Approach
- **Selective cloning**: Analyzes redaction paths and only clones necessary object branches
- **Reference sharing**: Non-redacted properties maintain original object references
- **Memory efficiency**: Dramatically reduced memory usage for large objects with minimal redaction
- **Setup-time optimization**: Path analysis happens once during setup, not per redaction
### When to Use @pinojs/redact
- When immutability is critical
- When you need to preserve original objects
- When objects are shared across multiple contexts
- In functional programming environments
- When debugging and you need to compare before/after
- **Large objects with selective redaction** (now performance-competitive!)
- When memory efficiency with reference sharing is important
### When to Use fast-redact
- When absolute maximum performance is critical
- In extremely high-throughput scenarios (>100,000 ops/sec)
- When you control the object lifecycle and mutation is acceptable
- Very small objects where setup overhead matters
## Performance Benchmarks
@pinojs/redact uses **selective cloning** that provides good performance while maintaining immutability guarantees:
### Performance Results
| Operation Type | @pinojs/redact | fast-redact | Performance Ratio |
|---------------|-------------|-------------|-------------------|
| **Small objects** | ~690ns | ~200ns | ~3.5x slower |
| **Large objects (minimal redaction)** | **~18μs** | ~17μs | **~same performance** |
| **Large objects (wildcards)** | **~48μs** | ~37μs | **~1.3x slower** |
| **No redaction (large objects)** | **~18μs** | ~17μs | **~same performance** |
### Performance Improvements
@pinojs/redact is performance-competitive with fast-redact for large objects.
1. **Selective cloning approach**: Only clones object paths that need redaction
2. **Reference sharing**: Non-redacted properties share original object references
3. **Setup-time optimization**: Path analysis happens once, not per redaction
4. **Memory efficiency**: Dramatically reduced memory usage for typical use cases
### Benchmark Details
**Small Objects (~180 bytes)**:
- @pinojs/redact: **690ns** per operation
- fast-redact: **200ns** per operation
- **Slight setup overhead for small objects**
**Large Objects (~18KB, minimal redaction)**:
- @pinojs/redact: **18μs** per operation
- fast-redact: **17μs** per operation
- Near-identical performance
**Large Objects (~18KB, wildcard patterns)**:
- @pinojs/redact: **48μs** per operation
- fast-redact: **37μs** per operation
- Competitive performance for complex patterns
**Memory Considerations**:
- @pinojs/redact: **Selective reference sharing** (much lower memory usage than before)
- fast-redact: Mutates in-place (lowest memory usage)
- Large objects with few redacted paths now share most references
### When Performance Matters
Choose **fast-redact** when:
- Absolute maximum performance is critical (>100,000 ops/sec)
- Working with very small objects frequently
- Mutation is acceptable and controlled
- Every microsecond counts
Choose **@pinojs/redact** when:
- Immutability is required (with competitive performance)
- Objects are shared across contexts
- Large objects with selective redaction
- Memory efficiency through reference sharing is important
- Safety and functionality are priorities
- Most production applications (performance gap is minimal)
Run benchmarks yourself:
```bash
npm run bench
```
## How Selective Cloning Works
@pinojs/redact uses an innovative **selective cloning** approach that provides immutability guarantees while dramatically improving performance:
### Traditional Approach (before optimization)
```js
// Old approach: Deep clone entire object, then redact
const fullClone = deepClone(originalObject) // Clone everything
redact(fullClone, paths) // Then redact specific paths
```
### Selective Cloning Approach (current)
```js
// New approach: Analyze paths, clone only what's needed
const pathStructure = buildPathStructure(paths) // One-time setup
const selectiveClone = cloneOnlyNeededPaths(obj, pathStructure) // Smart cloning
redact(selectiveClone, paths) // Redact pre-identified paths
```
### Key Innovations
1. **Path Analysis**: Pre-processes redaction paths into an efficient tree structure
2. **Selective Cloning**: Only creates new objects for branches that contain redaction targets
3. **Reference Sharing**: Non-redacted properties maintain exact same object references
4. **Setup Optimization**: Path parsing happens once during redactor creation, not per redaction
### Example: Reference Sharing in Action
```js
const largeConfig = {
database: { /* large config object */ },
api: { /* another large config */ },
secrets: { password: 'hidden', apiKey: 'secret' }
}
const redact = slowRedact({ paths: ['secrets.password'] })
const result = redact(largeConfig)
// Only secrets object is cloned, database and api share original references
console.log(result.database === largeConfig.database) // true - shared reference!
console.log(result.api === largeConfig.api) // true - shared reference!
console.log(result.secrets === largeConfig.secrets) // false - cloned for redaction
```
This approach provides **immutability where it matters** while **sharing references where it's safe**.
## Remove Option
The `remove: true` option provides full compatibility with fast-redact's key removal functionality:
```js
const redact = slowRedact({
paths: ['password', 'secrets.*', 'users.*.credentials'],
remove: true
})
const data = {
username: 'john',
password: 'secret123',
secrets: { apiKey: 'abc', token: 'xyz' },
users: [
{ name: 'Alice', credentials: { password: 'pass1' } },
{ name: 'Bob', credentials: { password: 'pass2' } }
]
}
console.log(redact(data))
// Output: {"username":"john","secrets":{},"users":[{"name":"Alice"},{"name":"Bob"}]}
```
### Remove vs Redact Behavior
| Option | Behavior | Output Example |
|--------|----------|----------------|
| Default (redact) | Replaces values with censor | `{"password":"[REDACTED]"}` |
| `remove: true` | Completely omits keys | `{}` |
### Compatibility Notes
- **Same output as fast-redact**: Identical JSON output when using `remove: true`
- **Wildcard support**: Works with all wildcard patterns (`*`, `users.*`, `items.*.secret`)
- **Array handling**: Array items are set to `undefined` (omitted in JSON output)
- **Nested paths**: Supports deep removal (`users.*.credentials.password`)
- **Serialize compatibility**: Only works with `JSON.stringify` serializer (like fast-redact)
## Testing
```bash
# Run unit tests
npm test
# Run integration tests comparing with fast-redact
npm run test:integration
# Run all tests (unit + integration)
npm run test:all
# Run benchmarks
npm run bench
```
### Test Coverage
- **16 unit tests**: Core functionality and edge cases
- **16 integration tests**: Output compatibility with fast-redact
- **All major features**: Paths, wildcards, serialization, custom censors
- **Performance benchmarks**: Direct comparison with fast-redact
## License
MIT
## Contributing
Pull requests welcome! Please ensure all tests pass and add tests for new features.

View File

@@ -0,0 +1,811 @@
# Vitest core license
Vitest is released under the MIT license:
MIT License
Copyright (c) 2021-Present VoidZero Inc. and Vitest contributors
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.
# Licenses of bundled dependencies
The published Vitest artifact additionally contains code with the following licenses:
BSD-3-Clause, ISC, MIT
# Bundled dependencies:
## @antfu/install-pkg
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu/install-pkg.git
> MIT License
>
> Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
>
> 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.
---------------------------------------
## @bomb.sh/tab
License: MIT
By: Bombshell Authors
Repository: git+https://github.com/bombshell-dev/tab.git
---------------------------------------
## @jridgewell/resolve-uri
License: MIT
By: Justin Ridgewell
Repository: https://github.com/jridgewell/resolve-uri
> Copyright 2019 Justin Ridgewell <jridgewell@google.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.
---------------------------------------
## @jridgewell/sourcemap-codec
License: MIT
By: Justin Ridgewell
Repository: git+https://github.com/jridgewell/sourcemaps.git
> Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
>
> 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.
---------------------------------------
## @jridgewell/trace-mapping
License: MIT
By: Justin Ridgewell
Repository: git+https://github.com/jridgewell/sourcemaps.git
> Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
>
> 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.
---------------------------------------
## @sinonjs/commons
License: BSD-3-Clause
Repository: git+https://github.com/sinonjs/commons.git
> BSD 3-Clause License
>
> Copyright (c) 2018, Sinon.JS
> All rights reserved.
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
>
> * Redistributions of source code must retain the above copyright notice, this
> list of conditions and the following disclaimer.
>
> * Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> * Neither the name of the copyright holder nor the names of its
> contributors may be used to endorse or promote products derived from
> this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------
## @sinonjs/fake-timers
License: BSD-3-Clause
By: Christian Johansen
Repository: git+https://github.com/sinonjs/fake-timers.git
> Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no. All rights reserved.
>
> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------
## acorn
License: MIT
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
Repository: https://github.com/acornjs/acorn.git
> MIT License
>
> Copyright (C) 2012-2022 by various contributors (see AUTHORS)
>
> 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.
---------------------------------------
## acorn-walk
License: MIT
By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine
Repository: https://github.com/acornjs/acorn.git
> MIT License
>
> Copyright (C) 2012-2020 by various contributors (see AUTHORS)
>
> 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.
---------------------------------------
## birpc
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu-collective/birpc.git
> MIT License
>
> Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
>
> 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.
---------------------------------------
## cac
License: MIT
By: egoist
Repository: egoist/cac
> The MIT License (MIT)
>
> Copyright (c) EGOIST <0x142857@gmail.com> (https://github.com/egoist)
>
> 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.
---------------------------------------
## empathic
License: MIT
By: Luke Edwards
Repository: lukeed/empathic
> MIT License
>
> 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.
---------------------------------------
## flatted
License: ISC
By: Andrea Giammarchi
Repository: git+https://github.com/WebReflection/flatted.git
> ISC License
>
> Copyright (c) 2018-2020, Andrea Giammarchi, @WebReflection
>
> Permission to use, copy, modify, and/or distribute this software for any
> purpose with or without fee is hereby granted, provided that the above
> copyright notice and this permission notice appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
> REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
> AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
> INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
> LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
> OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
> PERFORMANCE OF THIS SOFTWARE.
---------------------------------------
## js-tokens
License: MIT
By: Simon Lydell
Repository: lydell/js-tokens
> The MIT License (MIT)
>
> Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Simon Lydell
>
> 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.
---------------------------------------
## kleur
License: MIT
By: Luke Edwards
Repository: lukeed/kleur
> 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.
---------------------------------------
## local-pkg
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu-collective/local-pkg.git
> MIT License
>
> Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
>
> 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.
---------------------------------------
## mime
License: MIT
By: Robert Kieffer
Repository: https://github.com/broofa/mime
> MIT License
>
> Copyright (c) 2023 Robert Kieffer
>
> 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.
---------------------------------------
## mlly
License: MIT
Repository: unjs/mlly
> MIT License
>
> Copyright (c) Pooya Parsa <pooya@pi0.io>
>
> 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.
---------------------------------------
## package-manager-detector
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu-collective/package-manager-detector.git
> MIT License
>
> Copyright (c) 2020-PRESENT Anthony Fu <https://github.com/antfu>
>
> 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.
---------------------------------------
## prompts
License: MIT
By: Terkel Gjervig
Repository: terkelg/prompts
> MIT License
>
> Copyright (c) 2018 Terkel Gjervig Nielsen
>
> 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.
---------------------------------------
## quansync
License: MIT
By: Anthony Fu, 三咲智子 Kevin Deng
Repository: git+https://github.com/quansync-dev/quansync.git
> MIT License
>
> Copyright (c) 2025-PRESENT Anthony Fu <https://github.com/antfu> and Kevin Deng <https://github.com/sxzz>
>
> 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.
---------------------------------------
## sisteransi
License: MIT
By: Terkel Gjervig
Repository: https://github.com/terkelg/sisteransi
> MIT License
>
> Copyright (c) 2018 Terkel Gjervig Nielsen
>
> 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.
---------------------------------------
## strip-literal
License: MIT
By: Anthony Fu
Repository: git+https://github.com/antfu/strip-literal.git
> MIT License
>
> Copyright (c) 2022 Anthony Fu <https://github.com/antfu>
>
> 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.
---------------------------------------
## tinyhighlight
License: MIT
Repository: git+https://github.com/tinylibs/tinyhighlight.git
> # Tinyhighlight core license
>
> MIT License
>
> Copyright (c) 2023 Tinylibs
>
> 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.
>
> # Additionaly Tinyhighlight modifies code with the following licenses:
>
> MIT
>
> ## @babel/highlight
>
> MIT License
>
> Copyright (c) 2014-present Sebastian McKenzie and other contributors
>
> 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.
>
> ## @babel/helper-validator-identifier
>
> MIT License
>
> Copyright (c) 2014-present Sebastian McKenzie and other contributors
>
> 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.
---------------------------------------
## type-detect
License: MIT
By: Jake Luer, Keith Cirkel, David Losert, Aleksey Shvayka, Lucas Fernandes da Costa, Grant Snodgrass, Jeremy Tice, Edward Betts, dvlsg, Amila Welihinda, Jake Champion, Miroslav Bajtoš
Repository: git+ssh://git@github.com/chaijs/type-detect.git
> Copyright (c) 2013 Jake Luer <jake@alogicalparadox.com> (http://alogicalparadox.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.
---------------------------------------
## ufo
License: MIT
Repository: unjs/ufo
> MIT License
>
> Copyright (c) Pooya Parsa <pooya@pi0.io>
>
> 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.
---------------------------------------
## ws
License: MIT
By: Einar Otto Stangvik
Repository: git+https://github.com/websockets/ws.git
> Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
> Copyright (c) 2013 Arnout Kazemier and contributors
> Copyright (c) 2016 Luigi Pinca and contributors
>
> 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,391 @@
import net = require('net');
import tls = require('tls');
import https = require('https');
import http = require('http');
import events = require('events');
import Stream = require('stream');
import WebSocket = require('isomorphic-ws');
import * as connect from 'connect';
type ConstructorOf<Proto, CtorArgs extends any[]> = {
(...args: CtorArgs): Proto;
new(...args: CtorArgs): Proto;
prototype: Proto;
}
export interface UtilsJSONParseOptions {
reviver?: Function;
}
export interface UtilsJSONStringifyOptions {
replacer?: Function;
}
export interface GenerateRequestOptions {
version?: number;
notificationIdNull?: boolean;
generator?: IDGenerator;
}
export declare class Utils {
static request(method: string, params: RequestParamsLike, options?: GenerateRequestOptions): JSONRPCRequest;
static request(method: string, params: RequestParamsLike, id?: JSONRPCIDLike | null | undefined, options?: GenerateRequestOptions): JSONRPCRequest;
static response(error: JSONRPCError | undefined | null, result: JSONRPCResultLike | undefined | null, id: JSONRPCIDLike | null | undefined, version?: number): JSONRPCVersionTwoResponse;
static response(error: JSONRPCError | undefined | null, result: JSONRPCResultLike | undefined | null, id: JSONRPCIDLike | null | undefined, version:2): JSONRPCVersionTwoResponse;
static response(error: JSONRPCError | undefined | null, result: JSONRPCResultLike | undefined | null, id: JSONRPCIDLike | null | undefined, version:1): JSONRPCVersionOneResponse;
static generateId(): string;
static merge(...objs: object[]): object;
static parseStream(stream:Stream, options:UtilsJSONParseOptions, onRequest: (err?:Error, data?:any) => void): void;
static parseBody(stream:Stream, options:UtilsJSONParseOptions, callback: (err?:Error, obj?:any) => void): void;
static getHttpListener(self:http.Server, server:Server): Function;
static isContentType(request:http.IncomingMessage, typ:string): boolean;
static isMethod(request:http.IncomingMessage, method:string): boolean;
static walk(obj:object, key:string, fn: (key:string, value:any) => any): object;
static once<T extends (...args: any[]) => any>(fn: T): T;
static isPlainObject(obj: any): boolean;
static toArray(obj: any): Array<any>;
static toPlainObject(obj: any): object;
static pick(obj: object, keys: string[]): object;
static JSON: UtilsJSON;
static Request: UtilsRequest;
static Response: UtilsResponse;
}
// lowercase Utils
export declare class utils extends Utils {
}
type UtilsJSON = {
parse(str:string, options:UtilsJSONParseOptions | null | undefined, callback: (err?:Error, obj?:object) => void):void;
stringify(obj:object, options:UtilsJSONStringifyOptions | null | undefined, callback: (err?:Error, str?:string) => void):void;
}
type UtilsRequest = {
isBatch(request:any): boolean;
isNotification(request:any): boolean;
isValidVersionTwoRequest(request:any): boolean;
isValidVersionOneRequest(request:any): boolean;
isValidRequest(request:any, version?:number): boolean;
}
type UtilsResponse = {
isValidError(error:any, version?:number): boolean;
isValidResponse(response:any, version?:number): boolean;
}
export type RequestParamsLike = Array<any> | object | undefined;
export interface JSONRPCError {
code: number;
message: string;
data?: object;
}
export type JSONRPCErrorLike = Error | JSONRPCError;
export interface JSONRPCVersionOneRequest {
method: string;
params: Array<any>;
id: JSONRPCIDLike;
}
export interface JSONRPCVersionTwoRequest {
jsonrpc: string;
method: string;
params: RequestParamsLike;
id?: JSONRPCIDLike | null;
}
export type JSONRPCRequest = JSONRPCVersionOneRequest | JSONRPCVersionTwoRequest;
export interface JSONRPCVersionOneResponseWithResult {
result: any;
error: null;
id: any;
}
export interface JSONRPCVersionOneResponseWithError {
result: null;
error: object;
id: any;
}
export type JSONRPCVersionOneResponse = JSONRPCVersionOneResponseWithError | JSONRPCVersionOneResponseWithResult;
export interface JSONRPCVersionTwoResponseWithResult {
jsonrpc: string;
result: any;
id: JSONRPCIDLike | null;
}
export interface JSONRPCVersionTwoResponseWithError {
jsonrpc: string;
error: JSONRPCError;
id: JSONRPCIDLike | null;
}
export type JSONRPCVersionTwoResponse = JSONRPCVersionTwoResponseWithResult | JSONRPCVersionTwoResponseWithError;
export type JSONRPCResponseWithError = JSONRPCVersionOneResponseWithError | JSONRPCVersionTwoResponseWithError;
export type JSONRPCResponseWithResult = JSONRPCVersionOneResponseWithResult | JSONRPCVersionTwoResponseWithResult;
export type JSONRPCResponse = JSONRPCVersionOneResponse | JSONRPCVersionTwoResponse;
export type JSONRPCIDLike = number | string;
export type JSONRPCRequestLike = JSONRPCRequest | string;
export type JSONRPCResultLike = any;
export interface JSONRPCCallbackTypePlain {
(err?: JSONRPCErrorLike | null, result?: JSONRPCResultLike): void
}
export interface JSONRPCCallbackTypeSugared {
(err?: Error | null, error?: JSONRPCErrorLike, result?: JSONRPCResultLike): void
}
type JSONRPCCallbackType = JSONRPCCallbackTypePlain | JSONRPCCallbackTypeSugared;
export interface JSONRPCCallbackTypeBatchPlain {
(err: JSONRPCErrorLike, results?: Array<JSONRPCResultLike>): void
}
export interface JSONRPCCallbackTypeBatchSugared {
(err: Error, errors?: Array<JSONRPCErrorLike>, results?: Array<JSONRPCResultLike>): void
}
type JSONRPCCallbackTypeBatch = JSONRPCCallbackTypeBatchPlain | JSONRPCCallbackTypeBatchSugared;
export interface MethodHandler {
(this:Server, args:RequestParamsLike, callback:JSONRPCCallbackTypePlain): void;
}
export interface MethodHandlerContext {
(this:Server, args:RequestParamsLike, context:object, callback:JSONRPCCallbackTypePlain): void;
}
export type MethodHandlerType = MethodHandlerContext | MethodHandler;
export type MethodOptionsParamsLike = Array<any> | Object | object;
export interface MethodOptions {
handler?: MethodHandlerType;
useContext?: boolean;
params?: MethodOptionsParamsLike;
}
export type MethodExecuteCallbackType = {
(err?: Error | null, result?: JSONRPCResultLike): void
}
type MethodConstructor = ConstructorOf<Method, [options: MethodOptions] | [handler?: MethodHandlerType, options?: MethodOptions]>;
export interface Method {
getHandler(): MethodHandlerType;
setHandler(handler: MethodHandlerType): void;
execute(server: Server, requestParams: RequestParamsLike, callback: MethodExecuteCallbackType): any | Promise<any>;
execute(server: Server, requestParams: RequestParamsLike, context:object, callback: MethodExecuteCallbackType): any | Promise<any>;
}
export declare const Method: MethodConstructor;
// lowercase Method
export type method = Method;
export declare const method: MethodConstructor;
export type MethodLike = Function | Method | Client;
export type ServerRouterFunction = (this: Server, method: string, params: RequestParamsLike) => MethodLike;
export interface ServerOptions {
useContext?: boolean;
params?: MethodOptionsParamsLike;
version?: number;
reviver?: JSONParseReviver;
replacer?: JSONStringifyReplacer;
encoding?: string;
router?: ServerRouterFunction;
methodConstructor?: Function;
maxBatchLength?: number;
}
export type ServerCallCallbackType = {
(err?: JSONRPCResponseWithError | null, result?: JSONRPCResponseWithResult): void
}
export interface MethodMap { [methodName:string]: Method }
type ServerConstructor = ConstructorOf<Server, [methods?: {[methodName: string]: MethodLike}, options?: ServerOptions]> & {
errors: {[errorName: string]: number};
errorMessages: {[errorMessage: string]: string};
interfaces: {[interfaces: string]: Function};
}
export interface Server extends events.EventEmitter {
_methods: MethodMap;
options: ServerOptions;
errorMessages: {[errorMessage: string]: string};
http(options?: HttpServerOptions): HttpServer;
https(options?: HttpsServerOptions): HttpsServer;
tcp(options?: TcpServerOptions): TcpServer;
tls(options?: TlsServerOptions): TlsServer;
websocket(options?: WebsocketServerOptions): WebsocketServer;
middleware(options?: MiddlewareServerOptions): connect.HandleFunction;
method(name: string, definition: MethodLike): void;
methods(methods: {[methodName: string]: MethodLike}): void;
hasMethod(name: string): boolean;
removeMethod(name: string): void;
getMethod(name: string): MethodLike;
error(code?: number, message?: string, data?: object): JSONRPCError;
call(request: JSONRPCRequestLike | Array<JSONRPCRequestLike>, originalCallback?: ServerCallCallbackType): void;
call(request: JSONRPCRequestLike | Array<JSONRPCRequestLike>, context: object, originalCallback?: ServerCallCallbackType): void;
callp(request: JSONRPCRequestLike | Array<JSONRPCRequestLike>, context?: object): Promise<JSONRPCResultLike>;
}
export declare const Server: ServerConstructor;
// lowercase Server
export type server = Server;
export declare const server: ServerConstructor;
export interface MiddlewareServerOptions extends ServerOptions {
end?: boolean;
}
export interface HttpServerOptions extends ServerOptions {
}
declare class HttpServer extends http.Server {
constructor(server: Server, options?: HttpServerOptions);
}
export interface HttpsServerOptions extends ServerOptions, https.ServerOptions {
}
declare class HttpsServer extends https.Server {
constructor(server: Server, options?: HttpsServerOptions);
}
export interface TcpServerOptions extends ServerOptions {
}
declare class TcpServer extends net.Server {
constructor(server: Server, options?: TcpServerOptions);
}
export interface TlsServerOptions extends tls.TlsOptions {
}
declare class TlsServer extends tls.Server {
constructor(server: Server, options?: TlsServerOptions);
}
export interface WebsocketServerOptions extends ServerOptions, WebSocket.ServerOptions {
wss?: WebSocket.Server;
}
declare class WebsocketServer {
constructor(server: Server, options?: WebsocketServerOptions);
}
type JSONParseReviver = (key: string, value: any) => any;
type JSONStringifyReplacer = (key: string, value: any) => any;
type IDGenerator = () => JSONRPCIDLike;
export interface ClientOptions {
version?: number;
reviver?: JSONParseReviver;
replacer?: JSONStringifyReplacer;
generator?: IDGenerator;
notificationIdNull?: boolean;
}
export interface HttpClientOptions extends ClientOptions, http.RequestOptions {
}
declare class HttpClient extends Client {
constructor(options?: HttpClientOptions);
}
export interface TlsClientOptions extends ClientOptions, tls.ConnectionOptions {
}
declare class TlsClient extends Client {
constructor(options?: TlsClientOptions);
}
export interface TcpClientOptions extends ClientOptions, net.TcpSocketConnectOpts {
}
declare class TcpClient extends Client {
constructor(options?: TcpClientOptions);
}
export interface HttpsClientOptions extends ClientOptions, https.RequestOptions {
}
declare class HttpsClient extends Client {
constructor(options?: HttpsClientOptions);
}
export interface WebsocketClientOptions extends ClientOptions {
url?: string;
ws?: WebSocket;
timeout?: number;
}
declare class WebsocketClient extends Client {
constructor(options?: WebsocketClientOptions);
}
export type BrowserClientCallServerCallback = (err?: Error | null, response?: string) => void;
export type BrowserClientCallServerFunction = (request: string, callback: BrowserClientCallServerCallback) => void;
declare class BrowserClient {
constructor(callServer: BrowserClientCallServerFunction, options?: ClientOptions);
request(method: string, params: RequestParamsLike, id?: JSONRPCIDLike | null, callback?: JSONRPCCallbackType): JSONRPCRequest;
request(method: string, params: RequestParamsLike, callback?: JSONRPCCallbackType): JSONRPCRequest;
request(method: Array<JSONRPCRequestLike>, callback: JSONRPCCallbackTypeBatch): Array<JSONRPCRequest>;
}
type ClientConstructor = ConstructorOf<Client, [options: ClientOptions] | [server: Server, options?: ClientOptions]> & {
http(options?: HttpClientOptions): HttpClient;
https(options?: HttpsClientOptions): HttpsClient;
tcp(options?: TcpClientOptions): TcpClient;
tls(options?: TlsClientOptions): TlsClient;
websocket(options?: WebsocketClientOptions): WebsocketClient;
browser(callServer: BrowserClientCallServerFunction, options?: ClientOptions): BrowserClient;
}
export interface Client extends events.EventEmitter {
request(method: string, params: RequestParamsLike, id?: JSONRPCIDLike | null, callback?: JSONRPCCallbackType): JSONRPCRequest;
request(method: string, params: RequestParamsLike, callback?: JSONRPCCallbackType): JSONRPCRequest;
request(method: Array<JSONRPCRequestLike>, callback: JSONRPCCallbackTypeBatch): Array<JSONRPCRequest>;
}
export declare const Client: ClientConstructor;
// lowercase Client
export type client = Client;
export declare const client: ClientConstructor

View File

@@ -0,0 +1,35 @@
{
"for + if": {
"name": "for + if",
"browser": "Chrome Mobile 55.0.2883 (Android 6.0.0)",
"suite": "itar-short",
"hz": 235578.4947828406,
"success": true,
"fastest": true,
"rme": 0.03974005580662533,
"rhz": 1,
"sampleSize": 190
},
"while + if": {
"name": "while + if",
"browser": "Chrome Mobile 55.0.2883 (Android 6.0.0)",
"suite": "itar-short",
"hz": 225073.11912308275,
"success": true,
"fastest": false,
"rme": 0.029700688684889318,
"rhz": 0.9554060498202867,
"sampleSize": 193
},
"array join": {
"name": "array join",
"browser": "Chrome Mobile 55.0.2883 (Android 6.0.0)",
"suite": "itar-short",
"hz": 221468.15872985727,
"success": true,
"fastest": false,
"rme": 0.020249883449366055,
"rhz": 0.9401034628988931,
"sampleSize": 196
}
}

View File

@@ -0,0 +1,141 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const util = __importStar(require("../core/util.cjs"));
const error = () => {
const Sizable = {
string: { unit: "کاراکتر", verb: "داشته باشد" },
file: { unit: "بایت", verb: "داشته باشد" },
array: { unit: "آیتم", verb: "داشته باشد" },
set: { unit: "آیتم", verb: "داشته باشد" },
};
function getSizing(origin) {
return Sizable[origin] ?? null;
}
const FormatDictionary = {
regex: "ورودی",
email: "آدرس ایمیل",
url: "URL",
emoji: "ایموجی",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "تاریخ و زمان ایزو",
date: "تاریخ ایزو",
time: "زمان ایزو",
duration: "مدت زمان ایزو",
ipv4: "IPv4 آدرس",
ipv6: "IPv6 آدرس",
cidrv4: "IPv4 دامنه",
cidrv6: "IPv6 دامنه",
base64: "base64-encoded رشته",
base64url: "base64url-encoded رشته",
json_string: "JSON رشته",
e164: "E.164 عدد",
jwt: "JWT",
template_literal: "ورودی",
};
const TypeDictionary = {
nan: "NaN",
number: "عدد",
array: "آرایه",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `ورودی نامعتبر: می‌بایست instanceof ${issue.expected} می‌بود، ${received} دریافت شد`;
}
return `ورودی نامعتبر: می‌بایست ${expected} می‌بود، ${received} دریافت شد`;
}
case "invalid_value":
if (issue.values.length === 1) {
return `ورودی نامعتبر: می‌بایست ${util.stringifyPrimitive(issue.values[0])} می‌بود`;
}
return `گزینه نامعتبر: می‌بایست یکی از ${util.joinValues(issue.values, "|")} می‌بود`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing) {
return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} ${sizing.unit ?? "عنصر"} باشد`;
}
return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} باشد`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} ${sizing.unit} باشد`;
}
return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} باشد`;
}
case "invalid_format": {
const _issue = issue;
if (_issue.format === "starts_with") {
return `رشته نامعتبر: باید با "${_issue.prefix}" شروع شود`;
}
if (_issue.format === "ends_with") {
return `رشته نامعتبر: باید با "${_issue.suffix}" تمام شود`;
}
if (_issue.format === "includes") {
return `رشته نامعتبر: باید شامل "${_issue.includes}" باشد`;
}
if (_issue.format === "regex") {
return `رشته نامعتبر: باید با الگوی ${_issue.pattern} مطابقت داشته باشد`;
}
return `${FormatDictionary[_issue.format] ?? issue.format} نامعتبر`;
}
case "not_multiple_of":
return `عدد نامعتبر: باید مضرب ${issue.divisor} باشد`;
case "unrecognized_keys":
return `کلید${issue.keys.length > 1 ? "های" : ""} ناشناس: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `کلید ناشناس در ${issue.origin}`;
case "invalid_union":
return `ورودی نامعتبر`;
case "invalid_element":
return `مقدار نامعتبر در ${issue.origin}`;
default:
return `ورودی نامعتبر`;
}
};
};
function default_1() {
return {
localeError: error(),
};
}
module.exports = exports.default;

View File

@@ -0,0 +1,209 @@
'use strict';
const {Duplex} = require('stream');
class Pump {
constructor(iterator, readable) {
this.iterator = iterator;
this.readable = readable;
this.done = false;
}
start() {
if (this.done) return Promise.resolve();
for (;;) {
const item = this.iterator.next();
if (item.done) return Promise.resolve();
if (!this.readable.push(item.value)) break;
}
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
resume() {
if (!this.resolve) return;
for (;;) {
const item = this.iterator.next();
if (item.done) {
this.done = true;
this.resolve();
return;
}
if (!this.readable.push(item.value)) break;
}
}
}
function* dump(value, options, processed) {
if (!processed) {
if (typeof value?.toJSON == 'function') {
value = value.toJSON('');
}
if (options.replacer) {
value = options.replacer('', value);
}
}
switch (typeof value) {
case 'function':
case 'symbol':
case 'undefined':
return;
case 'number':
if (isNaN(value) || !isFinite(value)) {
yield {name: 'nullValue', value: null};
}
value = String(value);
if (options.streamNumbers) {
yield {name: 'startNumber'};
yield {name: 'numberChunk', value};
yield {name: 'endNumber'};
}
if (options.packNumbers) {
yield {name: 'numberValue', value};
}
return;
case 'string':
if (options.streamStrings) {
yield {name: 'startString'};
yield {name: 'stringChunk', value};
yield {name: 'endString'};
}
if (options.packStrings) {
yield {name: 'stringValue', value};
}
return;
case 'boolean':
yield value ? {name: 'trueValue', value: true} : {name: 'falseValue', value: false};
return;
case 'object':
break;
default:
return; // skip anything else
}
// null
if (value === null) {
yield {name: 'nullValue', value: null};
return;
}
// Array
if (Array.isArray(value)) {
yield {name: 'startArray'};
for (let i = 0; i < value.length; ++i) {
let v = value[i];
if (typeof v?.toJSON == 'function') {
v = v.toJSON(String(i));
}
if (options.replacer) {
v = options.replacer(String(i), v);
}
switch (typeof v) {
case 'function':
case 'symbol':
case 'undefined':
v = null; // force null
break;
}
yield* dump(v, options, true);
}
yield {name: 'endArray'};
return;
}
// Object
yield {name: 'startObject'};
for (let [k, v] of Object.entries(value)) {
if (options.dict && options.dict[k] !== 1) continue;
if (typeof v?.toJSON == 'function') {
v = v.toJSON(k);
}
if (options.replacer) {
v = options.replacer(k, v);
}
switch (typeof v) {
case 'function':
case 'symbol':
case 'undefined':
continue;
}
if (options.streamKeys) {
yield {name: 'startKey'};
yield {name: 'stringChunk', value: k};
yield {name: 'endKey'};
}
if (options.packKeys) {
yield {name: 'keyValue', value: k};
}
yield* dump(v, options, true);
}
yield {name: 'endObject'};
}
const kOptions = Symbol('options'),
kPump = Symbol('pump');
class Disassembler extends Duplex {
static make(options) {
return new Disassembler(options);
}
constructor(options) {
super(Object.assign({}, options, {writableObjectMode: true, readableObjectMode: true}));
const opt = {packKeys: true, packStrings: true, packNumbers: true, streamKeys: true, streamStrings: true, streamNumbers: true};
if (options) {
'packValues' in options && (opt.packKeys = opt.packStrings = opt.packNumbers = options.packValues);
'packKeys' in options && (opt.packKeys = options.packKeys);
'packStrings' in options && (opt.packStrings = options.packStrings);
'packNumbers' in options && (opt.packNumbers = options.packNumbers);
'streamValues' in options && (opt.streamKeys = opt.streamStrings = opt.streamNumbers = options.streamValues);
'streamKeys' in options && (opt.streamKeys = options.streamKeys);
'streamStrings' in options && (opt.streamStrings = options.streamStrings);
'streamNumbers' in options && (opt.streamNumbers = options.streamNumbers);
if (typeof options.replacer == 'function') {
opt.replacer = options.replacer;
} else if (Array.isArray(options.replacer)) {
opt.dict = options.replacer.reduce((acc, k) => ((acc[k] = 1), acc), {});
}
}
!opt.packKeys && (opt.streamKeys = true);
!opt.packStrings && (opt.streamStrings = true);
!opt.packNumbers && (opt.streamNumbers = true);
this[kOptions] = opt;
}
_read() {
this[kPump]?.resume();
}
_write(chunk, _, callback) {
const iterator = dump(chunk, this[kOptions]),
pump = (this[kPump] = new Pump(iterator, this));
pump.start().then(
() => ((this[kPump] = null), callback()),
error => ((this[kPump] = null), callback(error))
);
}
_final(callback) {
this.push(null);
callback();
}
}
Disassembler.disassembler = Disassembler.make;
Disassembler.make.Constructor = Disassembler;
module.exports = Disassembler;
module.exports.dump = dump;

View File

@@ -0,0 +1,10 @@
const MAX_PATTERN_LENGTH = 1024 * 64;
export const assertValidPattern = (pattern) => {
if (typeof pattern !== 'string') {
throw new TypeError('invalid pattern');
}
if (pattern.length > MAX_PATTERN_LENGTH) {
throw new TypeError('pattern is too long');
}
};
//# sourceMappingURL=assert-valid-pattern.js.map

View File

@@ -0,0 +1,429 @@
<h1 align="center">
<img width="250" src="https://jaredwray.com/images/keyv.svg" alt="keyv">
<br>
<br>
</h1>
> Simple key-value storage with support for multiple backends
[![build](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml)
[![codecov](https://codecov.io/gh/jaredwray/keyv/branch/main/graph/badge.svg?token=bRzR3RyOXZ)](https://codecov.io/gh/jaredwray/keyv)
[![npm](https://img.shields.io/npm/dm/keyv.svg)](https://www.npmjs.com/package/keyv)
[![npm](https://img.shields.io/npm/v/keyv.svg)](https://www.npmjs.com/package/keyv)
Keyv provides a consistent interface for key-value storage across multiple backends via storage adapters. It supports TTL based expiry, making it suitable as a cache or a persistent key-value store.
## Features
There are a few existing modules similar to Keyv, however Keyv is different because it:
- Isn't bloated
- Has a simple Promise based API
- Suitable as a TTL based cache or persistent key-value store
- [Easily embeddable](#add-cache-support-to-your-module) inside another module
- Works with any storage that implements the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) API
- Handles all JSON types plus `Buffer`
- Supports namespaces
- Wide range of [**efficient, well tested**](#official-storage-adapters) storage adapters
- Connection errors are passed through (db failures won't kill your app)
- Supports the current active LTS version of Node.js or higher
## Usage
Install Keyv.
```
npm install --save keyv
```
By default everything is stored in memory, you can optionally also install a storage adapter.
```
npm install --save @keyv/redis
npm install --save @keyv/mongo
npm install --save @keyv/sqlite
npm install --save @keyv/postgres
npm install --save @keyv/mysql
npm install --save @keyv/etcd
```
Create a new Keyv instance, passing your connection string if applicable. Keyv will automatically load the correct storage adapter.
```js
const Keyv = require('keyv');
// One of the following
const keyv = new Keyv();
const keyv = new Keyv('redis://user:pass@localhost:6379');
const keyv = new Keyv('mongodb://user:pass@localhost:27017/dbname');
const keyv = new Keyv('sqlite://path/to/database.sqlite');
const keyv = new Keyv('postgresql://user:pass@localhost:5432/dbname');
const keyv = new Keyv('mysql://user:pass@localhost:3306/dbname');
const keyv = new Keyv('etcd://localhost:2379');
// Handle DB connection errors
keyv.on('error', err => console.log('Connection Error', err));
await keyv.set('foo', 'expires in 1 second', 1000); // true
await keyv.set('foo', 'never expires'); // true
await keyv.get('foo'); // 'never expires'
await keyv.delete('foo'); // true
await keyv.clear(); // undefined
```
### Namespaces
You can namespace your Keyv instance to avoid key collisions and allow you to clear only a certain namespace while using the same database.
```js
const users = new Keyv('redis://user:pass@localhost:6379', { namespace: 'users' });
const cache = new Keyv('redis://user:pass@localhost:6379', { namespace: 'cache' });
await users.set('foo', 'users'); // true
await cache.set('foo', 'cache'); // true
await users.get('foo'); // 'users'
await cache.get('foo'); // 'cache'
await users.clear(); // undefined
await users.get('foo'); // undefined
await cache.get('foo'); // 'cache'
```
### Custom Serializers
Keyv uses [`json-buffer`](https://github.com/dominictarr/json-buffer) for data serialization to ensure consistency across different backends.
You can optionally provide your own serialization functions to support extra data types or to serialize to something other than JSON.
```js
const keyv = new Keyv({ serialize: JSON.stringify, deserialize: JSON.parse });
```
**Warning:** Using custom serializers means you lose any guarantee of data consistency. You should do extensive testing with your serialisation functions and chosen storage engine.
## Official Storage Adapters
The official storage adapters are covered by [over 150 integration tests](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml) to guarantee consistent behaviour. They are lightweight, efficient wrappers over the DB clients making use of indexes and native TTLs where available.
Database | Adapter | Native TTL
---|---|---
Redis | [@keyv/redis](https://github.com/jaredwray/keyv/tree/master/packages/redis) | Yes
MongoDB | [@keyv/mongo](https://github.com/jaredwray/keyv/tree/master/packages/mongo) | Yes
SQLite | [@keyv/sqlite](https://github.com/jaredwray/keyv/tree/master/packages/sqlite) | No
PostgreSQL | [@keyv/postgres](https://github.com/jaredwray/keyv/tree/master/packages/postgres) | No
MySQL | [@keyv/mysql](https://github.com/jaredwray/keyv/tree/master/packages/mysql) | No
Etcd | [@keyv/etcd](https://github.com/jaredwray/keyv/tree/master/packages/etcd) | Yes
Memcache | [@keyv/memcache](https://github.com/jaredwray/keyv/tree/master/packages/memcache) | Yes
## Third-party Storage Adapters
You can also use third-party storage adapters or build your own. Keyv will wrap these storage adapters in TTL functionality and handle complex types internally.
```js
const Keyv = require('keyv');
const myAdapter = require('./my-storage-adapter');
const keyv = new Keyv({ store: myAdapter });
```
Any store that follows the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) api will work.
```js
new Keyv({ store: new Map() });
```
For example, [`quick-lru`](https://github.com/sindresorhus/quick-lru) is a completely unrelated module that implements the Map API.
```js
const Keyv = require('keyv');
const QuickLRU = require('quick-lru');
const lru = new QuickLRU({ maxSize: 1000 });
const keyv = new Keyv({ store: lru });
```
The following are third-party storage adapters compatible with Keyv:
- [quick-lru](https://github.com/sindresorhus/quick-lru) - Simple "Least Recently Used" (LRU) cache
- [keyv-file](https://github.com/zaaack/keyv-file) - File system storage adapter for Keyv
- [keyv-dynamodb](https://www.npmjs.com/package/keyv-dynamodb) - DynamoDB storage adapter for Keyv
- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
- [keyv-firestore ](https://github.com/goto-bus-stop/keyv-firestore) Firebase Cloud Firestore adapter for Keyv
- [keyv-mssql](https://github.com/pmorgan3/keyv-mssql) - Microsoft Sql Server adapter for Keyv
- [keyv-azuretable](https://github.com/howlowck/keyv-azuretable) - Azure Table Storage/API adapter for Keyv
- [keyv-arango](https://github.com/TimMikeladze/keyv-arango) - ArangoDB storage adapter for Keyv
- [keyv-momento](https://github.com/momentohq/node-keyv-adaptor/) - Momento storage adapter for Keyv
## Add Cache Support to your Module
Keyv is designed to be easily embedded into other modules to add cache support. The recommended pattern is to expose a `cache` option in your modules options which is passed through to Keyv. Caching will work in memory by default and users have the option to also install a Keyv storage adapter and pass in a connection string, or any other storage that implements the `Map` API.
You should also set a namespace for your module so you can safely call `.clear()` without clearing unrelated app data.
Inside your module:
```js
class AwesomeModule {
constructor(opts) {
this.cache = new Keyv({
uri: typeof opts.cache === 'string' && opts.cache,
store: typeof opts.cache !== 'string' && opts.cache,
namespace: 'awesome-module'
});
}
}
```
Now it can be consumed like this:
```js
const AwesomeModule = require('awesome-module');
// Caches stuff in memory by default
const awesomeModule = new AwesomeModule();
// After npm install --save keyv-redis
const awesomeModule = new AwesomeModule({ cache: 'redis://localhost' });
// Some third-party module that implements the Map API
const awesomeModule = new AwesomeModule({ cache: some3rdPartyStore });
```
## Compression
Keyv supports `gzip` and `brotli` compression. To enable compression, pass the `compress` option to the constructor.
```js
const KeyvGzip = require('@keyv/compress-gzip');
const Keyv = require('keyv');
const keyvGzip = new KeyvGzip();
const keyv = new Keyv({ compression: KeyvGzip });
```
You can also pass a custom compression function to the `compression` option. Following the pattern of the official compression adapters.
### Want to build your own?
Great! Keyv is designed to be easily extended. You can build your own compression adapter by following the pattern of the official compression adapters based on this interface:
```typescript
interface CompressionAdapter {
async compress(value: any, options?: any);
async decompress(value: any, options?: any);
async serialize(value: any);
async deserialize(value: any);
}
```
In addition to the interface, you can test it with our compression test suite using @keyv/test-suite:
```js
const {keyvCompresstionTests} = require('@keyv/test-suite');
const KeyvGzip = require('@keyv/compress-gzip');
keyvCompresstionTests(test, new KeyvGzip());
```
## API
### new Keyv([uri], [options])
Returns a new Keyv instance.
The Keyv instance is also an `EventEmitter` that will emit an `'error'` event if the storage adapter connection fails.
### uri
Type: `String`<br>
Default: `undefined`
The connection string URI.
Merged into the options object as options.uri.
### options
Type: `Object`
The options object is also passed through to the storage adapter. Check your storage adapter docs for any extra options.
#### options.namespace
Type: `String`<br>
Default: `'keyv'`
Namespace for the current instance.
#### options.ttl
Type: `Number`<br>
Default: `undefined`
Default TTL. Can be overridden by specififying a TTL on `.set()`.
#### options.compression
Type: `@keyv/compress-<compression_package_name>`<br>
Default: `undefined`
Compression package to use. See [Compression](#compression) for more details.
#### options.serialize
Type: `Function`<br>
Default: `JSONB.stringify`
A custom serialization function.
#### options.deserialize
Type: `Function`<br>
Default: `JSONB.parse`
A custom deserialization function.
#### options.store
Type: `Storage adapter instance`<br>
Default: `new Map()`
The storage adapter instance to be used by Keyv.
#### options.adapter
Type: `String`<br>
Default: `undefined`
Specify an adapter to use. e.g `'redis'` or `'mongodb'`.
### Instance
Keys must always be strings. Values can be of any type.
#### .set(key, value, [ttl])
Set a value.
By default keys are persistent. You can set an expiry TTL in milliseconds.
Returns a promise which resolves to `true`.
#### .get(key, [options])
Returns a promise which resolves to the retrieved value.
##### options.raw
Type: `Boolean`<br>
Default: `false`
If set to true the raw DB object Keyv stores internally will be returned instead of just the value.
This contains the TTL timestamp.
#### .delete(key)
Deletes an entry.
Returns a promise which resolves to `true` if the key existed, `false` if not.
#### .clear()
Delete all entries in the current namespace.
Returns a promise which is resolved when the entries have been cleared.
#### .iterator()
Iterate over all entries of the current namespace.
Returns a iterable that can be iterated by for-of loops. For example:
```js
// please note that the "await" keyword should be used here
for await (const [key, value] of this.keyv.iterator()) {
console.log(key, value);
};
```
# How to Contribute
In this section of the documentation we will cover:
1) How to set up this repository locally
2) How to get started with running commands
3) How to contribute changes using Pull Requests
## Dependencies
This package requires the following dependencies to run:
1) [Yarn V1](https://yarnpkg.com/getting-started/install)
3) [Docker](https://docs.docker.com/get-docker/)
## Setting up your workspace
To contribute to this repository, start by setting up this project locally:
1) Fork this repository into your Git account
2) Clone the forked repository to your local directory using `git clone`
3) Install any of the above missing dependencies
## Launching the project
Once the project is installed locally, you are ready to start up its services:
1) Ensure that your Docker service is running.
2) From the root directory of your project, run the `yarn` command in the command prompt to install yarn.
3) Run the `yarn bootstrap` command to install any necessary dependencies.
4) Run `yarn test:services:start` to start up this project's Docker container. The container will launch all services within your workspace.
## Available Commands
Once the project is running, you can execute a variety of commands. The root workspace and each subpackage contain a `package.json` file with a `scripts` field listing all the commands that can be executed from that directory. This project also supports native `yarn`, and `docker` commands.
Here, we'll cover the primary commands that can be executed from the root directory. Unless otherwise noted, these commands can also be executed from a subpackage. If executed from a subpackage, they will only affect that subpackage, rather than the entire workspace.
### `yarn`
The `yarn` command installs yarn in the workspace.
### `yarn bootstrap`
The `yarn bootstrap` command installs all dependencies in the workspace.
### `yarn test:services:start`
The `yarn test:services:start` command starts up the project's Docker container, launching all services in the workspace. This command must be executed from the root directory.
### `yarn test:services:stop`
The `yarn test:services:stop` command brings down the project's Docker container, halting all services. This command must be executed from the root directory.
### `yarn test`
The `yarn test` command runs all tests in the workspace.
### `yarn clean`
The `yarn clean` command removes yarn and all dependencies installed by yarn. After executing this command, you must repeat the steps in *Setting up your workspace* to rebuild your workspace.
## Contributing Changes
Now that you've set up your workspace, you're ready to contribute changes to the `keyv` repository.
1) Make any changes that you would like to contribute in your local workspace.
2) After making these changes, ensure that the project's tests still pass by executing the `yarn test` command in the root directory.
3) Commit your changes and push them to your forked repository.
4) Navigate to the original `keyv` repository and go the *Pull Requests* tab.
5) Click the *New pull request* button, and open a pull request for the branch in your repository that contains your changes.
6) Once your pull request is created, ensure that all checks have passed and that your branch has no conflicts with the base branch. If there are any issues, resolve these changes in your local repository, and then commit and push them to git.
7) Similarly, respond to any reviewer comments or requests for changes by making edits to your local repository and pushing them to Git.
8) Once the pull request has been reviewed, those with write access to the branch will be able to merge your changes into the `keyv` repository.
If you need more information on the steps to create a pull request, you can find a detailed walkthrough in the [Github documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)
## License
MIT © Jared Wray

View File

@@ -0,0 +1,22 @@
var REACT_ELEMENT_TYPE;
function _createRawReactElement(e, r, E, l) {
REACT_ELEMENT_TYPE || (REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol["for"] && Symbol["for"]("react.element") || 60103);
var o = e && e.defaultProps,
n = arguments.length - 3;
if (r || 0 === n || (r = {
children: void 0
}), 1 === n) r.children = l;else if (n > 1) {
for (var t = Array(n), f = 0; f < n; f++) t[f] = arguments[f + 3];
r.children = t;
}
if (r && o) for (var i in o) void 0 === r[i] && (r[i] = o[i]);else r || (r = o || {});
return {
$$typeof: REACT_ELEMENT_TYPE,
type: e,
key: void 0 === E ? null : "" + E,
ref: null,
props: r,
_owner: null
};
}
export { _createRawReactElement as default };

View File

@@ -0,0 +1,12 @@
import Errors from './errors'
export default MockErrors
declare namespace MockErrors {
/** The request does not match any registered mock dispatches. */
export class MockNotMatchedError extends Errors.UndiciError {
constructor (message?: string)
name: 'MockNotMatchedError'
code: 'UND_MOCK_ERR_MOCK_NOT_MATCHED'
}
}

View File

@@ -0,0 +1,116 @@
import type { $ZodStringFormats } from "../core/checks.js";
import type * as errors from "../core/errors.js";
import * as util from "../core/util.js";
const error: () => errors.$ZodErrorMap = () => {
const Sizable: Record<string, { unit: string; verb: string }> = {
string: { unit: "caràcters", verb: "contenir" },
file: { unit: "bytes", verb: "contenir" },
array: { unit: "elements", verb: "contenir" },
set: { unit: "elements", verb: "contenir" },
};
function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}
const FormatDictionary: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "entrada",
email: "adreça electrònica",
url: "URL",
emoji: "emoji",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "data i hora ISO",
date: "data ISO",
time: "hora ISO",
duration: "durada ISO",
ipv4: "adreça IPv4",
ipv6: "adreça IPv6",
cidrv4: "rang IPv4",
cidrv6: "rang IPv6",
base64: "cadena codificada en base64",
base64url: "cadena codificada en base64url",
json_string: "cadena JSON",
e164: "número E.164",
jwt: "JWT",
template_literal: "entrada",
};
const TypeDictionary: {
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
} = {
nan: "NaN",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `Tipus invàlid: s'esperava instanceof ${issue.expected}, s'ha rebut ${received}`;
}
return `Tipus invàlid: s'esperava ${expected}, s'ha rebut ${received}`;
}
case "invalid_value":
if (issue.values.length === 1) return `Valor invàlid: s'esperava ${util.stringifyPrimitive(issue.values[0])}`;
return `Opció invàlida: s'esperava una de ${util.joinValues(issue.values, " o ")}`;
case "too_big": {
const adj = issue.inclusive ? "com a màxim" : "menys de";
const sizing = getSizing(issue.origin);
if (sizing)
return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} contingués ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "elements"}`;
return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} fos ${adj} ${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? "com a mínim" : "més de";
const sizing = getSizing(issue.origin);
if (sizing) {
return `Massa petit: s'esperava que ${issue.origin} contingués ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
}
return `Massa petit: s'esperava que ${issue.origin} fos ${adj} ${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") {
return `Format invàlid: ha de començar amb "${_issue.prefix}"`;
}
if (_issue.format === "ends_with") return `Format invàlid: ha d'acabar amb "${_issue.suffix}"`;
if (_issue.format === "includes") return `Format invàlid: ha d'incloure "${_issue.includes}"`;
if (_issue.format === "regex") return `Format invàlid: ha de coincidir amb el patró ${_issue.pattern}`;
return `Format invàlid per a ${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `Número invàlid: ha de ser múltiple de ${issue.divisor}`;
case "unrecognized_keys":
return `Clau${issue.keys.length > 1 ? "s" : ""} no reconeguda${issue.keys.length > 1 ? "s" : ""}: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `Clau invàlida a ${issue.origin}`;
case "invalid_union":
return "Entrada invàlida"; // Could also be "Tipus d'unió invàlid" but "Entrada invàlida" is more general
case "invalid_element":
return `Element invàlid a ${issue.origin}`;
default:
return `Entrada invàlida`;
}
};
};
export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,4 @@
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"mixed", [], import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,6 @@
function _overload_yield(value, /** 0: await 1: delegate */ kind) {
this.v = value;
this.k = kind;
}
export { _overload_yield as _ };

View File

@@ -0,0 +1,176 @@
/// <reference types="node" resolution-mode="require"/>
/**
* A class representing the Node.js implementation of Hfs.
* @implements {HfsImpl}
*/
export class NodeHfsImpl implements HfsImpl {
/**
* Creates a new instance.
* @param {object} [options] The options for the instance.
* @param {Fsp} [options.fsp] The file system module to use.
*/
constructor({ fsp }?: {
fsp?: Fsp;
});
/**
* Reads a file and returns the contents as an Uint8Array.
* @param {string|URL} filePath The path to the file to read.
* @returns {Promise<Uint8Array|undefined>} A promise that resolves with the contents
* of the file or undefined if the file doesn't exist.
* @throws {Error} If the file cannot be read.
* @throws {TypeError} If the file path is not a string.
*/
bytes(filePath: string | URL): Promise<Uint8Array | undefined>;
/**
* Writes a value to a file. If the value is a string, UTF-8 encoding is used.
* @param {string|URL} filePath The path to the file to write.
* @param {Uint8Array} contents The contents to write to the
* file.
* @returns {Promise<void>} A promise that resolves when the file is
* written.
* @throws {TypeError} If the file path is not a string.
* @throws {Error} If the file cannot be written.
*/
write(filePath: string | URL, contents: Uint8Array): Promise<void>;
/**
* Appends a value to a file. If the value is a string, UTF-8 encoding is used.
* @param {string|URL} filePath The path to the file to append to.
* @param {Uint8Array} contents The contents to append to the
* file.
* @returns {Promise<void>} A promise that resolves when the file is
* written.
* @throws {TypeError} If the file path is not a string.
* @throws {Error} If the file cannot be appended to.
*/
append(filePath: string | URL, contents: Uint8Array): Promise<void>;
/**
* Checks if a file exists.
* @param {string|URL} filePath The path to the file to check.
* @returns {Promise<boolean>} A promise that resolves with true if the
* file exists or false if it does not.
* @throws {Error} If the operation fails with a code other than ENOENT.
*/
isFile(filePath: string | URL): Promise<boolean>;
/**
* Checks if a directory exists.
* @param {string|URL} dirPath The path to the directory to check.
* @returns {Promise<boolean>} A promise that resolves with true if the
* directory exists or false if it does not.
* @throws {Error} If the operation fails with a code other than ENOENT.
*/
isDirectory(dirPath: string | URL): Promise<boolean>;
/**
* Creates a directory recursively.
* @param {string|URL} dirPath The path to the directory to create.
* @returns {Promise<void>} A promise that resolves when the directory is
* created.
*/
createDirectory(dirPath: string | URL): Promise<void>;
/**
* Deletes a file or empty directory.
* @param {string|URL} fileOrDirPath The path to the file or directory to
* delete.
* @returns {Promise<boolean>} A promise that resolves when the file or
* directory is deleted, true if the file or directory is deleted, false
* if the file or directory does not exist.
* @throws {TypeError} If the file or directory path is not a string.
* @throws {Error} If the file or directory cannot be deleted.
*/
delete(fileOrDirPath: string | URL): Promise<boolean>;
/**
* Deletes a file or directory recursively.
* @param {string|URL} fileOrDirPath The path to the file or directory to
* delete.
* @returns {Promise<boolean>} A promise that resolves when the file or
* directory is deleted, true if the file or directory is deleted, false
* if the file or directory does not exist.
* @throws {TypeError} If the file or directory path is not a string.
* @throws {Error} If the file or directory cannot be deleted.
*/
deleteAll(fileOrDirPath: string | URL): Promise<boolean>;
/**
* Returns a list of directory entries for the given path.
* @param {string|URL} dirPath The path to the directory to read.
* @returns {AsyncIterable<HfsDirectoryEntry>} A promise that resolves with the
* directory entries.
* @throws {TypeError} If the directory path is not a string.
* @throws {Error} If the directory cannot be read.
*/
list(dirPath: string | URL): AsyncIterable<HfsDirectoryEntry>;
/**
* Returns the size of a file. This method handles ENOENT errors
* and returns undefined in that case.
* @param {string|URL} filePath The path to the file to read.
* @returns {Promise<number|undefined>} A promise that resolves with the size of the
* file in bytes or undefined if the file doesn't exist.
*/
size(filePath: string | URL): Promise<number | undefined>;
/**
* Returns the last modified date of a file or directory. This method handles ENOENT errors
* and returns undefined in that case.
* @param {string|URL} fileOrDirPath The path to the file to read.
* @returns {Promise<Date|undefined>} A promise that resolves with the last modified
* date of the file or directory, or undefined if the file doesn't exist.
*/
lastModified(fileOrDirPath: string | URL): Promise<Date | undefined>;
/**
* Copies a file from one location to another.
* @param {string|URL} source The path to the file to copy.
* @param {string|URL} destination The path to copy the file to.
* @returns {Promise<void>} A promise that resolves when the file is copied.
* @throws {Error} If the source file does not exist.
* @throws {Error} If the source file is a directory.
* @throws {Error} If the destination file is a directory.
*/
copy(source: string | URL, destination: string | URL): Promise<void>;
/**
* Copies a file or directory from one location to another.
* @param {string|URL} source The path to the file or directory to copy.
* @param {string|URL} destination The path to copy the file or directory to.
* @returns {Promise<void>} A promise that resolves when the file or directory is
* copied.
* @throws {Error} If the source file or directory does not exist.
* @throws {Error} If the destination file or directory is a directory.
*/
copyAll(source: string | URL, destination: string | URL): Promise<void>;
/**
* Moves a file from the source path to the destination path.
* @param {string|URL} source The location of the file to move.
* @param {string|URL} destination The destination of the file to move.
* @returns {Promise<void>} A promise that resolves when the move is complete.
* @throws {TypeError} If the file paths are not strings.
* @throws {Error} If the file cannot be moved.
*/
move(source: string | URL, destination: string | URL): Promise<void>;
/**
* Moves a file or directory from the source path to the destination path.
* @param {string|URL} source The location of the file or directory to move.
* @param {string|URL} destination The destination of the file or directory to move.
* @returns {Promise<void>} A promise that resolves when the move is complete.
* @throws {TypeError} If the file paths are not strings.
* @throws {Error} If the file or directory cannot be moved.
*/
moveAll(source: string | URL, destination: string | URL): Promise<void>;
#private;
}
/**
* A class representing a file system utility library.
* @implements {HfsImpl}
*/
export class NodeHfs extends Hfs implements HfsImpl {
/**
* Creates a new instance.
* @param {object} [options] The options for the instance.
* @param {Fsp} [options.fsp] The file system module to use.
*/
constructor({ fsp }?: {
fsp?: Fsp;
});
}
export const hfs: NodeHfs;
export type HfsImpl = import("@humanfs/types").HfsImpl;
export type HfsDirectoryEntry = import("@humanfs/types").HfsDirectoryEntry;
export type Fsp = typeof nativeFsp;
export type Dirent = import("fs").Dirent;
import { Hfs } from "@humanfs/core";
import nativeFsp from "node:fs/promises";

View File

@@ -0,0 +1,62 @@
import { FileSpecification } from '@vitest/runner';
import { O as OTELCarrier } from './traces.d.D2T_R8rx.js';
import { T as TestExecutionMethod } from './worker.d.ZpHpO4yb.js';
type SerializedTestSpecification = [project: {
name: string | undefined;
root: string;
}, file: string, options: {
pool: string;
testLines?: number[] | undefined;
testIds?: string[] | undefined;
testNamePattern?: RegExp | undefined;
testTagsFilter?: string[] | undefined;
}];
interface ModuleDefinitionLocation {
line: number;
column: number;
}
interface SourceModuleLocations {
modules: ModuleDefinitionDiagnostic[];
untracked: ModuleDefinitionDiagnostic[];
}
interface ModuleDefinitionDiagnostic {
start: ModuleDefinitionLocation;
end: ModuleDefinitionLocation;
startIndex: number;
endIndex: number;
rawUrl: string;
resolvedUrl: string;
resolvedId: string;
}
interface ModuleDefinitionDurationsDiagnostic extends ModuleDefinitionDiagnostic {
selfTime: number;
totalTime: number;
transformTime?: number;
external?: boolean;
importer?: string;
}
interface UntrackedModuleDefinitionDiagnostic {
url: string;
resolvedId: string;
resolvedUrl: string;
selfTime: number;
totalTime: number;
transformTime?: number;
external?: boolean;
importer?: string;
}
interface SourceModuleDiagnostic {
modules: ModuleDefinitionDurationsDiagnostic[];
untrackedModules: UntrackedModuleDefinitionDiagnostic[];
}
interface BrowserTesterOptions {
method: TestExecutionMethod;
files: FileSpecification[];
providedContext: string;
otelCarrier?: OTELCarrier;
}
export type { BrowserTesterOptions as B, ModuleDefinitionDurationsDiagnostic as M, SerializedTestSpecification as S, UntrackedModuleDefinitionDiagnostic as U, ModuleDefinitionDiagnostic as a, ModuleDefinitionLocation as b, SourceModuleDiagnostic as c, SourceModuleLocations as d };

View File

@@ -0,0 +1,8 @@
import { Parser } from "../index.js";
export declare const parsers: {
__ng_action: Parser;
__ng_binding: Parser;
__ng_directive: Parser;
__ng_interpolation: Parser;
};