WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
function _arrayWithHoles(r) {
|
||||
if (Array.isArray(r)) return r;
|
||||
}
|
||||
module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,272 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag creation of function inside a loop
|
||||
* @author Ilya Volodin
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("eslint-scope").Reference} Reference */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const CONSTANT_BINDINGS = new Set(["const", "using", "await using"]);
|
||||
|
||||
/**
|
||||
* Identifies is a node is a FunctionExpression which is part of an IIFE
|
||||
* @param {ASTNode} node Node to test
|
||||
* @returns {boolean} True if it's an IIFE
|
||||
*/
|
||||
function isIIFE(node) {
|
||||
return (
|
||||
(node.type === "FunctionExpression" ||
|
||||
node.type === "ArrowFunctionExpression") &&
|
||||
node.parent &&
|
||||
node.parent.type === "CallExpression" &&
|
||||
node.parent.callee === node
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow function declarations that contain unsafe references inside loop statements",
|
||||
dialects: ["JavaScript", "TypeScript"],
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-loop-func",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unsafeRefs:
|
||||
"Function declared in a loop contains unsafe references to variable(s) {{ varNames }}.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const SKIPPED_IIFE_NODES = new Set();
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Gets the containing loop node of a specified node.
|
||||
*
|
||||
* We don't need to check nested functions, so this ignores those, with the exception of IIFE.
|
||||
* `Scope.through` contains references of nested functions.
|
||||
* @param {ASTNode} node An AST node to get.
|
||||
* @returns {ASTNode|null} The containing loop node of the specified node, or
|
||||
* `null`.
|
||||
*/
|
||||
function getContainingLoopNode(node) {
|
||||
for (
|
||||
let currentNode = node;
|
||||
currentNode.parent;
|
||||
currentNode = currentNode.parent
|
||||
) {
|
||||
const parent = currentNode.parent;
|
||||
|
||||
switch (parent.type) {
|
||||
case "WhileStatement":
|
||||
case "DoWhileStatement":
|
||||
return parent;
|
||||
|
||||
case "ForStatement":
|
||||
// `init` is outside of the loop.
|
||||
if (parent.init !== currentNode) {
|
||||
return parent;
|
||||
}
|
||||
break;
|
||||
|
||||
case "ForInStatement":
|
||||
case "ForOfStatement":
|
||||
// `right` is outside of the loop.
|
||||
if (parent.right !== currentNode) {
|
||||
return parent;
|
||||
}
|
||||
break;
|
||||
|
||||
case "ArrowFunctionExpression":
|
||||
case "FunctionExpression":
|
||||
case "FunctionDeclaration":
|
||||
// We need to check nested functions only in case of IIFE.
|
||||
if (SKIPPED_IIFE_NODES.has(parent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the containing loop node of a given node.
|
||||
* If the loop was nested, this returns the most outer loop.
|
||||
* @param {ASTNode} node A node to get. This is a loop node.
|
||||
* @param {ASTNode|null} excludedNode A node that the result node should not
|
||||
* include.
|
||||
* @returns {ASTNode} The most outer loop node.
|
||||
*/
|
||||
function getTopLoopNode(node, excludedNode) {
|
||||
const border = excludedNode ? excludedNode.range[1] : 0;
|
||||
let retv = node;
|
||||
let containingLoopNode = node;
|
||||
|
||||
while (
|
||||
containingLoopNode &&
|
||||
containingLoopNode.range[0] >= border
|
||||
) {
|
||||
retv = containingLoopNode;
|
||||
containingLoopNode = getContainingLoopNode(containingLoopNode);
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given reference which refers to an upper scope's variable is
|
||||
* safe or not.
|
||||
* @param {ASTNode} loopNode A containing loop node.
|
||||
* @param {Reference} reference A reference to check.
|
||||
* @returns {boolean} `true` if the reference is safe or not.
|
||||
*/
|
||||
function isSafe(loopNode, reference) {
|
||||
const variable = reference.resolved;
|
||||
const definition = variable && variable.defs[0];
|
||||
const declaration = definition && definition.parent;
|
||||
const kind =
|
||||
declaration && declaration.type === "VariableDeclaration"
|
||||
? declaration.kind
|
||||
: "";
|
||||
|
||||
// Constant variables are safe.
|
||||
if (CONSTANT_BINDINGS.has(kind)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Variables which are declared by `let` in the loop is safe.
|
||||
* It's a different instance from the next loop step's.
|
||||
*/
|
||||
if (
|
||||
kind === "let" &&
|
||||
declaration.range[0] > loopNode.range[0] &&
|
||||
declaration.range[1] < loopNode.range[1]
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* WriteReferences which exist after this border are unsafe because those
|
||||
* can modify the variable.
|
||||
*/
|
||||
const border = getTopLoopNode(
|
||||
loopNode,
|
||||
kind === "let" ? declaration : null,
|
||||
).range[0];
|
||||
|
||||
/**
|
||||
* Checks whether a given reference is safe or not.
|
||||
* The reference is every reference of the upper scope's variable we are
|
||||
* looking now.
|
||||
*
|
||||
* It's safe if the reference matches one of the following condition.
|
||||
* - is readonly.
|
||||
* - doesn't exist inside a local function and after the border.
|
||||
* @param {Reference} upperRef A reference to check.
|
||||
* @returns {boolean} `true` if the reference is safe.
|
||||
*/
|
||||
function isSafeReference(upperRef) {
|
||||
const id = upperRef.identifier;
|
||||
|
||||
return (
|
||||
!upperRef.isWrite() ||
|
||||
(variable.scope.variableScope ===
|
||||
upperRef.from.variableScope &&
|
||||
id.range[0] < border)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
Boolean(variable) && variable.references.every(isSafeReference)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports functions which match the following condition:
|
||||
*
|
||||
* - has a loop node in ancestors.
|
||||
* - has any references which refers to an unsafe variable.
|
||||
* @param {ASTNode} node The AST node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkForLoops(node) {
|
||||
const loopNode = getContainingLoopNode(node);
|
||||
|
||||
if (!loopNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const references = sourceCode.getScope(node).through;
|
||||
|
||||
// Check if the function is not asynchronous or a generator function
|
||||
if (!(node.async || node.generator)) {
|
||||
if (isIIFE(node)) {
|
||||
const isFunctionExpression =
|
||||
node.type === "FunctionExpression";
|
||||
|
||||
// Check if the function is referenced elsewhere in the code
|
||||
const isFunctionReferenced =
|
||||
isFunctionExpression && node.id
|
||||
? references.some(
|
||||
r => r.identifier.name === node.id.name,
|
||||
)
|
||||
: false;
|
||||
|
||||
if (!isFunctionReferenced) {
|
||||
SKIPPED_IIFE_NODES.add(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const unsafeRefs = [
|
||||
...new Set(
|
||||
references
|
||||
.filter(r => r.resolved && !isSafe(loopNode, r))
|
||||
.map(r => r.identifier.name),
|
||||
),
|
||||
];
|
||||
|
||||
if (unsafeRefs.length > 0) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unsafeRefs",
|
||||
data: { varNames: `'${unsafeRefs.join("', '")}'` },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ArrowFunctionExpression: checkForLoops,
|
||||
FunctionExpression: checkForLoops,
|
||||
FunctionDeclaration: checkForLoops,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,727 @@
|
||||
/*! *****************************************************************************
|
||||
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,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
/// <reference lib="es2020.intl" />
|
||||
|
||||
interface BigIntToLocaleStringOptions {
|
||||
/**
|
||||
* The locale matching algorithm to use.The default is "best fit". For information about this option, see the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation Intl page}.
|
||||
*/
|
||||
localeMatcher?: string;
|
||||
/**
|
||||
* The formatting style to use , the default is "decimal".
|
||||
*/
|
||||
style?: string;
|
||||
|
||||
numberingSystem?: string;
|
||||
/**
|
||||
* The unit to use in unit formatting, Possible values are core unit identifiers, defined in UTS #35, Part 2, Section 6. A subset of units from the full list was selected for use in ECMAScript. Pairs of simple units can be concatenated with "-per-" to make a compound unit. There is no default value; if the style is "unit", the unit property must be provided.
|
||||
*/
|
||||
unit?: string;
|
||||
|
||||
/**
|
||||
* The unit formatting style to use in unit formatting, the defaults is "short".
|
||||
*/
|
||||
unitDisplay?: string;
|
||||
|
||||
/**
|
||||
* The currency to use in currency formatting. Possible values are the ISO 4217 currency codes, such as "USD" for the US dollar, "EUR" for the euro, or "CNY" for the Chinese RMB — see the Current currency & funds code list. There is no default value; if the style is "currency", the currency property must be provided. It is only used when [[Style]] has the value "currency".
|
||||
*/
|
||||
currency?: string;
|
||||
|
||||
/**
|
||||
* How to display the currency in currency formatting. It is only used when [[Style]] has the value "currency". The default is "symbol".
|
||||
*
|
||||
* "symbol" to use a localized currency symbol such as €,
|
||||
*
|
||||
* "code" to use the ISO currency code,
|
||||
*
|
||||
* "name" to use a localized currency name such as "dollar"
|
||||
*/
|
||||
currencyDisplay?: string;
|
||||
|
||||
/**
|
||||
* Whether to use grouping separators, such as thousands separators or thousand/lakh/crore separators. The default is true.
|
||||
*/
|
||||
useGrouping?: boolean;
|
||||
|
||||
/**
|
||||
* The minimum number of integer digits to use. Possible values are from 1 to 21; the default is 1.
|
||||
*/
|
||||
minimumIntegerDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;
|
||||
|
||||
/**
|
||||
* The minimum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number and percent formatting is 0; the default for currency formatting is the number of minor unit digits provided by the {@link http://www.currency-iso.org/en/home/tables/table-a1.html ISO 4217 currency codes list} (2 if the list doesn't provide that information).
|
||||
*/
|
||||
minimumFractionDigits?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
|
||||
|
||||
/**
|
||||
* The maximum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number formatting is the larger of minimumFractionDigits and 3; the default for currency formatting is the larger of minimumFractionDigits and the number of minor unit digits provided by the {@link http://www.currency-iso.org/en/home/tables/table-a1.html ISO 4217 currency codes list} (2 if the list doesn't provide that information); the default for percent formatting is the larger of minimumFractionDigits and 0.
|
||||
*/
|
||||
maximumFractionDigits?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
|
||||
|
||||
/**
|
||||
* The minimum number of significant digits to use. Possible values are from 1 to 21; the default is 1.
|
||||
*/
|
||||
minimumSignificantDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;
|
||||
|
||||
/**
|
||||
* The maximum number of significant digits to use. Possible values are from 1 to 21; the default is 21.
|
||||
*/
|
||||
maximumSignificantDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;
|
||||
|
||||
/**
|
||||
* The formatting that should be displayed for the number, the defaults is "standard"
|
||||
*
|
||||
* "standard" plain number formatting
|
||||
*
|
||||
* "scientific" return the order-of-magnitude for formatted number.
|
||||
*
|
||||
* "engineering" return the exponent of ten when divisible by three
|
||||
*
|
||||
* "compact" string representing exponent, defaults is using the "short" form
|
||||
*/
|
||||
notation?: string;
|
||||
|
||||
/**
|
||||
* used only when notation is "compact"
|
||||
*/
|
||||
compactDisplay?: string;
|
||||
}
|
||||
|
||||
interface BigInt {
|
||||
/**
|
||||
* Returns a string representation of an object.
|
||||
* @param radix Specifies a radix for converting numeric values to strings.
|
||||
*/
|
||||
toString(radix?: number): string;
|
||||
|
||||
/** Returns a string representation appropriate to the host environment's current locale. */
|
||||
toLocaleString(locales?: Intl.LocalesArgument, options?: BigIntToLocaleStringOptions): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): bigint;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt";
|
||||
}
|
||||
|
||||
interface BigIntConstructor {
|
||||
(value: bigint | boolean | number | string): bigint;
|
||||
readonly prototype: BigInt;
|
||||
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as a 2's-complement signed integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asIntN(bits: number, int: bigint): bigint;
|
||||
/**
|
||||
* Interprets the low bits of a BigInt as an unsigned integer.
|
||||
* All higher bits are discarded.
|
||||
* @param bits The number of low bits to use
|
||||
* @param int The BigInt whose bits to extract
|
||||
*/
|
||||
asUintN(bits: number, int: bigint): bigint;
|
||||
}
|
||||
|
||||
declare var BigInt: BigIntConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigInt64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param predicate A function that accepts up to three arguments. The every method calls
|
||||
* the predicate function for each element in the array until the predicate returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Changes all array elements from `start` to `end` index to a static `value` and returns the modified array
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param predicate A function that accepts up to three arguments. The filter method calls
|
||||
* the predicate function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(predicate: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param predicate A function that accepts up to three arguments. The some method calls the
|
||||
* predicate function for each element in the array until the predicate returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin?: number, end?: number): BigInt64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(locales?: string | string[], options?: Intl.NumberFormatOptions): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): BigInt64Array;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigInt64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigInt64ArrayConstructor {
|
||||
readonly prototype: BigInt64Array;
|
||||
new (length?: number): BigInt64Array;
|
||||
new (array: Iterable<bigint>): BigInt64Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigInt64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigInt64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array;
|
||||
}
|
||||
|
||||
declare var BigInt64Array: BigInt64ArrayConstructor;
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated, an exception is raised.
|
||||
*/
|
||||
interface BigUint64Array {
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/** The ArrayBuffer instance referenced by the array. */
|
||||
readonly buffer: ArrayBufferLike;
|
||||
|
||||
/** The length in bytes of the array. */
|
||||
readonly byteLength: number;
|
||||
|
||||
/** The offset in bytes of the array. */
|
||||
readonly byteOffset: number;
|
||||
|
||||
/**
|
||||
* Returns the this object after copying a section of the array identified by start and end
|
||||
* to the same array starting at position target
|
||||
* @param target If target is negative, it is treated as length+target where length is the
|
||||
* length of the array.
|
||||
* @param start If start is negative, it is treated as length+start. If end is negative, it
|
||||
* is treated as length+end.
|
||||
* @param end If not specified, length of the this object is used as its default value.
|
||||
*/
|
||||
copyWithin(target: number, start: number, end?: number): this;
|
||||
|
||||
/** Yields index, value pairs for every entry in the array. */
|
||||
entries(): IterableIterator<[number, bigint]>;
|
||||
|
||||
/**
|
||||
* Determines whether all the members of an array satisfy the specified test.
|
||||
* @param predicate A function that accepts up to three arguments. The every method calls
|
||||
* the predicate function for each element in the array until the predicate returns false,
|
||||
* or until the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
every(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Changes all array elements from `start` to `end` index to a static `value` and returns the modified array
|
||||
* @param value value to fill array section with
|
||||
* @param start index to start filling the array at. If start is negative, it is treated as
|
||||
* length+start where length is the length of the array.
|
||||
* @param end index to stop filling the array at. If end is negative, it is treated as
|
||||
* length+end.
|
||||
*/
|
||||
fill(value: bigint, start?: number, end?: number): this;
|
||||
|
||||
/**
|
||||
* Returns the elements of an array that meet the condition specified in a callback function.
|
||||
* @param predicate A function that accepts up to three arguments. The filter method calls
|
||||
* the predicate function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(predicate: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found, find
|
||||
* immediately returns that element value. Otherwise, find returns undefined.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
* otherwise.
|
||||
* @param predicate find calls predicate once for each element of the array, in ascending
|
||||
* order, until it finds one where predicate returns true. If such an element is found,
|
||||
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
* @param callbackfn A function that accepts up to three arguments. forEach calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void;
|
||||
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
* @param searchElement The element to search for.
|
||||
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
||||
*/
|
||||
includes(searchElement: bigint, fromIndex?: number): boolean;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
indexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the
|
||||
* resulting String. If omitted, the array elements are separated with a comma.
|
||||
*/
|
||||
join(separator?: string): string;
|
||||
|
||||
/** Yields each index in the array. */
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a value in an array.
|
||||
* @param searchElement The value to locate in the array.
|
||||
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
|
||||
* search starts at index 0.
|
||||
*/
|
||||
lastIndexOf(searchElement: bigint, fromIndex?: number): number;
|
||||
|
||||
/** The length of the array. */
|
||||
readonly length: number;
|
||||
|
||||
/**
|
||||
* Calls a defined callback function on each element of an array, and returns an array that
|
||||
* contains the results.
|
||||
* @param callbackfn A function that accepts up to three arguments. The map method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
* the callback function is the accumulated result, and is provided as an argument in the next
|
||||
* call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
|
||||
* callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an
|
||||
* argument instead of an array value.
|
||||
*/
|
||||
reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array, in descending order.
|
||||
* The return value of the callback function is the accumulated result, and is provided as an
|
||||
* argument in the next call to the callback function.
|
||||
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
|
||||
* the callbackfn function one time for each element in the array.
|
||||
* @param initialValue If initialValue is specified, it is used as the initial value to start
|
||||
* the accumulation. The first call to the callbackfn function provides this value as an argument
|
||||
* instead of an array value.
|
||||
*/
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;
|
||||
|
||||
/** Reverses the elements in the array. */
|
||||
reverse(): this;
|
||||
|
||||
/**
|
||||
* Sets a value or an array of values.
|
||||
* @param array A typed or untyped array of values to set.
|
||||
* @param offset The index in the current array at which the values are to be written.
|
||||
*/
|
||||
set(array: ArrayLike<bigint>, offset?: number): void;
|
||||
|
||||
/**
|
||||
* Returns a section of an array.
|
||||
* @param start The beginning of the specified portion of the array.
|
||||
* @param end The end of the specified portion of the array.
|
||||
*/
|
||||
slice(start?: number, end?: number): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Determines whether the specified callback function returns true for any element of an array.
|
||||
* @param predicate A function that accepts up to three arguments. The some method calls the
|
||||
* predicate function for each element in the array until the predicate returns true, or until
|
||||
* the end of the array.
|
||||
* @param thisArg An object to which the this keyword can refer in the predicate function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
some(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;
|
||||
|
||||
/**
|
||||
* Sorts the array.
|
||||
* @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.
|
||||
*/
|
||||
sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;
|
||||
|
||||
/**
|
||||
* Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements
|
||||
* at begin, inclusive, up to end, exclusive.
|
||||
* @param begin The index of the beginning of the array.
|
||||
* @param end The index of the end of the array.
|
||||
*/
|
||||
subarray(begin?: number, end?: number): BigUint64Array;
|
||||
|
||||
/** Converts the array to a string by using the current locale. */
|
||||
toLocaleString(locales?: string | string[], options?: Intl.NumberFormatOptions): string;
|
||||
|
||||
/** Returns a string representation of the array. */
|
||||
toString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): BigUint64Array;
|
||||
|
||||
/** Yields each value in the array. */
|
||||
values(): IterableIterator<bigint>;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<bigint>;
|
||||
|
||||
readonly [Symbol.toStringTag]: "BigUint64Array";
|
||||
|
||||
[index: number]: bigint;
|
||||
}
|
||||
|
||||
interface BigUint64ArrayConstructor {
|
||||
readonly prototype: BigUint64Array;
|
||||
new (length?: number): BigUint64Array;
|
||||
new (array: Iterable<bigint>): BigUint64Array;
|
||||
new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array;
|
||||
|
||||
/** The size in bytes of each element in the array. */
|
||||
readonly BYTES_PER_ELEMENT: number;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
* @param items A set of elements to include in the new array object.
|
||||
*/
|
||||
of(...items: bigint[]): BigUint64Array;
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like or iterable object.
|
||||
* @param arrayLike An array-like or iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: ArrayLike<bigint>): BigUint64Array;
|
||||
from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array;
|
||||
}
|
||||
|
||||
declare var BigUint64Array: BigUint64ArrayConstructor;
|
||||
|
||||
interface DataView {
|
||||
/**
|
||||
* Gets the BigInt64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getBigInt64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Gets the BigUint64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getBigUint64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
/**
|
||||
* Stores a BigInt64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
|
||||
/**
|
||||
* Stores a BigUint64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
}
|
||||
|
||||
declare namespace Intl {
|
||||
interface NumberFormat {
|
||||
format(value: number | bigint): string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
function _skipFirstGeneratorNext(t) {
|
||||
return function () {
|
||||
var r = t.apply(this, arguments);
|
||||
return r.next(), r;
|
||||
};
|
||||
}
|
||||
export { _skipFirstGeneratorNext as default };
|
||||
@@ -0,0 +1,30 @@
|
||||
export declare enum TokenFlags {
|
||||
None = 0,
|
||||
PrecedingLineBreak = 1,
|
||||
PrecedingJSDocComment = 2,
|
||||
Unterminated = 4,
|
||||
ExtendedUnicodeEscape = 8,
|
||||
Scientific = 16,
|
||||
Octal = 32,
|
||||
HexSpecifier = 64,
|
||||
BinarySpecifier = 128,
|
||||
OctalSpecifier = 256,
|
||||
ContainsSeparator = 512,
|
||||
UnicodeEscape = 1024,
|
||||
ContainsInvalidEscape = 2048,
|
||||
HexEscape = 4096,
|
||||
ContainsLeadingZero = 8192,
|
||||
ContainsInvalidSeparator = 16384,
|
||||
PrecedingJSDocLeadingAsterisks = 32768,
|
||||
SingleQuote = 65536,
|
||||
PrecedingJSDocWithDeprecated = 131072,
|
||||
PrecedingJSDocWithSeeOrLink = 262144,
|
||||
BinaryOrOctalSpecifier = 384,
|
||||
WithSpecifier = 448,
|
||||
StringLiteralFlags = 72716,
|
||||
NumericLiteralFlags = 25584,
|
||||
TemplateLiteralLikeFlags = 7180,
|
||||
RegularExpressionLiteralFlags = 4,
|
||||
IsInvalid = 26656
|
||||
}
|
||||
//# sourceMappingURL=tokenFlags.enum.d.ts.map
|
||||
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('boolean and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'true', '--derp', 'true'];
|
||||
var regular = ['--herp', 'true', '-d', 'true'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'h',
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, ['--derp', '-d']);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean true any double hyphen argument is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
|
||||
boolean: true,
|
||||
unknown: unknownFn,
|
||||
});
|
||||
t.same(unknown, ['--tacos=good', 'cow', '-p']);
|
||||
t.same(argv, {
|
||||
honk: true,
|
||||
_: [],
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('string and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'hello', '--derp', 'goodbye'];
|
||||
var regular = ['--herp', 'hello', '-d', 'moon'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
string: 'h',
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, ['--derp', '-d']);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('default and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'hello'];
|
||||
var regular = ['--herp', 'hello'];
|
||||
var opts = {
|
||||
default: { h: 'bar' },
|
||||
alias: { h: 'herp' },
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, []);
|
||||
t.end();
|
||||
unknownFn(); // exercise fn for 100% coverage
|
||||
});
|
||||
|
||||
test('value following -- is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['--bad', '--', 'good', 'arg'];
|
||||
var opts = {
|
||||
'--': true,
|
||||
unknown: unknownFn,
|
||||
};
|
||||
var argv = parse(aliased, opts);
|
||||
|
||||
t.same(unknown, ['--bad']);
|
||||
t.same(argv, {
|
||||
'--': ['good', 'arg'],
|
||||
_: [],
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
@@ -0,0 +1,612 @@
|
||||
/**
|
||||
* @fileoverview Rule to require or disallow newlines between statements
|
||||
* @author Toru Nagashima
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`;
|
||||
const PADDING_LINE_SEQUENCE = new RegExp(
|
||||
String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`,
|
||||
"u",
|
||||
);
|
||||
const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u;
|
||||
const CJS_IMPORT = /^require\(/u;
|
||||
|
||||
/**
|
||||
* Creates tester which check if a node starts with specific keyword.
|
||||
* @param {string} keyword The keyword to test.
|
||||
* @returns {Object} the created tester.
|
||||
* @private
|
||||
*/
|
||||
function newKeywordTester(keyword) {
|
||||
return {
|
||||
test: (node, sourceCode) =>
|
||||
sourceCode.getFirstToken(node).value === keyword,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates tester which check if a node starts with specific keyword and spans a single line.
|
||||
* @param {string} keyword The keyword to test.
|
||||
* @returns {Object} the created tester.
|
||||
* @private
|
||||
*/
|
||||
function newSinglelineKeywordTester(keyword) {
|
||||
return {
|
||||
test: (node, sourceCode) =>
|
||||
node.loc.start.line === node.loc.end.line &&
|
||||
sourceCode.getFirstToken(node).value === keyword,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates tester which check if a node starts with specific keyword and spans multiple lines.
|
||||
* @param {string} keyword The keyword to test.
|
||||
* @returns {Object} the created tester.
|
||||
* @private
|
||||
*/
|
||||
function newMultilineKeywordTester(keyword) {
|
||||
return {
|
||||
test: (node, sourceCode) =>
|
||||
node.loc.start.line !== node.loc.end.line &&
|
||||
sourceCode.getFirstToken(node).value === keyword,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates tester which check if a node is specific type.
|
||||
* @param {string} type The node type to test.
|
||||
* @returns {Object} the created tester.
|
||||
* @private
|
||||
*/
|
||||
function newNodeTypeTester(type) {
|
||||
return {
|
||||
test: node => node.type === type,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given node is an expression statement of IIFE.
|
||||
* @param {ASTNode} node The node to check.
|
||||
* @returns {boolean} `true` if the node is an expression statement of IIFE.
|
||||
* @private
|
||||
*/
|
||||
function isIIFEStatement(node) {
|
||||
if (node.type === "ExpressionStatement") {
|
||||
let call = astUtils.skipChainExpression(node.expression);
|
||||
|
||||
if (call.type === "UnaryExpression") {
|
||||
call = astUtils.skipChainExpression(call.argument);
|
||||
}
|
||||
return (
|
||||
call.type === "CallExpression" && astUtils.isFunction(call.callee)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given node is a block-like statement.
|
||||
* This checks the last token of the node is the closing brace of a block.
|
||||
* @param {SourceCode} sourceCode The source code to get tokens.
|
||||
* @param {ASTNode} node The node to check.
|
||||
* @returns {boolean} `true` if the node is a block-like statement.
|
||||
* @private
|
||||
*/
|
||||
function isBlockLikeStatement(sourceCode, node) {
|
||||
// do-while with a block is a block-like statement.
|
||||
if (
|
||||
node.type === "DoWhileStatement" &&
|
||||
node.body.type === "BlockStatement"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* IIFE is a block-like statement specially from
|
||||
* JSCS#disallowPaddingNewLinesAfterBlocks.
|
||||
*/
|
||||
if (isIIFEStatement(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checks the last token is a closing brace of blocks.
|
||||
const lastToken = sourceCode.getLastToken(
|
||||
node,
|
||||
astUtils.isNotSemicolonToken,
|
||||
);
|
||||
const belongingNode =
|
||||
lastToken && astUtils.isClosingBraceToken(lastToken)
|
||||
? sourceCode.getNodeByRangeIndex(lastToken.range[0])
|
||||
: null;
|
||||
|
||||
return (
|
||||
Boolean(belongingNode) &&
|
||||
(belongingNode.type === "BlockStatement" ||
|
||||
belongingNode.type === "SwitchStatement")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the actual last token.
|
||||
*
|
||||
* If a semicolon is semicolon-less style's semicolon, this ignores it.
|
||||
* For example:
|
||||
*
|
||||
* foo()
|
||||
* ;[1, 2, 3].forEach(bar)
|
||||
* @param {SourceCode} sourceCode The source code to get tokens.
|
||||
* @param {ASTNode} node The node to get.
|
||||
* @returns {Token} The actual last token.
|
||||
* @private
|
||||
*/
|
||||
function getActualLastToken(sourceCode, node) {
|
||||
const semiToken = sourceCode.getLastToken(node);
|
||||
const prevToken = sourceCode.getTokenBefore(semiToken);
|
||||
const nextToken = sourceCode.getTokenAfter(semiToken);
|
||||
const isSemicolonLessStyle = Boolean(
|
||||
prevToken &&
|
||||
nextToken &&
|
||||
prevToken.range[0] >= node.range[0] &&
|
||||
astUtils.isSemicolonToken(semiToken) &&
|
||||
semiToken.loc.start.line !== prevToken.loc.end.line &&
|
||||
semiToken.loc.end.line === nextToken.loc.start.line,
|
||||
);
|
||||
|
||||
return isSemicolonLessStyle ? prevToken : semiToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the concatenation of the first 2 captured strings.
|
||||
* @param {string} _ Unused. Whole matched string.
|
||||
* @param {string} trailingSpaces The trailing spaces of the first line.
|
||||
* @param {string} indentSpaces The indentation spaces of the last line.
|
||||
* @returns {string} The concatenation of trailingSpaces and indentSpaces.
|
||||
* @private
|
||||
*/
|
||||
function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) {
|
||||
return trailingSpaces + indentSpaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and report statements for `any` configuration.
|
||||
* It does nothing.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function verifyForAny() {}
|
||||
|
||||
/**
|
||||
* Check and report statements for `never` configuration.
|
||||
* This autofix removes blank lines between the given 2 statements.
|
||||
* However, if comments exist between 2 blank lines, it does not remove those
|
||||
* blank lines automatically.
|
||||
* @param {RuleContext} context The rule context to report.
|
||||
* @param {ASTNode} _ Unused. The previous node to check.
|
||||
* @param {ASTNode} nextNode The next node to check.
|
||||
* @param {Array<Token[]>} paddingLines The array of token pairs that blank
|
||||
* lines exist between the pair.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function verifyForNever(context, _, nextNode, paddingLines) {
|
||||
if (paddingLines.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: nextNode,
|
||||
messageId: "unexpectedBlankLine",
|
||||
fix(fixer) {
|
||||
if (paddingLines.length >= 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const prevToken = paddingLines[0][0];
|
||||
const nextToken = paddingLines[0][1];
|
||||
const start = prevToken.range[1];
|
||||
const end = nextToken.range[0];
|
||||
const text = context.sourceCode.text
|
||||
.slice(start, end)
|
||||
.replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines);
|
||||
|
||||
return fixer.replaceTextRange([start, end], text);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and report statements for `always` configuration.
|
||||
* This autofix inserts a blank line between the given 2 statements.
|
||||
* If the `prevNode` has trailing comments, it inserts a blank line after the
|
||||
* trailing comments.
|
||||
* @param {RuleContext} context The rule context to report.
|
||||
* @param {ASTNode} prevNode The previous node to check.
|
||||
* @param {ASTNode} nextNode The next node to check.
|
||||
* @param {Array<Token[]>} paddingLines The array of token pairs that blank
|
||||
* lines exist between the pair.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function verifyForAlways(context, prevNode, nextNode, paddingLines) {
|
||||
if (paddingLines.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({
|
||||
node: nextNode,
|
||||
messageId: "expectedBlankLine",
|
||||
fix(fixer) {
|
||||
const sourceCode = context.sourceCode;
|
||||
let prevToken = getActualLastToken(sourceCode, prevNode);
|
||||
const nextToken =
|
||||
sourceCode.getFirstTokenBetween(prevToken, nextNode, {
|
||||
includeComments: true,
|
||||
|
||||
/**
|
||||
* Skip the trailing comments of the previous node.
|
||||
* This inserts a blank line after the last trailing comment.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* foo(); // trailing comment.
|
||||
* // comment.
|
||||
* bar();
|
||||
*
|
||||
* Get fixed to:
|
||||
*
|
||||
* foo(); // trailing comment.
|
||||
*
|
||||
* // comment.
|
||||
* bar();
|
||||
* @param {Token} token The token to check.
|
||||
* @returns {boolean} `true` if the token is not a trailing comment.
|
||||
* @private
|
||||
*/
|
||||
filter(token) {
|
||||
if (astUtils.isTokenOnSameLine(prevToken, token)) {
|
||||
prevToken = token;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}) || nextNode;
|
||||
const insertText = astUtils.isTokenOnSameLine(prevToken, nextToken)
|
||||
? "\n\n"
|
||||
: "\n";
|
||||
|
||||
return fixer.insertTextAfter(prevToken, insertText);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Types of blank lines.
|
||||
* `any`, `never`, and `always` are defined.
|
||||
* Those have `verify` method to check and report statements.
|
||||
* @private
|
||||
*/
|
||||
const PaddingTypes = {
|
||||
any: { verify: verifyForAny },
|
||||
never: { verify: verifyForNever },
|
||||
always: { verify: verifyForAlways },
|
||||
};
|
||||
|
||||
/**
|
||||
* Types of statements.
|
||||
* Those have `test` method to check it matches to the given statement.
|
||||
* @private
|
||||
*/
|
||||
const StatementTypes = {
|
||||
"*": { test: () => true },
|
||||
"block-like": {
|
||||
test: (node, sourceCode) => isBlockLikeStatement(sourceCode, node),
|
||||
},
|
||||
"cjs-export": {
|
||||
test: (node, sourceCode) =>
|
||||
node.type === "ExpressionStatement" &&
|
||||
node.expression.type === "AssignmentExpression" &&
|
||||
CJS_EXPORT.test(sourceCode.getText(node.expression.left)),
|
||||
},
|
||||
"cjs-import": {
|
||||
test: (node, sourceCode) =>
|
||||
node.type === "VariableDeclaration" &&
|
||||
node.declarations.length > 0 &&
|
||||
Boolean(node.declarations[0].init) &&
|
||||
CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init)),
|
||||
},
|
||||
directive: {
|
||||
test: astUtils.isDirective,
|
||||
},
|
||||
expression: {
|
||||
test: node =>
|
||||
node.type === "ExpressionStatement" && !astUtils.isDirective(node),
|
||||
},
|
||||
iife: {
|
||||
test: isIIFEStatement,
|
||||
},
|
||||
"multiline-block-like": {
|
||||
test: (node, sourceCode) =>
|
||||
node.loc.start.line !== node.loc.end.line &&
|
||||
isBlockLikeStatement(sourceCode, node),
|
||||
},
|
||||
"multiline-expression": {
|
||||
test: node =>
|
||||
node.loc.start.line !== node.loc.end.line &&
|
||||
node.type === "ExpressionStatement" &&
|
||||
!astUtils.isDirective(node),
|
||||
},
|
||||
|
||||
"multiline-const": newMultilineKeywordTester("const"),
|
||||
"multiline-let": newMultilineKeywordTester("let"),
|
||||
"multiline-var": newMultilineKeywordTester("var"),
|
||||
"singleline-const": newSinglelineKeywordTester("const"),
|
||||
"singleline-let": newSinglelineKeywordTester("let"),
|
||||
"singleline-var": newSinglelineKeywordTester("var"),
|
||||
|
||||
block: newNodeTypeTester("BlockStatement"),
|
||||
empty: newNodeTypeTester("EmptyStatement"),
|
||||
function: newNodeTypeTester("FunctionDeclaration"),
|
||||
|
||||
break: newKeywordTester("break"),
|
||||
case: newKeywordTester("case"),
|
||||
class: newKeywordTester("class"),
|
||||
const: newKeywordTester("const"),
|
||||
continue: newKeywordTester("continue"),
|
||||
debugger: newKeywordTester("debugger"),
|
||||
default: newKeywordTester("default"),
|
||||
do: newKeywordTester("do"),
|
||||
export: newKeywordTester("export"),
|
||||
for: newKeywordTester("for"),
|
||||
if: newKeywordTester("if"),
|
||||
import: newKeywordTester("import"),
|
||||
let: newKeywordTester("let"),
|
||||
return: newKeywordTester("return"),
|
||||
switch: newKeywordTester("switch"),
|
||||
throw: newKeywordTester("throw"),
|
||||
try: newKeywordTester("try"),
|
||||
var: newKeywordTester("var"),
|
||||
while: newKeywordTester("while"),
|
||||
with: newKeywordTester("with"),
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: {
|
||||
message: "Formatting rules are being moved out of ESLint core.",
|
||||
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
||||
deprecatedSince: "8.53.0",
|
||||
availableUntil: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin",
|
||||
url: "https://eslint.style",
|
||||
},
|
||||
rule: {
|
||||
name: "padding-line-between-statements",
|
||||
url: "https://eslint.style/rules/padding-line-between-statements",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description: "Require or disallow padding lines between statements",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/padding-line-between-statements",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: {
|
||||
definitions: {
|
||||
paddingType: {
|
||||
enum: Object.keys(PaddingTypes),
|
||||
},
|
||||
statementType: {
|
||||
anyOf: [
|
||||
{ enum: Object.keys(StatementTypes) },
|
||||
{
|
||||
type: "array",
|
||||
items: { enum: Object.keys(StatementTypes) },
|
||||
minItems: 1,
|
||||
uniqueItems: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
blankLine: { $ref: "#/definitions/paddingType" },
|
||||
prev: { $ref: "#/definitions/statementType" },
|
||||
next: { $ref: "#/definitions/statementType" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
required: ["blankLine", "prev", "next"],
|
||||
},
|
||||
},
|
||||
|
||||
messages: {
|
||||
unexpectedBlankLine: "Unexpected blank line before this statement.",
|
||||
expectedBlankLine: "Expected blank line before this statement.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
const configureList = context.options || [];
|
||||
let scopeInfo = null;
|
||||
|
||||
/**
|
||||
* Processes to enter to new scope.
|
||||
* This manages the current previous statement.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function enterScope() {
|
||||
scopeInfo = {
|
||||
upper: scopeInfo,
|
||||
prevNode: null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes to exit from the current scope.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function exitScope() {
|
||||
scopeInfo = scopeInfo.upper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given node matches the given type.
|
||||
* @param {ASTNode} node The statement node to check.
|
||||
* @param {string|string[]} type The statement type to check.
|
||||
* @returns {boolean} `true` if the statement node matched the type.
|
||||
* @private
|
||||
*/
|
||||
function match(node, type) {
|
||||
let innerStatementNode = node;
|
||||
|
||||
while (innerStatementNode.type === "LabeledStatement") {
|
||||
innerStatementNode = innerStatementNode.body;
|
||||
}
|
||||
if (Array.isArray(type)) {
|
||||
return type.some(match.bind(null, innerStatementNode));
|
||||
}
|
||||
return StatementTypes[type].test(innerStatementNode, sourceCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the last matched configure from configureList.
|
||||
* @param {ASTNode} prevNode The previous statement to match.
|
||||
* @param {ASTNode} nextNode The current statement to match.
|
||||
* @returns {Object} The tester of the last matched configure.
|
||||
* @private
|
||||
*/
|
||||
function getPaddingType(prevNode, nextNode) {
|
||||
for (let i = configureList.length - 1; i >= 0; --i) {
|
||||
const configure = configureList[i];
|
||||
const matched =
|
||||
match(prevNode, configure.prev) &&
|
||||
match(nextNode, configure.next);
|
||||
|
||||
if (matched) {
|
||||
return PaddingTypes[configure.blankLine];
|
||||
}
|
||||
}
|
||||
return PaddingTypes.any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets padding line sequences between the given 2 statements.
|
||||
* Comments are separators of the padding line sequences.
|
||||
* @param {ASTNode} prevNode The previous statement to count.
|
||||
* @param {ASTNode} nextNode The current statement to count.
|
||||
* @returns {Array<Token[]>} The array of token pairs.
|
||||
* @private
|
||||
*/
|
||||
function getPaddingLineSequences(prevNode, nextNode) {
|
||||
const pairs = [];
|
||||
let prevToken = getActualLastToken(sourceCode, prevNode);
|
||||
|
||||
if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) {
|
||||
do {
|
||||
const token = sourceCode.getTokenAfter(prevToken, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
if (token.loc.start.line - prevToken.loc.end.line >= 2) {
|
||||
pairs.push([prevToken, token]);
|
||||
}
|
||||
prevToken = token;
|
||||
} while (prevToken.range[0] < nextNode.range[0]);
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify padding lines between the given node and the previous node.
|
||||
* @param {ASTNode} node The node to verify.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function verify(node) {
|
||||
const parentType = node.parent.type;
|
||||
const validParent =
|
||||
astUtils.STATEMENT_LIST_PARENTS.has(parentType) ||
|
||||
parentType === "SwitchStatement";
|
||||
|
||||
if (!validParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save this node as the current previous statement.
|
||||
const prevNode = scopeInfo.prevNode;
|
||||
|
||||
// Verify.
|
||||
if (prevNode) {
|
||||
const type = getPaddingType(prevNode, node);
|
||||
const paddingLines = getPaddingLineSequences(prevNode, node);
|
||||
|
||||
type.verify(context, prevNode, node, paddingLines);
|
||||
}
|
||||
|
||||
scopeInfo.prevNode = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify padding lines between the given node and the previous node.
|
||||
* Then process to enter to new scope.
|
||||
* @param {ASTNode} node The node to verify.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function verifyThenEnterScope(node) {
|
||||
verify(node);
|
||||
enterScope();
|
||||
}
|
||||
|
||||
return {
|
||||
Program: enterScope,
|
||||
BlockStatement: enterScope,
|
||||
SwitchStatement: enterScope,
|
||||
StaticBlock: enterScope,
|
||||
"Program:exit": exitScope,
|
||||
"BlockStatement:exit": exitScope,
|
||||
"SwitchStatement:exit": exitScope,
|
||||
"StaticBlock:exit": exitScope,
|
||||
|
||||
":statement": verify,
|
||||
|
||||
SwitchCase: verifyThenEnterScope,
|
||||
"SwitchCase:exit": exitScope,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "uri-js",
|
||||
"version": "4.4.1",
|
||||
"description": "An RFC 3986/3987 compliant, scheme extendable URI/IRI parsing/validating/resolving library for JavaScript.",
|
||||
"main": "dist/es5/uri.all.js",
|
||||
"types": "dist/es5/uri.all.d.ts",
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"package.json",
|
||||
"yarn.lock",
|
||||
"README.md",
|
||||
"CHANGELOG",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"build:esnext": "tsc",
|
||||
"build:es5": "rollup -c && cp dist/esnext/uri.d.ts dist/es5/uri.all.d.ts && npm run build:es5:fix-sourcemap",
|
||||
"build:es5:fix-sourcemap": "sorcery -i dist/es5/uri.all.js",
|
||||
"build:es5:min": "uglifyjs dist/es5/uri.all.js --support-ie8 --output dist/es5/uri.all.min.js --in-source-map dist/es5/uri.all.js.map --source-map uri.all.min.js.map --comments --compress --mangle --pure-funcs merge subexp && mv uri.all.min.js.map dist/es5/ && cp dist/es5/uri.all.d.ts dist/es5/uri.all.min.d.ts",
|
||||
"build": "npm run build:esnext && npm run build:es5 && npm run build:es5:min",
|
||||
"clean": "rm -rf dist",
|
||||
"test": "mocha -u mocha-qunit-ui dist/es5/uri.all.js tests/tests.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/garycourt/uri-js"
|
||||
},
|
||||
"keywords": [
|
||||
"URI",
|
||||
"IRI",
|
||||
"IDN",
|
||||
"URN",
|
||||
"UUID",
|
||||
"HTTP",
|
||||
"HTTPS",
|
||||
"WS",
|
||||
"WSS",
|
||||
"MAILTO",
|
||||
"RFC3986",
|
||||
"RFC3987",
|
||||
"RFC5891",
|
||||
"RFC2616",
|
||||
"RFC2818",
|
||||
"RFC2141",
|
||||
"RFC4122",
|
||||
"RFC4291",
|
||||
"RFC5952",
|
||||
"RFC6068",
|
||||
"RFC6455",
|
||||
"RFC6874"
|
||||
],
|
||||
"author": "Gary Court <gary.court@gmail.com>",
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/garycourt/uri-js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/garycourt/uri-js",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-preset-latest": "^6.24.1",
|
||||
"mocha": "^8.2.1",
|
||||
"mocha-qunit-ui": "^0.1.3",
|
||||
"rollup": "^0.41.6",
|
||||
"rollup-plugin-babel": "^2.7.1",
|
||||
"rollup-plugin-node-resolve": "^2.0.0",
|
||||
"sorcery": "^0.10.0",
|
||||
"typescript": "^2.8.1",
|
||||
"uglify-js": "^2.8.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"characterCodes.d.ts","sourceRoot":"","sources":["../../src/enums/characterCodes.ts"],"names":[],"mappings":"AAAA,eAAO,IAAI,cAAc,EAAE,GAAG,CAAC"}
|
||||
@@ -0,0 +1,47 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
mapHttpResponse,
|
||||
resSerializer
|
||||
}
|
||||
|
||||
const rawSymbol = Symbol('pino-raw-res-ref')
|
||||
const pinoResProto = Object.create({}, {
|
||||
statusCode: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: 0
|
||||
},
|
||||
headers: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: ''
|
||||
},
|
||||
raw: {
|
||||
enumerable: false,
|
||||
get: function () {
|
||||
return this[rawSymbol]
|
||||
},
|
||||
set: function (val) {
|
||||
this[rawSymbol] = val
|
||||
}
|
||||
}
|
||||
})
|
||||
Object.defineProperty(pinoResProto, rawSymbol, {
|
||||
writable: true,
|
||||
value: {}
|
||||
})
|
||||
|
||||
function resSerializer (res) {
|
||||
const _res = Object.create(pinoResProto)
|
||||
_res.statusCode = res.headersSent ? res.statusCode : null
|
||||
_res.headers = res.getHeaders ? res.getHeaders() : res._headers
|
||||
_res.raw = res
|
||||
return _res
|
||||
}
|
||||
|
||||
function mapHttpResponse (res) {
|
||||
return {
|
||||
res: resSerializer(res)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
// Type definitions for ws 7.4
|
||||
// Project: https://github.com/websockets/ws
|
||||
// Definitions by: Paul Loyd <https://github.com/loyd>
|
||||
// Margus Lamp <https://github.com/mlamp>
|
||||
// Philippe D'Alva <https://github.com/TitaneBoy>
|
||||
// reduckted <https://github.com/reduckted>
|
||||
// teidesu <https://github.com/teidesu>
|
||||
// Bartosz Wojtkowiak <https://github.com/wojtkowiak>
|
||||
// Kyle Hensel <https://github.com/k-yle>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import { EventEmitter } from "events";
|
||||
import {
|
||||
Agent,
|
||||
ClientRequest,
|
||||
ClientRequestArgs,
|
||||
IncomingMessage,
|
||||
OutgoingHttpHeaders,
|
||||
Server as HTTPServer,
|
||||
} from "http";
|
||||
import { Server as HTTPSServer } from "https";
|
||||
import { Socket } from "net";
|
||||
import { Duplex, DuplexOptions } from "stream";
|
||||
import { SecureContextOptions } from "tls";
|
||||
import { URL } from "url";
|
||||
import { ZlibOptions } from "zlib";
|
||||
|
||||
// WebSocket socket.
|
||||
declare class WebSocket extends EventEmitter {
|
||||
/** The connection is not yet open. */
|
||||
static readonly CONNECTING: 0;
|
||||
/** The connection is open and ready to communicate. */
|
||||
static readonly OPEN: 1;
|
||||
/** The connection is in the process of closing. */
|
||||
static readonly CLOSING: 2;
|
||||
/** The connection is closed. */
|
||||
static readonly CLOSED: 3;
|
||||
|
||||
binaryType: "nodebuffer" | "arraybuffer" | "fragments";
|
||||
readonly bufferedAmount: number;
|
||||
readonly extensions: string;
|
||||
readonly protocol: string;
|
||||
/** The current state of the connection */
|
||||
readonly readyState:
|
||||
| typeof WebSocket.CONNECTING
|
||||
| typeof WebSocket.OPEN
|
||||
| typeof WebSocket.CLOSING
|
||||
| typeof WebSocket.CLOSED;
|
||||
readonly url: string;
|
||||
|
||||
/** The connection is not yet open. */
|
||||
readonly CONNECTING: 0;
|
||||
/** The connection is open and ready to communicate. */
|
||||
readonly OPEN: 1;
|
||||
/** The connection is in the process of closing. */
|
||||
readonly CLOSING: 2;
|
||||
/** The connection is closed. */
|
||||
readonly CLOSED: 3;
|
||||
|
||||
onopen: (event: WebSocket.OpenEvent) => void;
|
||||
onerror: (event: WebSocket.ErrorEvent) => void;
|
||||
onclose: (event: WebSocket.CloseEvent) => void;
|
||||
onmessage: (event: WebSocket.MessageEvent) => void;
|
||||
|
||||
constructor(address: string | URL, options?: WebSocket.ClientOptions | ClientRequestArgs);
|
||||
constructor(
|
||||
address: string | URL,
|
||||
protocols?: string | string[],
|
||||
options?: WebSocket.ClientOptions | ClientRequestArgs,
|
||||
);
|
||||
|
||||
close(code?: number, data?: string): void;
|
||||
ping(data?: any, mask?: boolean, cb?: (err: Error) => void): void;
|
||||
pong(data?: any, mask?: boolean, cb?: (err: Error) => void): void;
|
||||
send(data: any, cb?: (err?: Error) => void): void;
|
||||
send(
|
||||
data: any,
|
||||
options: { mask?: boolean | undefined; binary?: boolean | undefined; compress?: boolean | undefined; fin?: boolean | undefined },
|
||||
cb?: (err?: Error) => void,
|
||||
): void;
|
||||
terminate(): void;
|
||||
|
||||
// HTML5 WebSocket events
|
||||
addEventListener(
|
||||
method: "message",
|
||||
cb: (event: { data: any; type: string; target: WebSocket }) => void,
|
||||
options?: WebSocket.EventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
method: "close",
|
||||
cb: (event: { wasClean: boolean; code: number; reason: string; target: WebSocket }) => void,
|
||||
options?: WebSocket.EventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
method: "error",
|
||||
cb: (event: { error: any; message: any; type: string; target: WebSocket }) => void,
|
||||
options?: WebSocket.EventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
method: "open",
|
||||
cb: (event: { target: WebSocket }) => void,
|
||||
options?: WebSocket.EventListenerOptions,
|
||||
): void;
|
||||
addEventListener(method: string, listener: () => void, options?: WebSocket.EventListenerOptions): void;
|
||||
|
||||
removeEventListener(method: "message", cb?: (event: { data: any; type: string; target: WebSocket }) => void): void;
|
||||
removeEventListener(
|
||||
method: "close",
|
||||
cb?: (event: { wasClean: boolean; code: number; reason: string; target: WebSocket }) => void,
|
||||
): void;
|
||||
removeEventListener(
|
||||
method: "error",
|
||||
cb?: (event: { error: any; message: any; type: string; target: WebSocket }) => void,
|
||||
): void;
|
||||
removeEventListener(method: "open", cb?: (event: { target: WebSocket }) => void): void;
|
||||
removeEventListener(method: string, listener?: () => void): void;
|
||||
|
||||
// Events
|
||||
on(event: "close", listener: (this: WebSocket, code: number, reason: string) => void): this;
|
||||
on(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
||||
on(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
||||
on(event: "message", listener: (this: WebSocket, data: WebSocket.Data) => void): this;
|
||||
on(event: "open", listener: (this: WebSocket) => void): this;
|
||||
on(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
||||
on(
|
||||
event: "unexpected-response",
|
||||
listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
||||
): this;
|
||||
on(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
||||
|
||||
once(event: "close", listener: (this: WebSocket, code: number, reason: string) => void): this;
|
||||
once(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
||||
once(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
||||
once(event: "message", listener: (this: WebSocket, data: WebSocket.Data) => void): this;
|
||||
once(event: "open", listener: (this: WebSocket) => void): this;
|
||||
once(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
||||
once(
|
||||
event: "unexpected-response",
|
||||
listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
||||
): this;
|
||||
once(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
||||
|
||||
off(event: "close", listener: (this: WebSocket, code: number, reason: string) => void): this;
|
||||
off(event: "error", listener: (this: WebSocket, err: Error) => void): this;
|
||||
off(event: "upgrade", listener: (this: WebSocket, request: IncomingMessage) => void): this;
|
||||
off(event: "message", listener: (this: WebSocket, data: WebSocket.Data) => void): this;
|
||||
off(event: "open", listener: (this: WebSocket) => void): this;
|
||||
off(event: "ping" | "pong", listener: (this: WebSocket, data: Buffer) => void): this;
|
||||
off(
|
||||
event: "unexpected-response",
|
||||
listener: (this: WebSocket, request: ClientRequest, response: IncomingMessage) => void,
|
||||
): this;
|
||||
off(event: string | symbol, listener: (this: WebSocket, ...args: any[]) => void): this;
|
||||
|
||||
addListener(event: "close", listener: (code: number, message: string) => void): this;
|
||||
addListener(event: "error", listener: (err: Error) => void): this;
|
||||
addListener(event: "upgrade", listener: (request: IncomingMessage) => void): this;
|
||||
addListener(event: "message", listener: (data: WebSocket.Data) => void): this;
|
||||
addListener(event: "open", listener: () => void): this;
|
||||
addListener(event: "ping" | "pong", listener: (data: Buffer) => void): this;
|
||||
addListener(
|
||||
event: "unexpected-response",
|
||||
listener: (request: ClientRequest, response: IncomingMessage) => void,
|
||||
): this;
|
||||
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
removeListener(event: "close", listener: (code: number, message: string) => void): this;
|
||||
removeListener(event: "error", listener: (err: Error) => void): this;
|
||||
removeListener(event: "upgrade", listener: (request: IncomingMessage) => void): this;
|
||||
removeListener(event: "message", listener: (data: WebSocket.Data) => void): this;
|
||||
removeListener(event: "open", listener: () => void): this;
|
||||
removeListener(event: "ping" | "pong", listener: (data: Buffer) => void): this;
|
||||
removeListener(
|
||||
event: "unexpected-response",
|
||||
listener: (request: ClientRequest, response: IncomingMessage) => void,
|
||||
): this;
|
||||
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
|
||||
declare namespace WebSocket {
|
||||
/**
|
||||
* Data represents the message payload received over the WebSocket.
|
||||
*/
|
||||
type Data = string | Buffer | ArrayBuffer | Buffer[];
|
||||
|
||||
/**
|
||||
* CertMeta represents the accepted types for certificate & key data.
|
||||
*/
|
||||
type CertMeta = string | string[] | Buffer | Buffer[];
|
||||
|
||||
/**
|
||||
* VerifyClientCallbackSync is a synchronous callback used to inspect the
|
||||
* incoming message. The return value (boolean) of the function determines
|
||||
* whether or not to accept the handshake.
|
||||
*/
|
||||
type VerifyClientCallbackSync = (info: { origin: string; secure: boolean; req: IncomingMessage }) => boolean;
|
||||
|
||||
/**
|
||||
* VerifyClientCallbackAsync is an asynchronous callback used to inspect the
|
||||
* incoming message. The return value (boolean) of the function determines
|
||||
* whether or not to accept the handshake.
|
||||
*/
|
||||
type VerifyClientCallbackAsync = (
|
||||
info: { origin: string; secure: boolean; req: IncomingMessage },
|
||||
callback: (res: boolean, code?: number, message?: string, headers?: OutgoingHttpHeaders) => void,
|
||||
) => void;
|
||||
|
||||
interface ClientOptions extends SecureContextOptions {
|
||||
protocol?: string | undefined;
|
||||
followRedirects?: boolean | undefined;
|
||||
handshakeTimeout?: number | undefined;
|
||||
maxRedirects?: number | undefined;
|
||||
perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined;
|
||||
localAddress?: string | undefined;
|
||||
protocolVersion?: number | undefined;
|
||||
headers?: { [key: string]: string } | undefined;
|
||||
origin?: string | undefined;
|
||||
agent?: Agent | undefined;
|
||||
host?: string | undefined;
|
||||
family?: number | undefined;
|
||||
checkServerIdentity?(servername: string, cert: CertMeta): boolean;
|
||||
rejectUnauthorized?: boolean | undefined;
|
||||
maxPayload?: number | undefined;
|
||||
}
|
||||
|
||||
interface PerMessageDeflateOptions {
|
||||
serverNoContextTakeover?: boolean | undefined;
|
||||
clientNoContextTakeover?: boolean | undefined;
|
||||
serverMaxWindowBits?: number | undefined;
|
||||
clientMaxWindowBits?: number | undefined;
|
||||
zlibDeflateOptions?: {
|
||||
flush?: number | undefined;
|
||||
finishFlush?: number | undefined;
|
||||
chunkSize?: number | undefined;
|
||||
windowBits?: number | undefined;
|
||||
level?: number | undefined;
|
||||
memLevel?: number | undefined;
|
||||
strategy?: number | undefined;
|
||||
dictionary?: Buffer | Buffer[] | DataView | undefined;
|
||||
info?: boolean | undefined;
|
||||
} | undefined;
|
||||
zlibInflateOptions?: ZlibOptions | undefined;
|
||||
threshold?: number | undefined;
|
||||
concurrencyLimit?: number | undefined;
|
||||
}
|
||||
|
||||
interface OpenEvent {
|
||||
type: string;
|
||||
target: WebSocket;
|
||||
}
|
||||
|
||||
interface ErrorEvent {
|
||||
error: any;
|
||||
message: string;
|
||||
type: string;
|
||||
target: WebSocket;
|
||||
}
|
||||
|
||||
interface CloseEvent {
|
||||
wasClean: boolean;
|
||||
code: number;
|
||||
reason: string;
|
||||
type: string;
|
||||
target: WebSocket;
|
||||
}
|
||||
|
||||
interface MessageEvent {
|
||||
data: Data;
|
||||
type: string;
|
||||
target: WebSocket;
|
||||
}
|
||||
|
||||
interface EventListenerOptions {
|
||||
once?: boolean | undefined;
|
||||
}
|
||||
|
||||
interface ServerOptions {
|
||||
host?: string | undefined;
|
||||
port?: number | undefined;
|
||||
backlog?: number | undefined;
|
||||
server?: HTTPServer | HTTPSServer | undefined;
|
||||
verifyClient?: VerifyClientCallbackAsync | VerifyClientCallbackSync | undefined;
|
||||
handleProtocols?: any;
|
||||
path?: string | undefined;
|
||||
noServer?: boolean | undefined;
|
||||
clientTracking?: boolean | undefined;
|
||||
perMessageDeflate?: boolean | PerMessageDeflateOptions | undefined;
|
||||
maxPayload?: number | undefined;
|
||||
}
|
||||
|
||||
interface AddressInfo {
|
||||
address: string;
|
||||
family: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
// WebSocket Server
|
||||
class Server extends EventEmitter {
|
||||
options: ServerOptions;
|
||||
path: string;
|
||||
clients: Set<WebSocket>;
|
||||
|
||||
constructor(options?: ServerOptions, callback?: () => void);
|
||||
|
||||
address(): AddressInfo | string;
|
||||
close(cb?: (err?: Error) => void): void;
|
||||
handleUpgrade(
|
||||
request: IncomingMessage,
|
||||
socket: Socket,
|
||||
upgradeHead: Buffer,
|
||||
callback: (client: WebSocket, request: IncomingMessage) => void,
|
||||
): void;
|
||||
shouldHandle(request: IncomingMessage): boolean | Promise<boolean>;
|
||||
|
||||
// Events
|
||||
on(event: "connection", cb: (this: Server, socket: WebSocket, request: IncomingMessage) => void): this;
|
||||
on(event: "error", cb: (this: Server, error: Error) => void): this;
|
||||
on(event: "headers", cb: (this: Server, headers: string[], request: IncomingMessage) => void): this;
|
||||
on(event: "close" | "listening", cb: (this: Server) => void): this;
|
||||
on(event: string | symbol, listener: (this: Server, ...args: any[]) => void): this;
|
||||
|
||||
once(event: "connection", cb: (this: Server, socket: WebSocket, request: IncomingMessage) => void): this;
|
||||
once(event: "error", cb: (this: Server, error: Error) => void): this;
|
||||
once(event: "headers", cb: (this: Server, headers: string[], request: IncomingMessage) => void): this;
|
||||
once(event: "close" | "listening", cb: (this: Server) => void): this;
|
||||
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
off(event: "connection", cb: (this: Server, socket: WebSocket, request: IncomingMessage) => void): this;
|
||||
off(event: "error", cb: (this: Server, error: Error) => void): this;
|
||||
off(event: "headers", cb: (this: Server, headers: string[], request: IncomingMessage) => void): this;
|
||||
off(event: "close" | "listening", cb: (this: Server) => void): this;
|
||||
off(event: string | symbol, listener: (this: Server, ...args: any[]) => void): this;
|
||||
|
||||
addListener(event: "connection", cb: (client: WebSocket, request: IncomingMessage) => void): this;
|
||||
addListener(event: "error", cb: (err: Error) => void): this;
|
||||
addListener(event: "headers", cb: (headers: string[], request: IncomingMessage) => void): this;
|
||||
addListener(event: "close" | "listening", cb: () => void): this;
|
||||
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
|
||||
removeListener(event: "connection", cb: (client: WebSocket) => void): this;
|
||||
removeListener(event: "error", cb: (err: Error) => void): this;
|
||||
removeListener(event: "headers", cb: (headers: string[], request: IncomingMessage) => void): this;
|
||||
removeListener(event: "close" | "listening", cb: () => void): this;
|
||||
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
|
||||
// WebSocket stream
|
||||
function createWebSocketStream(websocket: WebSocket, options?: DuplexOptions): Duplex;
|
||||
}
|
||||
|
||||
export = WebSocket;
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @fileoverview Rule to check that spaced function application
|
||||
* @author Matt DuVall <http://www.mattduvall.com>
|
||||
* @deprecated in ESLint v3.3.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow spacing between function identifiers and their applications (deprecated)",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-spaced-func",
|
||||
},
|
||||
|
||||
deprecated: {
|
||||
message: "Formatting rules are being moved out of ESLint core.",
|
||||
url: "https://eslint.org/blog/2016/08/eslint-v3.3.0-released/#deprecated-rules",
|
||||
deprecatedSince: "3.3.0",
|
||||
availableUntil: "11.0.0",
|
||||
replacedBy: [
|
||||
{
|
||||
message:
|
||||
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
||||
url: "https://eslint.style/guide/migration",
|
||||
plugin: {
|
||||
name: "@stylistic/eslint-plugin",
|
||||
url: "https://eslint.style",
|
||||
},
|
||||
rule: {
|
||||
name: "function-call-spacing",
|
||||
url: "https://eslint.style/rules/function-call-spacing",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
noSpacedFunction:
|
||||
"Unexpected space between function name and paren.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Check if open space is present in a function name
|
||||
* @param {ASTNode} node node to evaluate
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function detectOpenSpaces(node) {
|
||||
const lastCalleeToken = sourceCode.getLastToken(node.callee);
|
||||
let prevToken = lastCalleeToken,
|
||||
parenToken = sourceCode.getTokenAfter(lastCalleeToken);
|
||||
|
||||
// advances to an open parenthesis.
|
||||
while (
|
||||
parenToken &&
|
||||
parenToken.range[1] < node.range[1] &&
|
||||
parenToken.value !== "("
|
||||
) {
|
||||
prevToken = parenToken;
|
||||
parenToken = sourceCode.getTokenAfter(parenToken);
|
||||
}
|
||||
|
||||
// look for a space between the callee and the open paren
|
||||
if (
|
||||
parenToken &&
|
||||
parenToken.range[1] < node.range[1] &&
|
||||
sourceCode.isSpaceBetween(prevToken, parenToken)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
loc: lastCalleeToken.loc.start,
|
||||
messageId: "noSpacedFunction",
|
||||
fix(fixer) {
|
||||
return fixer.removeRange([
|
||||
prevToken.range[1],
|
||||
parenToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: detectOpenSpaces,
|
||||
NewExpression: detectOpenSpaces,
|
||||
};
|
||||
},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import ThreadStream from '../index.js'
|
||||
import { join } from 'desm'
|
||||
import { file } from './helper.js'
|
||||
|
||||
test('preserves multibyte records that cross the buffer boundary', async () => {
|
||||
const dest = file()
|
||||
const stream = new ThreadStream({
|
||||
bufferSize: 128,
|
||||
filename: join(import.meta.url, 'to-file.js'),
|
||||
workerData: { dest },
|
||||
sync: false
|
||||
})
|
||||
|
||||
let expected = ''
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const line = `{"idx":${i},"alert":"🚨"}\n`
|
||||
expected += line
|
||||
stream.write(line)
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
stream.once('error', reject)
|
||||
stream.once('close', resolve)
|
||||
stream.end()
|
||||
})
|
||||
|
||||
const data = await readFile(dest, 'utf8')
|
||||
assert.strictEqual(data, expected)
|
||||
})
|
||||
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
// NOTE: this file is isolated to be shared across legacy and flat configs.
|
||||
/**
|
||||
* This is a compatibility ruleset that:
|
||||
* - disables rules from eslint:recommended which are already handled by TypeScript.
|
||||
* - enables rules that make sense due to TS's typechecking / transpilation.
|
||||
*/
|
||||
const config = (style) => ({
|
||||
files: style === 'glob'
|
||||
? // classic configs use glob syntax
|
||||
['*.ts', '*.tsx', '*.mts', '*.cts']
|
||||
: // flat configs use minimatch syntax
|
||||
['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
|
||||
rules: {
|
||||
'constructor-super': 'off', // ts(2335) & ts(2377)
|
||||
'getter-return': 'off', // ts(2378)
|
||||
'no-class-assign': 'off', // ts(2629)
|
||||
'no-const-assign': 'off', // ts(2588)
|
||||
'no-dupe-args': 'off', // ts(2300)
|
||||
'no-dupe-class-members': 'off', // ts(2393) & ts(2300)
|
||||
'no-dupe-keys': 'off', // ts(1117)
|
||||
'no-func-assign': 'off', // ts(2630)
|
||||
'no-import-assign': 'off', // ts(2632) & ts(2540)
|
||||
'no-new-native-nonconstructor': 'off', // ts(7009)
|
||||
// "no-new-symbol" was deprecated in ESLint 9.0.0 and will be removed in
|
||||
// ESLint v11.0.0. See:
|
||||
// https://eslint.org/docs/latest/rules/no-new-symbol
|
||||
// We need to keep the rule disabled until TSESLint drops support for
|
||||
// ESlint 8. See:
|
||||
// https://github.com/typescript-eslint/typescript-eslint/pull/8895
|
||||
'no-new-symbol': 'off', // ts(7009)
|
||||
'no-obj-calls': 'off', // ts(2349)
|
||||
'no-redeclare': 'off', // ts(2451)
|
||||
'no-setter-return': 'off', // ts(2408)
|
||||
'no-this-before-super': 'off', // ts(2376) & ts(17009)
|
||||
'no-undef': 'off', // ts(2304) & ts(2552)
|
||||
'no-unreachable': 'off', // ts(7027)
|
||||
'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358)
|
||||
'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more
|
||||
'no-with': 'off', // ts(1101) & ts(2410)
|
||||
'prefer-const': 'error', // ts provides better types with const
|
||||
'prefer-rest-params': 'error', // ts provides better types with rest args over arguments
|
||||
'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply
|
||||
},
|
||||
});
|
||||
module.exports = config;
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Following query was used to generate this file:
|
||||
|
||||
SELECT json_object_agg(UPPER(PT.typname), PT.oid::int4 ORDER BY pt.oid)
|
||||
FROM pg_type PT
|
||||
WHERE typnamespace = (SELECT pgn.oid FROM pg_namespace pgn WHERE nspname = 'pg_catalog') -- Take only builting Postgres types with stable OID (extension types are not guaranted to be stable)
|
||||
AND typtype = 'b' -- Only basic types
|
||||
AND typelem = 0 -- Ignore aliases
|
||||
AND typisdefined -- Ignore undefined types
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
BOOL: 16,
|
||||
BYTEA: 17,
|
||||
CHAR: 18,
|
||||
INT8: 20,
|
||||
INT2: 21,
|
||||
INT4: 23,
|
||||
REGPROC: 24,
|
||||
TEXT: 25,
|
||||
OID: 26,
|
||||
TID: 27,
|
||||
XID: 28,
|
||||
CID: 29,
|
||||
JSON: 114,
|
||||
XML: 142,
|
||||
PG_NODE_TREE: 194,
|
||||
SMGR: 210,
|
||||
PATH: 602,
|
||||
POLYGON: 604,
|
||||
CIDR: 650,
|
||||
FLOAT4: 700,
|
||||
FLOAT8: 701,
|
||||
ABSTIME: 702,
|
||||
RELTIME: 703,
|
||||
TINTERVAL: 704,
|
||||
CIRCLE: 718,
|
||||
MACADDR8: 774,
|
||||
MONEY: 790,
|
||||
MACADDR: 829,
|
||||
INET: 869,
|
||||
ACLITEM: 1033,
|
||||
BPCHAR: 1042,
|
||||
VARCHAR: 1043,
|
||||
DATE: 1082,
|
||||
TIME: 1083,
|
||||
TIMESTAMP: 1114,
|
||||
TIMESTAMPTZ: 1184,
|
||||
INTERVAL: 1186,
|
||||
TIMETZ: 1266,
|
||||
BIT: 1560,
|
||||
VARBIT: 1562,
|
||||
NUMERIC: 1700,
|
||||
REFCURSOR: 1790,
|
||||
REGPROCEDURE: 2202,
|
||||
REGOPER: 2203,
|
||||
REGOPERATOR: 2204,
|
||||
REGCLASS: 2205,
|
||||
REGTYPE: 2206,
|
||||
UUID: 2950,
|
||||
TXID_SNAPSHOT: 2970,
|
||||
PG_LSN: 3220,
|
||||
PG_NDISTINCT: 3361,
|
||||
PG_DEPENDENCIES: 3402,
|
||||
TSVECTOR: 3614,
|
||||
TSQUERY: 3615,
|
||||
GTSVECTOR: 3642,
|
||||
REGCONFIG: 3734,
|
||||
REGDICTIONARY: 3769,
|
||||
JSONB: 3802,
|
||||
REGNAMESPACE: 4089,
|
||||
REGROLE: 4096
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
import { _ as _object_without_properties_loose } from "./_object_without_properties_loose.js";
|
||||
|
||||
function _object_without_properties(source, excluded) {
|
||||
if (source == null) return {};
|
||||
|
||||
var target = {}, sourceKeys, key, i;
|
||||
if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
|
||||
sourceKeys = Reflect.ownKeys(Object(source));
|
||||
for (i = 0; i < sourceKeys.length; i++) {
|
||||
key = sourceKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
target = _object_without_properties_loose(source, excluded);
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
sourceKeys = Object.getOwnPropertySymbols(source);
|
||||
for (i = 0; i < sourceKeys.length; i++) {
|
||||
key = sourceKeys[i];
|
||||
if (excluded.indexOf(key) >= 0) continue;
|
||||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
export { _object_without_properties as _ };
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"type": "module",
|
||||
"main": "wrapper.js"
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { allProcessors } from "./json-schema-processors.js";
|
||||
import { extractDefs, finalize, initializeContext, process, } from "./to-json-schema.js";
|
||||
/**
|
||||
* Legacy class-based interface for JSON Schema generation.
|
||||
* This class wraps the new functional implementation to provide backward compatibility.
|
||||
*
|
||||
* @deprecated Use the `toJSONSchema` function instead for new code.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Legacy usage (still supported)
|
||||
* const gen = new JSONSchemaGenerator({ target: "draft-07" });
|
||||
* gen.process(schema);
|
||||
* const result = gen.emit(schema);
|
||||
*
|
||||
* // Preferred modern usage
|
||||
* const result = toJSONSchema(schema, { target: "draft-07" });
|
||||
* ```
|
||||
*/
|
||||
export class JSONSchemaGenerator {
|
||||
/** @deprecated Access via ctx instead */
|
||||
get metadataRegistry() {
|
||||
return this.ctx.metadataRegistry;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get target() {
|
||||
return this.ctx.target;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get unrepresentable() {
|
||||
return this.ctx.unrepresentable;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get override() {
|
||||
return this.ctx.override;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get io() {
|
||||
return this.ctx.io;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get counter() {
|
||||
return this.ctx.counter;
|
||||
}
|
||||
set counter(value) {
|
||||
this.ctx.counter = value;
|
||||
}
|
||||
/** @deprecated Access via ctx instead */
|
||||
get seen() {
|
||||
return this.ctx.seen;
|
||||
}
|
||||
constructor(params) {
|
||||
// Normalize target for internal context
|
||||
let normalizedTarget = params?.target ?? "draft-2020-12";
|
||||
if (normalizedTarget === "draft-4")
|
||||
normalizedTarget = "draft-04";
|
||||
if (normalizedTarget === "draft-7")
|
||||
normalizedTarget = "draft-07";
|
||||
this.ctx = initializeContext({
|
||||
processors: allProcessors,
|
||||
target: normalizedTarget,
|
||||
...(params?.metadata && { metadata: params.metadata }),
|
||||
...(params?.unrepresentable && { unrepresentable: params.unrepresentable }),
|
||||
...(params?.override && { override: params.override }),
|
||||
...(params?.io && { io: params.io }),
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Process a schema to prepare it for JSON Schema generation.
|
||||
* This must be called before emit().
|
||||
*/
|
||||
process(schema, _params = { path: [], schemaPath: [] }) {
|
||||
return process(schema, this.ctx, _params);
|
||||
}
|
||||
/**
|
||||
* Emit the final JSON Schema after processing.
|
||||
* Must call process() first.
|
||||
*/
|
||||
emit(schema, _params) {
|
||||
// Apply emit params to the context
|
||||
if (_params) {
|
||||
if (_params.cycles)
|
||||
this.ctx.cycles = _params.cycles;
|
||||
if (_params.reused)
|
||||
this.ctx.reused = _params.reused;
|
||||
if (_params.external)
|
||||
this.ctx.external = _params.external;
|
||||
}
|
||||
extractDefs(this.ctx, schema);
|
||||
const result = finalize(this.ctx, schema);
|
||||
// Strip ~standard property to match old implementation's return type
|
||||
const { "~standard": _, ...plainResult } = result;
|
||||
return plainResult;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.blake512 = exports.blake384 = exports.blake256 = exports.blake224 = exports.BLAKE512 = exports.BLAKE384 = exports.BLAKE256 = exports.BLAKE224 = void 0;
|
||||
/**
|
||||
* Blake1 legacy hash function, one of SHA3 proposals.
|
||||
* Rarely used. Check out blake2 or blake3 instead.
|
||||
* https://www.aumasson.jp/blake/blake.pdf
|
||||
*
|
||||
* In the best case, there are 0 allocations.
|
||||
*
|
||||
* Differences from blake2:
|
||||
*
|
||||
* - BE instead of LE
|
||||
* - Paddings, similar to MD5, RIPEMD, SHA1, SHA2, but:
|
||||
* - length flag is located before actual length
|
||||
* - padding block is compressed differently (no lengths)
|
||||
* Instead of msg[sigma[k]], we have `msg[sigma[k]] ^ constants[sigma[k-1]]`
|
||||
* (-1 for g1, g2 without -1)
|
||||
* - Salt is XOR-ed into constants instead of state
|
||||
* - Salt is XOR-ed with output in `compress`
|
||||
* - Additional rows (+64 bytes) in SIGMA for new rounds
|
||||
* - Different round count:
|
||||
* - 14 / 10 rounds in blake256 / blake2s
|
||||
* - 16 / 12 rounds in blake512 / blake2b
|
||||
* - blake512: G1b: rotr 24 -> 25, G2b: rotr 63 -> 11
|
||||
* @module
|
||||
*/
|
||||
const _blake_ts_1 = require("./_blake.js");
|
||||
const _md_ts_1 = require("./_md.js");
|
||||
const u64 = require("./_u64.js");
|
||||
// prettier-ignore
|
||||
const utils_ts_1 = require("./utils.js");
|
||||
// Empty zero-filled salt
|
||||
const EMPTY_SALT = /* @__PURE__ */ new Uint32Array(8);
|
||||
class BLAKE1 extends utils_ts_1.Hash {
|
||||
constructor(blockLen, outputLen, lengthFlag, counterLen, saltLen, constants, opts = {}) {
|
||||
super();
|
||||
this.finished = false;
|
||||
this.length = 0;
|
||||
this.pos = 0;
|
||||
this.destroyed = false;
|
||||
const { salt } = opts;
|
||||
this.blockLen = blockLen;
|
||||
this.outputLen = outputLen;
|
||||
this.lengthFlag = lengthFlag;
|
||||
this.counterLen = counterLen;
|
||||
this.buffer = new Uint8Array(blockLen);
|
||||
this.view = (0, utils_ts_1.createView)(this.buffer);
|
||||
if (salt) {
|
||||
let slt = salt;
|
||||
slt = (0, utils_ts_1.toBytes)(slt);
|
||||
(0, utils_ts_1.abytes)(slt);
|
||||
if (slt.length !== 4 * saltLen)
|
||||
throw new Error('wrong salt length');
|
||||
const salt32 = (this.salt = new Uint32Array(saltLen));
|
||||
const sv = (0, utils_ts_1.createView)(slt);
|
||||
this.constants = constants.slice();
|
||||
for (let i = 0, offset = 0; i < salt32.length; i++, offset += 4) {
|
||||
salt32[i] = sv.getUint32(offset, false);
|
||||
this.constants[i] ^= salt32[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.salt = EMPTY_SALT;
|
||||
this.constants = constants;
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
(0, utils_ts_1.aexists)(this);
|
||||
data = (0, utils_ts_1.toBytes)(data);
|
||||
(0, utils_ts_1.abytes)(data);
|
||||
// From _md, but update length before each compress
|
||||
const { view, buffer, blockLen } = this;
|
||||
const len = data.length;
|
||||
let dataView;
|
||||
for (let pos = 0; pos < len;) {
|
||||
const take = Math.min(blockLen - this.pos, len - pos);
|
||||
// Fast path: we have at least one block in input, cast it to view and process
|
||||
if (take === blockLen) {
|
||||
if (!dataView)
|
||||
dataView = (0, utils_ts_1.createView)(data);
|
||||
for (; blockLen <= len - pos; pos += blockLen) {
|
||||
this.length += blockLen;
|
||||
this.compress(dataView, pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
buffer.set(data.subarray(pos, pos + take), this.pos);
|
||||
this.pos += take;
|
||||
pos += take;
|
||||
if (this.pos === blockLen) {
|
||||
this.length += blockLen;
|
||||
this.compress(view, 0, true);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy() {
|
||||
this.destroyed = true;
|
||||
if (this.salt !== EMPTY_SALT) {
|
||||
(0, utils_ts_1.clean)(this.salt, this.constants);
|
||||
}
|
||||
}
|
||||
_cloneInto(to) {
|
||||
to || (to = new this.constructor());
|
||||
to.set(...this.get());
|
||||
const { buffer, length, finished, destroyed, constants, salt, pos } = this;
|
||||
to.buffer.set(buffer);
|
||||
to.constants = constants.slice();
|
||||
to.destroyed = destroyed;
|
||||
to.finished = finished;
|
||||
to.length = length;
|
||||
to.pos = pos;
|
||||
to.salt = salt.slice();
|
||||
return to;
|
||||
}
|
||||
clone() {
|
||||
return this._cloneInto();
|
||||
}
|
||||
digestInto(out) {
|
||||
(0, utils_ts_1.aexists)(this);
|
||||
(0, utils_ts_1.aoutput)(out, this);
|
||||
this.finished = true;
|
||||
// Padding
|
||||
const { buffer, blockLen, counterLen, lengthFlag, view } = this;
|
||||
(0, utils_ts_1.clean)(buffer.subarray(this.pos)); // clean buf
|
||||
const counter = BigInt((this.length + this.pos) * 8);
|
||||
const counterPos = blockLen - counterLen - 1;
|
||||
buffer[this.pos] |= 128; // End block flag
|
||||
this.length += this.pos; // add unwritten length
|
||||
// Not enough in buffer for length: write what we have.
|
||||
if (this.pos > counterPos) {
|
||||
this.compress(view, 0);
|
||||
(0, utils_ts_1.clean)(buffer);
|
||||
this.pos = 0;
|
||||
}
|
||||
// Difference with md: here we have lengthFlag!
|
||||
buffer[counterPos] |= lengthFlag; // Length flag
|
||||
// We always set 8 byte length flag. Because length will overflow significantly sooner.
|
||||
(0, _md_ts_1.setBigUint64)(view, blockLen - 8, counter, false);
|
||||
this.compress(view, 0, this.pos !== 0); // don't add length if length is not empty block?
|
||||
// Write output
|
||||
(0, utils_ts_1.clean)(buffer);
|
||||
const v = (0, utils_ts_1.createView)(out);
|
||||
const state = this.get();
|
||||
for (let i = 0; i < this.outputLen / 4; ++i)
|
||||
v.setUint32(i * 4, state[i]);
|
||||
}
|
||||
digest() {
|
||||
const { buffer, outputLen } = this;
|
||||
this.digestInto(buffer);
|
||||
const res = buffer.slice(0, outputLen);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
// Constants
|
||||
const B64C = /* @__PURE__ */ Uint32Array.from([
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b, 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
||||
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69,
|
||||
]);
|
||||
// first half of C512
|
||||
const B32C = B64C.slice(0, 16);
|
||||
const B256_IV = _md_ts_1.SHA256_IV.slice();
|
||||
const B224_IV = _md_ts_1.SHA224_IV.slice();
|
||||
const B384_IV = _md_ts_1.SHA384_IV.slice();
|
||||
const B512_IV = _md_ts_1.SHA512_IV.slice();
|
||||
function generateTBL256() {
|
||||
const TBL = [];
|
||||
for (let i = 0, j = 0; i < 14; i++, j += 16) {
|
||||
for (let offset = 1; offset < 16; offset += 2) {
|
||||
TBL.push(B32C[_blake_ts_1.BSIGMA[j + offset]]);
|
||||
TBL.push(B32C[_blake_ts_1.BSIGMA[j + offset - 1]]);
|
||||
}
|
||||
}
|
||||
return new Uint32Array(TBL);
|
||||
}
|
||||
const TBL256 = /* @__PURE__ */ generateTBL256(); // C256[SIGMA[X]] precompute
|
||||
// Reusable temporary buffer
|
||||
const BLAKE256_W = /* @__PURE__ */ new Uint32Array(16);
|
||||
class Blake1_32 extends BLAKE1 {
|
||||
constructor(outputLen, IV, lengthFlag, opts = {}) {
|
||||
super(64, outputLen, lengthFlag, 8, 4, B32C, opts);
|
||||
this.v0 = IV[0] | 0;
|
||||
this.v1 = IV[1] | 0;
|
||||
this.v2 = IV[2] | 0;
|
||||
this.v3 = IV[3] | 0;
|
||||
this.v4 = IV[4] | 0;
|
||||
this.v5 = IV[5] | 0;
|
||||
this.v6 = IV[6] | 0;
|
||||
this.v7 = IV[7] | 0;
|
||||
}
|
||||
get() {
|
||||
const { v0, v1, v2, v3, v4, v5, v6, v7 } = this;
|
||||
return [v0, v1, v2, v3, v4, v5, v6, v7];
|
||||
}
|
||||
// prettier-ignore
|
||||
set(v0, v1, v2, v3, v4, v5, v6, v7) {
|
||||
this.v0 = v0 | 0;
|
||||
this.v1 = v1 | 0;
|
||||
this.v2 = v2 | 0;
|
||||
this.v3 = v3 | 0;
|
||||
this.v4 = v4 | 0;
|
||||
this.v5 = v5 | 0;
|
||||
this.v6 = v6 | 0;
|
||||
this.v7 = v7 | 0;
|
||||
}
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
compress(view, offset, withLength = true) {
|
||||
for (let i = 0; i < 16; i++, offset += 4)
|
||||
BLAKE256_W[i] = view.getUint32(offset, false);
|
||||
// NOTE: we cannot re-use compress from blake2s, since there is additional xor over u256[SIGMA[e]]
|
||||
let v00 = this.v0 | 0;
|
||||
let v01 = this.v1 | 0;
|
||||
let v02 = this.v2 | 0;
|
||||
let v03 = this.v3 | 0;
|
||||
let v04 = this.v4 | 0;
|
||||
let v05 = this.v5 | 0;
|
||||
let v06 = this.v6 | 0;
|
||||
let v07 = this.v7 | 0;
|
||||
let v08 = this.constants[0] | 0;
|
||||
let v09 = this.constants[1] | 0;
|
||||
let v10 = this.constants[2] | 0;
|
||||
let v11 = this.constants[3] | 0;
|
||||
const { h, l } = u64.fromBig(BigInt(withLength ? this.length * 8 : 0));
|
||||
let v12 = (this.constants[4] ^ l) >>> 0;
|
||||
let v13 = (this.constants[5] ^ l) >>> 0;
|
||||
let v14 = (this.constants[6] ^ h) >>> 0;
|
||||
let v15 = (this.constants[7] ^ h) >>> 0;
|
||||
// prettier-ignore
|
||||
for (let i = 0, k = 0, j = 0; i < 14; i++) {
|
||||
({ a: v00, b: v04, c: v08, d: v12 } = (0, _blake_ts_1.G1s)(v00, v04, v08, v12, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v04, c: v08, d: v12 } = (0, _blake_ts_1.G2s)(v00, v04, v08, v12, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v05, c: v09, d: v13 } = (0, _blake_ts_1.G1s)(v01, v05, v09, v13, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v05, c: v09, d: v13 } = (0, _blake_ts_1.G2s)(v01, v05, v09, v13, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v06, c: v10, d: v14 } = (0, _blake_ts_1.G1s)(v02, v06, v10, v14, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v06, c: v10, d: v14 } = (0, _blake_ts_1.G2s)(v02, v06, v10, v14, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v07, c: v11, d: v15 } = (0, _blake_ts_1.G1s)(v03, v07, v11, v15, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v07, c: v11, d: v15 } = (0, _blake_ts_1.G2s)(v03, v07, v11, v15, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v05, c: v10, d: v15 } = (0, _blake_ts_1.G1s)(v00, v05, v10, v15, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v05, c: v10, d: v15 } = (0, _blake_ts_1.G2s)(v00, v05, v10, v15, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v06, c: v11, d: v12 } = (0, _blake_ts_1.G1s)(v01, v06, v11, v12, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v06, c: v11, d: v12 } = (0, _blake_ts_1.G2s)(v01, v06, v11, v12, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v07, c: v08, d: v13 } = (0, _blake_ts_1.G1s)(v02, v07, v08, v13, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v07, c: v08, d: v13 } = (0, _blake_ts_1.G2s)(v02, v07, v08, v13, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v04, c: v09, d: v14 } = (0, _blake_ts_1.G1s)(v03, v04, v09, v14, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v04, c: v09, d: v14 } = (0, _blake_ts_1.G2s)(v03, v04, v09, v14, BLAKE256_W[_blake_ts_1.BSIGMA[k++]] ^ TBL256[j++]));
|
||||
}
|
||||
this.v0 = (this.v0 ^ v00 ^ v08 ^ this.salt[0]) >>> 0;
|
||||
this.v1 = (this.v1 ^ v01 ^ v09 ^ this.salt[1]) >>> 0;
|
||||
this.v2 = (this.v2 ^ v02 ^ v10 ^ this.salt[2]) >>> 0;
|
||||
this.v3 = (this.v3 ^ v03 ^ v11 ^ this.salt[3]) >>> 0;
|
||||
this.v4 = (this.v4 ^ v04 ^ v12 ^ this.salt[0]) >>> 0;
|
||||
this.v5 = (this.v5 ^ v05 ^ v13 ^ this.salt[1]) >>> 0;
|
||||
this.v6 = (this.v6 ^ v06 ^ v14 ^ this.salt[2]) >>> 0;
|
||||
this.v7 = (this.v7 ^ v07 ^ v15 ^ this.salt[3]) >>> 0;
|
||||
(0, utils_ts_1.clean)(BLAKE256_W);
|
||||
}
|
||||
}
|
||||
const BBUF = /* @__PURE__ */ new Uint32Array(32);
|
||||
const BLAKE512_W = /* @__PURE__ */ new Uint32Array(32);
|
||||
function generateTBL512() {
|
||||
const TBL = [];
|
||||
for (let r = 0, k = 0; r < 16; r++, k += 16) {
|
||||
for (let offset = 1; offset < 16; offset += 2) {
|
||||
TBL.push(B64C[_blake_ts_1.BSIGMA[k + offset] * 2 + 0]);
|
||||
TBL.push(B64C[_blake_ts_1.BSIGMA[k + offset] * 2 + 1]);
|
||||
TBL.push(B64C[_blake_ts_1.BSIGMA[k + offset - 1] * 2 + 0]);
|
||||
TBL.push(B64C[_blake_ts_1.BSIGMA[k + offset - 1] * 2 + 1]);
|
||||
}
|
||||
}
|
||||
return new Uint32Array(TBL);
|
||||
}
|
||||
const TBL512 = /* @__PURE__ */ generateTBL512(); // C512[SIGMA[X]] precompute
|
||||
// Mixing function G splitted in two halfs
|
||||
function G1b(a, b, c, d, msg, k) {
|
||||
const Xpos = 2 * _blake_ts_1.BSIGMA[k];
|
||||
const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore
|
||||
let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore
|
||||
let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore
|
||||
let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore
|
||||
let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore
|
||||
// v[a] = (v[a] + v[b] + x) | 0;
|
||||
let ll = u64.add3L(Al, Bl, Xl);
|
||||
Ah = u64.add3H(ll, Ah, Bh, Xh) >>> 0;
|
||||
Al = (ll | 0) >>> 0;
|
||||
// v[d] = rotr(v[d] ^ v[a], 32)
|
||||
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||||
({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) });
|
||||
// v[c] = (v[c] + v[d]) | 0;
|
||||
({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl));
|
||||
// v[b] = rotr(v[b] ^ v[c], 25)
|
||||
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||||
({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 25), Bl: u64.rotrSL(Bh, Bl, 25) });
|
||||
(BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah);
|
||||
(BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh);
|
||||
(BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch);
|
||||
(BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh);
|
||||
}
|
||||
function G2b(a, b, c, d, msg, k) {
|
||||
const Xpos = 2 * _blake_ts_1.BSIGMA[k];
|
||||
const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore
|
||||
let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore
|
||||
let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore
|
||||
let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore
|
||||
let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore
|
||||
// v[a] = (v[a] + v[b] + x) | 0;
|
||||
let ll = u64.add3L(Al, Bl, Xl);
|
||||
Ah = u64.add3H(ll, Ah, Bh, Xh);
|
||||
Al = ll | 0;
|
||||
// v[d] = rotr(v[d] ^ v[a], 16)
|
||||
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||||
({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) });
|
||||
// v[c] = (v[c] + v[d]) | 0;
|
||||
({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl));
|
||||
// v[b] = rotr(v[b] ^ v[c], 11)
|
||||
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||||
({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 11), Bl: u64.rotrSL(Bh, Bl, 11) });
|
||||
(BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah);
|
||||
(BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh);
|
||||
(BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch);
|
||||
(BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh);
|
||||
}
|
||||
class Blake1_64 extends BLAKE1 {
|
||||
constructor(outputLen, IV, lengthFlag, opts = {}) {
|
||||
super(128, outputLen, lengthFlag, 16, 8, B64C, opts);
|
||||
this.v0l = IV[0] | 0;
|
||||
this.v0h = IV[1] | 0;
|
||||
this.v1l = IV[2] | 0;
|
||||
this.v1h = IV[3] | 0;
|
||||
this.v2l = IV[4] | 0;
|
||||
this.v2h = IV[5] | 0;
|
||||
this.v3l = IV[6] | 0;
|
||||
this.v3h = IV[7] | 0;
|
||||
this.v4l = IV[8] | 0;
|
||||
this.v4h = IV[9] | 0;
|
||||
this.v5l = IV[10] | 0;
|
||||
this.v5h = IV[11] | 0;
|
||||
this.v6l = IV[12] | 0;
|
||||
this.v6h = IV[13] | 0;
|
||||
this.v7l = IV[14] | 0;
|
||||
this.v7h = IV[15] | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
get() {
|
||||
let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this;
|
||||
return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h];
|
||||
}
|
||||
// prettier-ignore
|
||||
set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) {
|
||||
this.v0l = v0l | 0;
|
||||
this.v0h = v0h | 0;
|
||||
this.v1l = v1l | 0;
|
||||
this.v1h = v1h | 0;
|
||||
this.v2l = v2l | 0;
|
||||
this.v2h = v2h | 0;
|
||||
this.v3l = v3l | 0;
|
||||
this.v3h = v3h | 0;
|
||||
this.v4l = v4l | 0;
|
||||
this.v4h = v4h | 0;
|
||||
this.v5l = v5l | 0;
|
||||
this.v5h = v5h | 0;
|
||||
this.v6l = v6l | 0;
|
||||
this.v6h = v6h | 0;
|
||||
this.v7l = v7l | 0;
|
||||
this.v7h = v7h | 0;
|
||||
}
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
compress(view, offset, withLength = true) {
|
||||
for (let i = 0; i < 32; i++, offset += 4)
|
||||
BLAKE512_W[i] = view.getUint32(offset, false);
|
||||
this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state.
|
||||
BBUF.set(this.constants.subarray(0, 16), 16);
|
||||
if (withLength) {
|
||||
const { h, l } = u64.fromBig(BigInt(this.length * 8));
|
||||
BBUF[24] = (BBUF[24] ^ h) >>> 0;
|
||||
BBUF[25] = (BBUF[25] ^ l) >>> 0;
|
||||
BBUF[26] = (BBUF[26] ^ h) >>> 0;
|
||||
BBUF[27] = (BBUF[27] ^ l) >>> 0;
|
||||
}
|
||||
for (let i = 0, k = 0; i < 16; i++) {
|
||||
G1b(0, 4, 8, 12, BLAKE512_W, k++);
|
||||
G2b(0, 4, 8, 12, BLAKE512_W, k++);
|
||||
G1b(1, 5, 9, 13, BLAKE512_W, k++);
|
||||
G2b(1, 5, 9, 13, BLAKE512_W, k++);
|
||||
G1b(2, 6, 10, 14, BLAKE512_W, k++);
|
||||
G2b(2, 6, 10, 14, BLAKE512_W, k++);
|
||||
G1b(3, 7, 11, 15, BLAKE512_W, k++);
|
||||
G2b(3, 7, 11, 15, BLAKE512_W, k++);
|
||||
G1b(0, 5, 10, 15, BLAKE512_W, k++);
|
||||
G2b(0, 5, 10, 15, BLAKE512_W, k++);
|
||||
G1b(1, 6, 11, 12, BLAKE512_W, k++);
|
||||
G2b(1, 6, 11, 12, BLAKE512_W, k++);
|
||||
G1b(2, 7, 8, 13, BLAKE512_W, k++);
|
||||
G2b(2, 7, 8, 13, BLAKE512_W, k++);
|
||||
G1b(3, 4, 9, 14, BLAKE512_W, k++);
|
||||
G2b(3, 4, 9, 14, BLAKE512_W, k++);
|
||||
}
|
||||
this.v0l ^= BBUF[0] ^ BBUF[16] ^ this.salt[0];
|
||||
this.v0h ^= BBUF[1] ^ BBUF[17] ^ this.salt[1];
|
||||
this.v1l ^= BBUF[2] ^ BBUF[18] ^ this.salt[2];
|
||||
this.v1h ^= BBUF[3] ^ BBUF[19] ^ this.salt[3];
|
||||
this.v2l ^= BBUF[4] ^ BBUF[20] ^ this.salt[4];
|
||||
this.v2h ^= BBUF[5] ^ BBUF[21] ^ this.salt[5];
|
||||
this.v3l ^= BBUF[6] ^ BBUF[22] ^ this.salt[6];
|
||||
this.v3h ^= BBUF[7] ^ BBUF[23] ^ this.salt[7];
|
||||
this.v4l ^= BBUF[8] ^ BBUF[24] ^ this.salt[0];
|
||||
this.v4h ^= BBUF[9] ^ BBUF[25] ^ this.salt[1];
|
||||
this.v5l ^= BBUF[10] ^ BBUF[26] ^ this.salt[2];
|
||||
this.v5h ^= BBUF[11] ^ BBUF[27] ^ this.salt[3];
|
||||
this.v6l ^= BBUF[12] ^ BBUF[28] ^ this.salt[4];
|
||||
this.v6h ^= BBUF[13] ^ BBUF[29] ^ this.salt[5];
|
||||
this.v7l ^= BBUF[14] ^ BBUF[30] ^ this.salt[6];
|
||||
this.v7h ^= BBUF[15] ^ BBUF[31] ^ this.salt[7];
|
||||
(0, utils_ts_1.clean)(BBUF, BLAKE512_W);
|
||||
}
|
||||
}
|
||||
class BLAKE224 extends Blake1_32 {
|
||||
constructor(opts = {}) {
|
||||
super(28, B224_IV, 0, opts);
|
||||
}
|
||||
}
|
||||
exports.BLAKE224 = BLAKE224;
|
||||
class BLAKE256 extends Blake1_32 {
|
||||
constructor(opts = {}) {
|
||||
super(32, B256_IV, 1, opts);
|
||||
}
|
||||
}
|
||||
exports.BLAKE256 = BLAKE256;
|
||||
class BLAKE384 extends Blake1_64 {
|
||||
constructor(opts = {}) {
|
||||
super(48, B384_IV, 0, opts);
|
||||
}
|
||||
}
|
||||
exports.BLAKE384 = BLAKE384;
|
||||
class BLAKE512 extends Blake1_64 {
|
||||
constructor(opts = {}) {
|
||||
super(64, B512_IV, 1, opts);
|
||||
}
|
||||
}
|
||||
exports.BLAKE512 = BLAKE512;
|
||||
/** blake1-224 hash function */
|
||||
exports.blake224 = (0, utils_ts_1.createOptHasher)((opts) => new BLAKE224(opts));
|
||||
/** blake1-256 hash function */
|
||||
exports.blake256 = (0, utils_ts_1.createOptHasher)((opts) => new BLAKE256(opts));
|
||||
/** blake1-384 hash function */
|
||||
exports.blake384 = (0, utils_ts_1.createOptHasher)((opts) => new BLAKE384(opts));
|
||||
/** blake1-512 hash function */
|
||||
exports.blake512 = (0, utils_ts_1.createOptHasher)((opts) => new BLAKE512(opts));
|
||||
//# sourceMappingURL=blake1.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
"use strict";var r="4.23.12";exports.version=r;
|
||||
@@ -0,0 +1,4 @@
|
||||
function _class_check_private_static_access(receiver, classConstructor) {
|
||||
if (receiver !== classConstructor) throw new TypeError("Private static access of wrong provenance");
|
||||
}
|
||||
export { _class_check_private_static_access as _ };
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
function _is_native_function(fn) {
|
||||
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
||||
}
|
||||
exports._ = _is_native_function;
|
||||
@@ -0,0 +1,102 @@
|
||||
var pSlice = Array.prototype.slice;
|
||||
var Object_keys = typeof Object.keys === 'function'
|
||||
? Object.keys
|
||||
: function (obj) {
|
||||
var keys = [];
|
||||
for (var key in obj) keys.push(key);
|
||||
return keys;
|
||||
}
|
||||
;
|
||||
|
||||
var deepEqual = module.exports = function (actual, expected) {
|
||||
// enforce Object.is +0 !== -0
|
||||
if (actual === 0 && expected === 0) {
|
||||
return areZerosEqual(actual, expected);
|
||||
|
||||
// 7.1. All identical values are equivalent, as determined by ===.
|
||||
} else if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
} else if (isNumberNaN(actual)) {
|
||||
return isNumberNaN(expected);
|
||||
|
||||
// 7.3. Other pairs that do not both pass typeof value == 'object',
|
||||
// equivalence is determined by ==.
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
|
||||
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
||||
// determined by having the same number of owned properties (as verified
|
||||
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
||||
// (although not necessarily the same order), equivalent values for every
|
||||
// corresponding key, and an identical 'prototype' property. Note: this
|
||||
// accounts for both named and indexed properties on Arrays.
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
};
|
||||
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isArguments(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
function isNumberNaN(value) {
|
||||
// NaN === NaN -> false
|
||||
return typeof value == 'number' && value !== value;
|
||||
}
|
||||
|
||||
function areZerosEqual(zeroA, zeroB) {
|
||||
// (1 / +0|0) -> Infinity, but (1 / -0) -> -Infinity and (Infinity !== -Infinity)
|
||||
return (1 / zeroA) === (1 / zeroB);
|
||||
}
|
||||
|
||||
function objEquiv(a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
|
||||
// an identical 'prototype' property.
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
//~~~I've managed to break Object.keys through screwy arguments passing.
|
||||
// Converting to array solves the problem.
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return deepEqual(a, b);
|
||||
}
|
||||
try {
|
||||
var ka = Object_keys(a),
|
||||
kb = Object_keys(b),
|
||||
key, i;
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
// having the same number of owned properties (keys incorporates
|
||||
// hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!deepEqual(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user