WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABILITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
/// <reference lib="es2020" />
|
||||
/// <reference lib="dom" />
|
||||
/// <reference lib="webworker.importscripts" />
|
||||
/// <reference lib="scripthost" />
|
||||
/// <reference lib="dom.iterable" />
|
||||
/// <reference lib="dom.asynciterable" />
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"proto.js","sourceRoot":"","sources":["../../src/api/proto.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,qBAAqB,EACrB,qBAAqB,GACxB,MAAM,WAAW,CAAC;AA0BnB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,UAA8B;IAC1D,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,UAAU,CAAC;IACtB,CAAC;IACD,OAAO,qBAAqB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAA8B;IAC7D,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,UAAU,CAAC,GAAG,CAAC;AAC1B,CAAC;AAkED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACjE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;IAC5D,MAAM,kBAAkB,GAAG,WAAW,KAAK,SAAS;QAChD,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,YAAY,CAAC;IACnB,OAAO;QACH,GAAG,IAAI;QACP,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpF,CAAC;AACN,CAAC"}
|
||||
@@ -0,0 +1,47 @@
|
||||
var textParsers = require('./lib/textParsers');
|
||||
var binaryParsers = require('./lib/binaryParsers');
|
||||
var arrayParser = require('./lib/arrayParser');
|
||||
var builtinTypes = require('./lib/builtins');
|
||||
|
||||
exports.getTypeParser = getTypeParser;
|
||||
exports.setTypeParser = setTypeParser;
|
||||
exports.arrayParser = arrayParser;
|
||||
exports.builtins = builtinTypes;
|
||||
|
||||
var typeParsers = {
|
||||
text: {},
|
||||
binary: {}
|
||||
};
|
||||
|
||||
//the empty parse function
|
||||
function noParse (val) {
|
||||
return String(val);
|
||||
};
|
||||
|
||||
//returns a function used to convert a specific type (specified by
|
||||
//oid) into a result javascript type
|
||||
//note: the oid can be obtained via the following sql query:
|
||||
//SELECT oid FROM pg_type WHERE typname = 'TYPE_NAME_HERE';
|
||||
function getTypeParser (oid, format) {
|
||||
format = format || 'text';
|
||||
if (!typeParsers[format]) {
|
||||
return noParse;
|
||||
}
|
||||
return typeParsers[format][oid] || noParse;
|
||||
};
|
||||
|
||||
function setTypeParser (oid, format, parseFn) {
|
||||
if(typeof format == 'function') {
|
||||
parseFn = format;
|
||||
format = 'text';
|
||||
}
|
||||
typeParsers[format][oid] = parseFn;
|
||||
};
|
||||
|
||||
textParsers.init(function(oid, converter) {
|
||||
typeParsers.text[oid] = converter;
|
||||
});
|
||||
|
||||
binaryParsers.init(function(oid, converter) {
|
||||
typeParsers.binary[oid] = converter;
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { TSESTree } from '@typescript-eslint/types';
|
||||
import type { Referencer } from './Referencer';
|
||||
import { Visitor } from './Visitor';
|
||||
export declare class TypeVisitor extends Visitor {
|
||||
#private;
|
||||
constructor(referencer: Referencer);
|
||||
static visit(referencer: Referencer, node: TSESTree.Node): void;
|
||||
protected visitFunctionType(node: TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructorType | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSFunctionType | TSESTree.TSMethodSignature): void;
|
||||
protected visitPropertyKey(node: TSESTree.TSMethodSignature | TSESTree.TSPropertySignature): void;
|
||||
protected Identifier(node: TSESTree.Identifier): void;
|
||||
protected MemberExpression(node: TSESTree.MemberExpression): void;
|
||||
protected TSCallSignatureDeclaration(node: TSESTree.TSCallSignatureDeclaration): void;
|
||||
protected TSConditionalType(node: TSESTree.TSConditionalType): void;
|
||||
protected TSConstructorType(node: TSESTree.TSConstructorType): void;
|
||||
protected TSConstructSignatureDeclaration(node: TSESTree.TSConstructSignatureDeclaration): void;
|
||||
protected TSFunctionType(node: TSESTree.TSFunctionType): void;
|
||||
protected TSImportType(node: TSESTree.TSImportType): void;
|
||||
protected TSIndexSignature(node: TSESTree.TSIndexSignature): void;
|
||||
protected TSInferType(node: TSESTree.TSInferType): void;
|
||||
protected TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void;
|
||||
protected TSMappedType(node: TSESTree.TSMappedType): void;
|
||||
protected TSMethodSignature(node: TSESTree.TSMethodSignature): void;
|
||||
protected TSNamedTupleMember(node: TSESTree.TSNamedTupleMember): void;
|
||||
protected TSPropertySignature(node: TSESTree.TSPropertySignature): void;
|
||||
protected TSQualifiedName(node: TSESTree.TSQualifiedName): void;
|
||||
protected TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration): void;
|
||||
protected TSTypeParameter(node: TSESTree.TSTypeParameter): void;
|
||||
protected TSTypePredicate(node: TSESTree.TSTypePredicate): void;
|
||||
protected TSTypeAnnotation(node: TSESTree.TSTypeAnnotation): void;
|
||||
protected TSTypeQuery(node: TSESTree.TSTypeQuery): void;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
var classApplyDescriptorSet = require("./classApplyDescriptorSet.js");
|
||||
var classPrivateFieldGet2 = require("./classPrivateFieldGet2.js");
|
||||
function _classPrivateFieldSet(e, t, r) {
|
||||
var s = classPrivateFieldGet2(t, e);
|
||||
return classApplyDescriptorSet(e, s, r), r;
|
||||
}
|
||||
module.exports = _classPrivateFieldSet, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,29 @@
|
||||
declare const _default: {
|
||||
extends: string[];
|
||||
rules: {
|
||||
'@typescript-eslint/ban-ts-comment': "error";
|
||||
'no-array-constructor': "off";
|
||||
'@typescript-eslint/no-array-constructor': "error";
|
||||
'@typescript-eslint/no-duplicate-enum-values': "error";
|
||||
'@typescript-eslint/no-empty-object-type': "error";
|
||||
'@typescript-eslint/no-explicit-any': "error";
|
||||
'@typescript-eslint/no-extra-non-null-assertion': "error";
|
||||
'@typescript-eslint/no-misused-new': "error";
|
||||
'@typescript-eslint/no-namespace': "error";
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': "error";
|
||||
'@typescript-eslint/no-require-imports': "error";
|
||||
'@typescript-eslint/no-this-alias': "error";
|
||||
'@typescript-eslint/no-unnecessary-type-constraint': "error";
|
||||
'@typescript-eslint/no-unsafe-declaration-merging': "error";
|
||||
'@typescript-eslint/no-unsafe-function-type': "error";
|
||||
'no-unused-expressions': "off";
|
||||
'@typescript-eslint/no-unused-expressions': "error";
|
||||
'no-unused-vars': "off";
|
||||
'@typescript-eslint/no-unused-vars': "error";
|
||||
'@typescript-eslint/no-wrapper-object-types': "error";
|
||||
'@typescript-eslint/prefer-as-const': "error";
|
||||
'@typescript-eslint/prefer-namespace-keyword': "error";
|
||||
'@typescript-eslint/triple-slash-reference': "error";
|
||||
};
|
||||
};
|
||||
export = _default;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
// @ts-ignore TS6133
|
||||
import { test } from "vitest";
|
||||
|
||||
import { Mocker } from "./Mocker.js";
|
||||
|
||||
test("mocker", () => {
|
||||
const mocker = new Mocker();
|
||||
mocker.string;
|
||||
mocker.number;
|
||||
mocker.boolean;
|
||||
mocker.null;
|
||||
mocker.undefined;
|
||||
mocker.stringOptional;
|
||||
mocker.stringNullable;
|
||||
mocker.numberOptional;
|
||||
mocker.numberNullable;
|
||||
mocker.booleanOptional;
|
||||
mocker.booleanNullable;
|
||||
});
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @fileoverview Rule to disallow specified names in exports
|
||||
* @author Milos Djermanovic
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description: "Disallow specified names in exports",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-restricted-exports",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
anyOf: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
restrictedNamedExports: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
restrictedNamedExportsPattern: { type: "string" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
restrictedNamedExports: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string",
|
||||
pattern: "^(?!default$)",
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
restrictedNamedExportsPattern: { type: "string" },
|
||||
restrictDefaultExports: {
|
||||
type: "object",
|
||||
properties: {
|
||||
// Allow/Disallow `export default foo; export default 42; export default function foo() {}` format
|
||||
direct: {
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
// Allow/Disallow `export { foo as default };` declarations
|
||||
named: {
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
// Allow/Disallow `export { default } from "mod"; export { default as default } from "mod";` declarations
|
||||
defaultFrom: {
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
// Allow/Disallow `export { foo as default } from "mod";` declarations
|
||||
namedFrom: {
|
||||
type: "boolean",
|
||||
},
|
||||
|
||||
// Allow/Disallow `export * as default from "mod"`; declarations
|
||||
namespaceFrom: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
defaultOptions: [{}],
|
||||
|
||||
messages: {
|
||||
restrictedNamed:
|
||||
"'{{name}}' is restricted from being used as an exported name.",
|
||||
restrictedDefault: "Exporting 'default' is restricted.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const {
|
||||
restrictedNamedExports,
|
||||
restrictedNamedExportsPattern: restrictedNamePattern,
|
||||
restrictDefaultExports,
|
||||
} = context.options[0];
|
||||
const restrictedNames = new Set(restrictedNamedExports);
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Checks and reports given exported name.
|
||||
* @param {ASTNode} node exported `Identifier` or string `Literal` node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkExportedName(node) {
|
||||
const name = astUtils.getModuleExportName(node);
|
||||
|
||||
let matchesRestrictedNamePattern = false;
|
||||
|
||||
if (restrictedNamePattern && name !== "default") {
|
||||
const patternRegex = new RegExp(restrictedNamePattern, "u");
|
||||
|
||||
matchesRestrictedNamePattern = patternRegex.test(name);
|
||||
}
|
||||
|
||||
if (matchesRestrictedNamePattern || restrictedNames.has(name)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "restrictedNamed",
|
||||
data: { name },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (name === "default") {
|
||||
if (node.parent.type === "ExportAllDeclaration") {
|
||||
if (
|
||||
restrictDefaultExports &&
|
||||
restrictDefaultExports.namespaceFrom
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "restrictedDefault",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// ExportSpecifier
|
||||
const isSourceSpecified = !!node.parent.parent.source;
|
||||
const specifierLocalName = astUtils.getModuleExportName(
|
||||
node.parent.local,
|
||||
);
|
||||
|
||||
if (
|
||||
!isSourceSpecified &&
|
||||
restrictDefaultExports &&
|
||||
restrictDefaultExports.named
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "restrictedDefault",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSourceSpecified && restrictDefaultExports) {
|
||||
if (
|
||||
(specifierLocalName === "default" &&
|
||||
restrictDefaultExports.defaultFrom) ||
|
||||
(specifierLocalName !== "default" &&
|
||||
restrictDefaultExports.namedFrom)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "restrictedDefault",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ExportAllDeclaration(node) {
|
||||
if (node.exported) {
|
||||
checkExportedName(node.exported);
|
||||
}
|
||||
},
|
||||
|
||||
ExportDefaultDeclaration(node) {
|
||||
if (restrictDefaultExports && restrictDefaultExports.direct) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "restrictedDefault",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
ExportNamedDeclaration(node) {
|
||||
const declaration = node.declaration;
|
||||
|
||||
if (declaration) {
|
||||
if (
|
||||
declaration.type === "FunctionDeclaration" ||
|
||||
declaration.type === "ClassDeclaration"
|
||||
) {
|
||||
checkExportedName(declaration.id);
|
||||
} else if (declaration.type === "VariableDeclaration") {
|
||||
sourceCode
|
||||
.getDeclaredVariables(declaration)
|
||||
.map(v =>
|
||||
v.defs.find(d => d.parent === declaration),
|
||||
)
|
||||
.map(d => d.name) // Identifier nodes
|
||||
.forEach(checkExportedName);
|
||||
}
|
||||
} else {
|
||||
node.specifiers
|
||||
.map(s => s.exported)
|
||||
.forEach(checkExportedName);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
const file8 = require("./file8.js")
|
||||
|
||||
module.exports = function () {
|
||||
file8()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getParsedConfigFileFromTSServer = getParsedConfigFileFromTSServer;
|
||||
const tsconfig_utils_1 = require("@typescript-eslint/tsconfig-utils");
|
||||
function getParsedConfigFileFromTSServer(tsserver, defaultProject, throwOnFailure, tsconfigRootDir) {
|
||||
try {
|
||||
return (0, tsconfig_utils_1.getParsedConfigFile)(tsserver, defaultProject, tsconfigRootDir);
|
||||
}
|
||||
catch (error) {
|
||||
if (throwOnFailure) {
|
||||
throw new Error(`Could not read Project Service default project '${defaultProject}': ${error.message}`, { cause: error });
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
{{# def.definitions }}
|
||||
|
||||
{{## def._error:_rule:
|
||||
{{ 'istanbul ignore else'; }}
|
||||
{{? it.createErrors !== false }}
|
||||
{
|
||||
keyword: '{{= $errorKeyword || _rule }}'
|
||||
, dataPath: (dataPath || '') + {{= it.errorPath }}
|
||||
, schemaPath: {{=it.util.toQuotedString($errSchemaPath)}}
|
||||
, params: {{# def._errorParams[_rule] }}
|
||||
{{? it.opts.messages !== false }}
|
||||
, message: {{# def._errorMessages[_rule] }}
|
||||
{{?}}
|
||||
{{? it.opts.verbose }}
|
||||
, schema: {{# def._errorSchemas[_rule] }}
|
||||
, parentSchema: validate.schema{{=it.schemaPath}}
|
||||
, data: {{=$data}}
|
||||
{{?}}
|
||||
}
|
||||
{{??}}
|
||||
{}
|
||||
{{?}}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def._addError:_rule:
|
||||
if (vErrors === null) vErrors = [err];
|
||||
else vErrors.push(err);
|
||||
errors++;
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.addError:_rule:
|
||||
var err = {{# def._error:_rule }};
|
||||
{{# def._addError:_rule }}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.error:_rule:
|
||||
{{# def.beginDefOut}}
|
||||
{{# def._error:_rule }}
|
||||
{{# def.storeDefOut:__err }}
|
||||
|
||||
{{? !it.compositeRule && $breakOnError }}
|
||||
{{ 'istanbul ignore if'; }}
|
||||
{{? it.async }}
|
||||
throw new ValidationError([{{=__err}}]);
|
||||
{{??}}
|
||||
validate.errors = [{{=__err}}];
|
||||
return false;
|
||||
{{?}}
|
||||
{{??}}
|
||||
var err = {{=__err}};
|
||||
{{# def._addError:_rule }}
|
||||
{{?}}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.extraError:_rule:
|
||||
{{# def.addError:_rule}}
|
||||
{{? !it.compositeRule && $breakOnError }}
|
||||
{{ 'istanbul ignore if'; }}
|
||||
{{? it.async }}
|
||||
throw new ValidationError(vErrors);
|
||||
{{??}}
|
||||
validate.errors = vErrors;
|
||||
return false;
|
||||
{{?}}
|
||||
{{?}}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.checkError:_rule:
|
||||
if (!{{=$valid}}) {
|
||||
{{# def.error:_rule }}
|
||||
}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.resetErrors:
|
||||
errors = {{=$errs}};
|
||||
if (vErrors !== null) {
|
||||
if ({{=$errs}}) vErrors.length = {{=$errs}};
|
||||
else vErrors = null;
|
||||
}
|
||||
#}}
|
||||
|
||||
|
||||
{{## def.concatSchema:{{?$isData}}' + {{=$schemaValue}} + '{{??}}{{=$schema}}{{?}}#}}
|
||||
{{## def.appendSchema:{{?$isData}}' + {{=$schemaValue}}{{??}}{{=$schemaValue}}'{{?}}#}}
|
||||
{{## def.concatSchemaEQ:{{?$isData}}' + {{=$schemaValue}} + '{{??}}{{=it.util.escapeQuotes($schema)}}{{?}}#}}
|
||||
|
||||
{{## def._errorMessages = {
|
||||
'false schema': "'boolean schema is false'",
|
||||
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
|
||||
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
|
||||
additionalProperties: "'{{? it.opts._errorDataPathProperty }}is an invalid additional property{{??}}should NOT have additional properties{{?}}'",
|
||||
anyOf: "'should match some schema in anyOf'",
|
||||
const: "'should be equal to constant'",
|
||||
contains: "'should contain a valid item'",
|
||||
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
|
||||
'enum': "'should be equal to one of the allowed values'",
|
||||
format: "'should match format \"{{#def.concatSchemaEQ}}\"'",
|
||||
'if': "'should match \"' + {{=$ifClause}} + '\" schema'",
|
||||
_limit: "'should be {{=$opStr}} {{#def.appendSchema}}",
|
||||
_exclusiveLimit: "'{{=$exclusiveKeyword}} should be boolean'",
|
||||
_limitItems: "'should NOT have {{?$keyword=='maxItems'}}more{{??}}fewer{{?}} than {{#def.concatSchema}} items'",
|
||||
_limitLength: "'should NOT be {{?$keyword=='maxLength'}}longer{{??}}shorter{{?}} than {{#def.concatSchema}} characters'",
|
||||
_limitProperties:"'should NOT have {{?$keyword=='maxProperties'}}more{{??}}fewer{{?}} than {{#def.concatSchema}} properties'",
|
||||
multipleOf: "'should be multiple of {{#def.appendSchema}}",
|
||||
not: "'should NOT be valid'",
|
||||
oneOf: "'should match exactly one schema in oneOf'",
|
||||
pattern: "'should match pattern \"{{#def.concatSchemaEQ}}\"'",
|
||||
propertyNames: "'property name \\'{{=$invalidName}}\\' is invalid'",
|
||||
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
|
||||
type: "'should be {{? $typeIsArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
|
||||
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
|
||||
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
|
||||
patternRequired: "'should have property matching pattern \\'{{=$missingPattern}}\\''",
|
||||
switch: "'should pass \"switch\" keyword validation'",
|
||||
_formatLimit: "'should be {{=$opStr}} \"{{#def.concatSchemaEQ}}\"'",
|
||||
_formatExclusiveLimit: "'{{=$exclusiveKeyword}} should be boolean'"
|
||||
} #}}
|
||||
|
||||
|
||||
{{## def.schemaRefOrVal: {{?$isData}}validate.schema{{=$schemaPath}}{{??}}{{=$schema}}{{?}} #}}
|
||||
{{## def.schemaRefOrQS: {{?$isData}}validate.schema{{=$schemaPath}}{{??}}{{=it.util.toQuotedString($schema)}}{{?}} #}}
|
||||
|
||||
{{## def._errorSchemas = {
|
||||
'false schema': "false",
|
||||
$ref: "{{=it.util.toQuotedString($schema)}}",
|
||||
additionalItems: "false",
|
||||
additionalProperties: "false",
|
||||
anyOf: "validate.schema{{=$schemaPath}}",
|
||||
const: "validate.schema{{=$schemaPath}}",
|
||||
contains: "validate.schema{{=$schemaPath}}",
|
||||
dependencies: "validate.schema{{=$schemaPath}}",
|
||||
'enum': "validate.schema{{=$schemaPath}}",
|
||||
format: "{{#def.schemaRefOrQS}}",
|
||||
'if': "validate.schema{{=$schemaPath}}",
|
||||
_limit: "{{#def.schemaRefOrVal}}",
|
||||
_exclusiveLimit: "validate.schema{{=$schemaPath}}",
|
||||
_limitItems: "{{#def.schemaRefOrVal}}",
|
||||
_limitLength: "{{#def.schemaRefOrVal}}",
|
||||
_limitProperties:"{{#def.schemaRefOrVal}}",
|
||||
multipleOf: "{{#def.schemaRefOrVal}}",
|
||||
not: "validate.schema{{=$schemaPath}}",
|
||||
oneOf: "validate.schema{{=$schemaPath}}",
|
||||
pattern: "{{#def.schemaRefOrQS}}",
|
||||
propertyNames: "validate.schema{{=$schemaPath}}",
|
||||
required: "validate.schema{{=$schemaPath}}",
|
||||
type: "validate.schema{{=$schemaPath}}",
|
||||
uniqueItems: "{{#def.schemaRefOrVal}}",
|
||||
custom: "validate.schema{{=$schemaPath}}",
|
||||
patternRequired: "validate.schema{{=$schemaPath}}",
|
||||
switch: "validate.schema{{=$schemaPath}}",
|
||||
_formatLimit: "{{#def.schemaRefOrQS}}",
|
||||
_formatExclusiveLimit: "validate.schema{{=$schemaPath}}"
|
||||
} #}}
|
||||
|
||||
|
||||
{{## def.schemaValueQS: {{?$isData}}{{=$schemaValue}}{{??}}{{=it.util.toQuotedString($schema)}}{{?}} #}}
|
||||
|
||||
{{## def._errorParams = {
|
||||
'false schema': "{}",
|
||||
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
|
||||
additionalItems: "{ limit: {{=$schema.length}} }",
|
||||
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
|
||||
anyOf: "{}",
|
||||
const: "{ allowedValue: schema{{=$lvl}} }",
|
||||
contains: "{}",
|
||||
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{= it.util.escapeQuotes($deps.length==1 ? $deps[0] : $deps.join(\", \")) }}' }",
|
||||
'enum': "{ allowedValues: schema{{=$lvl}} }",
|
||||
format: "{ format: {{#def.schemaValueQS}} }",
|
||||
'if': "{ failingKeyword: {{=$ifClause}} }",
|
||||
_limit: "{ comparison: {{=$opExpr}}, limit: {{=$schemaValue}}, exclusive: {{=$exclusive}} }",
|
||||
_exclusiveLimit: "{}",
|
||||
_limitItems: "{ limit: {{=$schemaValue}} }",
|
||||
_limitLength: "{ limit: {{=$schemaValue}} }",
|
||||
_limitProperties:"{ limit: {{=$schemaValue}} }",
|
||||
multipleOf: "{ multipleOf: {{=$schemaValue}} }",
|
||||
not: "{}",
|
||||
oneOf: "{ passingSchemas: {{=$passingSchemas}} }",
|
||||
pattern: "{ pattern: {{#def.schemaValueQS}} }",
|
||||
propertyNames: "{ propertyName: '{{=$invalidName}}' }",
|
||||
required: "{ missingProperty: '{{=$missingProperty}}' }",
|
||||
type: "{ type: '{{? $typeIsArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
|
||||
uniqueItems: "{ i: i, j: j }",
|
||||
custom: "{ keyword: '{{=$rule.keyword}}' }",
|
||||
patternRequired: "{ missingPattern: '{{=$missingPattern}}' }",
|
||||
switch: "{ caseIndex: {{=$caseIndex}} }",
|
||||
_formatLimit: "{ comparison: {{=$opExpr}}, limit: {{#def.schemaValueQS}}, exclusive: {{=$exclusive}} }",
|
||||
_formatExclusiveLimit: "{}"
|
||||
} #}}
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Internal module for NIST P256, P384, P521 curves.
|
||||
* Do not use for now.
|
||||
* @module
|
||||
*/
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { sha256, sha384, sha512 } from '@noble/hashes/sha2.js';
|
||||
import { createCurve } from "./_shortw_utils.js";
|
||||
import { createHasher } from "./abstract/hash-to-curve.js";
|
||||
import { Field } from "./abstract/modular.js";
|
||||
import { mapToCurveSimpleSWU, } from "./abstract/weierstrass.js";
|
||||
// p = 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n - 1n
|
||||
// a = Fp256.create(BigInt('-3'));
|
||||
const p256_CURVE = {
|
||||
p: BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'),
|
||||
n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
|
||||
h: BigInt(1),
|
||||
a: BigInt('0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc'),
|
||||
b: BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'),
|
||||
Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
|
||||
Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
|
||||
};
|
||||
// p = 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
|
||||
const p384_CURVE = {
|
||||
p: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff'),
|
||||
n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
|
||||
h: BigInt(1),
|
||||
a: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc'),
|
||||
b: BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef'),
|
||||
Gx: BigInt('0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7'),
|
||||
Gy: BigInt('0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f'),
|
||||
};
|
||||
// p = 2n**521n - 1n
|
||||
const p521_CURVE = {
|
||||
p: BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
|
||||
n: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'),
|
||||
h: BigInt(1),
|
||||
a: BigInt('0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc'),
|
||||
b: BigInt('0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00'),
|
||||
Gx: BigInt('0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66'),
|
||||
Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
|
||||
};
|
||||
const Fp256 = Field(p256_CURVE.p);
|
||||
const Fp384 = Field(p384_CURVE.p);
|
||||
const Fp521 = Field(p521_CURVE.p);
|
||||
function createSWU(Point, opts) {
|
||||
const map = mapToCurveSimpleSWU(Point.Fp, opts);
|
||||
return (scalars) => map(scalars[0]);
|
||||
}
|
||||
/** NIST P256 (aka secp256r1, prime256v1) curve, ECDSA and ECDH methods. */
|
||||
export const p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false }, sha256);
|
||||
/** Hashing / encoding to p256 points / field. RFC 9380 methods. */
|
||||
export const p256_hasher = /* @__PURE__ */ (() => {
|
||||
return createHasher(p256.Point, createSWU(p256.Point, {
|
||||
A: p256_CURVE.a,
|
||||
B: p256_CURVE.b,
|
||||
Z: p256.Point.Fp.create(BigInt('-10')),
|
||||
}), {
|
||||
DST: 'P256_XMD:SHA-256_SSWU_RO_',
|
||||
encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
|
||||
p: p256_CURVE.p,
|
||||
m: 1,
|
||||
k: 128,
|
||||
expand: 'xmd',
|
||||
hash: sha256,
|
||||
});
|
||||
})();
|
||||
// export const p256_oprf: OPRF = createORPF({
|
||||
// name: 'P256-SHA256',
|
||||
// Point: p256.Point,
|
||||
// hash: sha256,
|
||||
// hashToGroup: p256_hasher.hashToCurve,
|
||||
// hashToScalar: p256_hasher.hashToScalar,
|
||||
// });
|
||||
/** NIST P384 (aka secp384r1) curve, ECDSA and ECDH methods. */
|
||||
export const p384 = createCurve({ ...p384_CURVE, Fp: Fp384, lowS: false }, sha384);
|
||||
/** Hashing / encoding to p384 points / field. RFC 9380 methods. */
|
||||
export const p384_hasher = /* @__PURE__ */ (() => {
|
||||
return createHasher(p384.Point, createSWU(p384.Point, {
|
||||
A: p384_CURVE.a,
|
||||
B: p384_CURVE.b,
|
||||
Z: p384.Point.Fp.create(BigInt('-12')),
|
||||
}), {
|
||||
DST: 'P384_XMD:SHA-384_SSWU_RO_',
|
||||
encodeDST: 'P384_XMD:SHA-384_SSWU_NU_',
|
||||
p: p384_CURVE.p,
|
||||
m: 1,
|
||||
k: 192,
|
||||
expand: 'xmd',
|
||||
hash: sha384,
|
||||
});
|
||||
})();
|
||||
// export const p384_oprf: OPRF = createORPF({
|
||||
// name: 'P384-SHA384',
|
||||
// Point: p384.Point,
|
||||
// hash: sha384,
|
||||
// hashToGroup: p384_hasher.hashToCurve,
|
||||
// hashToScalar: p384_hasher.hashToScalar,
|
||||
// });
|
||||
// const Fn521 = Field(p521_CURVE.n, { allowedScalarLengths: [65, 66] });
|
||||
/** NIST P521 (aka secp521r1) curve, ECDSA and ECDH methods. */
|
||||
export const p521 = createCurve({ ...p521_CURVE, Fp: Fp521, lowS: false, allowedPrivateKeyLengths: [130, 131, 132] }, sha512);
|
||||
/** @deprecated use `p256` for consistency with `p256_hasher` */
|
||||
export const secp256r1 = p256;
|
||||
/** @deprecated use `p384` for consistency with `p384_hasher` */
|
||||
export const secp384r1 = p384;
|
||||
/** @deprecated use `p521` for consistency with `p521_hasher` */
|
||||
export const secp521r1 = p521;
|
||||
/** Hashing / encoding to p521 points / field. RFC 9380 methods. */
|
||||
export const p521_hasher = /* @__PURE__ */ (() => {
|
||||
return createHasher(p521.Point, createSWU(p521.Point, {
|
||||
A: p521_CURVE.a,
|
||||
B: p521_CURVE.b,
|
||||
Z: p521.Point.Fp.create(BigInt('-4')),
|
||||
}), {
|
||||
DST: 'P521_XMD:SHA-512_SSWU_RO_',
|
||||
encodeDST: 'P521_XMD:SHA-512_SSWU_NU_',
|
||||
p: p521_CURVE.p,
|
||||
m: 1,
|
||||
k: 256,
|
||||
expand: 'xmd',
|
||||
hash: sha512,
|
||||
});
|
||||
})();
|
||||
// export const p521_oprf: OPRF = createORPF({
|
||||
// name: 'P521-SHA512',
|
||||
// Point: p521.Point,
|
||||
// hash: sha512,
|
||||
// hashToGroup: p521_hasher.hashToCurve,
|
||||
// hashToScalar: p521_hasher.hashToScalar, // produces L=98 just like in RFC
|
||||
// });
|
||||
//# sourceMappingURL=nist.js.map
|
||||
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* @fileoverview Manages the suppressed violations.
|
||||
* @author Iacovos Constantinou
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const { calculateStatsPerFile } = require("../shared/message-counts");
|
||||
const stringify = require("json-stable-stringify-without-jsonify");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// For VSCode IntelliSense
|
||||
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
||||
/** @typedef {import("../types").ESLint.LintResult} LintResult */
|
||||
/** @typedef {Record<string, Record<string, { count: number; }>>} SuppressedViolations */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Manages the suppressed violations.
|
||||
*/
|
||||
class SuppressionsService {
|
||||
static DEFAULT_SUPPRESSIONS_FILENAME = "eslint-suppressions.json";
|
||||
|
||||
filePath = "";
|
||||
cwd = "";
|
||||
|
||||
/**
|
||||
* Creates a new instance of SuppressionsService.
|
||||
* @param {Object} options The options.
|
||||
* @param {string} [options.filePath] The location of the suppressions file.
|
||||
* @param {string} [options.cwd] The current working directory.
|
||||
*/
|
||||
constructor({ filePath, cwd }) {
|
||||
this.filePath = filePath;
|
||||
this.cwd = cwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the suppressions file based on the current violations and the provided rules.
|
||||
* If no rules are provided, all violations are suppressed.
|
||||
* @param {LintResult[]|undefined} results The lint results.
|
||||
* @param {string[]|undefined} rules The rules to suppress.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async suppress(results, rules) {
|
||||
const suppressions = await this.load();
|
||||
|
||||
for (const result of results) {
|
||||
const relativeFilePath = this.getRelativeFilePath(result.filePath);
|
||||
const violationsByRule = SuppressionsService.countViolationsByRule(
|
||||
result.messages,
|
||||
);
|
||||
|
||||
for (const ruleId in violationsByRule) {
|
||||
if (rules && !rules.includes(ruleId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
suppressions[relativeFilePath] ??= {};
|
||||
suppressions[relativeFilePath][ruleId] =
|
||||
violationsByRule[ruleId];
|
||||
}
|
||||
}
|
||||
|
||||
return this.save(suppressions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes old, unused suppressions for violations that do not occur anymore.
|
||||
* @param {LintResult[]} results The lint results.
|
||||
* @returns {Promise<void>} No return value.
|
||||
*/
|
||||
async prune(results) {
|
||||
const suppressions = await this.load();
|
||||
const { unused } = this.applySuppressions(results, suppressions);
|
||||
|
||||
for (const file in unused) {
|
||||
if (!suppressions[file]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const rule in unused[file]) {
|
||||
if (!suppressions[file][rule]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const suppressionsCount = suppressions[file][rule].count;
|
||||
const violationsCount = unused[file][rule].count;
|
||||
|
||||
if (suppressionsCount === violationsCount) {
|
||||
// Remove unused rules
|
||||
delete suppressions[file][rule];
|
||||
} else {
|
||||
// Update the count to match the new number of violations
|
||||
suppressions[file][rule].count -= violationsCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup files with no rules
|
||||
if (Object.keys(suppressions[file]).length === 0) {
|
||||
delete suppressions[file];
|
||||
}
|
||||
}
|
||||
|
||||
for (const file of Object.keys(suppressions)) {
|
||||
const absolutePath = path.resolve(this.cwd, file);
|
||||
|
||||
if (!fs.existsSync(absolutePath)) {
|
||||
delete suppressions[file];
|
||||
}
|
||||
}
|
||||
|
||||
return this.save(suppressions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the provided suppressions against the lint results.
|
||||
*
|
||||
* For each file, counts the number of violations per rule.
|
||||
* For each rule in each file, compares the number of violations against the counter from the suppressions file.
|
||||
* If the number of violations is less or equal to the counter, messages are moved to `LintResult#suppressedMessages` and ignored.
|
||||
* Otherwise, all violations are reported as usual.
|
||||
* @param {LintResult[]} results The lint results.
|
||||
* @param {SuppressedViolations} suppressions The suppressions.
|
||||
* @returns {{
|
||||
* results: LintResult[],
|
||||
* unused: SuppressedViolations
|
||||
* }} The updated results and the unused suppressions.
|
||||
*/
|
||||
applySuppressions(results, suppressions) {
|
||||
/**
|
||||
* We copy the results to avoid modifying the original objects
|
||||
* We remove only result messages that are matched and hence suppressed
|
||||
* We leave the rest untouched to minimize the risk of losing parts of the original data
|
||||
*/
|
||||
const filtered = structuredClone(results);
|
||||
const unused = {};
|
||||
|
||||
for (const result of filtered) {
|
||||
const relativeFilePath = this.getRelativeFilePath(result.filePath);
|
||||
|
||||
if (!suppressions[relativeFilePath]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const violationsByRule = SuppressionsService.countViolationsByRule(
|
||||
result.messages,
|
||||
);
|
||||
let wasSuppressed = false;
|
||||
|
||||
for (const ruleId in violationsByRule) {
|
||||
if (!suppressions[relativeFilePath][ruleId]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const suppressionsCount =
|
||||
suppressions[relativeFilePath][ruleId].count;
|
||||
const violationsCount = violationsByRule[ruleId].count;
|
||||
|
||||
// Suppress messages if the number of violations is less or equal to the suppressions count
|
||||
if (violationsCount <= suppressionsCount) {
|
||||
SuppressionsService.suppressMessagesByRule(result, ruleId);
|
||||
wasSuppressed = true;
|
||||
}
|
||||
|
||||
// Update the count to match the new number of violations, otherwise remove the rule entirely
|
||||
if (violationsCount < suppressionsCount) {
|
||||
unused[relativeFilePath] ??= {};
|
||||
unused[relativeFilePath][ruleId] ??= {};
|
||||
unused[relativeFilePath][ruleId].count =
|
||||
suppressionsCount - violationsCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark as unused all the suppressions that were not matched against a rule
|
||||
for (const ruleId in suppressions[relativeFilePath]) {
|
||||
if (violationsByRule[ruleId]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unused[relativeFilePath] ??= {};
|
||||
unused[relativeFilePath][ruleId] =
|
||||
suppressions[relativeFilePath][ruleId];
|
||||
}
|
||||
|
||||
// Recalculate stats if messages were suppressed
|
||||
if (wasSuppressed) {
|
||||
Object.assign(result, calculateStatsPerFile(result.messages));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
results: filtered,
|
||||
unused,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the suppressions file.
|
||||
* @throws {Error} If the suppressions file cannot be parsed.
|
||||
* @returns {Promise<SuppressedViolations>} The suppressions.
|
||||
*/
|
||||
async load() {
|
||||
try {
|
||||
const data = await fs.promises.readFile(this.filePath, "utf8");
|
||||
|
||||
return JSON.parse(data);
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
return {};
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to parse suppressions file at ${this.filePath}`,
|
||||
{
|
||||
cause: err,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the suppressions file.
|
||||
* @param {SuppressedViolations} suppressions The suppressions to save.
|
||||
* @returns {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
save(suppressions) {
|
||||
return fs.promises.writeFile(
|
||||
this.filePath,
|
||||
stringify(suppressions, { space: 2 }),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the violations by rule, ignoring warnings.
|
||||
* @param {LintMessage[]} messages The messages to count.
|
||||
* @returns {Record<string, number>} The number of violations by rule.
|
||||
*/
|
||||
static countViolationsByRule(messages) {
|
||||
return messages.reduce((totals, message) => {
|
||||
if (message.severity === 2 && message.ruleId) {
|
||||
totals[message.ruleId] ??= { count: 0 };
|
||||
totals[message.ruleId].count++;
|
||||
}
|
||||
return totals;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative path of a file to the current working directory.
|
||||
* Always in POSIX format for consistency and interoperability.
|
||||
* @param {string} filePath The file path.
|
||||
* @returns {string} The relative file path.
|
||||
*/
|
||||
getRelativeFilePath(filePath) {
|
||||
return path
|
||||
.relative(this.cwd, filePath)
|
||||
.split(path.sep)
|
||||
.join(path.posix.sep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the messages matching the rule to `LintResult#suppressedMessages` and updates the stats.
|
||||
* @param {LintResult} result The result to update.
|
||||
* @param {string} ruleId The rule to suppress.
|
||||
* @returns {void}
|
||||
*/
|
||||
static suppressMessagesByRule(result, ruleId) {
|
||||
const suppressedMessages = result.messages.filter(
|
||||
message => message.ruleId === ruleId,
|
||||
);
|
||||
|
||||
result.suppressedMessages = result.suppressedMessages.concat(
|
||||
suppressedMessages.map(message => {
|
||||
message.suppressions = [
|
||||
{
|
||||
kind: "file",
|
||||
justification: "",
|
||||
},
|
||||
];
|
||||
|
||||
return message;
|
||||
}),
|
||||
);
|
||||
|
||||
result.messages = result.messages.filter(
|
||||
message => message.ruleId !== ruleId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { SuppressionsService };
|
||||
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag no-unneeded-ternary
|
||||
* @author Gyandeep Singh
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
// Operators that always result in a boolean value
|
||||
const BOOLEAN_OPERATORS = new Set([
|
||||
"==",
|
||||
"===",
|
||||
"!=",
|
||||
"!==",
|
||||
">",
|
||||
">=",
|
||||
"<",
|
||||
"<=",
|
||||
"in",
|
||||
"instanceof",
|
||||
]);
|
||||
const OPERATOR_INVERSES = {
|
||||
"==": "!=",
|
||||
"!=": "==",
|
||||
"===": "!==",
|
||||
"!==": "===",
|
||||
|
||||
// Operators like < and >= are not true inverses, since both will return false with NaN.
|
||||
};
|
||||
const OR_PRECEDENCE = astUtils.getPrecedence({
|
||||
type: "LogicalExpression",
|
||||
operator: "||",
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [{ defaultAssignment: true }],
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow ternary operators when simpler alternatives exist",
|
||||
recommended: false,
|
||||
frozen: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-unneeded-ternary",
|
||||
},
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
defaultAssignment: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
|
||||
fixable: "code",
|
||||
|
||||
messages: {
|
||||
unnecessaryConditionalExpression:
|
||||
"Unnecessary use of boolean literals in conditional expression.",
|
||||
unnecessaryConditionalAssignment:
|
||||
"Unnecessary use of conditional expression for default assignment.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const [{ defaultAssignment }] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Test if the node is a boolean literal
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @returns {boolean} True if the its a boolean literal
|
||||
* @private
|
||||
*/
|
||||
function isBooleanLiteral(node) {
|
||||
return node.type === "Literal" && typeof node.value === "boolean";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression that represents the boolean inverse of the expression represented by the original node
|
||||
* @param {ASTNode} node A node representing an expression
|
||||
* @returns {string} A string representing an inverted expression
|
||||
*/
|
||||
function invertExpression(node) {
|
||||
if (
|
||||
node.type === "BinaryExpression" &&
|
||||
Object.hasOwn(OPERATOR_INVERSES, node.operator)
|
||||
) {
|
||||
const operatorToken = sourceCode.getFirstTokenBetween(
|
||||
node.left,
|
||||
node.right,
|
||||
token => token.value === node.operator,
|
||||
);
|
||||
const text = sourceCode.getText();
|
||||
|
||||
return (
|
||||
text.slice(node.range[0], operatorToken.range[0]) +
|
||||
OPERATOR_INVERSES[node.operator] +
|
||||
text.slice(operatorToken.range[1], node.range[1])
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
astUtils.getPrecedence(node) <
|
||||
astUtils.getPrecedence({ type: "UnaryExpression" })
|
||||
) {
|
||||
return `!(${astUtils.getParenthesisedText(sourceCode, node)})`;
|
||||
}
|
||||
return `!${astUtils.getParenthesisedText(sourceCode, node)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a given node always evaluates to a boolean value
|
||||
* @param {ASTNode} node An expression node
|
||||
* @returns {boolean} True if it is determined that the node will always evaluate to a boolean value
|
||||
*/
|
||||
function isBooleanExpression(node) {
|
||||
return (
|
||||
(node.type === "BinaryExpression" &&
|
||||
BOOLEAN_OPERATORS.has(node.operator)) ||
|
||||
(node.type === "UnaryExpression" && node.operator === "!")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the node matches the pattern id ? id : expression
|
||||
* @param {ASTNode} node The ConditionalExpression to check.
|
||||
* @returns {boolean} True if the pattern is matched, and false otherwise
|
||||
* @private
|
||||
*/
|
||||
function matchesDefaultAssignment(node) {
|
||||
return (
|
||||
node.test.type === "Identifier" &&
|
||||
node.consequent.type === "Identifier" &&
|
||||
node.test.name === node.consequent.name
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
ConditionalExpression(node) {
|
||||
if (
|
||||
isBooleanLiteral(node.alternate) &&
|
||||
isBooleanLiteral(node.consequent)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalExpression",
|
||||
fix(fixer) {
|
||||
if (
|
||||
node.consequent.value === node.alternate.value
|
||||
) {
|
||||
// Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true`
|
||||
return node.test.type === "Identifier"
|
||||
? fixer.replaceText(
|
||||
node,
|
||||
node.consequent.value.toString(),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
if (node.alternate.value) {
|
||||
// Replace `foo() ? false : true` with `!(foo())`
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
invertExpression(node.test),
|
||||
);
|
||||
}
|
||||
|
||||
// Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise.
|
||||
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
isBooleanExpression(node.test)
|
||||
? astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.test,
|
||||
)
|
||||
: `!${invertExpression(node.test)}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
} else if (
|
||||
!defaultAssignment &&
|
||||
matchesDefaultAssignment(node)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalAssignment",
|
||||
fix(fixer) {
|
||||
const shouldParenthesizeAlternate =
|
||||
(astUtils.getPrecedence(node.alternate) <
|
||||
OR_PRECEDENCE ||
|
||||
astUtils.isCoalesceExpression(
|
||||
node.alternate,
|
||||
)) &&
|
||||
!astUtils.isParenthesised(
|
||||
sourceCode,
|
||||
node.alternate,
|
||||
);
|
||||
const alternateText = shouldParenthesizeAlternate
|
||||
? `(${sourceCode.getText(node.alternate)})`
|
||||
: astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.alternate,
|
||||
);
|
||||
const testText = astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.test,
|
||||
);
|
||||
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
`${testText} || ${alternateText}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export declare const DEFAULT_PROJECT_FILES_ERROR_EXPLANATION = "\n\nHaving many files run with the default project is known to cause performance issues and slow down linting.\n\nSee https://tseslint.com/allowdefaultproject-glob-too-wide\n";
|
||||
export declare function validateDefaultProjectForFilesGlob(allowDefaultProject: string[] | undefined): void;
|
||||
@@ -0,0 +1,181 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { z } from "../../../../index.js";
|
||||
import es from "../../../locales/es.js";
|
||||
|
||||
test("Spanish locale - type name translations in too_small errors", () => {
|
||||
z.config(es());
|
||||
|
||||
// Test string type translation
|
||||
const stringSchema = z.string().min(5);
|
||||
const stringResult = stringSchema.safeParse("abc");
|
||||
expect(stringResult.success).toBe(false);
|
||||
if (!stringResult.success) {
|
||||
expect(stringResult.error.issues[0].message).toBe(
|
||||
"Demasiado pequeño: se esperaba que texto tuviera >=5 caracteres"
|
||||
);
|
||||
}
|
||||
|
||||
// Test number type translation
|
||||
const numberSchema = z.number().min(10);
|
||||
const numberResult = numberSchema.safeParse(5);
|
||||
expect(numberResult.success).toBe(false);
|
||||
if (!numberResult.success) {
|
||||
expect(numberResult.error.issues[0].message).toBe("Demasiado pequeño: se esperaba que número fuera >=10");
|
||||
}
|
||||
|
||||
// Test array type translation
|
||||
const arraySchema = z.array(z.string()).min(3);
|
||||
const arrayResult = arraySchema.safeParse(["a", "b"]);
|
||||
expect(arrayResult.success).toBe(false);
|
||||
if (!arrayResult.success) {
|
||||
expect(arrayResult.error.issues[0].message).toBe(
|
||||
"Demasiado pequeño: se esperaba que arreglo tuviera >=3 elementos"
|
||||
);
|
||||
}
|
||||
|
||||
// Test set type translation
|
||||
const setSchema = z.set(z.string()).min(2);
|
||||
const setResult = setSchema.safeParse(new Set(["a"]));
|
||||
expect(setResult.success).toBe(false);
|
||||
if (!setResult.success) {
|
||||
expect(setResult.error.issues[0].message).toBe("Demasiado pequeño: se esperaba que conjunto tuviera >=2 elementos");
|
||||
}
|
||||
});
|
||||
|
||||
test("Spanish locale - type name translations in too_big errors", () => {
|
||||
z.config(es());
|
||||
|
||||
// Test string type translation
|
||||
const stringSchema = z.string().max(3);
|
||||
const stringResult = stringSchema.safeParse("abcde");
|
||||
expect(stringResult.success).toBe(false);
|
||||
if (!stringResult.success) {
|
||||
expect(stringResult.error.issues[0].message).toBe("Demasiado grande: se esperaba que texto tuviera <=3 caracteres");
|
||||
}
|
||||
|
||||
// Test number type translation
|
||||
const numberSchema = z.number().max(10);
|
||||
const numberResult = numberSchema.safeParse(15);
|
||||
expect(numberResult.success).toBe(false);
|
||||
if (!numberResult.success) {
|
||||
expect(numberResult.error.issues[0].message).toBe("Demasiado grande: se esperaba que número fuera <=10");
|
||||
}
|
||||
|
||||
// Test array type translation
|
||||
const arraySchema = z.array(z.string()).max(2);
|
||||
const arrayResult = arraySchema.safeParse(["a", "b", "c"]);
|
||||
expect(arrayResult.success).toBe(false);
|
||||
if (!arrayResult.success) {
|
||||
expect(arrayResult.error.issues[0].message).toBe("Demasiado grande: se esperaba que arreglo tuviera <=2 elementos");
|
||||
}
|
||||
});
|
||||
|
||||
test("Spanish locale - type name translations in invalid_type errors", () => {
|
||||
z.config(es());
|
||||
|
||||
// Test string expected, number received
|
||||
const stringSchema = z.string();
|
||||
const stringResult = stringSchema.safeParse(123);
|
||||
expect(stringResult.success).toBe(false);
|
||||
if (!stringResult.success) {
|
||||
expect(stringResult.error.issues[0].message).toBe("Entrada inválida: se esperaba texto, recibido número");
|
||||
}
|
||||
|
||||
// Test number expected, string received
|
||||
const numberSchema = z.number();
|
||||
const numberResult = numberSchema.safeParse("abc");
|
||||
expect(numberResult.success).toBe(false);
|
||||
if (!numberResult.success) {
|
||||
expect(numberResult.error.issues[0].message).toBe("Entrada inválida: se esperaba número, recibido texto");
|
||||
}
|
||||
|
||||
// Test boolean expected, null received
|
||||
const booleanSchema = z.boolean();
|
||||
const booleanResult = booleanSchema.safeParse(null);
|
||||
expect(booleanResult.success).toBe(false);
|
||||
if (!booleanResult.success) {
|
||||
expect(booleanResult.error.issues[0].message).toBe("Entrada inválida: se esperaba booleano, recibido nulo");
|
||||
}
|
||||
|
||||
// Test array expected, object received
|
||||
const arraySchema = z.array(z.string());
|
||||
const arrayResult = arraySchema.safeParse({});
|
||||
expect(arrayResult.success).toBe(false);
|
||||
if (!arrayResult.success) {
|
||||
expect(arrayResult.error.issues[0].message).toBe("Entrada inválida: se esperaba arreglo, recibido objeto");
|
||||
}
|
||||
});
|
||||
|
||||
test("Spanish locale - fallback for unknown type names", () => {
|
||||
z.config(es());
|
||||
|
||||
// Test with a type that's not in the TypeNames dictionary
|
||||
// This will test the fallback behavior
|
||||
const dateSchema = z.date().min(new Date("2025-01-01"));
|
||||
const dateResult = dateSchema.safeParse(new Date("2024-01-01"));
|
||||
expect(dateResult.success).toBe(false);
|
||||
if (!dateResult.success) {
|
||||
// Should use "fecha" since we included it in TypeNames
|
||||
expect(dateResult.error.issues[0].message).toContain("fecha");
|
||||
}
|
||||
});
|
||||
|
||||
test("Spanish locale - other error cases", () => {
|
||||
z.config(es());
|
||||
|
||||
// Test invalid_element with tuple
|
||||
const tupleSchema = z.tuple([z.string(), z.number()]);
|
||||
const tupleResult = tupleSchema.safeParse(["abc", "not a number"]);
|
||||
expect(tupleResult.success).toBe(false);
|
||||
if (!tupleResult.success) {
|
||||
expect(tupleResult.error.issues[0].message).toContain("Entrada inválida");
|
||||
}
|
||||
|
||||
// Test invalid_value with enum
|
||||
const enumSchema = z.enum(["a", "b"]);
|
||||
const enumResult = enumSchema.safeParse("c");
|
||||
expect(enumResult.success).toBe(false);
|
||||
if (!enumResult.success) {
|
||||
expect(enumResult.error.issues[0].message).toBe('Opción inválida: se esperaba una de "a"|"b"');
|
||||
}
|
||||
|
||||
// Test not_multiple_of
|
||||
const multipleSchema = z.number().multipleOf(3);
|
||||
const multipleResult = multipleSchema.safeParse(10);
|
||||
expect(multipleResult.success).toBe(false);
|
||||
if (!multipleResult.success) {
|
||||
expect(multipleResult.error.issues[0].message).toBe("Número inválido: debe ser múltiplo de 3");
|
||||
}
|
||||
|
||||
// Test unrecognized_keys
|
||||
const strictSchema = z.object({ a: z.string() }).strict();
|
||||
const strictResult = strictSchema.safeParse({ a: "test", b: "extra" });
|
||||
expect(strictResult.success).toBe(false);
|
||||
if (!strictResult.success) {
|
||||
expect(strictResult.error.issues[0].message).toBe('Llave desconocida: "b"');
|
||||
}
|
||||
|
||||
// Test invalid_union
|
||||
const unionSchema = z.union([z.string(), z.number()]);
|
||||
const unionResult = unionSchema.safeParse(true);
|
||||
expect(unionResult.success).toBe(false);
|
||||
if (!unionResult.success) {
|
||||
expect(unionResult.error.issues[0].message).toBe("Entrada inválida");
|
||||
}
|
||||
|
||||
// Test invalid_format with regex
|
||||
const regexSchema = z.string().regex(/^[a-z]+$/);
|
||||
const regexResult = regexSchema.safeParse("ABC123");
|
||||
expect(regexResult.success).toBe(false);
|
||||
if (!regexResult.success) {
|
||||
expect(regexResult.error.issues[0].message).toBe("Cadena inválida: debe coincidir con el patrón /^[a-z]+$/");
|
||||
}
|
||||
|
||||
// Test invalid_format with startsWith
|
||||
const startsWithSchema = z.string().startsWith("hello");
|
||||
const startsWithResult = startsWithSchema.safeParse("world");
|
||||
expect(startsWithResult.success).toBe(false);
|
||||
if (!startsWithResult.success) {
|
||||
expect(startsWithResult.error.issues[0].message).toBe('Cadena inválida: debe comenzar con "hello"');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { ParseSettings } from '../parseSettings';
|
||||
import type { ASTAndDefiniteProgram } from './shared';
|
||||
/**
|
||||
* @returns Returns a new source file and program corresponding to the linted code
|
||||
*/
|
||||
export declare function createIsolatedProgram(parseSettings: ParseSettings): ASTAndDefiniteProgram;
|
||||
@@ -0,0 +1,534 @@
|
||||
/**
|
||||
* Blake1 legacy hash function, one of SHA3 proposals.
|
||||
* Rarely used. Check out blake2 or blake3 instead.
|
||||
* https://www.aumasson.jp/blake/blake.pdf
|
||||
*
|
||||
* In the best case, there are 0 allocations.
|
||||
*
|
||||
* Differences from blake2:
|
||||
*
|
||||
* - BE instead of LE
|
||||
* - Paddings, similar to MD5, RIPEMD, SHA1, SHA2, but:
|
||||
* - length flag is located before actual length
|
||||
* - padding block is compressed differently (no lengths)
|
||||
* Instead of msg[sigma[k]], we have `msg[sigma[k]] ^ constants[sigma[k-1]]`
|
||||
* (-1 for g1, g2 without -1)
|
||||
* - Salt is XOR-ed into constants instead of state
|
||||
* - Salt is XOR-ed with output in `compress`
|
||||
* - Additional rows (+64 bytes) in SIGMA for new rounds
|
||||
* - Different round count:
|
||||
* - 14 / 10 rounds in blake256 / blake2s
|
||||
* - 16 / 12 rounds in blake512 / blake2b
|
||||
* - blake512: G1b: rotr 24 -> 25, G2b: rotr 63 -> 11
|
||||
* @module
|
||||
*/
|
||||
import { BSIGMA, G1s, G2s } from './_blake.ts';
|
||||
import { setBigUint64, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';
|
||||
import * as u64 from './_u64.ts';
|
||||
// prettier-ignore
|
||||
import {
|
||||
abytes, aexists, aoutput,
|
||||
clean, createOptHasher,
|
||||
createView, Hash, toBytes,
|
||||
type CHashO, type Input,
|
||||
} from './utils.ts';
|
||||
|
||||
/** Blake1 options. Basically just "salt" */
|
||||
export type BlakeOpts = {
|
||||
salt?: Uint8Array;
|
||||
};
|
||||
|
||||
// Empty zero-filled salt
|
||||
const EMPTY_SALT = /* @__PURE__ */ new Uint32Array(8);
|
||||
|
||||
abstract class BLAKE1<T extends BLAKE1<T>> extends Hash<T> {
|
||||
protected finished = false;
|
||||
protected length = 0;
|
||||
protected pos = 0;
|
||||
protected destroyed = false;
|
||||
// For partial updates less than block size
|
||||
protected buffer: Uint8Array;
|
||||
protected view: DataView;
|
||||
protected salt: Uint32Array;
|
||||
abstract compress(view: DataView, offset: number, withLength?: boolean): void;
|
||||
protected abstract get(): number[];
|
||||
protected abstract set(...args: number[]): void;
|
||||
|
||||
readonly blockLen: number;
|
||||
readonly outputLen: number;
|
||||
private lengthFlag: number;
|
||||
private counterLen: number;
|
||||
protected constants: Uint32Array;
|
||||
|
||||
constructor(
|
||||
blockLen: number,
|
||||
outputLen: number,
|
||||
lengthFlag: number,
|
||||
counterLen: number,
|
||||
saltLen: number,
|
||||
constants: Uint32Array,
|
||||
opts: BlakeOpts = {}
|
||||
) {
|
||||
super();
|
||||
const { salt } = opts;
|
||||
this.blockLen = blockLen;
|
||||
this.outputLen = outputLen;
|
||||
this.lengthFlag = lengthFlag;
|
||||
this.counterLen = counterLen;
|
||||
this.buffer = new Uint8Array(blockLen);
|
||||
this.view = createView(this.buffer);
|
||||
if (salt) {
|
||||
let slt = salt;
|
||||
slt = toBytes(slt);
|
||||
abytes(slt);
|
||||
if (slt.length !== 4 * saltLen) throw new Error('wrong salt length');
|
||||
const salt32 = (this.salt = new Uint32Array(saltLen));
|
||||
const sv = createView(slt);
|
||||
this.constants = constants.slice();
|
||||
for (let i = 0, offset = 0; i < salt32.length; i++, offset += 4) {
|
||||
salt32[i] = sv.getUint32(offset, false);
|
||||
this.constants[i] ^= salt32[i];
|
||||
}
|
||||
} else {
|
||||
this.salt = EMPTY_SALT;
|
||||
this.constants = constants;
|
||||
}
|
||||
}
|
||||
update(data: Input): this {
|
||||
aexists(this);
|
||||
data = toBytes(data);
|
||||
abytes(data);
|
||||
// From _md, but update length before each compress
|
||||
const { view, buffer, blockLen } = this;
|
||||
const len = data.length;
|
||||
let dataView;
|
||||
for (let pos = 0; pos < len; ) {
|
||||
const take = Math.min(blockLen - this.pos, len - pos);
|
||||
// Fast path: we have at least one block in input, cast it to view and process
|
||||
if (take === blockLen) {
|
||||
if (!dataView) dataView = createView(data);
|
||||
for (; blockLen <= len - pos; pos += blockLen) {
|
||||
this.length += blockLen;
|
||||
this.compress(dataView, pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
buffer.set(data.subarray(pos, pos + take), this.pos);
|
||||
this.pos += take;
|
||||
pos += take;
|
||||
if (this.pos === blockLen) {
|
||||
this.length += blockLen;
|
||||
this.compress(view, 0, true);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy(): void {
|
||||
this.destroyed = true;
|
||||
if (this.salt !== EMPTY_SALT) {
|
||||
clean(this.salt, this.constants);
|
||||
}
|
||||
}
|
||||
_cloneInto(to?: T): T {
|
||||
to ||= new (this.constructor as any)() as T;
|
||||
to.set(...this.get());
|
||||
const { buffer, length, finished, destroyed, constants, salt, pos } = this;
|
||||
to.buffer.set(buffer);
|
||||
to.constants = constants.slice();
|
||||
to.destroyed = destroyed;
|
||||
to.finished = finished;
|
||||
to.length = length;
|
||||
to.pos = pos;
|
||||
to.salt = salt.slice();
|
||||
return to;
|
||||
}
|
||||
clone(): T {
|
||||
return this._cloneInto();
|
||||
}
|
||||
digestInto(out: Uint8Array): void {
|
||||
aexists(this);
|
||||
aoutput(out, this);
|
||||
this.finished = true;
|
||||
// Padding
|
||||
const { buffer, blockLen, counterLen, lengthFlag, view } = this;
|
||||
clean(buffer.subarray(this.pos)); // clean buf
|
||||
const counter = BigInt((this.length + this.pos) * 8);
|
||||
const counterPos = blockLen - counterLen - 1;
|
||||
buffer[this.pos] |= 0b1000_0000; // End block flag
|
||||
this.length += this.pos; // add unwritten length
|
||||
// Not enough in buffer for length: write what we have.
|
||||
if (this.pos > counterPos) {
|
||||
this.compress(view, 0);
|
||||
clean(buffer);
|
||||
this.pos = 0;
|
||||
}
|
||||
// Difference with md: here we have lengthFlag!
|
||||
buffer[counterPos] |= lengthFlag; // Length flag
|
||||
// We always set 8 byte length flag. Because length will overflow significantly sooner.
|
||||
setBigUint64(view, blockLen - 8, counter, false);
|
||||
this.compress(view, 0, this.pos !== 0); // don't add length if length is not empty block?
|
||||
// Write output
|
||||
clean(buffer);
|
||||
const v = createView(out);
|
||||
const state = this.get();
|
||||
for (let i = 0; i < this.outputLen / 4; ++i) v.setUint32(i * 4, state[i]);
|
||||
}
|
||||
digest(): Uint8Array {
|
||||
const { buffer, outputLen } = this;
|
||||
this.digestInto(buffer);
|
||||
const res = buffer.slice(0, outputLen);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants
|
||||
const B64C = /* @__PURE__ */ Uint32Array.from([
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b, 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
||||
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69,
|
||||
]);
|
||||
// first half of C512
|
||||
const B32C = B64C.slice(0, 16);
|
||||
|
||||
const B256_IV = SHA256_IV.slice();
|
||||
const B224_IV = SHA224_IV.slice();
|
||||
const B384_IV = SHA384_IV.slice();
|
||||
const B512_IV = SHA512_IV.slice();
|
||||
|
||||
function generateTBL256() {
|
||||
const TBL = [];
|
||||
for (let i = 0, j = 0; i < 14; i++, j += 16) {
|
||||
for (let offset = 1; offset < 16; offset += 2) {
|
||||
TBL.push(B32C[BSIGMA[j + offset]]);
|
||||
TBL.push(B32C[BSIGMA[j + offset - 1]]);
|
||||
}
|
||||
}
|
||||
return new Uint32Array(TBL);
|
||||
}
|
||||
const TBL256 = /* @__PURE__ */ generateTBL256(); // C256[SIGMA[X]] precompute
|
||||
|
||||
// Reusable temporary buffer
|
||||
const BLAKE256_W = /* @__PURE__ */ new Uint32Array(16);
|
||||
|
||||
class Blake1_32 extends BLAKE1<Blake1_32> {
|
||||
private v0: number;
|
||||
private v1: number;
|
||||
private v2: number;
|
||||
private v3: number;
|
||||
private v4: number;
|
||||
private v5: number;
|
||||
private v6: number;
|
||||
private v7: number;
|
||||
constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts: BlakeOpts = {}) {
|
||||
super(64, outputLen, lengthFlag, 8, 4, B32C, opts);
|
||||
this.v0 = IV[0] | 0;
|
||||
this.v1 = IV[1] | 0;
|
||||
this.v2 = IV[2] | 0;
|
||||
this.v3 = IV[3] | 0;
|
||||
this.v4 = IV[4] | 0;
|
||||
this.v5 = IV[5] | 0;
|
||||
this.v6 = IV[6] | 0;
|
||||
this.v7 = IV[7] | 0;
|
||||
}
|
||||
protected get(): [number, number, number, number, number, number, number, number] {
|
||||
const { v0, v1, v2, v3, v4, v5, v6, v7 } = this;
|
||||
return [v0, v1, v2, v3, v4, v5, v6, v7];
|
||||
}
|
||||
// prettier-ignore
|
||||
protected set(
|
||||
v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number
|
||||
): void {
|
||||
this.v0 = v0 | 0;
|
||||
this.v1 = v1 | 0;
|
||||
this.v2 = v2 | 0;
|
||||
this.v3 = v3 | 0;
|
||||
this.v4 = v4 | 0;
|
||||
this.v5 = v5 | 0;
|
||||
this.v6 = v6 | 0;
|
||||
this.v7 = v7 | 0;
|
||||
}
|
||||
destroy(): void {
|
||||
super.destroy();
|
||||
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
compress(view: DataView, offset: number, withLength = true): void {
|
||||
for (let i = 0; i < 16; i++, offset += 4) BLAKE256_W[i] = view.getUint32(offset, false);
|
||||
// NOTE: we cannot re-use compress from blake2s, since there is additional xor over u256[SIGMA[e]]
|
||||
let v00 = this.v0 | 0;
|
||||
let v01 = this.v1 | 0;
|
||||
let v02 = this.v2 | 0;
|
||||
let v03 = this.v3 | 0;
|
||||
let v04 = this.v4 | 0;
|
||||
let v05 = this.v5 | 0;
|
||||
let v06 = this.v6 | 0;
|
||||
let v07 = this.v7 | 0;
|
||||
let v08 = this.constants[0] | 0;
|
||||
let v09 = this.constants[1] | 0;
|
||||
let v10 = this.constants[2] | 0;
|
||||
let v11 = this.constants[3] | 0;
|
||||
const { h, l } = u64.fromBig(BigInt(withLength ? this.length * 8 : 0));
|
||||
let v12 = (this.constants[4] ^ l) >>> 0;
|
||||
let v13 = (this.constants[5] ^ l) >>> 0;
|
||||
let v14 = (this.constants[6] ^ h) >>> 0;
|
||||
let v15 = (this.constants[7] ^ h) >>> 0;
|
||||
// prettier-ignore
|
||||
for (let i = 0, k = 0, j = 0; i < 14; i++) {
|
||||
({ a: v00, b: v04, c: v08, d: v12 } = G1s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v04, c: v08, d: v12 } = G2s(v00, v04, v08, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v05, c: v09, d: v13 } = G1s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v05, c: v09, d: v13 } = G2s(v01, v05, v09, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v06, c: v10, d: v14 } = G1s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v06, c: v10, d: v14 } = G2s(v02, v06, v10, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v07, c: v11, d: v15 } = G1s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v07, c: v11, d: v15 } = G2s(v03, v07, v11, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v05, c: v10, d: v15 } = G1s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v00, b: v05, c: v10, d: v15 } = G2s(v00, v05, v10, v15, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v06, c: v11, d: v12 } = G1s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v01, b: v06, c: v11, d: v12 } = G2s(v01, v06, v11, v12, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v07, c: v08, d: v13 } = G1s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v02, b: v07, c: v08, d: v13 } = G2s(v02, v07, v08, v13, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v04, c: v09, d: v14 } = G1s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
({ a: v03, b: v04, c: v09, d: v14 } = G2s(v03, v04, v09, v14, BLAKE256_W[BSIGMA[k++]] ^ TBL256[j++]));
|
||||
}
|
||||
this.v0 = (this.v0 ^ v00 ^ v08 ^ this.salt[0]) >>> 0;
|
||||
this.v1 = (this.v1 ^ v01 ^ v09 ^ this.salt[1]) >>> 0;
|
||||
this.v2 = (this.v2 ^ v02 ^ v10 ^ this.salt[2]) >>> 0;
|
||||
this.v3 = (this.v3 ^ v03 ^ v11 ^ this.salt[3]) >>> 0;
|
||||
this.v4 = (this.v4 ^ v04 ^ v12 ^ this.salt[0]) >>> 0;
|
||||
this.v5 = (this.v5 ^ v05 ^ v13 ^ this.salt[1]) >>> 0;
|
||||
this.v6 = (this.v6 ^ v06 ^ v14 ^ this.salt[2]) >>> 0;
|
||||
this.v7 = (this.v7 ^ v07 ^ v15 ^ this.salt[3]) >>> 0;
|
||||
clean(BLAKE256_W);
|
||||
}
|
||||
}
|
||||
|
||||
const BBUF = /* @__PURE__ */ new Uint32Array(32);
|
||||
const BLAKE512_W = /* @__PURE__ */ new Uint32Array(32);
|
||||
|
||||
function generateTBL512() {
|
||||
const TBL = [];
|
||||
for (let r = 0, k = 0; r < 16; r++, k += 16) {
|
||||
for (let offset = 1; offset < 16; offset += 2) {
|
||||
TBL.push(B64C[BSIGMA[k + offset] * 2 + 0]);
|
||||
TBL.push(B64C[BSIGMA[k + offset] * 2 + 1]);
|
||||
TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 0]);
|
||||
TBL.push(B64C[BSIGMA[k + offset - 1] * 2 + 1]);
|
||||
}
|
||||
}
|
||||
return new Uint32Array(TBL);
|
||||
}
|
||||
const TBL512 = /* @__PURE__ */ generateTBL512(); // C512[SIGMA[X]] precompute
|
||||
|
||||
// Mixing function G splitted in two halfs
|
||||
function G1b(a: number, b: number, c: number, d: number, msg: Uint32Array, k: number) {
|
||||
const Xpos = 2 * BSIGMA[k];
|
||||
const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore
|
||||
let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore
|
||||
let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore
|
||||
let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore
|
||||
let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore
|
||||
// v[a] = (v[a] + v[b] + x) | 0;
|
||||
let ll = u64.add3L(Al, Bl, Xl);
|
||||
Ah = u64.add3H(ll, Ah, Bh, Xh) >>> 0;
|
||||
Al = (ll | 0) >>> 0;
|
||||
// v[d] = rotr(v[d] ^ v[a], 32)
|
||||
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||||
({ Dh, Dl } = { Dh: u64.rotr32H(Dh, Dl), Dl: u64.rotr32L(Dh, Dl) });
|
||||
// v[c] = (v[c] + v[d]) | 0;
|
||||
({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl));
|
||||
// v[b] = rotr(v[b] ^ v[c], 25)
|
||||
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||||
({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 25), Bl: u64.rotrSL(Bh, Bl, 25) });
|
||||
(BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah);
|
||||
(BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh);
|
||||
(BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch);
|
||||
(BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh);
|
||||
}
|
||||
|
||||
function G2b(a: number, b: number, c: number, d: number, msg: Uint32Array, k: number) {
|
||||
const Xpos = 2 * BSIGMA[k];
|
||||
const Xl = msg[Xpos + 1] ^ TBL512[k * 2 + 1], Xh = msg[Xpos] ^ TBL512[k * 2]; // prettier-ignore
|
||||
let Al = BBUF[2 * a + 1], Ah = BBUF[2 * a]; // prettier-ignore
|
||||
let Bl = BBUF[2 * b + 1], Bh = BBUF[2 * b]; // prettier-ignore
|
||||
let Cl = BBUF[2 * c + 1], Ch = BBUF[2 * c]; // prettier-ignore
|
||||
let Dl = BBUF[2 * d + 1], Dh = BBUF[2 * d]; // prettier-ignore
|
||||
// v[a] = (v[a] + v[b] + x) | 0;
|
||||
let ll = u64.add3L(Al, Bl, Xl);
|
||||
Ah = u64.add3H(ll, Ah, Bh, Xh);
|
||||
Al = ll | 0;
|
||||
// v[d] = rotr(v[d] ^ v[a], 16)
|
||||
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||||
({ Dh, Dl } = { Dh: u64.rotrSH(Dh, Dl, 16), Dl: u64.rotrSL(Dh, Dl, 16) });
|
||||
// v[c] = (v[c] + v[d]) | 0;
|
||||
({ h: Ch, l: Cl } = u64.add(Ch, Cl, Dh, Dl));
|
||||
// v[b] = rotr(v[b] ^ v[c], 11)
|
||||
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||||
({ Bh, Bl } = { Bh: u64.rotrSH(Bh, Bl, 11), Bl: u64.rotrSL(Bh, Bl, 11) });
|
||||
(BBUF[2 * a + 1] = Al), (BBUF[2 * a] = Ah);
|
||||
(BBUF[2 * b + 1] = Bl), (BBUF[2 * b] = Bh);
|
||||
(BBUF[2 * c + 1] = Cl), (BBUF[2 * c] = Ch);
|
||||
(BBUF[2 * d + 1] = Dl), (BBUF[2 * d] = Dh);
|
||||
}
|
||||
|
||||
class Blake1_64 extends BLAKE1<Blake1_64> {
|
||||
private v0l: number;
|
||||
private v0h: number;
|
||||
private v1l: number;
|
||||
private v1h: number;
|
||||
private v2l: number;
|
||||
private v2h: number;
|
||||
private v3l: number;
|
||||
private v3h: number;
|
||||
private v4l: number;
|
||||
private v4h: number;
|
||||
private v5l: number;
|
||||
private v5h: number;
|
||||
private v6l: number;
|
||||
private v6h: number;
|
||||
private v7l: number;
|
||||
private v7h: number;
|
||||
constructor(outputLen: number, IV: Uint32Array, lengthFlag: number, opts: BlakeOpts = {}) {
|
||||
super(128, outputLen, lengthFlag, 16, 8, B64C, opts);
|
||||
this.v0l = IV[0] | 0;
|
||||
this.v0h = IV[1] | 0;
|
||||
this.v1l = IV[2] | 0;
|
||||
this.v1h = IV[3] | 0;
|
||||
this.v2l = IV[4] | 0;
|
||||
this.v2h = IV[5] | 0;
|
||||
this.v3l = IV[6] | 0;
|
||||
this.v3h = IV[7] | 0;
|
||||
this.v4l = IV[8] | 0;
|
||||
this.v4h = IV[9] | 0;
|
||||
this.v5l = IV[10] | 0;
|
||||
this.v5h = IV[11] | 0;
|
||||
this.v6l = IV[12] | 0;
|
||||
this.v6h = IV[13] | 0;
|
||||
this.v7l = IV[14] | 0;
|
||||
this.v7h = IV[15] | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
protected get(): [
|
||||
number, number, number, number, number, number, number, number,
|
||||
number, number, number, number, number, number, number, number
|
||||
] {
|
||||
let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this;
|
||||
return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h];
|
||||
}
|
||||
// prettier-ignore
|
||||
protected set(
|
||||
v0l: number, v0h: number, v1l: number, v1h: number,
|
||||
v2l: number, v2h: number, v3l: number, v3h: number,
|
||||
v4l: number, v4h: number, v5l: number, v5h: number,
|
||||
v6l: number, v6h: number, v7l: number, v7h: number
|
||||
): void {
|
||||
this.v0l = v0l | 0;
|
||||
this.v0h = v0h | 0;
|
||||
this.v1l = v1l | 0;
|
||||
this.v1h = v1h | 0;
|
||||
this.v2l = v2l | 0;
|
||||
this.v2h = v2h | 0;
|
||||
this.v3l = v3l | 0;
|
||||
this.v3h = v3h | 0;
|
||||
this.v4l = v4l | 0;
|
||||
this.v4h = v4h | 0;
|
||||
this.v5l = v5l | 0;
|
||||
this.v5h = v5h | 0;
|
||||
this.v6l = v6l | 0;
|
||||
this.v6h = v6h | 0;
|
||||
this.v7l = v7l | 0;
|
||||
this.v7h = v7h | 0;
|
||||
}
|
||||
destroy(): void {
|
||||
super.destroy();
|
||||
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
compress(view: DataView, offset: number, withLength = true): void {
|
||||
for (let i = 0; i < 32; i++, offset += 4) BLAKE512_W[i] = view.getUint32(offset, false);
|
||||
|
||||
this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state.
|
||||
BBUF.set(this.constants.subarray(0, 16), 16);
|
||||
if (withLength) {
|
||||
const { h, l } = u64.fromBig(BigInt(this.length * 8));
|
||||
BBUF[24] = (BBUF[24] ^ h) >>> 0;
|
||||
BBUF[25] = (BBUF[25] ^ l) >>> 0;
|
||||
BBUF[26] = (BBUF[26] ^ h) >>> 0;
|
||||
BBUF[27] = (BBUF[27] ^ l) >>> 0;
|
||||
}
|
||||
for (let i = 0, k = 0; i < 16; i++) {
|
||||
G1b(0, 4, 8, 12, BLAKE512_W, k++);
|
||||
G2b(0, 4, 8, 12, BLAKE512_W, k++);
|
||||
G1b(1, 5, 9, 13, BLAKE512_W, k++);
|
||||
G2b(1, 5, 9, 13, BLAKE512_W, k++);
|
||||
G1b(2, 6, 10, 14, BLAKE512_W, k++);
|
||||
G2b(2, 6, 10, 14, BLAKE512_W, k++);
|
||||
G1b(3, 7, 11, 15, BLAKE512_W, k++);
|
||||
G2b(3, 7, 11, 15, BLAKE512_W, k++);
|
||||
|
||||
G1b(0, 5, 10, 15, BLAKE512_W, k++);
|
||||
G2b(0, 5, 10, 15, BLAKE512_W, k++);
|
||||
G1b(1, 6, 11, 12, BLAKE512_W, k++);
|
||||
G2b(1, 6, 11, 12, BLAKE512_W, k++);
|
||||
G1b(2, 7, 8, 13, BLAKE512_W, k++);
|
||||
G2b(2, 7, 8, 13, BLAKE512_W, k++);
|
||||
G1b(3, 4, 9, 14, BLAKE512_W, k++);
|
||||
G2b(3, 4, 9, 14, BLAKE512_W, k++);
|
||||
}
|
||||
this.v0l ^= BBUF[0] ^ BBUF[16] ^ this.salt[0];
|
||||
this.v0h ^= BBUF[1] ^ BBUF[17] ^ this.salt[1];
|
||||
this.v1l ^= BBUF[2] ^ BBUF[18] ^ this.salt[2];
|
||||
this.v1h ^= BBUF[3] ^ BBUF[19] ^ this.salt[3];
|
||||
this.v2l ^= BBUF[4] ^ BBUF[20] ^ this.salt[4];
|
||||
this.v2h ^= BBUF[5] ^ BBUF[21] ^ this.salt[5];
|
||||
this.v3l ^= BBUF[6] ^ BBUF[22] ^ this.salt[6];
|
||||
this.v3h ^= BBUF[7] ^ BBUF[23] ^ this.salt[7];
|
||||
this.v4l ^= BBUF[8] ^ BBUF[24] ^ this.salt[0];
|
||||
this.v4h ^= BBUF[9] ^ BBUF[25] ^ this.salt[1];
|
||||
this.v5l ^= BBUF[10] ^ BBUF[26] ^ this.salt[2];
|
||||
this.v5h ^= BBUF[11] ^ BBUF[27] ^ this.salt[3];
|
||||
this.v6l ^= BBUF[12] ^ BBUF[28] ^ this.salt[4];
|
||||
this.v6h ^= BBUF[13] ^ BBUF[29] ^ this.salt[5];
|
||||
this.v7l ^= BBUF[14] ^ BBUF[30] ^ this.salt[6];
|
||||
this.v7h ^= BBUF[15] ^ BBUF[31] ^ this.salt[7];
|
||||
clean(BBUF, BLAKE512_W);
|
||||
}
|
||||
}
|
||||
|
||||
export class BLAKE224 extends Blake1_32 {
|
||||
constructor(opts: BlakeOpts = {}) {
|
||||
super(28, B224_IV, 0b0000_0000, opts);
|
||||
}
|
||||
}
|
||||
export class BLAKE256 extends Blake1_32 {
|
||||
constructor(opts: BlakeOpts = {}) {
|
||||
super(32, B256_IV, 0b0000_0001, opts);
|
||||
}
|
||||
}
|
||||
export class BLAKE384 extends Blake1_64 {
|
||||
constructor(opts: BlakeOpts = {}) {
|
||||
super(48, B384_IV, 0b0000_0000, opts);
|
||||
}
|
||||
}
|
||||
export class BLAKE512 extends Blake1_64 {
|
||||
constructor(opts: BlakeOpts = {}) {
|
||||
super(64, B512_IV, 0b0000_0001, opts);
|
||||
}
|
||||
}
|
||||
/** blake1-224 hash function */
|
||||
export const blake224: CHashO = /* @__PURE__ */ createOptHasher<BLAKE224, BlakeOpts>(
|
||||
(opts) => new BLAKE224(opts)
|
||||
);
|
||||
/** blake1-256 hash function */
|
||||
export const blake256: CHashO = /* @__PURE__ */ createOptHasher<BLAKE256, BlakeOpts>(
|
||||
(opts) => new BLAKE256(opts)
|
||||
);
|
||||
/** blake1-384 hash function */
|
||||
export const blake384: CHashO = /* @__PURE__ */ createOptHasher<BLAKE512, BlakeOpts>(
|
||||
(opts) => new BLAKE384(opts)
|
||||
);
|
||||
/** blake1-512 hash function */
|
||||
export const blake512: CHashO = /* @__PURE__ */ createOptHasher<BLAKE512, BlakeOpts>(
|
||||
(opts) => new BLAKE512(opts)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_create_super.js";
|
||||
@@ -0,0 +1,2 @@
|
||||
import type { LibDefinition } from '../variable';
|
||||
export declare const es2019_array: LibDefinition;
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["src/legacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAO,MAAM,EAAO,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,KAAK,KAAK,EAA6B,MAAM,YAAY,CAAC;AAUnE,8BAA8B;AAC9B,qBAAa,IAAK,SAAQ,MAAM,CAAC,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;IAC3B,OAAO,CAAC,CAAC,CAAkB;;IAK3B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAO1E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAIhB;AAED,6EAA6E;AAC7E,eAAO,MAAM,IAAI,EAAE,KAAsD,CAAC;AAa1E,6BAA6B;AAC7B,qBAAa,GAAI,SAAQ,MAAM,CAAC,GAAG,CAAC;IAClC,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;IAC1B,OAAO,CAAC,CAAC,CAAiB;;IAK1B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIjD,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAM/D,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAIhB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,GAAG,EAAE,KAAqD,CAAC;AA6CxE,qBAAa,SAAU,SAAQ,MAAM,CAAC,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,EAAE,CAAkB;;IAK5B,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAIzD,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAO/E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAmCvD,SAAS,CAAC,UAAU,IAAI,IAAI;IAG5B,OAAO,IAAI,IAAI;CAKhB;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAA2D,CAAC"}
|
||||
@@ -0,0 +1,209 @@
|
||||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('parse args', function (t) {
|
||||
t.deepEqual(
|
||||
parse(['--no-moo']),
|
||||
{ moo: false, _: [] },
|
||||
'no'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-v', 'a', '-v', 'b', '-v', 'c']),
|
||||
{ v: ['a', 'b', 'c'], _: [] },
|
||||
'multi'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('comprehensive', function (t) {
|
||||
t.deepEqual(
|
||||
parse([
|
||||
'--name=meowmers', 'bare', '-cats', 'woo',
|
||||
'-h', 'awesome', '--multi=quux',
|
||||
'--key', 'value',
|
||||
'-b', '--bool', '--no-meep', '--multi=baz',
|
||||
'--', '--not-a-flag', 'eek',
|
||||
]),
|
||||
{
|
||||
c: true,
|
||||
a: true,
|
||||
t: true,
|
||||
s: 'woo',
|
||||
h: 'awesome',
|
||||
b: true,
|
||||
bool: true,
|
||||
key: 'value',
|
||||
multi: ['quux', 'baz'],
|
||||
meep: false,
|
||||
name: 'meowmers',
|
||||
_: ['bare', '--not-a-flag', 'eek'],
|
||||
}
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean', function (t) {
|
||||
var argv = parse(['-t', 'moo'], { boolean: 't' });
|
||||
t.deepEqual(argv, { t: true, _: ['moo'] });
|
||||
t.deepEqual(typeof argv.t, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean value', function (t) {
|
||||
var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
|
||||
boolean: ['t', 'verbose'],
|
||||
default: { verbose: true },
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
verbose: false,
|
||||
t: true,
|
||||
_: ['moo'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.verbose, 'boolean');
|
||||
t.deepEqual(typeof argv.t, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('newlines in params', function (t) {
|
||||
var args = parse(['-s', 'X\nX']);
|
||||
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||
|
||||
// reproduce in bash:
|
||||
// VALUE="new
|
||||
// line"
|
||||
// node program.js --s="$VALUE"
|
||||
args = parse(['--s=X\nX']);
|
||||
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('strings', function (t) {
|
||||
var s = parse(['-s', '0001234'], { string: 's' }).s;
|
||||
t.equal(s, '0001234');
|
||||
t.equal(typeof s, 'string');
|
||||
|
||||
var x = parse(['-x', '56'], { string: 'x' }).x;
|
||||
t.equal(x, '56');
|
||||
t.equal(typeof x, 'string');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('stringArgs', function (t) {
|
||||
var s = parse([' ', ' '], { string: '_' })._;
|
||||
t.same(s.length, 2);
|
||||
t.same(typeof s[0], 'string');
|
||||
t.same(s[0], ' ');
|
||||
t.same(typeof s[1], 'string');
|
||||
t.same(s[1], ' ');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('empty strings', function (t) {
|
||||
var s = parse(['-s'], { string: 's' }).s;
|
||||
t.equal(s, '');
|
||||
t.equal(typeof s, 'string');
|
||||
|
||||
var str = parse(['--str'], { string: 'str' }).str;
|
||||
t.equal(str, '');
|
||||
t.equal(typeof str, 'string');
|
||||
|
||||
var letters = parse(['-art'], {
|
||||
string: ['a', 't'],
|
||||
});
|
||||
|
||||
t.equal(letters.a, '');
|
||||
t.equal(letters.r, true);
|
||||
t.equal(letters.t, '');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('string and alias', function (t) {
|
||||
var x = parse(['--str', '000123'], {
|
||||
string: 's',
|
||||
alias: { s: 'str' },
|
||||
});
|
||||
|
||||
t.equal(x.str, '000123');
|
||||
t.equal(typeof x.str, 'string');
|
||||
t.equal(x.s, '000123');
|
||||
t.equal(typeof x.s, 'string');
|
||||
|
||||
var y = parse(['-s', '000123'], {
|
||||
string: 'str',
|
||||
alias: { str: 's' },
|
||||
});
|
||||
|
||||
t.equal(y.str, '000123');
|
||||
t.equal(typeof y.str, 'string');
|
||||
t.equal(y.s, '000123');
|
||||
t.equal(typeof y.s, 'string');
|
||||
|
||||
var z = parse(['-s123'], {
|
||||
alias: { str: ['s', 'S'] },
|
||||
string: ['str'],
|
||||
});
|
||||
|
||||
t.deepEqual(
|
||||
z,
|
||||
{ _: [], s: '123', S: '123', str: '123' },
|
||||
'opt.string works with multiple aliases'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('slashBreak', function (t) {
|
||||
t.same(
|
||||
parse(['-I/foo/bar/baz']),
|
||||
{ I: '/foo/bar/baz', _: [] }
|
||||
);
|
||||
t.same(
|
||||
parse(['-xyz/foo/bar/baz']),
|
||||
{ x: true, y: true, z: '/foo/bar/baz', _: [] }
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('alias', function (t) {
|
||||
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||
alias: { z: 'zoom' },
|
||||
});
|
||||
t.equal(argv.zoom, 55);
|
||||
t.equal(argv.z, argv.zoom);
|
||||
t.equal(argv.f, 11);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('multiAlias', function (t) {
|
||||
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||
alias: { z: ['zm', 'zoom'] },
|
||||
});
|
||||
t.equal(argv.zoom, 55);
|
||||
t.equal(argv.z, argv.zoom);
|
||||
t.equal(argv.z, argv.zm);
|
||||
t.equal(argv.f, 11);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nested dotted objects', function (t) {
|
||||
var argv = parse([
|
||||
'--foo.bar', '3', '--foo.baz', '4',
|
||||
'--foo.quux.quibble', '5', '--foo.quux.o_O',
|
||||
'--beep.boop',
|
||||
]);
|
||||
|
||||
t.same(argv.foo, {
|
||||
bar: 3,
|
||||
baz: 4,
|
||||
quux: {
|
||||
quibble: 5,
|
||||
o_O: true,
|
||||
},
|
||||
});
|
||||
t.same(argv.beep, { boop: true });
|
||||
t.end();
|
||||
});
|
||||
@@ -0,0 +1,272 @@
|
||||
/**
|
||||
* Blake3 fast hash is Blake2 with reduced security (round count). Can also be used as MAC & KDF.
|
||||
*
|
||||
* It is advertised as "the fastest cryptographic hash". However, it isn't true in JS.
|
||||
* Why is this so slow? While it should be 6x faster than blake2b, perf diff is only 20%:
|
||||
*
|
||||
* * There is only 30% reduction in number of rounds from blake2s
|
||||
* * Speed-up comes from tree structure, which is parallelized using SIMD & threading.
|
||||
* These features are not present in JS, so we only get overhead from trees.
|
||||
* * Parallelization only happens on 1024-byte chunks: there is no benefit for small inputs.
|
||||
* * It is still possible to make it faster using: a) loop unrolling b) web workers c) wasm
|
||||
* @module
|
||||
*/
|
||||
import { SHA256_IV } from './_md.ts';
|
||||
import { fromBig } from './_u64.ts';
|
||||
import { BLAKE2, compress } from './blake2.ts';
|
||||
// prettier-ignore
|
||||
import {
|
||||
abytes, aexists, anumber, aoutput,
|
||||
clean, createXOFer, swap32IfBE, toBytes, u32, u8,
|
||||
type CHashXO, type HashXOF, type Input
|
||||
} from './utils.ts';
|
||||
|
||||
// Flag bitset
|
||||
const B3_Flags = {
|
||||
CHUNK_START: 0b1,
|
||||
CHUNK_END: 0b10,
|
||||
PARENT: 0b100,
|
||||
ROOT: 0b1000,
|
||||
KEYED_HASH: 0b10000,
|
||||
DERIVE_KEY_CONTEXT: 0b100000,
|
||||
DERIVE_KEY_MATERIAL: 0b1000000,
|
||||
} as const;
|
||||
|
||||
const B3_IV = SHA256_IV.slice();
|
||||
|
||||
const B3_SIGMA: Uint8Array = /* @__PURE__ */ (() => {
|
||||
const Id = Array.from({ length: 16 }, (_, i) => i);
|
||||
const permute = (arr: number[]) =>
|
||||
[2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]);
|
||||
const res: number[] = [];
|
||||
for (let i = 0, v = Id; i < 7; i++, v = permute(v)) res.push(...v);
|
||||
return Uint8Array.from(res);
|
||||
})();
|
||||
|
||||
/**
|
||||
* Ensure to use EITHER `key` OR `context`, not both.
|
||||
*
|
||||
* * `key`: 32-byte MAC key.
|
||||
* * `context`: string for KDF. Should be hardcoded, globally unique, and application - specific.
|
||||
* A good default format for the context string is "[application] [commit timestamp] [purpose]".
|
||||
*/
|
||||
export type Blake3Opts = { dkLen?: number; key?: Input; context?: Input };
|
||||
|
||||
/** Blake3 hash. Can be used as MAC and KDF. */
|
||||
export class BLAKE3 extends BLAKE2<BLAKE3> implements HashXOF<BLAKE3> {
|
||||
private chunkPos = 0; // Position of current block in chunk
|
||||
private chunksDone = 0; // How many chunks we already have
|
||||
private flags = 0 | 0;
|
||||
private IV: Uint32Array;
|
||||
private state: Uint32Array;
|
||||
private stack: Uint32Array[] = [];
|
||||
// Output
|
||||
private posOut = 0;
|
||||
private bufferOut32 = new Uint32Array(16);
|
||||
private bufferOut: Uint8Array;
|
||||
private chunkOut = 0; // index of output chunk
|
||||
private enableXOF = true;
|
||||
|
||||
constructor(opts: Blake3Opts = {}, flags = 0) {
|
||||
super(64, opts.dkLen === undefined ? 32 : opts.dkLen);
|
||||
const { key, context } = opts;
|
||||
const hasContext = context !== undefined;
|
||||
if (key !== undefined) {
|
||||
if (hasContext) throw new Error('Only "key" or "context" can be specified at same time');
|
||||
const k = toBytes(key).slice();
|
||||
abytes(k, 32);
|
||||
this.IV = u32(k);
|
||||
swap32IfBE(this.IV);
|
||||
this.flags = flags | B3_Flags.KEYED_HASH;
|
||||
} else if (hasContext) {
|
||||
const ctx = toBytes(context);
|
||||
const contextKey = new BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT)
|
||||
.update(ctx)
|
||||
.digest();
|
||||
this.IV = u32(contextKey);
|
||||
swap32IfBE(this.IV);
|
||||
this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL;
|
||||
} else {
|
||||
this.IV = B3_IV.slice();
|
||||
this.flags = flags;
|
||||
}
|
||||
this.state = this.IV.slice();
|
||||
this.bufferOut = u8(this.bufferOut32);
|
||||
}
|
||||
// Unused
|
||||
protected get(): [] {
|
||||
return [];
|
||||
}
|
||||
protected set(): void {}
|
||||
private b2Compress(counter: number, flags: number, buf: Uint32Array, bufPos: number = 0) {
|
||||
const { state: s, pos } = this;
|
||||
const { h, l } = fromBig(BigInt(counter), true);
|
||||
// prettier-ignore
|
||||
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } =
|
||||
compress(
|
||||
B3_SIGMA, bufPos, buf, 7,
|
||||
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
||||
B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags
|
||||
);
|
||||
s[0] = v0 ^ v8;
|
||||
s[1] = v1 ^ v9;
|
||||
s[2] = v2 ^ v10;
|
||||
s[3] = v3 ^ v11;
|
||||
s[4] = v4 ^ v12;
|
||||
s[5] = v5 ^ v13;
|
||||
s[6] = v6 ^ v14;
|
||||
s[7] = v7 ^ v15;
|
||||
}
|
||||
protected compress(buf: Uint32Array, bufPos: number = 0, isLast: boolean = false): void {
|
||||
// Compress last block
|
||||
let flags = this.flags;
|
||||
if (!this.chunkPos) flags |= B3_Flags.CHUNK_START;
|
||||
if (this.chunkPos === 15 || isLast) flags |= B3_Flags.CHUNK_END;
|
||||
if (!isLast) this.pos = this.blockLen;
|
||||
this.b2Compress(this.chunksDone, flags, buf, bufPos);
|
||||
this.chunkPos += 1;
|
||||
// If current block is last in chunk (16 blocks), then compress chunks
|
||||
if (this.chunkPos === 16 || isLast) {
|
||||
let chunk = this.state;
|
||||
this.state = this.IV.slice();
|
||||
// If not the last one, compress only when there are trailing zeros in chunk counter
|
||||
// chunks used as binary tree where current stack is path. Zero means current leaf is finished and can be compressed.
|
||||
// 1 (001) - leaf not finished (just push current chunk to stack)
|
||||
// 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back)
|
||||
// 3 (011) - last leaf not finished
|
||||
// 4 (100) - leafs finished at depth=1 and depth=2
|
||||
for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) {
|
||||
if (!(last = this.stack.pop())) break;
|
||||
this.buffer32.set(last, 0);
|
||||
this.buffer32.set(chunk, 8);
|
||||
this.pos = this.blockLen;
|
||||
this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0);
|
||||
chunk = this.state;
|
||||
this.state = this.IV.slice();
|
||||
}
|
||||
this.chunksDone++;
|
||||
this.chunkPos = 0;
|
||||
this.stack.push(chunk);
|
||||
}
|
||||
this.pos = 0;
|
||||
}
|
||||
_cloneInto(to?: BLAKE3): BLAKE3 {
|
||||
to = super._cloneInto(to) as BLAKE3;
|
||||
const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this;
|
||||
to.state.set(state.slice());
|
||||
to.stack = stack.map((i) => Uint32Array.from(i));
|
||||
to.IV.set(IV);
|
||||
to.flags = flags;
|
||||
to.chunkPos = chunkPos;
|
||||
to.chunksDone = chunksDone;
|
||||
to.posOut = posOut;
|
||||
to.chunkOut = chunkOut;
|
||||
to.enableXOF = this.enableXOF;
|
||||
to.bufferOut32.set(this.bufferOut32);
|
||||
return to;
|
||||
}
|
||||
destroy(): void {
|
||||
this.destroyed = true;
|
||||
clean(this.state, this.buffer32, this.IV, this.bufferOut32);
|
||||
clean(...this.stack);
|
||||
}
|
||||
// Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8)
|
||||
private b2CompressOut() {
|
||||
const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this;
|
||||
const { h, l } = fromBig(BigInt(this.chunkOut++));
|
||||
swap32IfBE(buffer32);
|
||||
// prettier-ignore
|
||||
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } =
|
||||
compress(
|
||||
B3_SIGMA, 0, buffer32, 7,
|
||||
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
||||
B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags
|
||||
);
|
||||
out32[0] = v0 ^ v8;
|
||||
out32[1] = v1 ^ v9;
|
||||
out32[2] = v2 ^ v10;
|
||||
out32[3] = v3 ^ v11;
|
||||
out32[4] = v4 ^ v12;
|
||||
out32[5] = v5 ^ v13;
|
||||
out32[6] = v6 ^ v14;
|
||||
out32[7] = v7 ^ v15;
|
||||
out32[8] = s[0] ^ v8;
|
||||
out32[9] = s[1] ^ v9;
|
||||
out32[10] = s[2] ^ v10;
|
||||
out32[11] = s[3] ^ v11;
|
||||
out32[12] = s[4] ^ v12;
|
||||
out32[13] = s[5] ^ v13;
|
||||
out32[14] = s[6] ^ v14;
|
||||
out32[15] = s[7] ^ v15;
|
||||
swap32IfBE(buffer32);
|
||||
swap32IfBE(out32);
|
||||
this.posOut = 0;
|
||||
}
|
||||
protected finish(): void {
|
||||
if (this.finished) return;
|
||||
this.finished = true;
|
||||
// Padding
|
||||
clean(this.buffer.subarray(this.pos));
|
||||
// Process last chunk
|
||||
let flags = this.flags | B3_Flags.ROOT;
|
||||
if (this.stack.length) {
|
||||
flags |= B3_Flags.PARENT;
|
||||
swap32IfBE(this.buffer32);
|
||||
this.compress(this.buffer32, 0, true);
|
||||
swap32IfBE(this.buffer32);
|
||||
this.chunksDone = 0;
|
||||
this.pos = this.blockLen;
|
||||
} else {
|
||||
flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END;
|
||||
}
|
||||
this.flags = flags;
|
||||
this.b2CompressOut();
|
||||
}
|
||||
private writeInto(out: Uint8Array) {
|
||||
aexists(this, false);
|
||||
abytes(out);
|
||||
this.finish();
|
||||
const { blockLen, bufferOut } = this;
|
||||
for (let pos = 0, len = out.length; pos < len; ) {
|
||||
if (this.posOut >= blockLen) this.b2CompressOut();
|
||||
const take = Math.min(blockLen - this.posOut, len - pos);
|
||||
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
||||
this.posOut += take;
|
||||
pos += take;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
xofInto(out: Uint8Array): Uint8Array {
|
||||
if (!this.enableXOF) throw new Error('XOF is not possible after digest call');
|
||||
return this.writeInto(out);
|
||||
}
|
||||
xof(bytes: number): Uint8Array {
|
||||
anumber(bytes);
|
||||
return this.xofInto(new Uint8Array(bytes));
|
||||
}
|
||||
digestInto(out: Uint8Array): Uint8Array {
|
||||
aoutput(out, this);
|
||||
if (this.finished) throw new Error('digest() was already called');
|
||||
this.enableXOF = false;
|
||||
this.writeInto(out);
|
||||
this.destroy();
|
||||
return out;
|
||||
}
|
||||
digest(): Uint8Array {
|
||||
return this.digestInto(new Uint8Array(this.outputLen));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BLAKE3 hash function. Can be used as MAC and KDF.
|
||||
* @param msg - message that would be hashed
|
||||
* @param opts - `dkLen` for output length, `key` for MAC mode, `context` for KDF mode
|
||||
* @example
|
||||
* const data = new Uint8Array(32);
|
||||
* const hash = blake3(data);
|
||||
* const mac = blake3(data, { key: new Uint8Array(32) });
|
||||
* const kdf = blake3(data, { context: 'application name' });
|
||||
*/
|
||||
export const blake3: CHashXO = /* @__PURE__ */ createXOFer<BLAKE3, Blake3Opts>(
|
||||
(opts) => new BLAKE3(opts)
|
||||
);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
import { r as runBaseTests, s as setupBaseEnvironment } from '../chunks/base.B6Opl8PE.js';
|
||||
import { w as workerInit } from '../chunks/init-forks.H5ZuobOQ.js';
|
||||
import 'node:vm';
|
||||
import '@vitest/spy';
|
||||
import '../chunks/index.DXx9Dtk7.js';
|
||||
import '@vitest/expect';
|
||||
import 'node:async_hooks';
|
||||
import '../chunks/setup-common.DYx3LtFI.js';
|
||||
import '../chunks/coverage.CTzCuANN.js';
|
||||
import '@vitest/snapshot';
|
||||
import '@vitest/utils/timers';
|
||||
import '../chunks/utils.BX5Fg8C4.js';
|
||||
import '../chunks/rpc.MzXet3jl.js';
|
||||
import '../chunks/index.Chj8NDwU.js';
|
||||
import '../chunks/test.DNmyFkvJ.js';
|
||||
import '@vitest/runner';
|
||||
import '@vitest/utils/helpers';
|
||||
import '../chunks/benchmark.CX_oY03V.js';
|
||||
import '@vitest/runner/utils';
|
||||
import '@vitest/utils/error';
|
||||
import 'pathe';
|
||||
import '@vitest/utils/offset';
|
||||
import '@vitest/utils/source-map';
|
||||
import '../chunks/_commonjsHelpers.D26ty3Ew.js';
|
||||
import '../chunks/init.k9zZ9sLh.js';
|
||||
import 'node:fs';
|
||||
import 'node:module';
|
||||
import 'node:url';
|
||||
import 'vite/module-runner';
|
||||
import '../chunks/startVitestModuleRunner.DB-7oCpn.js';
|
||||
import '../chunks/modules.BJuCwlRJ.js';
|
||||
import '../path.js';
|
||||
import 'node:path';
|
||||
import '../module-evaluator.js';
|
||||
import '../chunks/traces.DT5aQ62U.js';
|
||||
import '@vitest/mocker';
|
||||
import '@vitest/mocker/redirect';
|
||||
import '../chunks/index.DC7d2Pf8.js';
|
||||
import 'node:console';
|
||||
import '@vitest/utils/serialize';
|
||||
import 'tinyrainbow';
|
||||
import '../chunks/inspector.CvyFGlXm.js';
|
||||
import '../chunks/evaluatedModules.Dg1zASAC.js';
|
||||
import '../chunks/nativeModuleRunner.BIakptoF.js';
|
||||
import '../chunks/index.BCY_7LL2.js';
|
||||
import 'node:process';
|
||||
import 'node:fs/promises';
|
||||
import 'node:assert';
|
||||
import 'node:v8';
|
||||
import 'node:util';
|
||||
import 'node:perf_hooks';
|
||||
import 'node:timers';
|
||||
import 'node:timers/promises';
|
||||
import '@vitest/utils/constants';
|
||||
import '../chunks/index.DdgEv5B1.js';
|
||||
import 'expect-type';
|
||||
|
||||
workerInit({
|
||||
runTests: runBaseTests,
|
||||
setup: setupBaseEnvironment
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* The Standard Schema interface.
|
||||
*/
|
||||
export type StandardSchemaV1<Input = unknown, Output = Input> = {
|
||||
/**
|
||||
* The Standard Schema properties.
|
||||
*/
|
||||
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
||||
};
|
||||
|
||||
export declare namespace StandardSchemaV1 {
|
||||
/**
|
||||
* The Standard Schema properties interface.
|
||||
*/
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The version number of the standard.
|
||||
*/
|
||||
readonly version: 1;
|
||||
/**
|
||||
* The vendor name of the schema library.
|
||||
*/
|
||||
readonly vendor: string;
|
||||
/**
|
||||
* Validates unknown input values.
|
||||
*/
|
||||
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
||||
/**
|
||||
* Inferred types associated with the schema.
|
||||
*/
|
||||
readonly types?: Types<Input, Output> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result interface of the validate function.
|
||||
*/
|
||||
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
||||
|
||||
/**
|
||||
* The result interface if validation succeeds.
|
||||
*/
|
||||
export interface SuccessResult<Output> {
|
||||
/**
|
||||
* The typed output value.
|
||||
*/
|
||||
readonly value: Output;
|
||||
/**
|
||||
* The non-existent issues.
|
||||
*/
|
||||
readonly issues?: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result interface if validation fails.
|
||||
*/
|
||||
export interface FailureResult {
|
||||
/**
|
||||
* The issues of failed validation.
|
||||
*/
|
||||
readonly issues: ReadonlyArray<Issue>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The issue interface of the failure output.
|
||||
*/
|
||||
export interface Issue {
|
||||
/**
|
||||
* The error message of the issue.
|
||||
*/
|
||||
readonly message: string;
|
||||
/**
|
||||
* The path of the issue, if any.
|
||||
*/
|
||||
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The path segment interface of the issue.
|
||||
*/
|
||||
export interface PathSegment {
|
||||
/**
|
||||
* The key representing a path segment.
|
||||
*/
|
||||
readonly key: PropertyKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Standard Schema types interface.
|
||||
*/
|
||||
export interface Types<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The input type of the schema.
|
||||
*/
|
||||
readonly input: Input;
|
||||
/**
|
||||
* The output type of the schema.
|
||||
*/
|
||||
readonly output: Output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infers the input type of a Standard Schema.
|
||||
*/
|
||||
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
|
||||
|
||||
/**
|
||||
* Infers the output type of a Standard Schema.
|
||||
*/
|
||||
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
||||
|
||||
// biome-ignore lint/complexity/noUselessEmptyExport: needed for granular visibility control of TS namespace
|
||||
export {};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# `@typescript-eslint/scope-manager`
|
||||
|
||||
[](https://www.npmjs.com/package/@typescript-eslint/scope-manager)
|
||||
[](https://www.npmjs.com/package/@typescript-eslint/scope-manager)
|
||||
|
||||
👉 See **https://typescript-eslint.io/packages/scope-manager** for documentation on this package.
|
||||
|
||||
> See https://typescript-eslint.io for general documentation on typescript-eslint, the tooling that allows you to run ESLint and Prettier on TypeScript code.
|
||||
|
||||
<!-- Local path for docs: docs/packages/Scope_Manager.mdx -->
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_create_class.js";
|
||||
@@ -0,0 +1,51 @@
|
||||
{{## def.coerceType:
|
||||
{{
|
||||
var $dataType = 'dataType' + $lvl
|
||||
, $coerced = 'coerced' + $lvl;
|
||||
}}
|
||||
var {{=$dataType}} = typeof {{=$data}};
|
||||
var {{=$coerced}} = undefined;
|
||||
|
||||
{{? it.opts.coerceTypes == 'array' }}
|
||||
if ({{=$dataType}} == 'object' && Array.isArray({{=$data}}) && {{=$data}}.length == 1) {
|
||||
{{=$data}} = {{=$data}}[0];
|
||||
{{=$dataType}} = typeof {{=$data}};
|
||||
if ({{=it.util.checkDataType(it.schema.type, $data, it.opts.strictNumbers)}}) {{=$coerced}} = {{=$data}};
|
||||
}
|
||||
{{?}}
|
||||
|
||||
if ({{=$coerced}} !== undefined) ;
|
||||
{{~ $coerceToTypes:$type:$i }}
|
||||
{{? $type == 'string' }}
|
||||
else if ({{=$dataType}} == 'number' || {{=$dataType}} == 'boolean')
|
||||
{{=$coerced}} = '' + {{=$data}};
|
||||
else if ({{=$data}} === null) {{=$coerced}} = '';
|
||||
{{?? $type == 'number' || $type == 'integer' }}
|
||||
else if ({{=$dataType}} == 'boolean' || {{=$data}} === null
|
||||
|| ({{=$dataType}} == 'string' && {{=$data}} && {{=$data}} == +{{=$data}}
|
||||
{{? $type == 'integer' }} && !({{=$data}} % 1){{?}}))
|
||||
{{=$coerced}} = +{{=$data}};
|
||||
{{?? $type == 'boolean' }}
|
||||
else if ({{=$data}} === 'false' || {{=$data}} === 0 || {{=$data}} === null)
|
||||
{{=$coerced}} = false;
|
||||
else if ({{=$data}} === 'true' || {{=$data}} === 1)
|
||||
{{=$coerced}} = true;
|
||||
{{?? $type == 'null' }}
|
||||
else if ({{=$data}} === '' || {{=$data}} === 0 || {{=$data}} === false)
|
||||
{{=$coerced}} = null;
|
||||
{{?? it.opts.coerceTypes == 'array' && $type == 'array' }}
|
||||
else if ({{=$dataType}} == 'string' || {{=$dataType}} == 'number' || {{=$dataType}} == 'boolean' || {{=$data}} == null)
|
||||
{{=$coerced}} = [{{=$data}}];
|
||||
{{?}}
|
||||
{{~}}
|
||||
else {
|
||||
{{# def.error:'type' }}
|
||||
}
|
||||
|
||||
if ({{=$coerced}} !== undefined) {
|
||||
{{# def.setParentData }}
|
||||
{{=$data}} = {{=$coerced}};
|
||||
{{? !$dataLvl }}if ({{=$parentData}} !== undefined){{?}}
|
||||
{{=$parentData}}[{{=$parentDataProperty}}] = {{=$coerced}};
|
||||
}
|
||||
#}}
|
||||
@@ -0,0 +1,73 @@
|
||||
eyes
|
||||
====
|
||||
|
||||
a customizable value inspector for Node.js
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
I was tired of looking at cluttered output in the console -- something needed to be done,
|
||||
`sys.inspect()` didn't display regexps correctly, and was too verbose, and I had an hour or two to spare.
|
||||
So I decided to have some fun. _eyes_ were born.
|
||||
|
||||

|
||||
|
||||
_example of the output of a user-customized eyes.js inspector_
|
||||
|
||||
*eyes* also deals with circular objects in an intelligent way, and can pretty-print object literals.
|
||||
|
||||
usage
|
||||
-----
|
||||
|
||||
var inspect = require('eyes').inspector({styles: {all: 'magenta'}});
|
||||
|
||||
inspect(something); // inspect with the settings passed to `inspector`
|
||||
|
||||
or
|
||||
|
||||
var eyes = require('eyes');
|
||||
|
||||
eyes.inspect(something); // inspect with the default settings
|
||||
|
||||
you can pass a _label_ to `inspect()`, to keep track of your inspections:
|
||||
|
||||
eyes.inspect(something, "a random value");
|
||||
|
||||
If you want to return the output of eyes without printing it, you can set it up this way:
|
||||
|
||||
var inspect = require('eyes').inspector({ stream: null });
|
||||
|
||||
sys.puts(inspect({ something: 42 }));
|
||||
|
||||
customization
|
||||
-------------
|
||||
|
||||
These are the default styles and settings used by _eyes_.
|
||||
|
||||
styles: { // Styles applied to stdout
|
||||
all: 'cyan', // Overall style applied to everything
|
||||
label: 'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`
|
||||
other: 'inverted', // Objects which don't have a literal representation, such as functions
|
||||
key: 'bold', // The keys in object literals, like 'a' in `{a: 1}`
|
||||
special: 'grey', // null, undefined...
|
||||
string: 'green',
|
||||
number: 'magenta',
|
||||
bool: 'blue', // true false
|
||||
regexp: 'green', // /\d+/
|
||||
},
|
||||
|
||||
pretty: true, // Indent object literals
|
||||
hideFunctions: false, // Don't output functions at all
|
||||
stream: process.stdout, // Stream to write to, or null
|
||||
maxLength: 2048 // Truncate output if longer
|
||||
|
||||
You can overwrite them with your own, by passing a similar object to `inspector()` or `inspect()`.
|
||||
|
||||
var inspect = require('eyes').inspector({
|
||||
styles: {
|
||||
all: 'magenta',
|
||||
special: 'bold'
|
||||
},
|
||||
maxLength: 512
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user