WIP: bootstrap and partial real Solana watcher implementation

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

View File

@@ -0,0 +1,70 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTypeFlags = getTypeFlags;
exports.isTypeFlagSet = isTypeFlagSet;
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const ANY_OR_UNKNOWN = ts.TypeFlags.Any | ts.TypeFlags.Unknown;
/**
* Gets all of the type flags in a type, iterating through unions automatically.
*/
function getTypeFlags(type) {
// @ts-expect-error Since typescript 5.0, this is invalid, but uses 0 as the default value of TypeFlags.
let flags = 0;
for (const t of tsutils.unionConstituents(type)) {
flags |= t.flags;
}
return flags;
}
/**
* @param flagsToCheck The composition of one or more `ts.TypeFlags`.
* @param isReceiver Whether the type is a receiving type (e.g. the type of a
* called function's parameter).
* @remarks
* Note that if the type is a union, this function will decompose it into the
* parts and get the flags of every union constituent. If this is not desired,
* use the `isTypeFlag` function from tsutils.
*/
function isTypeFlagSet(type, flagsToCheck,
/** @deprecated This params is not used and will be removed in the future.*/
isReceiver) {
const flags = getTypeFlags(type);
// eslint-disable-next-line @typescript-eslint/no-deprecated -- not used
if (isReceiver && flags & ANY_OR_UNKNOWN) {
return true;
}
return (flags & flagsToCheck) !== 0;
}

View File

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

View File

@@ -0,0 +1,11 @@
'use strict'
const { test } = require('node:test')
const assert = require('node:assert')
const indexes = require('../lib/indexes')
for (const index of Object.keys(indexes)) {
test(`${index} is lock free`, function () {
assert.strictEqual(Atomics.isLockFree(indexes[index]), true)
})
}

View File

@@ -0,0 +1,10 @@
import type { TSESLint } from '@typescript-eslint/utils';
export type Options = [
{
checkNever: boolean;
}
];
declare const _default: TSESLint.RuleModule<"meaninglessVoidOperator" | "removeVoid", Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
name: string;
};
export default _default;

View File

@@ -0,0 +1,52 @@
# path-exists [![Build Status](https://travis-ci.org/sindresorhus/path-exists.svg?branch=master)](https://travis-ci.org/sindresorhus/path-exists)
> Check if a path exists
NOTE: `fs.existsSync` has been un-deprecated in Node.js since 6.8.0. If you only need to check synchronously, this module is not needed.
While [`fs.exists()`](https://nodejs.org/api/fs.html#fs_fs_exists_path_callback) is being [deprecated](https://github.com/iojs/io.js/issues/103), there's still a genuine use-case of being able to check if a path exists for other purposes than doing IO with it.
Never use this before handling a file though:
> In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to `fs.exists()` and `fs.open()`. Just open the file and handle the error when it's not there.
## Install
```
$ npm install path-exists
```
## Usage
```js
// foo.js
const pathExists = require('path-exists');
(async () => {
console.log(await pathExists('foo.js'));
//=> true
})();
```
## API
### pathExists(path)
Returns a `Promise<boolean>` of whether the path exists.
### pathExists.sync(path)
Returns a `boolean` of whether the path exists.
## Related
- [path-exists-cli](https://github.com/sindresorhus/path-exists-cli) - CLI for this module
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,29 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/adjacent-overload-signatures': "error";
'@typescript-eslint/array-type': "error";
'@typescript-eslint/ban-tslint-comment': "error";
'@typescript-eslint/class-literal-property-style': "error";
'@typescript-eslint/consistent-generic-constructors': "error";
'@typescript-eslint/consistent-indexed-object-style': "error";
'@typescript-eslint/consistent-type-assertions': "error";
'@typescript-eslint/consistent-type-definitions': "error";
'dot-notation': "off";
'@typescript-eslint/dot-notation': "error";
'@typescript-eslint/no-confusing-non-null-assertion': "error";
'no-empty-function': "off";
'@typescript-eslint/no-empty-function': "error";
'@typescript-eslint/no-inferrable-types': "error";
'@typescript-eslint/non-nullable-type-assertion-style': "error";
'@typescript-eslint/prefer-find': "error";
'@typescript-eslint/prefer-for-of': "error";
'@typescript-eslint/prefer-function-type': "error";
'@typescript-eslint/prefer-includes': "error";
'@typescript-eslint/prefer-nullish-coalescing': "error";
'@typescript-eslint/prefer-optional-chain': "error";
'@typescript-eslint/prefer-regexp-exec': "error";
'@typescript-eslint/prefer-string-starts-ends-with': "error";
};
};
export = _default;

View File

@@ -0,0 +1,794 @@
// @ts-self-types="./index.d.ts"
import fs from 'node:fs';
import path from 'node:path';
/**
* @fileoverview defineConfig helper
* @author Nicholas C. Zakas
*/
//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------
/** @import * as $eslintcore from "@eslint/core"; */
/** @typedef {$eslintcore.ConfigObject} ConfigObject */
/** @typedef {$eslintcore.LegacyConfigObject} LegacyConfig */
/** @typedef {$eslintcore.Plugin} Plugin */
/** @typedef {$eslintcore.RuleConfig} RuleConfig */
/** @import * as $typests from "./types.ts"; */
/** @typedef {$typests.Config} Config */
/** @typedef {$typests.ExtendsElement} ExtendsElement */
/** @typedef {$typests.ExtensionConfigObject} ExtensionConfigObject */
/** @typedef {$typests.SimpleExtendsElement} SimpleExtendsElement */
/** @typedef {$typests.ConfigWithExtends} ConfigWithExtends */
/** @typedef {$typests.InfiniteArray<ConfigObject>} InfiniteConfigArray */
/** @typedef {$typests.ConfigWithExtendsArray} ConfigWithExtendsArray */
//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------
const eslintrcKeys = [
"env",
"extends",
"globals",
"ignorePatterns",
"noInlineConfig",
"overrides",
"parser",
"parserOptions",
"reportUnusedDisableDirectives",
"root",
];
const allowedGlobalIgnoreKeys = new Set(["basePath", "ignores", "name"]);
/**
* Gets the name of a config object.
* @param {ConfigObject} config The config object.
* @param {string} indexPath The index path of the config object.
* @return {string} The name of the config object.
*/
function getConfigName(config, indexPath) {
if (config.name) {
return config.name;
}
return `UserConfig${indexPath}`;
}
/**
* Gets the name of an extension.
* @param {SimpleExtendsElement} extension The extension.
* @param {string} indexPath The index of the extension.
* @return {string} The name of the extension.
*/
function getExtensionName(extension, indexPath) {
if (typeof extension === "string") {
return extension;
}
if (extension.name) {
return extension.name;
}
return `ExtendedConfig${indexPath}`;
}
/**
* Determines if a config object is a legacy config.
* @param {ConfigObject|LegacyConfig} config The config object to check.
* @return {config is LegacyConfig} `true` if the config object is a legacy config.
*/
function isLegacyConfig(config) {
// eslintrc's plugins must be an array; while flat config's must be an object.
if (Array.isArray(config.plugins)) {
return true;
}
for (const key of eslintrcKeys) {
if (key in config) {
return true;
}
}
return false;
}
/**
* Determines if a config object is a global ignores config.
* @param {ConfigObject} config The config object to check.
* @return {boolean} `true` if the config object is a global ignores config.
*/
function isGlobalIgnores(config) {
return Object.keys(config).every(key => allowedGlobalIgnoreKeys.has(key));
}
/**
* Parses a plugin member ID (rule, processor, etc.) and returns
* the namespace and member name.
* @param {string} id The ID to parse.
* @returns {{namespace:string, name:string}} The namespace and member name.
*/
function getPluginMember(id) {
const firstSlashIndex = id.indexOf("/");
if (firstSlashIndex === -1) {
return { namespace: "", name: id };
}
let namespace = id.slice(0, firstSlashIndex);
/*
* Special cases:
* 1. The namespace is `@`, that means it's referring to the
* core plugin so `@` is the full namespace.
* 2. The namespace starts with `@`, that means it's referring to
* an npm scoped package. That means the namespace is the scope
* and the package name (i.e., `@eslint/core`).
*/
if (namespace[0] === "@" && namespace !== "@") {
const secondSlashIndex = id.indexOf("/", firstSlashIndex + 1);
if (secondSlashIndex !== -1) {
namespace = id.slice(0, secondSlashIndex);
return { namespace, name: id.slice(secondSlashIndex + 1) };
}
}
const name = id.slice(firstSlashIndex + 1);
return { namespace, name };
}
/**
* Normalizes the plugin config by replacing the namespace with the plugin namespace.
* @param {string} userNamespace The namespace of the plugin.
* @param {Plugin} plugin The plugin config object.
* @param {ConfigObject} config The config object to normalize.
* @return {ConfigObject} The normalized config object.
*/
function normalizePluginConfig(userNamespace, plugin, config) {
const pluginNamespace = plugin.meta?.namespace;
// don't do anything if the plugin doesn't have a namespace or rules
if (
!pluginNamespace ||
pluginNamespace === userNamespace ||
(!config.rules && !config.processor && !config.language)
) {
return config;
}
const result = { ...config };
// update the rules
if (result.rules) {
const ruleIds = Object.keys(result.rules);
/** @type {Record<string,RuleConfig|undefined>} */
const newRules = {};
for (let i = 0; i < ruleIds.length; i++) {
const ruleId = ruleIds[i];
const { namespace: ruleNamespace, name: ruleName } =
getPluginMember(ruleId);
if (ruleNamespace === pluginNamespace) {
newRules[`${userNamespace}/${ruleName}`] = result.rules[ruleId];
} else {
newRules[ruleId] = result.rules[ruleId];
}
}
result.rules = newRules;
}
// update the processor
if (typeof result.processor === "string") {
const { namespace: processorNamespace, name: processorName } =
getPluginMember(result.processor);
if (processorNamespace) {
if (processorNamespace === pluginNamespace) {
result.processor = `${userNamespace}/${processorName}`;
}
}
}
// update the language
if (typeof result.language === "string") {
const { namespace: languageNamespace, name: languageName } =
getPluginMember(result.language);
if (languageNamespace === pluginNamespace) {
result.language = `${userNamespace}/${languageName}`;
}
}
return result;
}
/**
* Deeply normalizes a plugin config, traversing recursively into an arrays.
* @param {string} userPluginNamespace The namespace of the plugin.
* @param {Plugin} plugin The plugin object.
* @param {ConfigObject|LegacyConfig|(ConfigObject|LegacyConfig)[]} pluginConfig The plugin config to normalize.
* @param {string} pluginConfigName The name of the plugin config.
* @return {InfiniteConfigArray} The normalized plugin config.
* @throws {TypeError} If the plugin config is a legacy config.
*/
function deepNormalizePluginConfig(
userPluginNamespace,
plugin,
pluginConfig,
pluginConfigName,
) {
// if it's an array then it's definitely a new config
if (Array.isArray(pluginConfig)) {
return pluginConfig.map(pluginSubConfig =>
deepNormalizePluginConfig(
userPluginNamespace,
plugin,
pluginSubConfig,
pluginConfigName,
),
);
}
// if it's a legacy config, throw an error
if (isLegacyConfig(pluginConfig)) {
throw new TypeError(
`Plugin config "${pluginConfigName}" is an eslintrc config and cannot be used in this context.`,
);
}
return normalizePluginConfig(userPluginNamespace, plugin, pluginConfig);
}
/**
* Finds a plugin config by name in the given config.
* @param {ConfigObject} config The config object.
* @param {string} pluginConfigName The name of the plugin config.
* @return {InfiniteConfigArray} The plugin config.
* @throws {TypeError} If the plugin config is not found or is a legacy config.
*/
function findPluginConfig(config, pluginConfigName) {
const { namespace: userPluginNamespace, name: configName } =
getPluginMember(pluginConfigName);
const plugin = config.plugins?.[userPluginNamespace];
if (!plugin) {
throw new TypeError(`Plugin "${userPluginNamespace}" not found.`);
}
const directConfig = plugin.configs?.[configName];
// Prefer direct config, but fall back to flat config if available
if (directConfig) {
// Arrays are always flat configs, and non-legacy configs can be used directly
if (Array.isArray(directConfig) || !isLegacyConfig(directConfig)) {
return deepNormalizePluginConfig(
userPluginNamespace,
plugin,
directConfig,
pluginConfigName,
);
}
}
// If it's a legacy config, or the config does not exist => look for the flat version
const flatConfig = plugin.configs?.[`flat/${configName}`];
if (
flatConfig &&
(Array.isArray(flatConfig) || !isLegacyConfig(flatConfig))
) {
return deepNormalizePluginConfig(
userPluginNamespace,
plugin,
flatConfig,
pluginConfigName,
);
}
// If we get here, then the config was either not found or is a legacy config
const message =
directConfig || flatConfig
? `Plugin config "${configName}" in plugin "${userPluginNamespace}" is an eslintrc config and cannot be used in this context.`
: `Plugin config "${configName}" not found in plugin "${userPluginNamespace}".`;
throw new TypeError(message);
}
/**
* Flattens an array while keeping track of the index path.
* @param {any[]} configList The array to traverse.
* @param {string} indexPath The index path of the value in a multidimensional array.
* @return {IterableIterator<{indexPath:string, value:any}>} The flattened list of values.
*/
function* flatTraverse(configList, indexPath = "") {
for (let i = 0; i < configList.length; i++) {
const newIndexPath = indexPath ? `${indexPath}[${i}]` : `[${i}]`;
// if it's an array then traverse it as well
if (Array.isArray(configList[i])) {
yield* flatTraverse(configList[i], newIndexPath);
continue;
}
yield { indexPath: newIndexPath, value: configList[i] };
}
}
/**
* Extends a list of config files by creating every combination of base and extension files.
* @param {(string|string[])[]} [baseFiles] The base files.
* @param {(string|string[])[]} [extensionFiles] The extension files.
* @return {(string|string[])[]} The extended files.
*/
function extendConfigFiles(baseFiles = [], extensionFiles = []) {
if (!extensionFiles.length) {
return baseFiles.concat();
}
if (!baseFiles.length) {
return extensionFiles.concat();
}
/** @type {(string|string[])[]} */
const result = [];
for (const baseFile of baseFiles) {
for (const extensionFile of extensionFiles) {
/*
* Each entry can be a string or array of strings. The end result
* needs to be an array of strings, so we need to be sure to include
* all of the items when there's an array.
*/
const entry = [];
if (Array.isArray(baseFile)) {
entry.push(...baseFile);
} else {
entry.push(baseFile);
}
if (Array.isArray(extensionFile)) {
entry.push(...extensionFile);
} else {
entry.push(extensionFile);
}
result.push(entry);
}
}
return result;
}
/**
* Extends a config object with another config object.
* @param {ConfigObject} baseConfig The base config object.
* @param {string} baseConfigName The name of the base config object.
* @param {ConfigObject} extension The extension config object.
* @param {string} extensionName The index of the extension config object.
* @return {ConfigObject} The extended config object.
*/
function extendConfig(baseConfig, baseConfigName, extension, extensionName) {
const result = { ...extension };
// for global ignores there is no further work to be done, we just keep everything
if (!isGlobalIgnores(extension)) {
// for files we need to create every combination of base and extension files
if (baseConfig.files) {
result.files = extendConfigFiles(baseConfig.files, extension.files);
}
// for ignores we just concatenation the extension ignores onto the base ignores
if (baseConfig.ignores) {
result.ignores = baseConfig.ignores.concat(extension.ignores ?? []);
}
}
result.name = `${baseConfigName} > ${extensionName}`;
if (baseConfig.basePath) {
result.basePath = baseConfig.basePath;
}
return result;
}
/**
* Processes a list of extends elements.
* @param {ConfigWithExtends} config The config object.
* @param {WeakMap<ConfigObject, string>} configNames The map of config objects to their names.
* @return {ConfigObject[]} The flattened list of config objects.
* @throws {TypeError} If the `extends` property is not an array or if nested `extends` is found.
*/
function processExtends(config, configNames) {
if (!config.extends) {
return [config];
}
if (!Array.isArray(config.extends)) {
throw new TypeError("The `extends` property must be an array.");
}
const {
/** @type {ConfigObject[]} */
extends: extendsList,
/** @type {ConfigObject} */
...configObject
} = config;
const extensionNames = new WeakMap();
// replace strings with the actual configs
const objectExtends = extendsList.map(extendsElement => {
if (typeof extendsElement === "string") {
const pluginConfig = findPluginConfig(config, extendsElement);
// assign names
if (Array.isArray(pluginConfig)) {
pluginConfig.forEach((pluginConfigElement, index) => {
extensionNames.set(
pluginConfigElement,
`${extendsElement}[${index}]`,
);
});
} else {
extensionNames.set(pluginConfig, extendsElement);
}
return pluginConfig;
}
return /** @type {ConfigObject} */ (extendsElement);
});
const result = [];
for (const { indexPath, value: extendsElement } of flatTraverse(
objectExtends,
)) {
const extension = /** @type {ConfigObject} */ (extendsElement);
if ("basePath" in extension) {
throw new TypeError("'basePath' in `extends` is not allowed.");
}
if ("extends" in extension) {
throw new TypeError("Nested 'extends' is not allowed.");
}
const baseConfigName = /** @type {string} */ (configNames.get(config));
const extensionName =
extensionNames.get(extendsElement) ??
getExtensionName(extendsElement, indexPath);
result.push(
extendConfig(
configObject,
baseConfigName,
extension,
extensionName,
),
);
}
/*
* If the base config object has only `ignores` and `extends`, then
* removing `extends` turns it into a global ignores, which is not what
* we want. So we need to check if the base config object is a global ignores
* and if so, we don't add it to the array.
*
* (The other option would be to add a `files` entry, but that would result
* in a config that didn't actually do anything because there are no
* other keys in the config.)
*/
if (!isGlobalIgnores(configObject)) {
result.push(configObject);
}
return result.flat();
}
/**
* Processes a list of config objects and arrays.
* @param {ConfigWithExtends[]} configList The list of config objects and arrays.
* @param {WeakMap<ConfigObject, string>} configNames The map of config objects to their names.
* @return {ConfigObject[]} The flattened list of config objects.
*/
function processConfigList(configList, configNames) {
return configList.flatMap(config => processExtends(config, configNames));
}
//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------
/**
* Helper function to define a config array.
* @param {ConfigWithExtendsArray} args The arguments to the function.
* @returns {ConfigObject[]} The config array.
* @throws {TypeError} If no arguments are provided or if an argument is not an object.
*/
function defineConfig(...args) {
const configNames = new WeakMap();
const configs = [];
if (args.length === 0) {
throw new TypeError("Expected one or more arguments.");
}
// first flatten the list of configs and get the names
for (const { indexPath, value } of flatTraverse(args)) {
if (typeof value !== "object" || value === null) {
throw new TypeError(
`Expected an object but received ${String(value)}.`,
);
}
const config = /** @type {ConfigWithExtends} */ (value);
// save config name for easy reference later
configNames.set(config, getConfigName(config, indexPath));
configs.push(config);
}
return processConfigList(configs, configNames);
}
/**
* @fileoverview Global ignores helper function.
* @author Nicholas C. Zakas
*/
//-----------------------------------------------------------------------------
// Type Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------
let globalIgnoreCount = 0;
//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------
/**
* Creates a global ignores config with the given patterns.
* @param {string[]} ignorePatterns The ignore patterns.
* @param {string} [name] The name of the global ignores config.
* @returns {ConfigObject} The global ignores config.
* @throws {TypeError} If ignorePatterns is not an array or if it is empty.
*/
function globalIgnores(ignorePatterns, name) {
if (!Array.isArray(ignorePatterns)) {
throw new TypeError("ignorePatterns must be an array");
}
if (ignorePatterns.length === 0) {
throw new TypeError("ignorePatterns must contain at least one pattern");
}
const id = globalIgnoreCount++;
return {
name: name || `globalIgnores ${id}`,
ignores: ignorePatterns,
};
}
/**
* @fileoverview Ignore file utilities for the config-helpers package.
* This file was forked from the source code for the compat package.
*
* @author Nicholas C. Zakas
* @author Kirk Waiblinger
*/
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
/**
* @typedef {object} IncludeIgnoreFileOptionsObject
* @property {boolean} [gitignoreResolution] Whether to interpret the contents of an ignore file relative to the config file or the ignore file.
* - gitignoreResolution: false (default): Interprets ignore patterns relative to the config file
* - gitignoreResolution: true: Interprets the ignore patterns in a file relative to the ignore file
* @property {string} [name] The name to give the output config object(s).
*/
/**
* Options for `includeIgnoreFile()`. May be provided as an object or, for
* legacy compatibility with `@eslint/compat`, as a string which is treated as
* the `name` option.
* @typedef {IncludeIgnoreFileOptionsObject | string} IncludeIgnoreFileOptions
*/
//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------
/**
* Converts an ESLint ignore pattern to a minimatch pattern.
* @param {string} pattern The .eslintignore or .gitignore pattern to convert.
* @returns {string} The converted pattern.
*/
function convertIgnorePatternToMinimatch(pattern) {
const isNegated = pattern.startsWith("!");
const negatedPrefix = isNegated ? "!" : "";
const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd();
// special cases
if (["", "**", "/**", "**/"].includes(patternToTest)) {
return `${negatedPrefix}${patternToTest}`;
}
const firstIndexOfSlash = patternToTest.indexOf("/");
const matchEverywherePrefix =
firstIndexOfSlash < 0 || firstIndexOfSlash === patternToTest.length - 1
? "**/"
: "";
const patternWithoutLeadingSlash =
firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest;
/*
* Escape `{` and `(` because in gitignore patterns they are just
* literal characters without any specific syntactic meaning,
* while in minimatch patterns they can form brace expansion or extglob syntax.
*
* For example, gitignore pattern `src/{a,b}.js` ignores file `src/{a,b}.js`.
* But, the same minimatch pattern `src/{a,b}.js` ignores files `src/a.js` and `src/b.js`.
* Minimatch pattern `src/\{a,b}.js` is equivalent to gitignore pattern `src/{a,b}.js`.
*/
const escapedPatternWithoutLeadingSlash =
patternWithoutLeadingSlash.replaceAll(
// eslint-disable-next-line regexp/no-empty-lookarounds-assertion -- False positive
/(?=((?:\\.|[^{(])*))\1([{(])/guy,
"$1\\$2",
);
const matchInsideSuffix = patternToTest.endsWith("/**") ? "/*" : "";
return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`;
}
/**
* @param {string} ignoreFilePath
* @returns {string[]}
*/
function ignoreFilePathToPatterns(ignoreFilePath) {
const ignoreFile = fs.readFileSync(ignoreFilePath, "utf8");
const lines = ignoreFile.split(/\r?\n/u);
return lines
.map(line => line.trim())
.filter(line => line && !line.startsWith("#"))
.map(convertIgnorePatternToMinimatch);
}
/**
* Helper to parse and validate the options to `includeIgnoreFile()`
*
* @param {string | { gitignoreResolution?: unknown, name?: unknown } | undefined} options
* @returns {{ gitignoreResolution: boolean, name: string }}
*/
function parseOptions(options) {
// legacy compatibility with @eslint/compat's `includeIgnoreFile`
if (typeof options === "string") {
return { gitignoreResolution: false, name: options };
}
const optionsObject = options ?? {};
if (typeof optionsObject !== "object" || Array.isArray(optionsObject)) {
throw new TypeError(
"The options argument to `includeIgnoreFile()` should be an object or a string.",
);
}
const gitignoreResolution = optionsObject.gitignoreResolution ?? false;
if (typeof gitignoreResolution !== "boolean") {
throw new TypeError(
"The `gitignoreResolution` option must be specified a boolean or omitted",
);
}
const name = optionsObject.name ?? `Imported .gitignore patterns`;
if (typeof name !== "string") {
throw new TypeError(
"The `name` option must be specified as a string or omitted.",
);
}
return { gitignoreResolution, name };
}
/**
* @overload
*
* Reads ignore files and returns objects with the ignore patterns.
*
* @param {string[]} ignoreFilePathArg The paths of ignore files to include.
* @param {IncludeIgnoreFileOptions} [options]
* @returns {ConfigObject[]}
*/
/**
* @overload
*
* Reads an ignore file and returns an object with the ignore patterns.
*
* @param {string} ignoreFilePathArg The path of the ignore file to include.
* @param {IncludeIgnoreFileOptions} [options]
* @returns {ConfigObject}
*/
/**
* @overload
*
* Reads an ignore file(s) and returns an object(s) with the ignore patterns.
*
* @param {string[] | string} ignoreFilePathArg The path(s) of the ignore file(s) to include.
* @param {IncludeIgnoreFileOptions} [options]
* @returns {ConfigObject[] | ConfigObject}
*/
/**
* Reads an ignore file(s) and returns an object(s) with the ignore patterns.
*
* @param {string[] | string} ignoreFilePathArg The path(s) of the ignore file(s) to include.
* @param {IncludeIgnoreFileOptions} [options]
* @returns {ConfigObject[] | ConfigObject}
*/
function includeIgnoreFile(ignoreFilePathArg, options) {
const returnSingleObject = !Array.isArray(ignoreFilePathArg);
const ignoreFilePaths = Array.isArray(ignoreFilePathArg)
? ignoreFilePathArg
: [ignoreFilePathArg];
for (const ignorePath of ignoreFilePaths) {
if (typeof ignorePath !== "string") {
throw new TypeError(
"The first argument to `includeIgnoreFile()` should be a string or array of strings",
);
}
if (!path.isAbsolute(ignorePath)) {
throw new Error(
`The ignore file location must be an absolute path. Received ${ignorePath}`,
);
}
}
const { gitignoreResolution, name } = parseOptions(options);
if (returnSingleObject) {
return {
name,
ignores: ignoreFilePathToPatterns(ignoreFilePathArg),
...(gitignoreResolution
? { basePath: path.dirname(ignoreFilePathArg) }
: {}),
};
}
return ignoreFilePaths.map((ignoreFilePath, i) => ({
name: `${name} (${i})`,
ignores: ignoreFilePathToPatterns(ignoreFilePath),
...(gitignoreResolution
? { basePath: path.dirname(ignoreFilePath) }
: {}),
}));
}
export { convertIgnorePatternToMinimatch, defineConfig, globalIgnores, includeIgnoreFile };

View File

@@ -0,0 +1,694 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "zod/v4";
test("_values", () => {
expect(z.string()._zod.values).toEqual(undefined);
expect(z.enum(["a", "b"])._zod.values).toEqual(new Set(["a", "b"]));
expect(z.nativeEnum({ a: "A", b: "B" })._zod.values).toEqual(new Set(["A", "B"]));
expect(z.literal("test")._zod.values).toEqual(new Set(["test"]));
expect(z.literal(123)._zod.values).toEqual(new Set([123]));
expect(z.literal(true)._zod.values).toEqual(new Set([true]));
expect(z.literal(BigInt(123))._zod.values).toEqual(new Set([BigInt(123)]));
expect(z.undefined()._zod.values).toEqual(new Set([undefined]));
expect(z.null()._zod.values).toEqual(new Set([null]));
const t = z.literal("test");
expect(t.optional()._zod.values).toEqual(new Set(["test", undefined]));
expect(t.nullable()._zod.values).toEqual(new Set(["test", null]));
expect(t.default("test")._zod.values).toEqual(new Set(["test"]));
expect(t.catch("test")._zod.values).toEqual(new Set(["test"]));
const pre = z.preprocess((val) => String(val), z.string()).pipe(z.literal("test"));
expect(pre._zod.values).toEqual(undefined);
const post = z.literal("test").transform((_) => Math.random());
expect(post._zod.values).toEqual(new Set(["test"]));
// Test that readonly literals pass through their values property
expect(z.literal("test").readonly()._zod.values).toEqual(new Set(["test"]));
});
test("valid parse - object", () => {
expect(
z
.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
])
.parse({ type: "a", a: "abc" })
).toEqual({ type: "a", a: "abc" });
});
test("valid - include discriminator key (deprecated)", () => {
expect(
z
.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
])
.parse({ type: "a", a: "abc" })
).toEqual({ type: "a", a: "abc" });
});
test("valid - optional discriminator (object)", () => {
const schema = z.discriminatedUnion("type", [
z.object({ type: z.literal("a").optional(), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
]);
expect(schema.parse({ type: "a", a: "abc" })).toEqual({ type: "a", a: "abc" });
expect(schema.parse({ a: "abc" })).toEqual({ a: "abc" });
});
test("valid - discriminator value of various primitive types", () => {
const schema = z.discriminatedUnion("type", [
z.object({ type: z.literal("1"), val: z.string() }),
z.object({ type: z.literal(1), val: z.string() }),
z.object({ type: z.literal(BigInt(1)), val: z.string() }),
z.object({ type: z.literal("true"), val: z.string() }),
z.object({ type: z.literal(true), val: z.string() }),
z.object({ type: z.literal("null"), val: z.string() }),
z.object({ type: z.null(), val: z.string() }),
z.object({ type: z.literal("undefined"), val: z.string() }),
z.object({ type: z.undefined(), val: z.string() }),
]);
expect(schema.parse({ type: "1", val: "val" })).toEqual({ type: "1", val: "val" });
expect(schema.parse({ type: 1, val: "val" })).toEqual({ type: 1, val: "val" });
expect(schema.parse({ type: BigInt(1), val: "val" })).toEqual({
type: BigInt(1),
val: "val",
});
expect(schema.parse({ type: "true", val: "val" })).toEqual({
type: "true",
val: "val",
});
expect(schema.parse({ type: true, val: "val" })).toEqual({
type: true,
val: "val",
});
expect(schema.parse({ type: "null", val: "val" })).toEqual({
type: "null",
val: "val",
});
expect(schema.parse({ type: null, val: "val" })).toEqual({
type: null,
val: "val",
});
expect(schema.parse({ type: "undefined", val: "val" })).toEqual({
type: "undefined",
val: "val",
});
expect(schema.parse({ type: undefined, val: "val" })).toEqual({
type: undefined,
val: "val",
});
const fail = schema.safeParse({
type: "not_a_key",
val: "val",
});
expect(fail.error).toBeInstanceOf(z.ZodError);
});
test("invalid - null", () => {
try {
z.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
]).parse(null);
throw new Error();
} catch (e: any) {
// [
// {
// code: z.ZodIssueCode.invalid_type,
// expected: z.ZodParsedType.object,
// input: null,
// message: "Expected object, received null",
// received: z.ZodParsedType.null,
// path: [],
// },
// ];
expect(e.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_type",
"expected": "object",
"message": "Invalid input: expected object, received null",
"path": [],
},
]
`);
}
});
test("invalid discriminator value", () => {
const result = z
.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
])
.safeParse({ type: "x", a: "abc" });
expect(result).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"code": "invalid_union",
"errors": [],
"note": "No matching discriminator",
"discriminator": "type",
"options": [
"a",
"b"
],
"path": [
"type"
],
"message": "Invalid discriminator value. Expected 'a' | 'b'"
}
]],
"success": false,
}
`);
});
test("invalid discriminator value - unionFallback", () => {
const result = z
.discriminatedUnion(
"type",
[z.object({ type: z.literal("a"), a: z.string() }), z.object({ type: z.literal("b"), b: z.string() })],
{ unionFallback: true }
)
.safeParse({ type: "x", a: "abc" });
expect(result).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"code": "invalid_union",
"errors": [
[
{
"code": "invalid_value",
"values": [
"a"
],
"path": [
"type"
],
"message": "Invalid input: expected \\"a\\""
}
],
[
{
"code": "invalid_value",
"values": [
"b"
],
"path": [
"type"
],
"message": "Invalid input: expected \\"b\\""
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"b"
],
"message": "Invalid input: expected string, received undefined"
}
]
],
"path": [],
"message": "Invalid input"
}
]],
"success": false,
}
`);
});
test("valid discriminator value, invalid data", () => {
const result = z
.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ type: z.literal("b"), b: z.string() }),
])
.safeParse({ type: "a", b: "abc" });
// [
// {
// code: z.ZodIssueCode.invalid_type,
// expected: z.ZodParsedType.string,
// message: "Required",
// path: ["a"],
// received: z.ZodParsedType.undefined,
// },
// ];
expect(result).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"expected": "string",
"code": "invalid_type",
"path": [
"a"
],
"message": "Invalid input: expected string, received undefined"
}
]],
"success": false,
}
`);
});
test("wrong schema - missing discriminator", () => {
// @ts-expect-error missing discriminator property
z.discriminatedUnion("type", [z.object({ value: z.string() })]);
try {
z.discriminatedUnion("type", [
z.object({ type: z.literal("a"), a: z.string() }),
z.object({ b: z.string() }) as any,
])._zod.propValues;
throw new Error();
} catch (e: any) {
expect(e.message.includes("Invalid discriminated union option")).toBe(true);
}
});
// removed to account for unions of unions
// test("wrong schema - duplicate discriminator values", () => {
// try {
// z.discriminatedUnion("type",[
// z.object({ type: z.literal("a"), a: z.string() }),
// z.object({ type: z.literal("a"), b: z.string() }),
// ]);
// throw new Error();
// } catch (e: any) {
// expect(e.message.includes("Duplicate discriminator value")).toEqual(true);
// }
// });
test("async - valid", async () => {
const schema = await z.discriminatedUnion("type", [
z.object({
type: z.literal("a"),
a: z
.string()
.refine(async () => true)
.transform(async (val) => Number(val)),
}),
z.object({
type: z.literal("b"),
b: z.string(),
}),
]);
const data = { type: "a", a: "1" };
const result = await schema.safeParseAsync(data);
expect(result.data).toEqual({ type: "a", a: 1 });
});
test("async - invalid", async () => {
// try {
const a = z.discriminatedUnion("type", [
z.object({
type: z.literal("a"),
a: z
.string()
.refine(async () => true)
.transform(async (val) => val),
}),
z.object({
type: z.literal("b"),
b: z.string(),
}),
]);
const result = await a.safeParseAsync({ type: "a", a: 1 });
// expect(JSON.parse(e.message)).toEqual([
// {
// code: "invalid_type",
// expected: "string",
// input: 1,
// received: "number",
// path: ["a"],
// message: "Expected string, received number",
// },
// ]);
expect(result.error).toMatchInlineSnapshot(`
[ZodError: [
{
"expected": "string",
"code": "invalid_type",
"path": [
"a"
],
"message": "Invalid input: expected string, received number"
}
]]
`);
});
test("valid - literals with .default or .pipe", () => {
const schema = z.discriminatedUnion("type", [
z.object({
type: z.literal("foo").default("foo"),
a: z.string(),
}),
z.object({
type: z.literal("custom"),
method: z.string(),
}),
z.object({
type: z.literal("bar").transform((val) => val),
c: z.string(),
}),
]);
expect(schema.parse({ type: "foo", a: "foo" })).toEqual({
type: "foo",
a: "foo",
});
});
test("enum and nativeEnum", () => {
enum MyEnum {
d = 0,
e = "e",
}
const schema = z.discriminatedUnion("key", [
z.object({
key: z.literal("a"),
// Add other properties specific to this option
}),
z.object({
key: z.enum(["b", "c"]),
// Add other properties specific to this option
}),
z.object({
key: z.nativeEnum(MyEnum),
// Add other properties specific to this option
}),
]);
type schema = z.infer<typeof schema>;
expectTypeOf<schema>().toEqualTypeOf<{ key: "a" } | { key: "b" | "c" } | { key: MyEnum.d | MyEnum.e }>();
schema.parse({ key: "a" });
schema.parse({ key: "b" });
schema.parse({ key: "c" });
schema.parse({ key: MyEnum.d });
schema.parse({ key: MyEnum.e });
schema.parse({ key: "e" });
});
test("branded", () => {
const schema = z.discriminatedUnion("key", [
z.object({
key: z.literal("a"),
// Add other properties specific to this option
}),
z.object({
key: z.literal("b").brand<"asdfasdf">(),
// Add other properties specific to this option
}),
]);
type schema = z.infer<typeof schema>;
expectTypeOf<schema>().toEqualTypeOf<{ key: "a" } | { key: "b" & z.core.$brand<"asdfasdf"> }>();
schema.parse({ key: "a" });
schema.parse({ key: "b" });
expect(() => {
schema.parse({ key: "c" });
}).toThrow();
});
test("optional and nullable", () => {
const schema = z.discriminatedUnion("key", [
z.object({
key: z.literal("a").optional(),
a: z.literal(true),
}),
z.object({
key: z.literal("b").nullable(),
b: z.literal(true),
// Add other properties specific to this option
}),
]);
type schema = z.infer<typeof schema>;
expectTypeOf<schema>().toEqualTypeOf<{ key?: "a" | undefined; a: true } | { key: "b" | null; b: true }>();
schema.parse({ key: "a", a: true });
schema.parse({ key: undefined, a: true });
schema.parse({ key: "b", b: true });
schema.parse({ key: null, b: true });
expect(() => {
schema.parse({ key: null, a: true });
}).toThrow();
expect(() => {
schema.parse({ key: "b", a: true });
}).toThrow();
const value = schema.parse({ key: null, b: true });
if (!("key" in value)) value.a;
if (value.key === undefined) value.a;
if (value.key === "a") value.a;
if (value.key === "b") value.b;
if (value.key === null) value.b;
});
test("multiple discriminators", () => {
const FreeConfig = z.object({
type: z.literal("free"),
min_cents: z.null(),
});
// console.log(FreeConfig.shape.type);
const PricedConfig = z.object({
type: z.literal("fiat-price"),
// min_cents: z.int().nullable(),
min_cents: z.null(),
});
const Config = z.discriminatedUnion("type", [FreeConfig, PricedConfig]);
Config.parse({
min_cents: null,
type: "fiat-price",
name: "Standard",
});
expect(() => {
Config.parse({
min_cents: null,
type: "not real",
name: "Standard",
});
}).toThrow();
});
test("single element union", () => {
const schema = z.object({
a: z.literal("discKey"),
b: z.enum(["apple", "banana"]),
c: z.object({ id: z.string() }),
});
const input = {
a: "discKey",
b: "apple",
c: {}, // Invalid, as schema requires `id` property
};
// Validation must fail here, but it doesn't
const u = z.discriminatedUnion("a", [schema]);
const result = u.safeParse(input);
expect(result).toMatchObject({ success: false });
expect(result).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"expected": "string",
"code": "invalid_type",
"path": [
"c",
"id"
],
"message": "Invalid input: expected string, received undefined"
}
]],
"success": false,
}
`);
expect(u.options.length).toEqual(1);
});
test("nested discriminated unions", () => {
const BaseError = z.object({ status: z.literal("failed"), message: z.string() });
const MyErrors = z.discriminatedUnion("code", [
BaseError.extend({ code: z.literal(400) }),
BaseError.extend({ code: z.literal(401) }),
BaseError.extend({ code: z.literal(500) }),
]);
const MyResult = z.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.string() }),
MyErrors,
]);
expect(MyErrors._zod.propValues).toMatchInlineSnapshot(`
{
"code": Set {
400,
401,
500,
},
"status": Set {
"failed",
},
}
`);
expect(MyResult._zod.propValues).toMatchInlineSnapshot(`
{
"code": Set {
400,
401,
500,
},
"status": Set {
"success",
"failed",
},
}
`);
const result = MyResult.parse({ status: "success", data: "hello" });
expect(result).toMatchInlineSnapshot(`
{
"data": "hello",
"status": "success",
}
`);
const result2 = MyResult.parse({ status: "failed", code: 400, message: "bad request" });
expect(result2).toMatchInlineSnapshot(`
{
"code": 400,
"message": "bad request",
"status": "failed",
}
`);
const result3 = MyResult.parse({ status: "failed", code: 401, message: "unauthorized" });
expect(result3).toMatchInlineSnapshot(`
{
"code": 401,
"message": "unauthorized",
"status": "failed",
}
`);
const result4 = MyResult.parse({ status: "failed", code: 500, message: "internal server error" });
expect(result4).toMatchInlineSnapshot(`
{
"code": 500,
"message": "internal server error",
"status": "failed",
}
`);
});
test("readonly literal discriminator", () => {
const discUnion = z.discriminatedUnion("type", [
z.object({ type: z.literal("a").readonly(), a: z.string() }),
z.object({ type: z.literal("b"), b: z.number() }),
]);
// Test that both discriminator values are correctly included in propValues
const propValues = discUnion._zod.propValues;
expect(propValues?.type?.has("a")).toBe(true);
expect(propValues?.type?.has("b")).toBe(true);
// Test that the discriminated union works correctly
const result1 = discUnion.parse({ type: "a", a: "hello" });
expect(result1).toEqual({ type: "a", a: "hello" });
const result2 = discUnion.parse({ type: "b", b: 42 });
expect(result2).toEqual({ type: "b", b: 42 });
// Test that invalid discriminator values are rejected
expect(() => {
discUnion.parse({ type: "c", a: "hello" });
}).toThrow();
});
test("pipes", () => {
const schema = z
.object({
type: z.literal("foo"),
})
.transform((s) => ({ ...s, v: 2 }));
expect(schema._zod.propValues).toMatchInlineSnapshot(`
{
"type": Set {
"foo",
},
}
`);
const schema2 = z.object({
type: z.literal("bar"),
});
const combinedSchema = z.discriminatedUnion("type", [schema, schema2], {
unionFallback: false,
});
combinedSchema.parse({
type: "foo",
v: 2,
});
});
test("def", () => {
const schema = z.discriminatedUnion(
"type",
[z.object({ type: z.literal("play") }), z.object({ type: z.literal("pause") })],
{ unionFallback: true }
);
expect(schema.def).toBeDefined();
expect(schema.def.discriminator).toEqual("type");
expect(schema.def.unionFallback).toEqual(true);
});
test("encode with codec discriminator", () => {
const codec1 = z.codec(z.literal(1), z.literal("one"), {
decode: () => "one" as const,
encode: () => 1 as const,
});
const codec2 = z.codec(z.literal(2), z.literal("two"), {
decode: () => "two" as const,
encode: () => 2 as const,
});
const schema = z.discriminatedUnion("type", [
z.object({ type: codec1, value: z.string() }),
z.object({ type: codec2, value: z.number() }),
]);
// decode (forward) should work
const decoded = schema.decode({ type: 1, value: "hello" });
expect(decoded).toEqual({ type: "one", value: "hello" });
// encode (backward) should also work — the discriminator values differ
// between forward (1, 2) and backward ("one", "two") directions
const encoded = z.encode(schema, { type: "one", value: "hello" });
expect(encoded).toEqual({ type: 1, value: "hello" });
});

View File

@@ -0,0 +1,3 @@
var p=Object.defineProperty;var t=(o,r)=>p(o,"name",{value:r,configurable:!0});import a from"node:repl";import{v as l}from"./package-B13bX4zz.mjs";import{t as c}from"./index-DQtFPMc2.mjs";import"node:path";import"node:url";import"esbuild";import"node:crypto";import"./node-features-JeyyvQz6.mjs";import"node:fs";import"node:os";import"./temporary-directory-BDDVQOvU.mjs";console.log(`Welcome to tsx v${l} (Node.js ${process.version}).
Type ".help" for more information.`);const s=a.start(),{eval:f}=s,v=t(async function(o,r,e,i){const m=await c(o,e,{loader:"ts",tsconfigRaw:{compilerOptions:{preserveValueImports:!0}},define:{require:"global.require"}}).catch(n=>(console.log(n.message),{code:`
`}));return f.call(this,m.code,r,e,i)},"preEval");s.eval=v;

View File

@@ -0,0 +1,295 @@
{
"name": "@noble/curves",
"version": "1.9.7",
"description": "Audited & minimal JS implementation of elliptic curve cryptography",
"files": [
"*.js",
"*.js.map",
"*.d.ts",
"*.d.ts.map",
"esm",
"src",
"abstract",
"!oprf.*",
"!webcrypto.*"
],
"scripts": {
"bench": "npm run bench:install; cd test/benchmark; node secp256k1.js; node curves.js; node utils.js; node bls.js",
"bench:install": "cd test/benchmark; npm install; npm install ../.. --install-links",
"build": "tsc && tsc -p tsconfig.cjs.json",
"build:release": "npx jsbt esbuild test/build",
"build:clean": "rm {.,esm,abstract,esm/abstract}/*.{js,d.ts,d.ts.map,js.map} 2> /dev/null",
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
"test": "node --disable-warning=ExperimentalWarning test/index.js",
"test:bun": "bun test/index.js",
"test:deno": "deno --allow-env --allow-read test/index.js",
"test:coverage": "npm install --no-save c8@10.1.2 && npx c8 npm test"
},
"author": "Paul Miller (https://paulmillr.com)",
"homepage": "https://paulmillr.com/noble/",
"repository": {
"type": "git",
"url": "git+https://github.com/paulmillr/noble-curves.git"
},
"license": "MIT",
"dependencies": {
"@noble/hashes": "1.8.0"
},
"devDependencies": {
"@paulmillr/jsbt": "0.4.0",
"@types/node": "22.15.21",
"fast-check": "4.1.1",
"micro-bmark": "0.4.2",
"micro-should": "0.5.3",
"prettier": "3.5.3",
"typescript": "5.8.3"
},
"sideEffects": false,
"main": "index.js",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./index.js"
},
"./abstract/bls": {
"import": "./esm/abstract/bls.js",
"require": "./abstract/bls.js"
},
"./abstract/curve": {
"import": "./esm/abstract/curve.js",
"require": "./abstract/curve.js"
},
"./abstract/edwards": {
"import": "./esm/abstract/edwards.js",
"require": "./abstract/edwards.js"
},
"./abstract/hash-to-curve": {
"import": "./esm/abstract/hash-to-curve.js",
"require": "./abstract/hash-to-curve.js"
},
"./abstract/modular": {
"import": "./esm/abstract/modular.js",
"require": "./abstract/modular.js"
},
"./abstract/montgomery": {
"import": "./esm/abstract/montgomery.js",
"require": "./abstract/montgomery.js"
},
"./abstract/poseidon": {
"import": "./esm/abstract/poseidon.js",
"require": "./abstract/poseidon.js"
},
"./abstract/tower": {
"import": "./esm/abstract/tower.js",
"require": "./abstract/tower.js"
},
"./abstract/utils": {
"import": "./esm/abstract/utils.js",
"require": "./abstract/utils.js"
},
"./abstract/weierstrass": {
"import": "./esm/abstract/weierstrass.js",
"require": "./abstract/weierstrass.js"
},
"./abstract/fft": {
"import": "./esm/abstract/fft.js",
"require": "./abstract/fft.js"
},
"./_shortw_utils": {
"import": "./esm/_shortw_utils.js",
"require": "./_shortw_utils.js"
},
"./bls12-381": {
"import": "./esm/bls12-381.js",
"require": "./bls12-381.js"
},
"./bn254": {
"import": "./esm/bn254.js",
"require": "./bn254.js"
},
"./ed448": {
"import": "./esm/ed448.js",
"require": "./ed448.js"
},
"./ed25519": {
"import": "./esm/ed25519.js",
"require": "./ed25519.js"
},
"./index": {
"import": "./esm/index.js",
"require": "./index.js"
},
"./jubjub": {
"import": "./esm/jubjub.js",
"require": "./jubjub.js"
},
"./misc": {
"import": "./esm/misc.js",
"require": "./misc.js"
},
"./nist": {
"import": "./esm/nist.js",
"require": "./nist.js"
},
"./p256": {
"import": "./esm/p256.js",
"require": "./p256.js"
},
"./p384": {
"import": "./esm/p384.js",
"require": "./p384.js"
},
"./p521": {
"import": "./esm/p521.js",
"require": "./p521.js"
},
"./pasta": {
"import": "./esm/pasta.js",
"require": "./pasta.js"
},
"./secp256k1": {
"import": "./esm/secp256k1.js",
"require": "./secp256k1.js"
},
"./utils": {
"import": "./esm/utils.js",
"require": "./utils.js"
},
"./abstract/bls.js": {
"import": "./esm/abstract/bls.js",
"require": "./abstract/bls.js"
},
"./abstract/curve.js": {
"import": "./esm/abstract/curve.js",
"require": "./abstract/curve.js"
},
"./abstract/edwards.js": {
"import": "./esm/abstract/edwards.js",
"require": "./abstract/edwards.js"
},
"./abstract/hash-to-curve.js": {
"import": "./esm/abstract/hash-to-curve.js",
"require": "./abstract/hash-to-curve.js"
},
"./abstract/modular.js": {
"import": "./esm/abstract/modular.js",
"require": "./abstract/modular.js"
},
"./abstract/montgomery.js": {
"import": "./esm/abstract/montgomery.js",
"require": "./abstract/montgomery.js"
},
"./abstract/poseidon.js": {
"import": "./esm/abstract/poseidon.js",
"require": "./abstract/poseidon.js"
},
"./abstract/tower.js": {
"import": "./esm/abstract/tower.js",
"require": "./abstract/tower.js"
},
"./abstract/utils.js": {
"import": "./esm/abstract/utils.js",
"require": "./abstract/utils.js"
},
"./abstract/weierstrass.js": {
"import": "./esm/abstract/weierstrass.js",
"require": "./abstract/weierstrass.js"
},
"./abstract/fft.js": {
"import": "./esm/abstract/fft.js",
"require": "./abstract/fft.js"
},
"./_shortw_utils.js": {
"import": "./esm/_shortw_utils.js",
"require": "./_shortw_utils.js"
},
"./bls12-381.js": {
"import": "./esm/bls12-381.js",
"require": "./bls12-381.js"
},
"./bn254.js": {
"import": "./esm/bn254.js",
"require": "./bn254.js"
},
"./utils.js": {
"import": "./esm/utils.js",
"require": "./utils.js"
},
"./ed448.js": {
"import": "./esm/ed448.js",
"require": "./ed448.js"
},
"./ed25519.js": {
"import": "./esm/ed25519.js",
"require": "./ed25519.js"
},
"./index.js": {
"import": "./esm/index.js",
"require": "./index.js"
},
"./jubjub.js": {
"import": "./esm/jubjub.js",
"require": "./jubjub.js"
},
"./misc.js": {
"import": "./esm/misc.js",
"require": "./misc.js"
},
"./nist.js": {
"import": "./esm/nist.js",
"require": "./nist.js"
},
"./p256.js": {
"import": "./esm/p256.js",
"require": "./p256.js"
},
"./p384.js": {
"import": "./esm/p384.js",
"require": "./p384.js"
},
"./p521.js": {
"import": "./esm/p521.js",
"require": "./p521.js"
},
"./pasta.js": {
"import": "./esm/pasta.js",
"require": "./pasta.js"
},
"./secp256k1.js": {
"import": "./esm/secp256k1.js",
"require": "./secp256k1.js"
}
},
"engines": {
"node": "^14.21.3 || >=16"
},
"keywords": [
"elliptic",
"curve",
"cryptography",
"secp256k1",
"ed25519",
"p256",
"p384",
"p521",
"secp256r1",
"ed448",
"x25519",
"ed25519",
"bls12-381",
"bn254",
"alt_bn128",
"bls",
"noble",
"ecc",
"ecdsa",
"eddsa",
"weierstrass",
"montgomery",
"edwards",
"schnorr",
"fft"
],
"funding": "https://paulmillr.com/funding/"
}

View File

@@ -0,0 +1,7 @@
var getPrototypeOf = require("./getPrototypeOf.js");
var isNativeReflectConstruct = require("./isNativeReflectConstruct.js");
var possibleConstructorReturn = require("./possibleConstructorReturn.js");
function _callSuper(t, o, e) {
return o = getPrototypeOf(o), possibleConstructorReturn(t, isNativeReflectConstruct() ? Reflect.construct(o, e || [], getPrototypeOf(t).constructor) : o.apply(t, e));
}
module.exports = _callSuper, module.exports.__esModule = true, module.exports["default"] = module.exports;

View File

@@ -0,0 +1,13 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
// npx nx generate-lib repo
Object.defineProperty(exports, "__esModule", { value: true });
exports.es2020_date = void 0;
const base_config_1 = require("./base-config");
const es2020_intl_1 = require("./es2020.intl");
exports.es2020_date = {
libs: [es2020_intl_1.es2020_intl],
variables: [['Date', base_config_1.TYPE]],
};

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStringLength = getStringLength;
let segmenter;
function isASCII(value) {
return /^[\u0020-\u007f]*$/u.test(value);
}
function getStringLength(value) {
if (isASCII(value)) {
return value.length;
}
segmenter ??= new Intl.Segmenter();
return [...segmenter.segment(value)].length;
}

View File

@@ -0,0 +1,655 @@
(function () { 'use strict';
// This is free and unencumbered software released into the public domain.
// See LICENSE.md for more information.
//
// Utilities
//
/**
* @param {number} a The number to test.
* @param {number} min The minimum value in the range, inclusive.
* @param {number} max The maximum value in the range, inclusive.
* @return {boolean} True if a >= min and a <= max.
*/
function inRange(a, min, max) {
return min <= a && a <= max;
}
/**
* @param {*} o
* @return {Object}
*/
function ToDictionary(o) {
if (o === undefined) return {};
if (o === Object(o)) return o;
throw TypeError('Could not convert argument to dictionary');
}
/**
* @param {string} string Input string of UTF-16 code units.
* @return {!Array.<number>} Code points.
*/
function stringToCodePoints(string) {
// https://heycam.github.io/webidl/#dfn-obtain-unicode
// 1. Let S be the DOMString value.
var s = String(string);
// 2. Let n be the length of S.
var n = s.length;
// 3. Initialize i to 0.
var i = 0;
// 4. Initialize U to be an empty sequence of Unicode characters.
var u = [];
// 5. While i < n:
while (i < n) {
// 1. Let c be the code unit in S at index i.
var c = s.charCodeAt(i);
// 2. Depending on the value of c:
// c < 0xD800 or c > 0xDFFF
if (c < 0xD800 || c > 0xDFFF) {
// Append to U the Unicode character with code point c.
u.push(c);
}
// 0xDC00 ≤ c ≤ 0xDFFF
else if (0xDC00 <= c && c <= 0xDFFF) {
// Append to U a U+FFFD REPLACEMENT CHARACTER.
u.push(0xFFFD);
}
// 0xD800 ≤ c ≤ 0xDBFF
else if (0xD800 <= c && c <= 0xDBFF) {
// 1. If i = n1, then append to U a U+FFFD REPLACEMENT
// CHARACTER.
if (i === n - 1) {
u.push(0xFFFD);
}
// 2. Otherwise, i < n1:
else {
// 1. Let d be the code unit in S at index i+1.
var d = string.charCodeAt(i + 1);
// 2. If 0xDC00 ≤ d ≤ 0xDFFF, then:
if (0xDC00 <= d && d <= 0xDFFF) {
// 1. Let a be c & 0x3FF.
var a = c & 0x3FF;
// 2. Let b be d & 0x3FF.
var b = d & 0x3FF;
// 3. Append to U the Unicode character with code point
// 2^16+2^10*a+b.
u.push(0x10000 + (a << 10) + b);
// 4. Set i to i+1.
i += 1;
}
// 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a
// U+FFFD REPLACEMENT CHARACTER.
else {
u.push(0xFFFD);
}
}
}
// 3. Set i to i+1.
i += 1;
}
// 6. Return U.
return u;
}
/**
* @param {!Array.<number>} code_points Array of code points.
* @return {string} string String of UTF-16 code units.
*/
function codePointsToString(code_points) {
var s = '';
for (var i = 0; i < code_points.length; ++i) {
var cp = code_points[i];
if (cp <= 0xFFFF) {
s += String.fromCharCode(cp);
} else {
cp -= 0x10000;
s += String.fromCharCode((cp >> 10) + 0xD800,
(cp & 0x3FF) + 0xDC00);
}
}
return s;
}
//
// Implementation of Encoding specification
// https://encoding.spec.whatwg.org/
//
//
// 3. Terminology
//
/**
* End-of-stream is a special token that signifies no more tokens
* are in the stream.
* @const
*/ var end_of_stream = -1;
/**
* A stream represents an ordered sequence of tokens.
*
* @constructor
* @param {!(Array.<number>|Uint8Array)} tokens Array of tokens that provide the
* stream.
*/
function Stream(tokens) {
/** @type {!Array.<number>} */
this.tokens = [].slice.call(tokens);
}
Stream.prototype = {
/**
* @return {boolean} True if end-of-stream has been hit.
*/
endOfStream: function() {
return !this.tokens.length;
},
/**
* When a token is read from a stream, the first token in the
* stream must be returned and subsequently removed, and
* end-of-stream must be returned otherwise.
*
* @return {number} Get the next token from the stream, or
* end_of_stream.
*/
read: function() {
if (!this.tokens.length)
return end_of_stream;
return this.tokens.shift();
},
/**
* When one or more tokens are prepended to a stream, those tokens
* must be inserted, in given order, before the first token in the
* stream.
*
* @param {(number|!Array.<number>)} token The token(s) to prepend to the stream.
*/
prepend: function(token) {
if (Array.isArray(token)) {
var tokens = /**@type {!Array.<number>}*/(token);
while (tokens.length)
this.tokens.unshift(tokens.pop());
} else {
this.tokens.unshift(token);
}
},
/**
* When one or more tokens are pushed to a stream, those tokens
* must be inserted, in given order, after the last token in the
* stream.
*
* @param {(number|!Array.<number>)} token The tokens(s) to prepend to the stream.
*/
push: function(token) {
if (Array.isArray(token)) {
var tokens = /**@type {!Array.<number>}*/(token);
while (tokens.length)
this.tokens.push(tokens.shift());
} else {
this.tokens.push(token);
}
}
};
//
// 4. Encodings
//
// 4.1 Encoders and decoders
/** @const */
var finished = -1;
/**
* @param {boolean} fatal If true, decoding errors raise an exception.
* @param {number=} opt_code_point Override the standard fallback code point.
* @return {number} The code point to insert on a decoding error.
*/
function decoderError(fatal, opt_code_point) {
if (fatal)
throw TypeError('Decoder error');
return opt_code_point || 0xFFFD;
}
//
// 7. API
//
/** @const */ var DEFAULT_ENCODING = 'utf-8';
// 7.1 Interface TextDecoder
/**
* @constructor
* @param {string=} encoding The label of the encoding;
* defaults to 'utf-8'.
* @param {Object=} options
*/
function TextDecoder$1(encoding, options) {
if (!(this instanceof TextDecoder$1)) {
return new TextDecoder$1(encoding, options);
}
encoding = encoding !== undefined ? String(encoding).toLowerCase() : DEFAULT_ENCODING;
if (encoding !== DEFAULT_ENCODING) {
throw new Error('Encoding not supported. Only utf-8 is supported');
}
options = ToDictionary(options);
/** @private @type {boolean} */
this._streaming = false;
/** @private @type {boolean} */
this._BOMseen = false;
/** @private @type {?Decoder} */
this._decoder = null;
/** @private @type {boolean} */
this._fatal = Boolean(options['fatal']);
/** @private @type {boolean} */
this._ignoreBOM = Boolean(options['ignoreBOM']);
Object.defineProperty(this, 'encoding', {value: 'utf-8'});
Object.defineProperty(this, 'fatal', {value: this._fatal});
Object.defineProperty(this, 'ignoreBOM', {value: this._ignoreBOM});
}
TextDecoder$1.prototype = {
/**
* @param {ArrayBufferView=} input The buffer of bytes to decode.
* @param {Object=} options
* @return {string} The decoded string.
*/
decode: function decode(input, options) {
var bytes;
if (typeof input === 'object' && input instanceof ArrayBuffer) {
bytes = new Uint8Array(input);
} else if (typeof input === 'object' && 'buffer' in input &&
input.buffer instanceof ArrayBuffer) {
bytes = new Uint8Array(input.buffer,
input.byteOffset,
input.byteLength);
} else {
bytes = new Uint8Array(0);
}
options = ToDictionary(options);
if (!this._streaming) {
this._decoder = new UTF8Decoder({fatal: this._fatal});
this._BOMseen = false;
}
this._streaming = Boolean(options['stream']);
var input_stream = new Stream(bytes);
var code_points = [];
/** @type {?(number|!Array.<number>)} */
var result;
while (!input_stream.endOfStream()) {
result = this._decoder.handler(input_stream, input_stream.read());
if (result === finished)
break;
if (result === null)
continue;
if (Array.isArray(result))
code_points.push.apply(code_points, /**@type {!Array.<number>}*/(result));
else
code_points.push(result);
}
if (!this._streaming) {
do {
result = this._decoder.handler(input_stream, input_stream.read());
if (result === finished)
break;
if (result === null)
continue;
if (Array.isArray(result))
code_points.push.apply(code_points, /**@type {!Array.<number>}*/(result));
else
code_points.push(result);
} while (!input_stream.endOfStream());
this._decoder = null;
}
if (code_points.length) {
// If encoding is one of utf-8, utf-16be, and utf-16le, and
// ignore BOM flag and BOM seen flag are unset, run these
// subsubsteps:
if (['utf-8'].indexOf(this.encoding) !== -1 &&
!this._ignoreBOM && !this._BOMseen) {
// If token is U+FEFF, set BOM seen flag.
if (code_points[0] === 0xFEFF) {
this._BOMseen = true;
code_points.shift();
} else {
// Otherwise, if token is not end-of-stream, set BOM seen
// flag and append token to output.
this._BOMseen = true;
}
}
}
return codePointsToString(code_points);
}
};
// 7.2 Interface TextEncoder
/**
* @constructor
* @param {string=} encoding The label of the encoding;
* defaults to 'utf-8'.
* @param {Object=} options
*/
function TextEncoder$1(encoding, options) {
if (!(this instanceof TextEncoder$1))
return new TextEncoder$1(encoding, options);
encoding = encoding !== undefined ? String(encoding).toLowerCase() : DEFAULT_ENCODING;
if (encoding !== DEFAULT_ENCODING) {
throw new Error('Encoding not supported. Only utf-8 is supported');
}
options = ToDictionary(options);
/** @private @type {boolean} */
this._streaming = false;
/** @private @type {?Encoder} */
this._encoder = null;
/** @private @type {{fatal: boolean}} */
this._options = {fatal: Boolean(options['fatal'])};
Object.defineProperty(this, 'encoding', {value: 'utf-8'});
}
TextEncoder$1.prototype = {
/**
* @param {string=} opt_string The string to encode.
* @param {Object=} options
* @return {Uint8Array} Encoded bytes, as a Uint8Array.
*/
encode: function encode(opt_string, options) {
opt_string = opt_string ? String(opt_string) : '';
options = ToDictionary(options);
// NOTE: This option is nonstandard. None of the encodings
// permitted for encoding (i.e. UTF-8, UTF-16) are stateful,
// so streaming is not necessary.
if (!this._streaming)
this._encoder = new UTF8Encoder(this._options);
this._streaming = Boolean(options['stream']);
var bytes = [];
var input_stream = new Stream(stringToCodePoints(opt_string));
/** @type {?(number|!Array.<number>)} */
var result;
while (!input_stream.endOfStream()) {
result = this._encoder.handler(input_stream, input_stream.read());
if (result === finished)
break;
if (Array.isArray(result))
bytes.push.apply(bytes, /**@type {!Array.<number>}*/(result));
else
bytes.push(result);
}
if (!this._streaming) {
while (true) {
result = this._encoder.handler(input_stream, input_stream.read());
if (result === finished)
break;
if (Array.isArray(result))
bytes.push.apply(bytes, /**@type {!Array.<number>}*/(result));
else
bytes.push(result);
}
this._encoder = null;
}
return new Uint8Array(bytes);
}
};
//
// 8. The encoding
//
// 8.1 utf-8
/**
* @constructor
* @implements {Decoder}
* @param {{fatal: boolean}} options
*/
function UTF8Decoder(options) {
var fatal = options.fatal;
// utf-8's decoder's has an associated utf-8 code point, utf-8
// bytes seen, and utf-8 bytes needed (all initially 0), a utf-8
// lower boundary (initially 0x80), and a utf-8 upper boundary
// (initially 0xBF).
var /** @type {number} */ utf8_code_point = 0,
/** @type {number} */ utf8_bytes_seen = 0,
/** @type {number} */ utf8_bytes_needed = 0,
/** @type {number} */ utf8_lower_boundary = 0x80,
/** @type {number} */ utf8_upper_boundary = 0xBF;
/**
* @param {Stream} stream The stream of bytes being decoded.
* @param {number} bite The next byte read from the stream.
* @return {?(number|!Array.<number>)} The next code point(s)
* decoded, or null if not enough data exists in the input
* stream to decode a complete code point.
*/
this.handler = function(stream, bite) {
// 1. If byte is end-of-stream and utf-8 bytes needed is not 0,
// set utf-8 bytes needed to 0 and return error.
if (bite === end_of_stream && utf8_bytes_needed !== 0) {
utf8_bytes_needed = 0;
return decoderError(fatal);
}
// 2. If byte is end-of-stream, return finished.
if (bite === end_of_stream)
return finished;
// 3. If utf-8 bytes needed is 0, based on byte:
if (utf8_bytes_needed === 0) {
// 0x00 to 0x7F
if (inRange(bite, 0x00, 0x7F)) {
// Return a code point whose value is byte.
return bite;
}
// 0xC2 to 0xDF
if (inRange(bite, 0xC2, 0xDF)) {
// Set utf-8 bytes needed to 1 and utf-8 code point to byte
// 0xC0.
utf8_bytes_needed = 1;
utf8_code_point = bite - 0xC0;
}
// 0xE0 to 0xEF
else if (inRange(bite, 0xE0, 0xEF)) {
// 1. If byte is 0xE0, set utf-8 lower boundary to 0xA0.
if (bite === 0xE0)
utf8_lower_boundary = 0xA0;
// 2. If byte is 0xED, set utf-8 upper boundary to 0x9F.
if (bite === 0xED)
utf8_upper_boundary = 0x9F;
// 3. Set utf-8 bytes needed to 2 and utf-8 code point to
// byte 0xE0.
utf8_bytes_needed = 2;
utf8_code_point = bite - 0xE0;
}
// 0xF0 to 0xF4
else if (inRange(bite, 0xF0, 0xF4)) {
// 1. If byte is 0xF0, set utf-8 lower boundary to 0x90.
if (bite === 0xF0)
utf8_lower_boundary = 0x90;
// 2. If byte is 0xF4, set utf-8 upper boundary to 0x8F.
if (bite === 0xF4)
utf8_upper_boundary = 0x8F;
// 3. Set utf-8 bytes needed to 3 and utf-8 code point to
// byte 0xF0.
utf8_bytes_needed = 3;
utf8_code_point = bite - 0xF0;
}
// Otherwise
else {
// Return error.
return decoderError(fatal);
}
// Then (byte is in the range 0xC2 to 0xF4) set utf-8 code
// point to utf-8 code point << (6 × utf-8 bytes needed) and
// return continue.
utf8_code_point = utf8_code_point << (6 * utf8_bytes_needed);
return null;
}
// 4. If byte is not in the range utf-8 lower boundary to utf-8
// upper boundary, run these substeps:
if (!inRange(bite, utf8_lower_boundary, utf8_upper_boundary)) {
// 1. Set utf-8 code point, utf-8 bytes needed, and utf-8
// bytes seen to 0, set utf-8 lower boundary to 0x80, and set
// utf-8 upper boundary to 0xBF.
utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
utf8_lower_boundary = 0x80;
utf8_upper_boundary = 0xBF;
// 2. Prepend byte to stream.
stream.prepend(bite);
// 3. Return error.
return decoderError(fatal);
}
// 5. Set utf-8 lower boundary to 0x80 and utf-8 upper boundary
// to 0xBF.
utf8_lower_boundary = 0x80;
utf8_upper_boundary = 0xBF;
// 6. Increase utf-8 bytes seen by one and set utf-8 code point
// to utf-8 code point + (byte 0x80) << (6 × (utf-8 bytes
// needed utf-8 bytes seen)).
utf8_bytes_seen += 1;
utf8_code_point += (bite - 0x80) << (6 * (utf8_bytes_needed - utf8_bytes_seen));
// 7. If utf-8 bytes seen is not equal to utf-8 bytes needed,
// continue.
if (utf8_bytes_seen !== utf8_bytes_needed)
return null;
// 8. Let code point be utf-8 code point.
var code_point = utf8_code_point;
// 9. Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes
// seen to 0.
utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
// 10. Return a code point whose value is code point.
return code_point;
};
}
/**
* @constructor
* @implements {Encoder}
* @param {{fatal: boolean}} options
*/
function UTF8Encoder(options) {
var fatal = options.fatal;
/**
* @param {Stream} stream Input stream.
* @param {number} code_point Next code point read from the stream.
* @return {(number|!Array.<number>)} Byte(s) to emit.
*/
this.handler = function(stream, code_point) {
// 1. If code point is end-of-stream, return finished.
if (code_point === end_of_stream)
return finished;
// 2. If code point is in the range U+0000 to U+007F, return a
// byte whose value is code point.
if (inRange(code_point, 0x0000, 0x007f))
return code_point;
// 3. Set count and offset based on the range code point is in:
var count, offset;
// U+0080 to U+07FF: 1 and 0xC0
if (inRange(code_point, 0x0080, 0x07FF)) {
count = 1;
offset = 0xC0;
}
// U+0800 to U+FFFF: 2 and 0xE0
else if (inRange(code_point, 0x0800, 0xFFFF)) {
count = 2;
offset = 0xE0;
}
// U+10000 to U+10FFFF: 3 and 0xF0
else if (inRange(code_point, 0x10000, 0x10FFFF)) {
count = 3;
offset = 0xF0;
}
// 4.Let bytes be a byte sequence whose first byte is (code
// point >> (6 × count)) + offset.
var bytes = [(code_point >> (6 * count)) + offset];
// 5. Run these substeps while count is greater than 0:
while (count > 0) {
// 1. Set temp to code point >> (6 × (count 1)).
var temp = code_point >> (6 * (count - 1));
// 2. Append to bytes 0x80 | (temp & 0x3F).
bytes.push(0x80 | (temp & 0x3F));
// 3. Decrease count by one.
count -= 1;
}
// 6. Return bytes bytes, in order.
return bytes;
};
}
function getGlobal() {
if (typeof self !== 'undefined') return self;
if (typeof global !== 'undefined') return global;
throw new Error('No global found');
}
if (typeof TextDecoder !== 'function') {
getGlobal().TextDecoder = TextDecoder$1;
}
if (typeof TextEncoder !== 'function') {
getGlobal().TextEncoder = TextEncoder$1;
}
})();

View File

@@ -0,0 +1,49 @@
'use strict'
const fs = require('fs')
const SonicBoom = require('../')
const { file, runTests } = require('./helper')
runTests(buildTests)
function buildTests (test, sync) {
// Reset the umask for testing
process.umask(0o000)
test('destroy', (t) => {
t.plan(5)
const dest = file()
const fd = fs.openSync(dest, 'w')
const stream = new SonicBoom({ fd, sync })
t.ok(stream.write('hello world\n'))
stream.destroy()
t.throws(() => { stream.write('hello world\n') })
fs.readFile(dest, 'utf8', function (err, data) {
t.error(err)
t.equal(data, 'hello world\n')
})
stream.on('finish', () => {
t.fail('finish emitted')
})
stream.on('close', () => {
t.pass('close emitted')
})
})
test('destroy while opening', (t) => {
t.plan(1)
const dest = file()
const stream = new SonicBoom({ dest })
stream.destroy()
stream.on('close', () => {
t.pass('close emitted')
})
})
}

View File

@@ -0,0 +1,20 @@
/**
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
*
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
*
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
* @module
* @deprecated
*/
import { SHA224 as SHA224n, sha224 as sha224n, SHA256 as SHA256n, sha256 as sha256n, } from "./sha2.js";
/** @deprecated Use import from `noble/hashes/sha2` module */
export const SHA256 = SHA256n;
/** @deprecated Use import from `noble/hashes/sha2` module */
export const sha256 = sha256n;
/** @deprecated Use import from `noble/hashes/sha2` module */
export const SHA224 = SHA224n;
/** @deprecated Use import from `noble/hashes/sha2` module */
export const sha224 = sha224n;
//# sourceMappingURL=sha256.js.map

View File

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

View File

@@ -0,0 +1,223 @@
'use strict';
//
// Allowed token characters:
//
// '!', '#', '$', '%', '&', ''', '*', '+', '-',
// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'
//
// tokenChars[32] === 0 // ' '
// tokenChars[33] === 1 // '!'
// tokenChars[34] === 0 // '"'
// ...
//
// prettier-ignore
const tokenChars = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127
];
/**
* Adds an offer to the map of extension offers or a parameter to the map of
* parameters.
*
* @param {Object} dest The map of extension offers or parameters
* @param {String} name The extension or parameter name
* @param {(Object|Boolean|String)} elem The extension parameters or the
* parameter value
* @private
*/
function push(dest, name, elem) {
if (dest[name] === undefined) dest[name] = [elem];
else dest[name].push(elem);
}
/**
* Parses the `Sec-WebSocket-Extensions` header into an object.
*
* @param {String} header The field value of the header
* @return {Object} The parsed object
* @public
*/
function parse(header) {
const offers = Object.create(null);
if (header === undefined || header === '') return offers;
let params = Object.create(null);
let mustUnescape = false;
let isEscaping = false;
let inQuotes = false;
let extensionName;
let paramName;
let start = -1;
let end = -1;
let i = 0;
for (; i < header.length; i++) {
const code = header.charCodeAt(i);
if (extensionName === undefined) {
if (end === -1 && tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (code === 0x20 /* ' ' */ || code === 0x09 /* '\t' */) {
if (end === -1 && start !== -1) end = i;
} else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
if (start === -1) {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
if (end === -1) end = i;
const name = header.slice(start, end);
if (code === 0x2c) {
push(offers, name, params);
params = Object.create(null);
} else {
extensionName = name;
}
start = end = -1;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
} else if (paramName === undefined) {
if (end === -1 && tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (code === 0x20 || code === 0x09) {
if (end === -1 && start !== -1) end = i;
} else if (code === 0x3b || code === 0x2c) {
if (start === -1) {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
if (end === -1) end = i;
push(params, header.slice(start, end), true);
if (code === 0x2c) {
push(offers, extensionName, params);
params = Object.create(null);
extensionName = undefined;
}
start = end = -1;
} else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
paramName = header.slice(start, i);
start = end = -1;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
} else {
//
// The value of a quoted-string after unescaping must conform to the
// token ABNF, so only token characters are valid.
// Ref: https://tools.ietf.org/html/rfc6455#section-9.1
//
if (isEscaping) {
if (tokenChars[code] !== 1) {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
if (start === -1) start = i;
else if (!mustUnescape) mustUnescape = true;
isEscaping = false;
} else if (inQuotes) {
if (tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (code === 0x22 /* '"' */ && start !== -1) {
inQuotes = false;
end = i;
} else if (code === 0x5c /* '\' */) {
isEscaping = true;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
} else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {
inQuotes = true;
} else if (end === -1 && tokenChars[code] === 1) {
if (start === -1) start = i;
} else if (start !== -1 && (code === 0x20 || code === 0x09)) {
if (end === -1) end = i;
} else if (code === 0x3b || code === 0x2c) {
if (start === -1) {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
if (end === -1) end = i;
let value = header.slice(start, end);
if (mustUnescape) {
value = value.replace(/\\/g, '');
mustUnescape = false;
}
push(params, paramName, value);
if (code === 0x2c) {
push(offers, extensionName, params);
params = Object.create(null);
extensionName = undefined;
}
paramName = undefined;
start = end = -1;
} else {
throw new SyntaxError(`Unexpected character at index ${i}`);
}
}
}
if (start === -1 || inQuotes) {
throw new SyntaxError('Unexpected end of input');
}
if (end === -1) end = i;
const token = header.slice(start, end);
if (extensionName === undefined) {
push(offers, token, params);
} else {
if (paramName === undefined) {
push(params, token, true);
} else if (mustUnescape) {
push(params, paramName, token.replace(/\\/g, ''));
} else {
push(params, paramName, token);
}
push(offers, extensionName, params);
}
return offers;
}
/**
* Builds the `Sec-WebSocket-Extensions` header field value.
*
* @param {Object} extensions The map of extensions and parameters to format
* @return {String} A string representing the given object
* @public
*/
function format(extensions) {
return Object.keys(extensions)
.map((extension) => {
let configurations = extensions[extension];
if (!Array.isArray(configurations)) configurations = [configurations];
return configurations
.map((params) => {
return [extension]
.concat(
Object.keys(params).map((k) => {
let values = params[k];
if (!Array.isArray(values)) values = [values];
return values
.map((v) => (v === true ? k : `${k}=${v}`))
.join('; ');
})
)
.join('; ');
})
.join(', ');
})
.join(', ');
}
module.exports = { format, parse };

View File

@@ -0,0 +1 @@
{"version":3,"file":"symbolFlags.enum.d.ts","sourceRoot":"","sources":["../../src/enums/symbolFlags.enum.ts"],"names":[],"mappings":"AAEA,oBAAY,WAAW;IACnB,IAAI,IAAI;IACR,sBAAsB,IAAS;IAC/B,mBAAmB,IAAS;IAC5B,QAAQ,IAAS;IACjB,UAAU,IAAS;IACnB,QAAQ,KAAS;IACjB,KAAK,KAAS;IACd,SAAS,KAAS;IAClB,SAAS,MAAS;IAClB,WAAW,MAAS;IACpB,WAAW,MAAS;IACpB,eAAe,OAAU;IACzB,WAAW,OAAU;IACrB,aAAa,OAAU;IACvB,MAAM,OAAU;IAChB,WAAW,QAAU;IACrB,WAAW,QAAU;IACrB,WAAW,QAAU;IACrB,SAAS,SAAU;IACnB,aAAa,SAAU;IACvB,SAAS,SAAU;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;IACf,SAAS,UAAU;IACnB,UAAU,UAAU;IACpB,QAAQ,WAAU;IAClB,SAAS,WAAU;IACnB,UAAU,WAAU;IACpB,aAAa,YAAU;IACvB,mBAAmB,YAAU;IAC7B,mBAAmB,YAAU;IAC7B,YAAY,aAAU;IACtB,GAAG,YAAc;IACjB,IAAI,MAA0B;IAC9B,QAAQ,IAA+C;IACvD,KAAK,SAAgI;IACrI,IAAI,SAAkF;IACtF,SAAS,OAAuC;IAChD,MAAM,OAAgC;IACtC,QAAQ,QAA4B;IACpC,8BAA8B,SAAkC;IAChE,2BAA2B,SAAQ;IACnC,iBAAiB,SAAQ;IACzB,gBAAgB,QAAiC;IACjD,kBAAkB,SAAe;IACjC,gBAAgB,SAA4C;IAC5D,aAAa,SAAyD;IACtE,iBAAiB,SAA8B;IAC/C,mBAAmB,SAAgD;IACnE,iBAAiB,SAA8B;IAC/C,mBAAmB,SAA0D;IAC7E,uBAAuB,IAAO;IAC9B,cAAc,SAAkB;IAChC,mBAAmB,QAAoC;IACvD,mBAAmB,QAAoC;IACvD,gBAAgB,SAAoB;IACpC,qBAAqB,SAAwB;IAC7C,iBAAiB,SAAO;IACxB,aAAa,UAAQ;IACrB,YAAY,UAA8E;IAC1F,cAAc,MAAwC;IACtD,WAAW,MAAqC;IAChD,kBAAkB,QAAsB;IACxC,WAAW,SAA+B;IAC1C,6BAA6B,MAA+B;IAC5D,mCAAmC,OAAiC;IACpE,YAAY,UAAwE;IACpF,oBAAoB,OAA6D;CACpF"}

View File

@@ -0,0 +1,43 @@
import { expectType, expectError } from 'tsd'
import sjson from '..'
expectError(sjson.parse(null))
expectType<any>(sjson.parse('{"anything":0}'))
sjson.parse('"test"', null, { protoAction: 'remove' })
expectError(sjson.parse('"test"', null, { protoAction: 'incorrect' }))
sjson.parse('"test"', null, { constructorAction: 'ignore' })
expectError(sjson.parse('"test"', null, { constructorAction: 'incorrect' }))
expectError(sjson.parse('"test"', { constructorAction: 'incorrect' }))
sjson.parse('test', { constructorAction: 'remove' })
sjson.parse('test', { protoAction: 'ignore' })
sjson.parse('test', () => {}, { protoAction: 'ignore', constructorAction: 'remove' })
sjson.parse('"test"', null, { safe: true })
sjson.parse('"test"', { safe: true })
sjson.parse('test', () => {}, { safe: false })
sjson.parse('test', { protoAction: 'remove', safe: true })
expectError(sjson.parse('"test"', null, { safe: 'incorrect' }))
sjson.safeParse('"test"', null)
sjson.safeParse('"test"')
expectError(sjson.safeParse(null))
sjson.scan({}, { protoAction: 'remove' })
sjson.scan({}, { protoAction: 'ignore' })
sjson.scan({}, { constructorAction: 'error' })
sjson.scan({}, { constructorAction: 'ignore' })
sjson.scan([], {})
sjson.scan({}, { safe: true })
sjson.scan({}, { protoAction: 'remove', safe: false })
expectError(sjson.scan({}, { safe: 'incorrect' }))
declare const input: Buffer
sjson.parse(input)
sjson.safeParse(input)
sjson.parse('{"anything":0}', (key, value) => {
expectType<string>(key)
})
sjson.safeParse('{"anything":0}', (key, value) => {
expectType<string>(key)
})