WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,882 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
const assertionFunctionUtils_1 = require("../util/assertionFunctionUtils");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'strict-boolean-expressions',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Disallow certain types in boolean expressions',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
hasSuggestions: true,
|
||||
messages: {
|
||||
conditionErrorAny: 'Unexpected any value in {{context}}. ' +
|
||||
'An explicit comparison or type conversion is required.',
|
||||
conditionErrorNullableBoolean: 'Unexpected nullable boolean value in {{context}}. ' +
|
||||
'Please handle the nullish case explicitly.',
|
||||
conditionErrorNullableEnum: 'Unexpected nullable enum value in {{context}}. ' +
|
||||
'Please handle the nullish/zero/NaN cases explicitly.',
|
||||
conditionErrorNullableNumber: 'Unexpected nullable number value in {{context}}. ' +
|
||||
'Please handle the nullish/zero/NaN cases explicitly.',
|
||||
conditionErrorNullableObject: 'Unexpected nullable object value in {{context}}. ' +
|
||||
'An explicit null check is required.',
|
||||
conditionErrorNullableString: 'Unexpected nullable string value in {{context}}. ' +
|
||||
'Please handle the nullish/empty cases explicitly.',
|
||||
conditionErrorNullish: 'Unexpected nullish value in conditional. ' +
|
||||
'The condition is always false.',
|
||||
conditionErrorNumber: 'Unexpected number value in {{context}}. ' +
|
||||
'An explicit zero/NaN check is required.',
|
||||
conditionErrorObject: 'Unexpected object value in {{context}}. ' +
|
||||
'The condition is always true.',
|
||||
conditionErrorOther: 'Unexpected value in conditional. ' +
|
||||
'A boolean expression is required.',
|
||||
conditionErrorString: 'Unexpected string value in {{context}}. ' +
|
||||
'An explicit empty string check is required.',
|
||||
conditionFixCastBoolean: 'Explicitly convert value to a boolean (`Boolean(value)`)',
|
||||
conditionFixCompareArrayLengthNonzero: "Change condition to check array's length (`value.length > 0`)",
|
||||
conditionFixCompareArrayLengthZero: "Change condition to check array's length (`value.length === 0`)",
|
||||
conditionFixCompareEmptyString: 'Change condition to check for empty string (`value !== ""`)',
|
||||
conditionFixCompareFalse: 'Change condition to check if false (`value === false`)',
|
||||
conditionFixCompareNaN: 'Change condition to check for NaN (`!Number.isNaN(value)`)',
|
||||
conditionFixCompareNullish: 'Change condition to check for null/undefined (`value != null`)',
|
||||
conditionFixCompareStringLength: "Change condition to check string's length (`value.length !== 0`)",
|
||||
conditionFixCompareTrue: 'Change condition to check if true (`value === true`)',
|
||||
conditionFixCompareZero: 'Change condition to check for 0 (`value !== 0`)',
|
||||
conditionFixDefaultEmptyString: 'Explicitly treat nullish value the same as an empty string (`value ?? ""`)',
|
||||
conditionFixDefaultFalse: 'Explicitly treat nullish value the same as false (`value ?? false`)',
|
||||
conditionFixDefaultZero: 'Explicitly treat nullish value the same as 0 (`value ?? 0`)',
|
||||
explicitBooleanReturnType: 'Add an explicit `boolean` return type annotation.',
|
||||
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
|
||||
predicateCannotBeAsync: "Predicate function should not be 'async'; expected a boolean return type.",
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowAny: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow `any`s in a boolean context.',
|
||||
},
|
||||
allowNullableBoolean: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow nullable `boolean`s in a boolean context.',
|
||||
},
|
||||
allowNullableEnum: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow nullable `enum`s in a boolean context.',
|
||||
},
|
||||
allowNullableNumber: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow nullable `number`s in a boolean context.',
|
||||
},
|
||||
allowNullableObject: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow nullable `object`s, `symbol`s, and functions in a boolean context.',
|
||||
},
|
||||
allowNullableString: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow nullable `string`s in a boolean context.',
|
||||
},
|
||||
allowNumber: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow `number`s in a boolean context.',
|
||||
},
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
|
||||
type: 'boolean',
|
||||
description: 'Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.',
|
||||
},
|
||||
allowString: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow `string`s in a boolean context.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowAny: false,
|
||||
allowNullableBoolean: false,
|
||||
allowNullableEnum: false,
|
||||
allowNullableNumber: false,
|
||||
allowNullableObject: true,
|
||||
allowNullableString: false,
|
||||
allowNumber: true,
|
||||
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
|
||||
allowString: true,
|
||||
},
|
||||
],
|
||||
create(context, [options]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const checker = services.program.getTypeChecker();
|
||||
const compilerOptions = services.program.getCompilerOptions();
|
||||
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
|
||||
if (!isStrictNullChecks &&
|
||||
options.allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { column: 0, line: 0 },
|
||||
end: { column: 0, line: 0 },
|
||||
},
|
||||
messageId: 'noStrictNullCheck',
|
||||
});
|
||||
}
|
||||
const traversedNodes = new Set();
|
||||
return {
|
||||
CallExpression: traverseCallExpression,
|
||||
ConditionalExpression: traverseTestExpression,
|
||||
DoWhileStatement: traverseTestExpression,
|
||||
ForStatement: traverseTestExpression,
|
||||
IfStatement: traverseTestExpression,
|
||||
'LogicalExpression[operator!="??"]': traverseLogicalExpression,
|
||||
'UnaryExpression[operator="!"]': traverseUnaryLogicalExpression,
|
||||
WhileStatement: traverseTestExpression,
|
||||
};
|
||||
/**
|
||||
* Inspects condition of a test expression. (`if`, `while`, `for`, etc.)
|
||||
*/
|
||||
function traverseTestExpression(node) {
|
||||
if (node.test == null) {
|
||||
return;
|
||||
}
|
||||
traverseNode(node.test, true);
|
||||
}
|
||||
/**
|
||||
* Inspects the argument of a unary logical expression (`!`).
|
||||
*/
|
||||
function traverseUnaryLogicalExpression(node) {
|
||||
traverseNode(node.argument, true);
|
||||
}
|
||||
/**
|
||||
* Inspects the arguments of a logical expression (`&&`, `||`).
|
||||
*
|
||||
* If the logical expression is a descendant of a test expression,
|
||||
* the `isCondition` flag should be set to true.
|
||||
* Otherwise, if the logical expression is there on it's own,
|
||||
* it's used for control flow and is not a condition itself.
|
||||
*/
|
||||
function traverseLogicalExpression(node, isCondition = false) {
|
||||
// left argument is always treated as a condition
|
||||
traverseNode(node.left, true);
|
||||
// if the logical expression is used for control flow,
|
||||
// then its right argument is used for its side effects only
|
||||
traverseNode(node.right, isCondition);
|
||||
}
|
||||
function traverseCallExpression(node) {
|
||||
const assertedArgument = (0, assertionFunctionUtils_1.findTruthinessAssertedArgument)(services, node);
|
||||
if (assertedArgument != null) {
|
||||
traverseNode(assertedArgument, true);
|
||||
}
|
||||
if ((0, util_1.isArrayMethodCallWithPredicate)(context, services, node)) {
|
||||
const predicate = node.arguments.at(0);
|
||||
if (predicate) {
|
||||
checkArrayMethodCallPredicate(predicate);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Dedicated function to check array method predicate calls. Reports predicate
|
||||
* arguments that don't return a boolean value.
|
||||
*/
|
||||
function checkArrayMethodCallPredicate(predicateNode) {
|
||||
const isFunctionExpression = utils_1.ASTUtils.isFunction(predicateNode);
|
||||
// custom message for accidental `async` function expressions
|
||||
if (isFunctionExpression && predicateNode.async) {
|
||||
return context.report({
|
||||
node: predicateNode,
|
||||
messageId: 'predicateCannotBeAsync',
|
||||
});
|
||||
}
|
||||
const returnTypes = services
|
||||
.getTypeAtLocation(predicateNode)
|
||||
.getCallSignatures()
|
||||
.map(signature => {
|
||||
const type = signature.getReturnType();
|
||||
if (tsutils.isTypeParameter(type)) {
|
||||
return checker.getBaseConstraintOfType(type) ?? type;
|
||||
}
|
||||
return type;
|
||||
});
|
||||
const flattenTypes = [
|
||||
...new Set(returnTypes.flatMap(type => tsutils.unionConstituents(type))),
|
||||
];
|
||||
const types = inspectVariantTypes(flattenTypes);
|
||||
const reportType = determineReportType(types);
|
||||
if (reportType == null) {
|
||||
return;
|
||||
}
|
||||
const suggestions = [];
|
||||
if (isFunctionExpression &&
|
||||
predicateNode.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
||||
suggestions.push(...getSuggestionsForConditionError(predicateNode.body, reportType));
|
||||
}
|
||||
if (isFunctionExpression && !predicateNode.returnType) {
|
||||
suggestions.push({
|
||||
messageId: 'explicitBooleanReturnType',
|
||||
fix: fixer => {
|
||||
if (predicateNode.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
|
||||
(0, util_1.isParenlessArrowFunction)(predicateNode, context.sourceCode)) {
|
||||
return [
|
||||
fixer.insertTextBefore(predicateNode.params[0], '('),
|
||||
fixer.insertTextAfter(predicateNode.params[0], '): boolean'),
|
||||
];
|
||||
}
|
||||
if (predicateNode.params.length === 0) {
|
||||
const closingBracket = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(predicateNode, token => token.value === ')'), 'function expression has to have a closing parenthesis.');
|
||||
return fixer.insertTextAfter(closingBracket, ': boolean');
|
||||
}
|
||||
const lastClosingParenthesis = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(predicateNode.params[predicateNode.params.length - 1], token => token.value === ')'), 'function expression has to have a closing parenthesis.');
|
||||
return fixer.insertTextAfter(lastClosingParenthesis, ': boolean');
|
||||
},
|
||||
});
|
||||
}
|
||||
return context.report({
|
||||
node: predicateNode,
|
||||
messageId: reportType,
|
||||
data: {
|
||||
context: 'array predicate return type',
|
||||
},
|
||||
suggest: suggestions,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Inspects any node.
|
||||
*
|
||||
* If it's a logical expression then it recursively traverses its arguments.
|
||||
* If it's any other kind of node then it's type is finally checked against the rule,
|
||||
* unless `isCondition` flag is set to false, in which case
|
||||
* it's assumed to be used for side effects only and is skipped.
|
||||
*/
|
||||
function traverseNode(node, isCondition) {
|
||||
// prevent checking the same node multiple times
|
||||
if (traversedNodes.has(node)) {
|
||||
return;
|
||||
}
|
||||
traversedNodes.add(node);
|
||||
// for logical operator, we check its operands
|
||||
if (node.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
||||
node.operator !== '??') {
|
||||
traverseLogicalExpression(node, isCondition);
|
||||
return;
|
||||
}
|
||||
// skip if node is not a condition
|
||||
if (!isCondition) {
|
||||
return;
|
||||
}
|
||||
checkNode(node);
|
||||
}
|
||||
function determineReportType(types) {
|
||||
const is = (...wantedTypes) => types.size === wantedTypes.length &&
|
||||
wantedTypes.every(type => types.has(type));
|
||||
// boolean
|
||||
if (is('boolean') || is('truthy boolean')) {
|
||||
// boolean is always ok
|
||||
return undefined;
|
||||
}
|
||||
// never
|
||||
if (is('never')) {
|
||||
// never is always okay
|
||||
return undefined;
|
||||
}
|
||||
// nullish
|
||||
if (is('nullish')) {
|
||||
// condition is always false
|
||||
return 'conditionErrorNullish';
|
||||
}
|
||||
// Known edge case: boolean `true` and nullish values are always valid boolean expressions
|
||||
if (is('nullish', 'truthy boolean')) {
|
||||
return;
|
||||
}
|
||||
// nullable boolean
|
||||
if (is('nullish', 'boolean')) {
|
||||
return !options.allowNullableBoolean
|
||||
? 'conditionErrorNullableBoolean'
|
||||
: undefined;
|
||||
}
|
||||
// Known edge case: truthy primitives and nullish values are always valid boolean expressions
|
||||
if ((options.allowNumber && is('nullish', 'truthy number')) ||
|
||||
(options.allowString && is('nullish', 'truthy string'))) {
|
||||
return;
|
||||
}
|
||||
// string
|
||||
if (is('string') || is('truthy string')) {
|
||||
return !options.allowString ? 'conditionErrorString' : undefined;
|
||||
}
|
||||
// nullable string
|
||||
if (is('nullish', 'string')) {
|
||||
return !options.allowNullableString
|
||||
? 'conditionErrorNullableString'
|
||||
: undefined;
|
||||
}
|
||||
// number
|
||||
if (is('number') || is('truthy number')) {
|
||||
return !options.allowNumber ? 'conditionErrorNumber' : undefined;
|
||||
}
|
||||
// nullable number
|
||||
if (is('nullish', 'number')) {
|
||||
return !options.allowNullableNumber
|
||||
? 'conditionErrorNullableNumber'
|
||||
: undefined;
|
||||
}
|
||||
// object
|
||||
if (is('object')) {
|
||||
return 'conditionErrorObject';
|
||||
}
|
||||
// nullable object
|
||||
if (is('nullish', 'object')) {
|
||||
return !options.allowNullableObject
|
||||
? 'conditionErrorNullableObject'
|
||||
: undefined;
|
||||
}
|
||||
// nullable enum
|
||||
if (is('nullish', 'number', 'enum') ||
|
||||
is('nullish', 'string', 'enum') ||
|
||||
is('nullish', 'truthy number', 'enum') ||
|
||||
is('nullish', 'truthy string', 'enum') ||
|
||||
// mixed enums
|
||||
is('nullish', 'truthy number', 'truthy string', 'enum') ||
|
||||
is('nullish', 'truthy number', 'string', 'enum') ||
|
||||
is('nullish', 'truthy string', 'number', 'enum') ||
|
||||
is('nullish', 'number', 'string', 'enum')) {
|
||||
return !options.allowNullableEnum
|
||||
? 'conditionErrorNullableEnum'
|
||||
: undefined;
|
||||
}
|
||||
// any
|
||||
if (is('any')) {
|
||||
return !options.allowAny ? 'conditionErrorAny' : undefined;
|
||||
}
|
||||
return 'conditionErrorOther';
|
||||
}
|
||||
function getSuggestionsForConditionError(node, conditionError) {
|
||||
switch (conditionError) {
|
||||
case 'conditionErrorAny':
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNullableBoolean':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!nullableBoolean)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixDefaultFalse',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? false`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCompareFalse',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} === false`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (nullableBoolean)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixDefaultFalse',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? false`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCompareTrue',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} === true`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNullableEnum':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} == null`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} != null`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNullableNumber':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!nullableNumber)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} == null`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixDefaultZero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `!Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (nullableNumber)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} != null`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixDefaultZero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNullableObject':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!nullableObject)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} == null`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (nullableObject)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} != null`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNullableString':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!nullableString)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} == null`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixDefaultEmptyString',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? ""`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `!Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (nullableString)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareNullish',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} != null`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixDefaultEmptyString',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} ?? ""`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorNumber':
|
||||
if (isArrayLengthExpression(node, checker, services)) {
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!array.length)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareArrayLengthZero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} === 0`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (array.length)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareArrayLengthNonzero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} > 0`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!number)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareZero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
// TODO: we have to compare to 0n if the type is bigint
|
||||
wrap: code => `${code} === 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
// TODO: don't suggest this for bigint because it can't be NaN
|
||||
messageId: 'conditionFixCompareNaN',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Number.isNaN(${code})`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `!Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (number)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareZero',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} !== 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCompareNaN',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `!Number.isNaN(${code})`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorString':
|
||||
if (isLogicalNegationExpression(node.parent)) {
|
||||
// if (!string)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareStringLength',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code}.length === 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCompareEmptyString',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} === ""`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node: node.parent,
|
||||
innerNode: node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `!Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
// if (string)
|
||||
return [
|
||||
{
|
||||
messageId: 'conditionFixCompareStringLength',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code}.length > 0`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCompareEmptyString',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `${code} !== ""`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
messageId: 'conditionFixCastBoolean',
|
||||
fix: (0, util_1.getWrappingFixer)({
|
||||
node,
|
||||
sourceCode: context.sourceCode,
|
||||
wrap: code => `Boolean(${code})`,
|
||||
}),
|
||||
},
|
||||
];
|
||||
case 'conditionErrorObject':
|
||||
case 'conditionErrorNullish':
|
||||
case 'conditionErrorOther':
|
||||
return [];
|
||||
default:
|
||||
conditionError;
|
||||
throw new Error('Unreachable');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This function does the actual type check on a node.
|
||||
* It analyzes the type of a node and checks if it is allowed in a boolean context.
|
||||
*/
|
||||
function checkNode(node) {
|
||||
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
||||
const types = inspectVariantTypes(tsutils.unionConstituents(type));
|
||||
const reportType = determineReportType(types);
|
||||
if (reportType != null) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: reportType,
|
||||
data: {
|
||||
context: 'conditional',
|
||||
},
|
||||
suggest: getSuggestionsForConditionError(node, reportType),
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check union variants for the types we care about
|
||||
*/
|
||||
function inspectVariantTypes(types) {
|
||||
const variantTypes = new Set();
|
||||
if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike))) {
|
||||
variantTypes.add('nullish');
|
||||
}
|
||||
const booleans = types.filter(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.BooleanLike));
|
||||
// If incoming type is either "true" or "false", there will be one type
|
||||
// object with intrinsicName set accordingly
|
||||
// If incoming type is boolean, there will be two type objects with
|
||||
// intrinsicName set "true" and "false" each because of ts-api-utils.unionConstituents()
|
||||
if (booleans.length === 1) {
|
||||
variantTypes.add(tsutils.isTrueLiteralType(booleans[0]) ? 'truthy boolean' : 'boolean');
|
||||
}
|
||||
else if (booleans.length === 2) {
|
||||
variantTypes.add('boolean');
|
||||
}
|
||||
const strings = types.filter(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike));
|
||||
if (strings.length) {
|
||||
if (strings.every(type => type.isStringLiteral() && type.value !== '')) {
|
||||
variantTypes.add('truthy string');
|
||||
}
|
||||
else {
|
||||
variantTypes.add('string');
|
||||
}
|
||||
}
|
||||
const numbers = types.filter(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike));
|
||||
if (numbers.length) {
|
||||
if (numbers.every(type => type.isNumberLiteral() && type.value !== 0)) {
|
||||
variantTypes.add('truthy number');
|
||||
}
|
||||
else {
|
||||
variantTypes.add('number');
|
||||
}
|
||||
}
|
||||
if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.EnumLike))) {
|
||||
variantTypes.add('enum');
|
||||
}
|
||||
if (types.some(type => !tsutils.isTypeFlagSet(type, ts.TypeFlags.Null |
|
||||
ts.TypeFlags.Undefined |
|
||||
ts.TypeFlags.VoidLike |
|
||||
ts.TypeFlags.BooleanLike |
|
||||
ts.TypeFlags.StringLike |
|
||||
ts.TypeFlags.NumberLike |
|
||||
ts.TypeFlags.BigIntLike |
|
||||
ts.TypeFlags.TypeParameter |
|
||||
ts.TypeFlags.Any |
|
||||
ts.TypeFlags.Unknown |
|
||||
ts.TypeFlags.Never))) {
|
||||
variantTypes.add(types.some(isBrandedBoolean) ? 'boolean' : 'object');
|
||||
}
|
||||
if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.TypeParameter |
|
||||
ts.TypeFlags.Any |
|
||||
ts.TypeFlags.Unknown))) {
|
||||
variantTypes.add('any');
|
||||
}
|
||||
if (types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.Never))) {
|
||||
variantTypes.add('never');
|
||||
}
|
||||
return variantTypes;
|
||||
}
|
||||
},
|
||||
});
|
||||
function isLogicalNegationExpression(node) {
|
||||
return node.type === utils_1.AST_NODE_TYPES.UnaryExpression && node.operator === '!';
|
||||
}
|
||||
function isArrayLengthExpression(node, typeChecker, services) {
|
||||
if (node.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
|
||||
return false;
|
||||
}
|
||||
if (node.computed) {
|
||||
return false;
|
||||
}
|
||||
if (node.property.name !== 'length') {
|
||||
return false;
|
||||
}
|
||||
const objectType = (0, util_1.getConstrainedTypeAtLocation)(services, node.object);
|
||||
return (0, util_1.isTypeArrayTypeOrUnionOfArrayTypes)(objectType, typeChecker);
|
||||
}
|
||||
/**
|
||||
* Verify is the type is a branded boolean (e.g. `type Foo = boolean & { __brand: 'Foo' }`)
|
||||
*
|
||||
* @param type The type checked
|
||||
*/
|
||||
function isBrandedBoolean(type) {
|
||||
return (type.isIntersection() &&
|
||||
type.types.some(childType => isBooleanType(childType)));
|
||||
}
|
||||
function isBooleanType(expressionType) {
|
||||
return tsutils.isTypeFlagSet(expressionType, ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral);
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const util_1 = require("../util");
|
||||
const explicitReturnTypeUtils_1 = require("../util/explicitReturnTypeUtils");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'explicit-function-return-type',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Require explicit return types on functions and class methods',
|
||||
},
|
||||
messages: {
|
||||
missingReturnType: 'Missing return type on function.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowConciseArrowFunctionExpressionsStartingWithVoid: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow arrow functions that start with the `void` keyword.',
|
||||
},
|
||||
allowDirectConstAssertionInArrowFunctions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore arrow functions immediately returning a `as const` value.',
|
||||
},
|
||||
allowedNames: {
|
||||
type: 'array',
|
||||
description: 'An array of function/method names that will not have their arguments or return values checked.',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
allowExpressions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore function expressions (functions which are not part of a declaration).',
|
||||
},
|
||||
allowFunctionsWithoutTypeParameters: {
|
||||
type: 'boolean',
|
||||
description: "Whether to ignore functions that don't have generic type parameters.",
|
||||
},
|
||||
allowHigherOrderFunctions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore functions immediately returning another function expression.',
|
||||
},
|
||||
allowIIFEs: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore immediately invoked function expressions (IIFEs).',
|
||||
},
|
||||
allowTypedFunctionExpressions: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to ignore type annotations on the variable of function expressions.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowConciseArrowFunctionExpressionsStartingWithVoid: false,
|
||||
allowDirectConstAssertionInArrowFunctions: true,
|
||||
allowedNames: [],
|
||||
allowExpressions: false,
|
||||
allowFunctionsWithoutTypeParameters: false,
|
||||
allowHigherOrderFunctions: true,
|
||||
allowIIFEs: false,
|
||||
allowTypedFunctionExpressions: true,
|
||||
},
|
||||
],
|
||||
create(context, [options]) {
|
||||
const functionInfoStack = [];
|
||||
function enterFunction(node) {
|
||||
functionInfoStack.push({
|
||||
node,
|
||||
returns: [],
|
||||
});
|
||||
}
|
||||
function popFunctionInfo(exitNodeType) {
|
||||
return (0, util_1.nullThrows)(functionInfoStack.pop(), `Stack should exist on ${exitNodeType} exit`);
|
||||
}
|
||||
function isAllowedFunction(node) {
|
||||
if (options.allowFunctionsWithoutTypeParameters && !node.typeParameters) {
|
||||
return true;
|
||||
}
|
||||
if (options.allowIIFEs && isIIFE(node)) {
|
||||
return true;
|
||||
}
|
||||
if (!options.allowedNames?.length) {
|
||||
return false;
|
||||
}
|
||||
if (node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
||||
node.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
||||
const parent = node.parent;
|
||||
let funcName;
|
||||
if (node.id?.name) {
|
||||
funcName = node.id.name;
|
||||
}
|
||||
else {
|
||||
switch (parent.type) {
|
||||
case utils_1.AST_NODE_TYPES.VariableDeclarator: {
|
||||
if (parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
|
||||
funcName = parent.id.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case utils_1.AST_NODE_TYPES.MethodDefinition:
|
||||
case utils_1.AST_NODE_TYPES.PropertyDefinition:
|
||||
case utils_1.AST_NODE_TYPES.Property: {
|
||||
if (parent.key.type === utils_1.AST_NODE_TYPES.Identifier &&
|
||||
!parent.computed) {
|
||||
funcName = parent.key.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!!funcName && options.allowedNames.includes(funcName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration &&
|
||||
node.id &&
|
||||
options.allowedNames.includes(node.id.name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isIIFE(node) {
|
||||
return node.parent.type === utils_1.AST_NODE_TYPES.CallExpression;
|
||||
}
|
||||
function exitFunctionExpression(node) {
|
||||
const info = popFunctionInfo('function expression');
|
||||
if (options.allowConciseArrowFunctionExpressionsStartingWithVoid &&
|
||||
node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
|
||||
node.expression &&
|
||||
node.body.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||||
node.body.operator === 'void') {
|
||||
return;
|
||||
}
|
||||
if (isAllowedFunction(node)) {
|
||||
return;
|
||||
}
|
||||
if (options.allowTypedFunctionExpressions &&
|
||||
((0, explicitReturnTypeUtils_1.isValidFunctionExpressionReturnType)(node, options) ||
|
||||
(0, explicitReturnTypeUtils_1.ancestorHasReturnType)(node))) {
|
||||
return;
|
||||
}
|
||||
(0, explicitReturnTypeUtils_1.checkFunctionReturnType)(info, options, context.sourceCode, loc => context.report({
|
||||
loc,
|
||||
node,
|
||||
messageId: 'missingReturnType',
|
||||
}));
|
||||
}
|
||||
return {
|
||||
'ArrowFunctionExpression, FunctionExpression, FunctionDeclaration': enterFunction,
|
||||
'ArrowFunctionExpression:exit': exitFunctionExpression,
|
||||
'FunctionDeclaration:exit'(node) {
|
||||
const info = popFunctionInfo('function declaration');
|
||||
if (isAllowedFunction(node)) {
|
||||
return;
|
||||
}
|
||||
if (options.allowTypedFunctionExpressions && node.returnType) {
|
||||
return;
|
||||
}
|
||||
(0, explicitReturnTypeUtils_1.checkFunctionReturnType)(info, options, context.sourceCode, loc => context.report({
|
||||
loc,
|
||||
node,
|
||||
messageId: 'missingReturnType',
|
||||
}));
|
||||
},
|
||||
'FunctionExpression:exit': exitFunctionExpression,
|
||||
ReturnStatement(node) {
|
||||
functionInfoStack.at(-1)?.returns.push(node);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,589 @@
|
||||
declare module "node:zlib" {
|
||||
import { NonSharedBuffer } from "node:buffer";
|
||||
import * as stream from "node:stream";
|
||||
interface ZlibOptions {
|
||||
/**
|
||||
* @default constants.Z_NO_FLUSH
|
||||
*/
|
||||
flush?: number | undefined;
|
||||
/**
|
||||
* @default constants.Z_FINISH
|
||||
*/
|
||||
finishFlush?: number | undefined;
|
||||
/**
|
||||
* @default 16*1024
|
||||
*/
|
||||
chunkSize?: number | undefined;
|
||||
windowBits?: number | undefined;
|
||||
/** compression only */
|
||||
level?: number | undefined;
|
||||
/** compression only */
|
||||
memLevel?: number | undefined;
|
||||
/** compression only */
|
||||
strategy?: number | undefined;
|
||||
/** deflate/inflate only, empty dictionary by default */
|
||||
dictionary?: NodeJS.ArrayBufferView | ArrayBuffer | undefined;
|
||||
/**
|
||||
* If `true`, returns an object with `buffer` and `engine`.
|
||||
*/
|
||||
info?: boolean | undefined;
|
||||
/**
|
||||
* Limits output size when using convenience methods.
|
||||
* @default buffer.kMaxLength
|
||||
*/
|
||||
maxOutputLength?: number | undefined;
|
||||
}
|
||||
interface BrotliOptions {
|
||||
/**
|
||||
* @default constants.BROTLI_OPERATION_PROCESS
|
||||
*/
|
||||
flush?: number | undefined;
|
||||
/**
|
||||
* @default constants.BROTLI_OPERATION_FINISH
|
||||
*/
|
||||
finishFlush?: number | undefined;
|
||||
/**
|
||||
* @default 16*1024
|
||||
*/
|
||||
chunkSize?: number | undefined;
|
||||
params?:
|
||||
| {
|
||||
/**
|
||||
* Each key is a `constants.BROTLI_*` constant.
|
||||
*/
|
||||
[key: number]: boolean | number;
|
||||
}
|
||||
| undefined;
|
||||
/**
|
||||
* Limits output size when using [convenience methods](https://nodejs.org/docs/latest-v26.x/api/zlib.html#convenience-methods).
|
||||
* @default buffer.kMaxLength
|
||||
*/
|
||||
maxOutputLength?: number | undefined;
|
||||
/**
|
||||
* If `true`, returns an object with `buffer` and `engine`.
|
||||
*/
|
||||
info?: boolean | undefined;
|
||||
}
|
||||
interface ZstdOptions {
|
||||
/**
|
||||
* @default constants.ZSTD_e_continue
|
||||
*/
|
||||
flush?: number | undefined;
|
||||
/**
|
||||
* @default constants.ZSTD_e_end
|
||||
*/
|
||||
finishFlush?: number | undefined;
|
||||
/**
|
||||
* @default 16 * 1024
|
||||
*/
|
||||
chunkSize?: number | undefined;
|
||||
/**
|
||||
* Key-value object containing indexed
|
||||
* [Zstd parameters](https://nodejs.org/docs/latest-v26.x/api/zlib.html#zstd-constants).
|
||||
*/
|
||||
params?: { [key: number]: number | boolean } | undefined;
|
||||
/**
|
||||
* Limits output size when using
|
||||
* [convenience methods](https://nodejs.org/docs/latest-v26.x/api/zlib.html#convenience-methods).
|
||||
* @default buffer.kMaxLength
|
||||
*/
|
||||
maxOutputLength?: number | undefined;
|
||||
/**
|
||||
* If `true`, returns an object with `buffer` and `engine`.
|
||||
*/
|
||||
info?: boolean | undefined;
|
||||
/**
|
||||
* Optional dictionary used to improve compression efficiency when compressing or decompressing data that
|
||||
* shares common patterns with the dictionary.
|
||||
* @since v24.6.0
|
||||
*/
|
||||
dictionary?: NodeJS.ArrayBufferView | undefined;
|
||||
}
|
||||
interface Zlib {
|
||||
readonly bytesWritten: number;
|
||||
shell?: boolean | string | undefined;
|
||||
close(callback?: () => void): void;
|
||||
flush(kind?: number, callback?: () => void): void;
|
||||
flush(callback?: () => void): void;
|
||||
}
|
||||
interface ZlibParams {
|
||||
params(level: number, strategy: number, callback: () => void): void;
|
||||
}
|
||||
interface ZlibReset {
|
||||
reset(): void;
|
||||
}
|
||||
/**
|
||||
* @since v10.16.0
|
||||
*/
|
||||
class BrotliCompress extends stream.Transform {
|
||||
constructor(options?: BrotliOptions);
|
||||
}
|
||||
interface BrotliCompress extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v10.16.0
|
||||
*/
|
||||
class BrotliDecompress extends stream.Transform {
|
||||
constructor(options?: BrotliOptions);
|
||||
}
|
||||
interface BrotliDecompress extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class Gzip extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface Gzip extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class Gunzip extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface Gunzip extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class Deflate extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface Deflate extends stream.Transform, Zlib, ZlibReset, ZlibParams {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class Inflate extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface Inflate extends stream.Transform, Zlib, ZlibReset {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class DeflateRaw extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface DeflateRaw extends stream.Transform, Zlib, ZlibReset, ZlibParams {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class InflateRaw extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface InflateRaw extends stream.Transform, Zlib, ZlibReset {}
|
||||
/**
|
||||
* @since v0.5.8
|
||||
*/
|
||||
class Unzip extends stream.Transform {
|
||||
constructor(options?: ZlibOptions);
|
||||
}
|
||||
interface Unzip extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
class ZstdCompress extends stream.Transform {
|
||||
constructor(options?: ZstdOptions);
|
||||
}
|
||||
interface ZstdCompress extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
class ZstdDecompress extends stream.Transform {
|
||||
constructor(options?: ZstdOptions);
|
||||
}
|
||||
interface ZstdDecompress extends stream.Transform, Zlib {}
|
||||
/**
|
||||
* Computes a 32-bit [Cyclic Redundancy Check](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) checksum of `data`.
|
||||
* If `value` is specified, it is used as the starting value of the checksum, otherwise, 0 is used as the starting value.
|
||||
* @param data When `data` is a string, it will be encoded as UTF-8 before being used for computation.
|
||||
* @param value An optional starting value. It must be a 32-bit unsigned integer. @default 0
|
||||
* @returns A 32-bit unsigned integer containing the checksum.
|
||||
* @since v22.2.0
|
||||
*/
|
||||
function crc32(data: string | NodeJS.ArrayBufferView, value?: number): number;
|
||||
/**
|
||||
* Creates and returns a new `BrotliCompress` object.
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function createBrotliCompress(options?: BrotliOptions): BrotliCompress;
|
||||
/**
|
||||
* Creates and returns a new `BrotliDecompress` object.
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function createBrotliDecompress(options?: BrotliOptions): BrotliDecompress;
|
||||
/**
|
||||
* Creates and returns a new `Gzip` object.
|
||||
* See `example`.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createGzip(options?: ZlibOptions): Gzip;
|
||||
/**
|
||||
* Creates and returns a new `Gunzip` object.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createGunzip(options?: ZlibOptions): Gunzip;
|
||||
/**
|
||||
* Creates and returns a new `Deflate` object.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createDeflate(options?: ZlibOptions): Deflate;
|
||||
/**
|
||||
* Creates and returns a new `Inflate` object.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createInflate(options?: ZlibOptions): Inflate;
|
||||
/**
|
||||
* Creates and returns a new `DeflateRaw` object.
|
||||
*
|
||||
* An upgrade of zlib from 1.2.8 to 1.2.11 changed behavior when `windowBits` is set to 8 for raw deflate streams. zlib would automatically set `windowBits` to 9 if was initially set to 8. Newer
|
||||
* versions of zlib will throw an exception,
|
||||
* so Node.js restored the original behavior of upgrading a value of 8 to 9,
|
||||
* since passing `windowBits = 9` to zlib actually results in a compressed stream
|
||||
* that effectively uses an 8-bit window only.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createDeflateRaw(options?: ZlibOptions): DeflateRaw;
|
||||
/**
|
||||
* Creates and returns a new `InflateRaw` object.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createInflateRaw(options?: ZlibOptions): InflateRaw;
|
||||
/**
|
||||
* Creates and returns a new `Unzip` object.
|
||||
* @since v0.5.8
|
||||
*/
|
||||
function createUnzip(options?: ZlibOptions): Unzip;
|
||||
/**
|
||||
* Creates and returns a new `ZstdCompress` object.
|
||||
* @since v22.15.0
|
||||
*/
|
||||
function createZstdCompress(options?: ZstdOptions): ZstdCompress;
|
||||
/**
|
||||
* Creates and returns a new `ZstdDecompress` object.
|
||||
* @since v22.15.0
|
||||
*/
|
||||
function createZstdDecompress(options?: ZstdOptions): ZstdDecompress;
|
||||
type InputType = string | ArrayBuffer | NodeJS.ArrayBufferView;
|
||||
type CompressCallback = (error: Error | null, result: NonSharedBuffer) => void;
|
||||
/**
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function brotliCompress(buf: InputType, options: BrotliOptions, callback: CompressCallback): void;
|
||||
function brotliCompress(buf: InputType, callback: CompressCallback): void;
|
||||
namespace brotliCompress {
|
||||
function __promisify__(buffer: InputType, options?: BrotliOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Compress a chunk of data with `BrotliCompress`.
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function brotliCompressSync(buf: InputType, options?: BrotliOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function brotliDecompress(buf: InputType, options: BrotliOptions, callback: CompressCallback): void;
|
||||
function brotliDecompress(buf: InputType, callback: CompressCallback): void;
|
||||
namespace brotliDecompress {
|
||||
function __promisify__(buffer: InputType, options?: BrotliOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `BrotliDecompress`.
|
||||
* @since v11.7.0, v10.16.0
|
||||
*/
|
||||
function brotliDecompressSync(buf: InputType, options?: BrotliOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function deflate(buf: InputType, callback: CompressCallback): void;
|
||||
function deflate(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace deflate {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Compress a chunk of data with `Deflate`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function deflateSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function deflateRaw(buf: InputType, callback: CompressCallback): void;
|
||||
function deflateRaw(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace deflateRaw {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Compress a chunk of data with `DeflateRaw`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function deflateRawSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function gzip(buf: InputType, callback: CompressCallback): void;
|
||||
function gzip(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace gzip {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Compress a chunk of data with `Gzip`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function gzipSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function gunzip(buf: InputType, callback: CompressCallback): void;
|
||||
function gunzip(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace gunzip {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `Gunzip`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function gunzipSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function inflate(buf: InputType, callback: CompressCallback): void;
|
||||
function inflate(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace inflate {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `Inflate`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function inflateSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function inflateRaw(buf: InputType, callback: CompressCallback): void;
|
||||
function inflateRaw(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace inflateRaw {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `InflateRaw`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function inflateRawSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v0.6.0
|
||||
*/
|
||||
function unzip(buf: InputType, callback: CompressCallback): void;
|
||||
function unzip(buf: InputType, options: ZlibOptions, callback: CompressCallback): void;
|
||||
namespace unzip {
|
||||
function __promisify__(buffer: InputType, options?: ZlibOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `Unzip`.
|
||||
* @since v0.11.12
|
||||
*/
|
||||
function unzipSync(buf: InputType, options?: ZlibOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
function zstdCompress(buf: InputType, callback: CompressCallback): void;
|
||||
function zstdCompress(buf: InputType, options: ZstdOptions, callback: CompressCallback): void;
|
||||
namespace zstdCompress {
|
||||
function __promisify__(buffer: InputType, options?: ZstdOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Compress a chunk of data with `ZstdCompress`.
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
function zstdCompressSync(buf: InputType, options?: ZstdOptions): NonSharedBuffer;
|
||||
/**
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
function zstdDecompress(buf: InputType, callback: CompressCallback): void;
|
||||
function zstdDecompress(buf: InputType, options: ZstdOptions, callback: CompressCallback): void;
|
||||
namespace zstdDecompress {
|
||||
function __promisify__(buffer: InputType, options?: ZstdOptions): Promise<NonSharedBuffer>;
|
||||
}
|
||||
/**
|
||||
* Decompress a chunk of data with `ZstdDecompress`.
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
function zstdDecompressSync(buf: InputType, options?: ZstdOptions): NonSharedBuffer;
|
||||
namespace constants {
|
||||
const BROTLI_DECODE: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: number;
|
||||
const BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: number;
|
||||
const BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_DISTANCE: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_PADDING_1: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_PADDING_2: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_RESERVED: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: number;
|
||||
const BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: number;
|
||||
const BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: number;
|
||||
const BROTLI_DECODER_ERROR_UNREACHABLE: number;
|
||||
const BROTLI_DECODER_NEEDS_MORE_INPUT: number;
|
||||
const BROTLI_DECODER_NEEDS_MORE_OUTPUT: number;
|
||||
const BROTLI_DECODER_NO_ERROR: number;
|
||||
const BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: number;
|
||||
const BROTLI_DECODER_PARAM_LARGE_WINDOW: number;
|
||||
const BROTLI_DECODER_RESULT_ERROR: number;
|
||||
const BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: number;
|
||||
const BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: number;
|
||||
const BROTLI_DECODER_RESULT_SUCCESS: number;
|
||||
const BROTLI_DECODER_SUCCESS: number;
|
||||
const BROTLI_DEFAULT_MODE: number;
|
||||
const BROTLI_DEFAULT_QUALITY: number;
|
||||
const BROTLI_DEFAULT_WINDOW: number;
|
||||
const BROTLI_ENCODE: number;
|
||||
const BROTLI_LARGE_MAX_WINDOW_BITS: number;
|
||||
const BROTLI_MAX_INPUT_BLOCK_BITS: number;
|
||||
const BROTLI_MAX_QUALITY: number;
|
||||
const BROTLI_MAX_WINDOW_BITS: number;
|
||||
const BROTLI_MIN_INPUT_BLOCK_BITS: number;
|
||||
const BROTLI_MIN_QUALITY: number;
|
||||
const BROTLI_MIN_WINDOW_BITS: number;
|
||||
const BROTLI_MODE_FONT: number;
|
||||
const BROTLI_MODE_GENERIC: number;
|
||||
const BROTLI_MODE_TEXT: number;
|
||||
const BROTLI_OPERATION_EMIT_METADATA: number;
|
||||
const BROTLI_OPERATION_FINISH: number;
|
||||
const BROTLI_OPERATION_FLUSH: number;
|
||||
const BROTLI_OPERATION_PROCESS: number;
|
||||
const BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: number;
|
||||
const BROTLI_PARAM_LARGE_WINDOW: number;
|
||||
const BROTLI_PARAM_LGBLOCK: number;
|
||||
const BROTLI_PARAM_LGWIN: number;
|
||||
const BROTLI_PARAM_MODE: number;
|
||||
const BROTLI_PARAM_NDIRECT: number;
|
||||
const BROTLI_PARAM_NPOSTFIX: number;
|
||||
const BROTLI_PARAM_QUALITY: number;
|
||||
const BROTLI_PARAM_SIZE_HINT: number;
|
||||
const DEFLATE: number;
|
||||
const DEFLATERAW: number;
|
||||
const GUNZIP: number;
|
||||
const GZIP: number;
|
||||
const INFLATE: number;
|
||||
const INFLATERAW: number;
|
||||
const UNZIP: number;
|
||||
const ZLIB_VERNUM: number;
|
||||
const ZSTD_CLEVEL_DEFAULT: number;
|
||||
const ZSTD_COMPRESS: number;
|
||||
const ZSTD_DECOMPRESS: number;
|
||||
const ZSTD_btlazy2: number;
|
||||
const ZSTD_btopt: number;
|
||||
const ZSTD_btultra: number;
|
||||
const ZSTD_btultra2: number;
|
||||
const ZSTD_c_chainLog: number;
|
||||
const ZSTD_c_checksumFlag: number;
|
||||
const ZSTD_c_compressionLevel: number;
|
||||
const ZSTD_c_contentSizeFlag: number;
|
||||
const ZSTD_c_dictIDFlag: number;
|
||||
const ZSTD_c_enableLongDistanceMatching: number;
|
||||
const ZSTD_c_hashLog: number;
|
||||
const ZSTD_c_jobSize: number;
|
||||
const ZSTD_c_ldmBucketSizeLog: number;
|
||||
const ZSTD_c_ldmHashLog: number;
|
||||
const ZSTD_c_ldmHashRateLog: number;
|
||||
const ZSTD_c_ldmMinMatch: number;
|
||||
const ZSTD_c_minMatch: number;
|
||||
const ZSTD_c_nbWorkers: number;
|
||||
const ZSTD_c_overlapLog: number;
|
||||
const ZSTD_c_searchLog: number;
|
||||
const ZSTD_c_strategy: number;
|
||||
const ZSTD_c_targetLength: number;
|
||||
const ZSTD_c_windowLog: number;
|
||||
const ZSTD_d_windowLogMax: number;
|
||||
const ZSTD_dfast: number;
|
||||
const ZSTD_e_continue: number;
|
||||
const ZSTD_e_end: number;
|
||||
const ZSTD_e_flush: number;
|
||||
const ZSTD_error_GENERIC: number;
|
||||
const ZSTD_error_checksum_wrong: number;
|
||||
const ZSTD_error_corruption_detected: number;
|
||||
const ZSTD_error_dictionaryCreation_failed: number;
|
||||
const ZSTD_error_dictionary_corrupted: number;
|
||||
const ZSTD_error_dictionary_wrong: number;
|
||||
const ZSTD_error_dstBuffer_null: number;
|
||||
const ZSTD_error_dstSize_tooSmall: number;
|
||||
const ZSTD_error_frameParameter_unsupported: number;
|
||||
const ZSTD_error_frameParameter_windowTooLarge: number;
|
||||
const ZSTD_error_init_missing: number;
|
||||
const ZSTD_error_literals_headerWrong: number;
|
||||
const ZSTD_error_maxSymbolValue_tooLarge: number;
|
||||
const ZSTD_error_maxSymbolValue_tooSmall: number;
|
||||
const ZSTD_error_memory_allocation: number;
|
||||
const ZSTD_error_noForwardProgress_destFull: number;
|
||||
const ZSTD_error_noForwardProgress_inputEmpty: number;
|
||||
const ZSTD_error_no_error: number;
|
||||
const ZSTD_error_parameter_combination_unsupported: number;
|
||||
const ZSTD_error_parameter_outOfBound: number;
|
||||
const ZSTD_error_parameter_unsupported: number;
|
||||
const ZSTD_error_prefix_unknown: number;
|
||||
const ZSTD_error_srcSize_wrong: number;
|
||||
const ZSTD_error_stabilityCondition_notRespected: number;
|
||||
const ZSTD_error_stage_wrong: number;
|
||||
const ZSTD_error_tableLog_tooLarge: number;
|
||||
const ZSTD_error_version_unsupported: number;
|
||||
const ZSTD_error_workSpace_tooSmall: number;
|
||||
const ZSTD_fast: number;
|
||||
const ZSTD_greedy: number;
|
||||
const ZSTD_lazy: number;
|
||||
const ZSTD_lazy2: number;
|
||||
const Z_BEST_COMPRESSION: number;
|
||||
const Z_BEST_SPEED: number;
|
||||
const Z_BLOCK: number;
|
||||
const Z_BUF_ERROR: number;
|
||||
const Z_DATA_ERROR: number;
|
||||
const Z_DEFAULT_CHUNK: number;
|
||||
const Z_DEFAULT_COMPRESSION: number;
|
||||
const Z_DEFAULT_LEVEL: number;
|
||||
const Z_DEFAULT_MEMLEVEL: number;
|
||||
const Z_DEFAULT_STRATEGY: number;
|
||||
const Z_DEFAULT_WINDOWBITS: number;
|
||||
const Z_ERRNO: number;
|
||||
const Z_FILTERED: number;
|
||||
const Z_FINISH: number;
|
||||
const Z_FIXED: number;
|
||||
const Z_FULL_FLUSH: number;
|
||||
const Z_HUFFMAN_ONLY: number;
|
||||
const Z_MAX_CHUNK: number;
|
||||
const Z_MAX_LEVEL: number;
|
||||
const Z_MAX_MEMLEVEL: number;
|
||||
const Z_MAX_WINDOWBITS: number;
|
||||
const Z_MEM_ERROR: number;
|
||||
const Z_MIN_CHUNK: number;
|
||||
const Z_MIN_LEVEL: number;
|
||||
const Z_MIN_MEMLEVEL: number;
|
||||
const Z_MIN_WINDOWBITS: number;
|
||||
const Z_NEED_DICT: number;
|
||||
const Z_NO_COMPRESSION: number;
|
||||
const Z_NO_FLUSH: number;
|
||||
const Z_OK: number;
|
||||
const Z_PARTIAL_FLUSH: number;
|
||||
const Z_RLE: number;
|
||||
const Z_STREAM_END: number;
|
||||
const Z_STREAM_ERROR: number;
|
||||
const Z_SYNC_FLUSH: number;
|
||||
const Z_VERSION_ERROR: number;
|
||||
}
|
||||
}
|
||||
declare module "zlib" {
|
||||
export * from "node:zlib";
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
'use strict'
|
||||
|
||||
const parse = require('./parse')
|
||||
const prerelease = (version, options) => {
|
||||
const parsed = parse(version, options)
|
||||
return (parsed && parsed.prerelease.length) ? parsed.prerelease : null
|
||||
}
|
||||
module.exports = prerelease
|
||||
@@ -0,0 +1,58 @@
|
||||
let crypto = require('crypto')
|
||||
|
||||
let { urlAlphabet } = require('./url-alphabet/index.cjs')
|
||||
|
||||
const POOL_SIZE_MULTIPLIER = 128
|
||||
let pool, poolOffset
|
||||
|
||||
let fillPool = bytes => {
|
||||
if (bytes < 0 || bytes > 1024) throw new RangeError('Wrong ID size')
|
||||
if (!pool || pool.length < bytes) {
|
||||
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
|
||||
crypto.randomFillSync(pool)
|
||||
poolOffset = 0
|
||||
} else if (poolOffset + bytes > pool.length) {
|
||||
crypto.randomFillSync(pool)
|
||||
poolOffset = 0
|
||||
}
|
||||
poolOffset += bytes
|
||||
}
|
||||
|
||||
let random = bytes => {
|
||||
fillPool((bytes |= 0))
|
||||
return pool.subarray(poolOffset - bytes, poolOffset)
|
||||
}
|
||||
|
||||
let customRandom = (alphabet, defaultSize, getRandom) => {
|
||||
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
||||
|
||||
|
||||
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
||||
|
||||
return (size = defaultSize) => {
|
||||
if (size <= 0) return ''
|
||||
let id = ''
|
||||
while (true) {
|
||||
let bytes = getRandom(step)
|
||||
let i = step
|
||||
while (i--) {
|
||||
id += alphabet[bytes[i] & mask] || ''
|
||||
if (id.length === size) return id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let customAlphabet = (alphabet, size = 21) =>
|
||||
customRandom(alphabet, size, random)
|
||||
|
||||
let nanoid = (size = 21) => {
|
||||
fillPool((size |= 0))
|
||||
let id = ''
|
||||
for (let i = poolOffset - size; i < poolOffset; i++) {
|
||||
id += urlAlphabet[pool[i] & 63]
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
||||
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PatternMatcher = void 0;
|
||||
const eslintUtils = __importStar(require("@eslint-community/eslint-utils"));
|
||||
/**
|
||||
* The class to find a pattern in strings as handling escape sequences.
|
||||
* It ignores the found pattern if it's escaped with `\`.
|
||||
*
|
||||
* @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#patternmatcher-class}
|
||||
*/
|
||||
exports.PatternMatcher = eslintUtils.PatternMatcher;
|
||||
@@ -0,0 +1,32 @@
|
||||
export {
|
||||
_lt as lt,
|
||||
_lte as lte,
|
||||
_lte as maximum,
|
||||
_gt as gt,
|
||||
_gte as gte,
|
||||
_gte as minimum,
|
||||
_positive as positive,
|
||||
_negative as negative,
|
||||
_nonpositive as nonpositive,
|
||||
_nonnegative as nonnegative,
|
||||
_multipleOf as multipleOf,
|
||||
_maxSize as maxSize,
|
||||
_minSize as minSize,
|
||||
_size as size,
|
||||
_maxLength as maxLength,
|
||||
_minLength as minLength,
|
||||
_length as length,
|
||||
_regex as regex,
|
||||
_lowercase as lowercase,
|
||||
_uppercase as uppercase,
|
||||
_includes as includes,
|
||||
_startsWith as startsWith,
|
||||
_endsWith as endsWith,
|
||||
_property as property,
|
||||
_mime as mime,
|
||||
_overwrite as overwrite,
|
||||
_normalize as normalize,
|
||||
_trim as trim,
|
||||
_toLowerCase as toLowerCase,
|
||||
_toUpperCase as toUpperCase,
|
||||
} from "../core/index.js";
|
||||
@@ -0,0 +1,59 @@
|
||||
# 0.9.0
|
||||
- update dependencies, in particular `levn` and `type-check` - this could affect behaviour of argument parsing
|
||||
|
||||
# 0.8.3
|
||||
- changes dependency from `wordwrap` to `word-wrap` due to license issue
|
||||
- update dependencies
|
||||
|
||||
# 0.8.2
|
||||
- fix bug #18 - detect missing value when flag is last item
|
||||
- update dependencies
|
||||
|
||||
# 0.8.1
|
||||
- update `fast-levenshtein` dependency
|
||||
|
||||
# 0.8.0
|
||||
- update `levn` dependency - supplying a float value to an option with type `Int` now throws an error, instead of silently converting to an `Int`
|
||||
|
||||
# 0.7.1
|
||||
- fix bug with use of `defaults` and `concatRepeatedArrays` or `mergeRepeatedObjects`
|
||||
|
||||
# 0.7.0
|
||||
- added `concatrepeatedarrays` option: `oneValuePerFlag`, only allows one array value per flag
|
||||
- added `typeAliases` option
|
||||
- added `parseArgv` which takes an array and parses with the first two items sliced off
|
||||
- changed enum help style
|
||||
- bug fixes (#12)
|
||||
- use of `concatRepeatedArrays` and `mergeRepeatedObjects` at the top level is deprecated, use it as either a per-option option, or set them in the `defaults` object to set them for all objects
|
||||
|
||||
# 0.6.0
|
||||
- added `defaults` lib-option flag, allowing one to set default properties for all options
|
||||
- added `concatRepeatedArrays` and `mergeRepeatedObjects` as option level properties, allowing you to turn this feature on for specific options only
|
||||
|
||||
# 0.5.0
|
||||
- `Boolean` flags with `default: 'true'`, and no short aliases, will by default show the `--no` version in help
|
||||
|
||||
# 0.4.0
|
||||
- add `mergeRepeatedObjects` setting
|
||||
|
||||
# 0.3.0
|
||||
- add `concatRepeatedArrays` setting
|
||||
- add `overrideRequired` option setting
|
||||
- use just Levenshtein string compare algo rather than Levenshtein Damerau to due dependency license issue
|
||||
|
||||
# 0.2.2
|
||||
- bug fixes
|
||||
|
||||
# 0.2.1
|
||||
- improved interpolation
|
||||
- added changelog
|
||||
|
||||
# 0.2.0
|
||||
- add dependency checks to options - added `dependsOn` as an option property
|
||||
- add interpolation for `prepend` and `append` text with new `generateHelp` option, `interpolate`
|
||||
|
||||
# 0.1.1
|
||||
- update dependencies
|
||||
|
||||
# 0.1.0
|
||||
- initial release
|
||||
@@ -0,0 +1,261 @@
|
||||
[](https://www.npmjs.com/package/espree)
|
||||
[](https://www.npmjs.com/package/espree)
|
||||
[](https://github.com/js/espree/actions)
|
||||
[](https://www.bountysource.com/trackers/9348450-eslint?utm_source=9348450&utm_medium=shield&utm_campaign=TRACKER_BADGE)
|
||||
|
||||
# Espree
|
||||
|
||||
Espree started out as a fork of [Esprima](http://esprima.org) v1.2.2, the last stable published released of Esprima before work on ECMAScript 6 began. Espree is now built on top of [Acorn](https://github.com/ternjs/acorn), which has a modular architecture that allows extension of core functionality. The goal of Espree is to produce output that is similar to Esprima with a similar API so that it can be used in place of Esprima.
|
||||
|
||||
## Usage
|
||||
|
||||
Install:
|
||||
|
||||
```
|
||||
npm i espree
|
||||
```
|
||||
|
||||
To use in an ESM file:
|
||||
|
||||
```js
|
||||
import * as espree from "espree";
|
||||
|
||||
const ast = espree.parse(code);
|
||||
```
|
||||
|
||||
To use in a Common JS file:
|
||||
|
||||
```js
|
||||
const espree = require("espree");
|
||||
|
||||
const ast = espree.parse(code);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `parse()`
|
||||
|
||||
`parse` parses the given code and returns a abstract syntax tree (AST). It takes two parameters.
|
||||
|
||||
- `code` [string]() - the code which needs to be parsed.
|
||||
- `options (Optional)` [Object]() - read more about this [here](#options).
|
||||
|
||||
```js
|
||||
import * as espree from "espree";
|
||||
|
||||
const ast = espree.parse(code);
|
||||
```
|
||||
|
||||
**Example :**
|
||||
|
||||
```js
|
||||
const ast = espree.parse('let foo = "bar"', { ecmaVersion: 6 });
|
||||
console.log(ast);
|
||||
```
|
||||
|
||||
<details><summary>Output</summary>
|
||||
<p>
|
||||
|
||||
```
|
||||
Node {
|
||||
type: 'Program',
|
||||
start: 0,
|
||||
end: 15,
|
||||
body: [
|
||||
Node {
|
||||
type: 'VariableDeclaration',
|
||||
start: 0,
|
||||
end: 15,
|
||||
declarations: [Array],
|
||||
kind: 'let'
|
||||
}
|
||||
],
|
||||
sourceType: 'script'
|
||||
}
|
||||
```
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### `tokenize()`
|
||||
|
||||
`tokenize` returns the tokens of a given code. It takes two parameters.
|
||||
|
||||
- `code` [string]() - the code which needs to be parsed.
|
||||
- `options (Optional)` [Object]() - read more about this [here](#options).
|
||||
|
||||
Even if `options` is empty or undefined or `options.tokens` is `false`, it assigns it to `true` in order to get the `tokens` array
|
||||
|
||||
**Example :**
|
||||
|
||||
```js
|
||||
import * as espree from "espree";
|
||||
|
||||
const tokens = espree.tokenize('let foo = "bar"', { ecmaVersion: 6 });
|
||||
console.log(tokens);
|
||||
```
|
||||
|
||||
<details><summary>Output</summary>
|
||||
<p>
|
||||
|
||||
```
|
||||
Token { type: 'Keyword', value: 'let', start: 0, end: 3 },
|
||||
Token { type: 'Identifier', value: 'foo', start: 4, end: 7 },
|
||||
Token { type: 'Punctuator', value: '=', start: 8, end: 9 },
|
||||
Token { type: 'String', value: '"bar"', start: 10, end: 15 }
|
||||
```
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### `version`
|
||||
|
||||
Returns the current `espree` version
|
||||
|
||||
### `VisitorKeys`
|
||||
|
||||
Returns all visitor keys for traversing the AST from [eslint-visitor-keys](https://github.com/eslint/js/tree/main/packages/eslint-visitor-keys)
|
||||
|
||||
### `latestEcmaVersion`
|
||||
|
||||
Returns the latest ECMAScript supported by `espree`
|
||||
|
||||
### `supportedEcmaVersions`
|
||||
|
||||
Returns an array of all supported ECMAScript versions
|
||||
|
||||
## Options
|
||||
|
||||
```js
|
||||
const options = {
|
||||
// attach range information to each node
|
||||
range: false,
|
||||
|
||||
// attach line/column location information to each node
|
||||
loc: false,
|
||||
|
||||
// create a top-level comments array containing all comments
|
||||
comment: false,
|
||||
|
||||
// create a top-level tokens array containing all tokens
|
||||
tokens: false,
|
||||
|
||||
// Set to 3, 5 (the default), 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 or 17 to specify the version of ECMAScript syntax you want to use.
|
||||
// You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), 2022 (same as 13), 2023 (same as 14), 2024 (same as 15), 2025 (same as 16) or 2026 (same as 17) to use the year-based naming.
|
||||
// You can also set "latest" to use the most recently supported version.
|
||||
ecmaVersion: 3,
|
||||
|
||||
allowReserved: true, // only allowed when ecmaVersion is 3
|
||||
|
||||
// specify which type of script you're parsing ("script", "module", or "commonjs")
|
||||
sourceType: "script",
|
||||
|
||||
// specify additional language features
|
||||
ecmaFeatures: {
|
||||
// enable JSX parsing
|
||||
jsx: false,
|
||||
|
||||
// enable return in global scope (set to true automatically when sourceType is "commonjs")
|
||||
globalReturn: false,
|
||||
|
||||
// enable implied strict mode (if ecmaVersion >= 5)
|
||||
impliedStrict: false,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Esprima Compatibility Going Forward
|
||||
|
||||
The primary goal is to produce the exact same AST structure and tokens as Esprima, and that takes precedence over anything else. (The AST structure being the [ESTree](https://github.com/estree/estree) API with JSX extensions.) Separate from that, Espree may deviate from what Esprima outputs in terms of where and how comments are attached, as well as what additional information is available on AST nodes. That is to say, Espree may add more things to the AST nodes than Esprima does but the overall AST structure produced will be the same.
|
||||
|
||||
Espree may also deviate from Esprima in the interface it exposes.
|
||||
|
||||
## Contributing
|
||||
|
||||
Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/js/issues).
|
||||
|
||||
Espree is licensed under a permissive BSD 2-clause license.
|
||||
|
||||
## Security Policy
|
||||
|
||||
We work hard to ensure that Espree is safe for everyone and that security issues are addressed quickly and responsibly. Read the full [security policy](https://github.com/eslint/.github/blob/master/SECURITY.md).
|
||||
|
||||
## Build Commands
|
||||
|
||||
- `npm test` - run all tests
|
||||
- `npm run lint` - run all linting
|
||||
|
||||
## Differences from Espree 2.x
|
||||
|
||||
- The `tokenize()` method does not use `ecmaFeatures`. Any string will be tokenized completely based on ECMAScript 6 semantics.
|
||||
- Trailing whitespace no longer is counted as part of a node.
|
||||
- `let` and `const` declarations are no longer parsed by default. You must opt-in by using an `ecmaVersion` newer than `5` or setting `sourceType` to `module`.
|
||||
- The `esparse` and `esvalidate` binary scripts have been removed.
|
||||
- There is no `tolerant` option. We will investigate adding this back in the future.
|
||||
|
||||
## Known Incompatibilities
|
||||
|
||||
In an effort to help those wanting to transition from other parsers to Espree, the following is a list of noteworthy incompatibilities with other parsers. These are known differences that we do not intend to change.
|
||||
|
||||
### Esprima 1.2.2
|
||||
|
||||
- Esprima counts trailing whitespace as part of each AST node while Espree does not. In Espree, the end of a node is where the last token occurs.
|
||||
- Espree does not parse `let` and `const` declarations by default.
|
||||
- Error messages returned for parsing errors are different.
|
||||
- There are two addition properties on every node and token: `start` and `end`. These represent the same data as `range` and are used internally by Acorn.
|
||||
|
||||
### Esprima 2.x
|
||||
|
||||
- Esprima 2.x uses a different comment attachment algorithm that results in some comments being added in different places than Espree. The algorithm Espree uses is the same one used in Esprima 1.2.2.
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### Why another parser
|
||||
|
||||
[ESLint](http://eslint.org) had been relying on Esprima as its parser from the beginning. While that was fine when the JavaScript language was evolving slowly, the pace of development increased dramatically and Esprima had fallen behind. ESLint, like many other tools reliant on Esprima, has been stuck in using new JavaScript language features until Esprima updates, and that caused our users frustration.
|
||||
|
||||
We decided the only way for us to move forward was to create our own parser, bringing us inline with JSHint and JSLint, and allowing us to keep implementing new features as we need them. We chose to fork Esprima instead of starting from scratch in order to move as quickly as possible with a compatible API.
|
||||
|
||||
With Espree 2.0.0, we are no longer a fork of Esprima but rather a translation layer between Acorn and Esprima syntax. This allows us to put work back into a community-supported parser (Acorn) that is continuing to grow and evolve while maintaining an Esprima-compatible parser for those utilities still built on Esprima.
|
||||
|
||||
### Have you tried working with Esprima?
|
||||
|
||||
Yes. Since the start of ESLint, we've regularly filed bugs and feature requests with Esprima and will continue to do so. However, there are some different philosophies around how the projects work that need to be worked through. The initial goal was to have Espree track Esprima and eventually merge the two back together, but we ultimately decided that building on top of Acorn was a better choice due to Acorn's plugin support.
|
||||
|
||||
### Why don't you just use Acorn?
|
||||
|
||||
Acorn is a great JavaScript parser that produces an AST that is compatible with Esprima. Unfortunately, ESLint relies on more than just the AST to do its job. It relies on Esprima's tokens and comment attachment features to get a complete picture of the source code. We investigated switching to Acorn, but the inconsistencies between Esprima and Acorn created too much work for a project like ESLint.
|
||||
|
||||
We are building on top of Acorn, however, so that we can contribute back and help make Acorn even better.
|
||||
|
||||
### What ECMAScript features do you support?
|
||||
|
||||
Espree supports all ECMAScript 2025 features and partially supports ECMAScript 2026 features.
|
||||
|
||||
Because ECMAScript 2026 is still under development, we are implementing features as they are finalized. Currently, Espree supports:
|
||||
|
||||
- [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management)
|
||||
|
||||
See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized.
|
||||
|
||||
### How do you determine which experimental features to support?
|
||||
|
||||
In general, we do not support experimental JavaScript features. We may make exceptions from time to time depending on the maturity of the features.
|
||||
|
||||
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
||||
<!--sponsorsstart-->
|
||||
|
||||
## Sponsors
|
||||
|
||||
The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
|
||||
to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
||||
|
||||
<h3>Platinum Sponsors</h3>
|
||||
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a></p><h3>Gold Sponsors</h3>
|
||||
<p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a></p><h3>Silver Sponsors</h3>
|
||||
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/d472863/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
|
||||
<p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://opensource.sap.com"><img src="https://avatars.githubusercontent.com/u/2531208" alt="SAP" height="32"></a> <a href="https://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://depot.dev"><img src="https://images.opencollective.com/depot/39125a1/logo.png" alt="Depot" height="32"></a> <a href="https://www.n-ix.com/"><img src="https://images.opencollective.com/n-ix-ltd/575a7a5/logo.png" alt="N-iX Ltd" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="TestMu AI Open Source Office (Formerly LambdaTest)" height="32"></a></p>
|
||||
<h3>Technology Sponsors</h3>
|
||||
Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
|
||||
<p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
|
||||
<!--sponsorsend-->
|
||||
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const Replace = require('./Replace');
|
||||
const withParser = require('../utils/withParser');
|
||||
|
||||
class Ignore extends Replace {
|
||||
static make(options) {
|
||||
return new Ignore(options);
|
||||
}
|
||||
|
||||
static withParser(options) {
|
||||
return withParser(Ignore.make, options);
|
||||
}
|
||||
|
||||
constructor(options) {
|
||||
super(options);
|
||||
this._replacement = Replace.arrayReplacement([]);
|
||||
this._allowEmptyReplacement = true;
|
||||
}
|
||||
}
|
||||
Ignore.ignore = Ignore.make;
|
||||
Ignore.make.Constructor = Ignore;
|
||||
|
||||
module.exports = Ignore;
|
||||
@@ -0,0 +1,132 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CancellationTokenSource = exports.CancellationToken = void 0;
|
||||
const ral_1 = __importDefault(require("./ral"));
|
||||
const Is = __importStar(require("./is"));
|
||||
const events_1 = require("./events");
|
||||
var CancellationToken;
|
||||
(function (CancellationToken) {
|
||||
CancellationToken.None = Object.freeze({
|
||||
isCancellationRequested: false,
|
||||
onCancellationRequested: events_1.Event.None
|
||||
});
|
||||
CancellationToken.Cancelled = Object.freeze({
|
||||
isCancellationRequested: true,
|
||||
onCancellationRequested: events_1.Event.None
|
||||
});
|
||||
function is(value) {
|
||||
const candidate = value;
|
||||
return candidate && (candidate === CancellationToken.None
|
||||
|| candidate === CancellationToken.Cancelled
|
||||
|| (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));
|
||||
}
|
||||
CancellationToken.is = is;
|
||||
})(CancellationToken || (exports.CancellationToken = CancellationToken = {}));
|
||||
const shortcutEvent = Object.freeze(function (callback, context) {
|
||||
const handle = (0, ral_1.default)().timer.setTimeout(callback.bind(context), 0);
|
||||
return { dispose() { handle.dispose(); } };
|
||||
});
|
||||
class MutableToken {
|
||||
_isCancelled = false;
|
||||
_emitter;
|
||||
cancel() {
|
||||
if (!this._isCancelled) {
|
||||
this._isCancelled = true;
|
||||
if (this._emitter) {
|
||||
this._emitter.fire(undefined);
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
get isCancellationRequested() {
|
||||
return this._isCancelled;
|
||||
}
|
||||
get onCancellationRequested() {
|
||||
if (this._isCancelled) {
|
||||
return shortcutEvent;
|
||||
}
|
||||
if (!this._emitter) {
|
||||
this._emitter = new events_1.Emitter();
|
||||
}
|
||||
return this._emitter.event;
|
||||
}
|
||||
dispose() {
|
||||
if (this._emitter) {
|
||||
this._emitter.dispose();
|
||||
this._emitter = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
class CancellationTokenSource {
|
||||
_token;
|
||||
get token() {
|
||||
if (!this._token) {
|
||||
// be lazy and create the token only when
|
||||
// actually needed
|
||||
this._token = new MutableToken();
|
||||
}
|
||||
return this._token;
|
||||
}
|
||||
cancel() {
|
||||
if (!this._token) {
|
||||
// save an object by returning the default
|
||||
// cancelled token when cancellation happens
|
||||
// before someone asks for the token
|
||||
this._token = CancellationToken.Cancelled;
|
||||
}
|
||||
else {
|
||||
this._token.cancel();
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
if (!this._token) {
|
||||
// ensure to initialize with an empty token if we had none
|
||||
this._token = CancellationToken.None;
|
||||
}
|
||||
else if (this._token instanceof MutableToken) {
|
||||
// actually dispose
|
||||
this._token.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.CancellationTokenSource = CancellationTokenSource;
|
||||
@@ -0,0 +1,15 @@
|
||||
# Installation
|
||||
> `npm install --save @types/chai`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for chai (http://chaijs.com/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chai.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Mon, 20 Oct 2025 23:32:35 GMT
|
||||
* Dependencies: [@types/deep-eql](https://npmjs.com/package/@types/deep-eql), [assertion-error](https://npmjs.com/package/assertion-error)
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Bart van der Schoor](https://github.com/Bartvds), [Andrew Brown](https://github.com/AGBrown), [Olivier Chevet](https://github.com/olivr70), [Matt Wistrand](https://github.com/mwistrand), [Shaun Luttin](https://github.com/shaunluttin), [Satana Charuwichitratana](https://github.com/micksatana), [Erik Schierboom](https://github.com/ErikSchierboom), [Bogdan Paranytsia](https://github.com/bparan), [CXuesong](https://github.com/CXuesong), and [Joey Kilpatrick](https://github.com/joeykilpatrick).
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
var _array_with_holes = require("./_array_with_holes.cjs");
|
||||
var _iterable_to_array_limit = require("./_iterable_to_array_limit.cjs");
|
||||
var _non_iterable_rest = require("./_non_iterable_rest.cjs");
|
||||
var _unsupported_iterable_to_array = require("./_unsupported_iterable_to_array.cjs");
|
||||
|
||||
function _sliced_to_array(arr, i) {
|
||||
return _array_with_holes._(arr) || _iterable_to_array_limit._(arr, i) || _unsupported_iterable_to_array._(arr, i) || _non_iterable_rest._();
|
||||
}
|
||||
exports._ = _sliced_to_array;
|
||||
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isHigherPrecedenceThanAwait = isHigherPrecedenceThanAwait;
|
||||
const ts = __importStar(require("typescript"));
|
||||
const getOperatorPrecedence_1 = require("./getOperatorPrecedence");
|
||||
function isHigherPrecedenceThanAwait(tsNode) {
|
||||
const operator = ts.isBinaryExpression(tsNode)
|
||||
? tsNode.operatorToken.kind
|
||||
: ts.SyntaxKind.Unknown;
|
||||
const nodePrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(tsNode.kind, operator);
|
||||
const awaitPrecedence = (0, getOperatorPrecedence_1.getOperatorPrecedence)(ts.SyntaxKind.AwaitExpression, ts.SyntaxKind.Unknown);
|
||||
return nodePrecedence > awaitPrecedence;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @fileoverview Utilities to operate on option objects.
|
||||
* @author Josh Goldberg
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Determines whether any of input's properties are different
|
||||
* from values that already exist in original.
|
||||
* @template T
|
||||
* @param {Partial<T>} input New value.
|
||||
* @param {T} original Original value.
|
||||
* @returns {boolean} Whether input includes an explicit difference.
|
||||
*/
|
||||
function containsDifferentProperty(input, original) {
|
||||
if (input === original) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof input !== typeof original ||
|
||||
Array.isArray(input) !== Array.isArray(original)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(input)) {
|
||||
return (
|
||||
input.length !== original.length ||
|
||||
input.some((value, i) =>
|
||||
containsDifferentProperty(value, original[i]),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof input === "object") {
|
||||
if (input === null || original === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const inputKeys = Object.keys(input);
|
||||
const originalKeys = Object.keys(original);
|
||||
|
||||
return (
|
||||
inputKeys.length !== originalKeys.length ||
|
||||
inputKeys.some(
|
||||
inputKey =>
|
||||
!Object.hasOwn(original, inputKey) ||
|
||||
containsDifferentProperty(
|
||||
input[inputKey],
|
||||
original[inputKey],
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
containsDifferentProperty,
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
import type { $ZodStringFormats } from "../core/checks.js";
|
||||
import type * as errors from "../core/errors.js";
|
||||
import * as util from "../core/util.js";
|
||||
|
||||
const error: () => errors.$ZodErrorMap = () => {
|
||||
const Sizable: Record<string, { unit: string; verb: string }> = {
|
||||
string: { unit: "simvol", verb: "olmalıdır" },
|
||||
file: { unit: "bayt", verb: "olmalıdır" },
|
||||
array: { unit: "element", verb: "olmalıdır" },
|
||||
set: { unit: "element", verb: "olmalıdır" },
|
||||
};
|
||||
|
||||
function getSizing(origin: string): { unit: string; verb: string } | null {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
|
||||
const FormatDictionary: {
|
||||
[k in $ZodStringFormats | (string & {})]?: string;
|
||||
} = {
|
||||
regex: "input",
|
||||
email: "email address",
|
||||
url: "URL",
|
||||
emoji: "emoji",
|
||||
uuid: "UUID",
|
||||
uuidv4: "UUIDv4",
|
||||
uuidv6: "UUIDv6",
|
||||
nanoid: "nanoid",
|
||||
guid: "GUID",
|
||||
cuid: "cuid",
|
||||
cuid2: "cuid2",
|
||||
ulid: "ULID",
|
||||
xid: "XID",
|
||||
ksuid: "KSUID",
|
||||
datetime: "ISO datetime",
|
||||
date: "ISO date",
|
||||
time: "ISO time",
|
||||
duration: "ISO duration",
|
||||
ipv4: "IPv4 address",
|
||||
ipv6: "IPv6 address",
|
||||
cidrv4: "IPv4 range",
|
||||
cidrv6: "IPv6 range",
|
||||
base64: "base64-encoded string",
|
||||
base64url: "base64url-encoded string",
|
||||
json_string: "JSON string",
|
||||
e164: "E.164 number",
|
||||
jwt: "JWT",
|
||||
template_literal: "input",
|
||||
};
|
||||
|
||||
const TypeDictionary: {
|
||||
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
|
||||
} = {
|
||||
nan: "NaN",
|
||||
};
|
||||
|
||||
return (issue) => {
|
||||
switch (issue.code) {
|
||||
case "invalid_type": {
|
||||
const expected = TypeDictionary[issue.expected] ?? issue.expected;
|
||||
const receivedType = util.parsedType(issue.input);
|
||||
const received = TypeDictionary[receivedType] ?? receivedType;
|
||||
if (/^[A-Z]/.test(issue.expected)) {
|
||||
return `Yanlış dəyər: gözlənilən instanceof ${issue.expected}, daxil olan ${received}`;
|
||||
}
|
||||
return `Yanlış dəyər: gözlənilən ${expected}, daxil olan ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1) return `Yanlış dəyər: gözlənilən ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Yanlış seçim: aşağıdakılardan biri olmalıdır: ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `Çox böyük: gözlənilən ${issue.origin ?? "dəyər"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "element"}`;
|
||||
return `Çox böyük: gözlənilən ${issue.origin ?? "dəyər"} ${adj}${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) return `Çox kiçik: gözlənilən ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
||||
return `Çox kiçik: gözlənilən ${issue.origin} ${adj}${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue as errors.$ZodStringFormatIssues;
|
||||
if (_issue.format === "starts_with") return `Yanlış mətn: "${_issue.prefix}" ilə başlamalıdır`;
|
||||
if (_issue.format === "ends_with") return `Yanlış mətn: "${_issue.suffix}" ilə bitməlidir`;
|
||||
if (_issue.format === "includes") return `Yanlış mətn: "${_issue.includes}" daxil olmalıdır`;
|
||||
if (_issue.format === "regex") return `Yanlış mətn: ${_issue.pattern} şablonuna uyğun olmalıdır`;
|
||||
return `Yanlış ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Yanlış ədəd: ${issue.divisor} ilə bölünə bilən olmalıdır`;
|
||||
case "unrecognized_keys":
|
||||
return `Tanınmayan açar${issue.keys.length > 1 ? "lar" : ""}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `${issue.origin} daxilində yanlış açar`;
|
||||
case "invalid_union":
|
||||
return "Yanlış dəyər";
|
||||
case "invalid_element":
|
||||
return `${issue.origin} daxilində yanlış dəyər`;
|
||||
default:
|
||||
return `Yanlış dəyər`;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default function (): { localeError: errors.$ZodErrorMap } {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* A `StructFailure` represents a single specific failure in validation.
|
||||
*/
|
||||
export type Failure = {
|
||||
value: any;
|
||||
key: any;
|
||||
type: string;
|
||||
refinement: string | undefined;
|
||||
message: string;
|
||||
explanation?: string;
|
||||
branch: Array<any>;
|
||||
path: Array<any>;
|
||||
};
|
||||
/**
|
||||
* `StructError` objects are thrown (or returned) when validation fails.
|
||||
*
|
||||
* Validation logic is design to exit early for maximum performance. The error
|
||||
* represents the first error encountered during validation. For more detail,
|
||||
* the `error.failures` property is a generator function that can be run to
|
||||
* continue validation and receive all the failures in the data.
|
||||
*/
|
||||
export declare class StructError extends TypeError {
|
||||
value: any;
|
||||
key: any;
|
||||
type: string;
|
||||
refinement: string | undefined;
|
||||
path: Array<any>;
|
||||
branch: Array<any>;
|
||||
failures: () => Array<Failure>;
|
||||
[x: string]: any;
|
||||
constructor(failure: Failure, failures: () => Generator<Failure>);
|
||||
}
|
||||
//# sourceMappingURL=error.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sha256.js","sourceRoot":"","sources":["../src/sha256.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,MAAM,IAAI,OAAO,EACjB,MAAM,IAAI,OAAO,EACjB,MAAM,IAAI,OAAO,EACjB,MAAM,IAAI,OAAO,GAClB,MAAM,WAAW,CAAC;AACnB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC"}
|
||||
@@ -0,0 +1,110 @@
|
||||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { ZodIssueCode } from "zod/v3";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const stringMap = z.map(z.string(), z.string());
|
||||
type stringMap = z.infer<typeof stringMap>;
|
||||
|
||||
test("type inference", () => {
|
||||
util.assertEqual<stringMap, Map<string, string>>(true);
|
||||
});
|
||||
|
||||
test("valid parse", () => {
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(true);
|
||||
if (result.success) {
|
||||
expect(result.data.has("first")).toEqual(true);
|
||||
expect(result.data.has("second")).toEqual(true);
|
||||
expect(result.data.get("first")).toEqual("foo");
|
||||
expect(result.data.get("second")).toEqual("bar");
|
||||
}
|
||||
});
|
||||
|
||||
test("valid parse async", async () => {
|
||||
const result = await stringMap.spa(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(true);
|
||||
if (result.success) {
|
||||
expect(result.data.has("first")).toEqual(true);
|
||||
expect(result.data.has("second")).toEqual(true);
|
||||
expect(result.data.get("first")).toEqual("foo");
|
||||
expect(result.data.get("second")).toEqual("bar");
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when a Set is given", () => {
|
||||
const result = stringMap.safeParse(new Set([]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has invalid key and invalid input", () => {
|
||||
const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[0].path).toEqual([0, "key"]);
|
||||
expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[1].path).toEqual([0, "value"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has multiple invalid entries", () => {
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
[1, "foo"],
|
||||
["bar", 2],
|
||||
] as [any, any][]) as Map<any, any>
|
||||
);
|
||||
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[0].path).toEqual([0, "key"]);
|
||||
expect(result.error.issues[1].code).toEqual(ZodIssueCode.invalid_type);
|
||||
expect(result.error.issues[1].path).toEqual([1, "value"]);
|
||||
}
|
||||
});
|
||||
|
||||
test("dirty", async () => {
|
||||
const map = z.map(
|
||||
z.string().refine((val) => val === val.toUpperCase(), {
|
||||
message: "Keys must be uppercase",
|
||||
}),
|
||||
z.string()
|
||||
);
|
||||
const result = await map.spa(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].code).toEqual(z.ZodIssueCode.custom);
|
||||
expect(result.error.issues[0].message).toEqual("Keys must be uppercase");
|
||||
expect(result.error.issues[1].code).toEqual(z.ZodIssueCode.custom);
|
||||
expect(result.error.issues[1].message).toEqual("Keys must be uppercase");
|
||||
}
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sha512.js","sourceRoot":"","sources":["../src/sha512.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,MAAM,IAAI,OAAO,EACjB,MAAM,IAAI,OAAO,EACjB,UAAU,IAAI,WAAW,EACzB,UAAU,IAAI,WAAW,EACzB,UAAU,IAAI,WAAW,EACzB,UAAU,IAAI,WAAW,EACzB,MAAM,IAAI,OAAO,EACjB,MAAM,IAAI,OAAO,GAClB,MAAM,WAAW,CAAC;AACnB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,MAAM,GAAmB,OAAO,CAAC;AAC9C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAuB,WAAW,CAAC;AAC1D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAuB,WAAW,CAAC;AAC1D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAuB,WAAW,CAAC;AAC1D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAuB,WAAW,CAAC"}
|
||||
@@ -0,0 +1,51 @@
|
||||
# real-require
|
||||
|
||||
Keep require and import consistent after bundling or transpiling.
|
||||
|
||||
## Installation
|
||||
|
||||
Just run:
|
||||
|
||||
```bash
|
||||
npm install real-require
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The package provides two drop-ins functions, `realRequire` and `realImport`,
|
||||
which can be used in scenarios where tools like transpilers or bundlers change
|
||||
the native `require` or `await import` calls.
|
||||
|
||||
The current `realRequire` functions only handles webpack at the moment, wrapping
|
||||
the `__non_webpack__require__` implementation that webpack provides for the
|
||||
final bundle.
|
||||
|
||||
### Example
|
||||
|
||||
```js
|
||||
// After bundling, real-require will be embedded in the bundle
|
||||
const { realImport, realRequire } = require('real-require')
|
||||
|
||||
/*
|
||||
By using realRequire, at build time the module will not be embedded and at runtime it will try to load path from the local filesytem.
|
||||
This is useful in situations where the build tool does not support skipping modules to embed.
|
||||
*/
|
||||
const { join } = realRequire('path')
|
||||
|
||||
async function main() {
|
||||
// Similarly, this make sure the import call is not modified by the build tools
|
||||
const localFunction = await realImport('./source.js')
|
||||
|
||||
localFunction()
|
||||
}
|
||||
|
||||
main().catch(console.error)
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](./CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
|
||||
Copyright Paolo Insogna and real-require contributors 2021. Licensed under the [MIT License](http://www.apache.org/licenses/MIT).
|
||||
@@ -0,0 +1,46 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
import * as core from "zod/v4/core";
|
||||
|
||||
const { allowsEval } = core.util;
|
||||
|
||||
// Regression test for the CSP feature-probe issue (#4461, #5414):
|
||||
// `allowsEval` used to always invoke `new Function("")` even when the
|
||||
// user had opted into `z.config({ jitless: true })`, producing a
|
||||
// `securitypolicyviolation` report on strict-CSP pages (no 'unsafe-eval')
|
||||
// that Chrome DevTools surfaces as an Issue.
|
||||
//
|
||||
// The fix: when `globalConfig.jitless` is true, `allowsEval.value`
|
||||
// returns `false` without triggering the probe. This test lives in its
|
||||
// own file because vitest isolates ESM graphs per file, so the cached
|
||||
// `allowsEval.value` is fresh and is never accessed before the config
|
||||
// mutation below.
|
||||
|
||||
test("globalConfig.jitless=true short-circuits the allowsEval probe", () => {
|
||||
// Set BEFORE first access to allowsEval.value — the getter is memoised
|
||||
// via `cached()`, so the contract is "configure at app entry".
|
||||
z.config({ jitless: true });
|
||||
|
||||
// Sanity: config is wired
|
||||
expect(core.globalConfig.jitless).toBe(true);
|
||||
|
||||
// Spy: if the probe were still attempted, `new Function("")` would be
|
||||
// called. Swap the global `Function` constructor with a throwing stub
|
||||
// and verify the stub is NEVER invoked.
|
||||
const origFunction = globalThis.Function;
|
||||
let probeAttempted = false;
|
||||
// @ts-expect-error assigning a stub to the Function global for the test
|
||||
globalThis.Function = function StubFunction(..._args: unknown[]): never {
|
||||
probeAttempted = true;
|
||||
throw new Error("allowsEval probe should have been skipped under jitless=true");
|
||||
};
|
||||
|
||||
try {
|
||||
expect(allowsEval.value).toBe(false);
|
||||
expect(probeAttempted).toBe(false);
|
||||
} finally {
|
||||
globalThis.Function = origFunction;
|
||||
// Restore config so other test files in the same worker see default
|
||||
delete core.globalConfig.jitless;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user