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,75 @@
# strip-json-comments
> Strip comments from JSON. Lets you use comments in your JSON files!
This is now possible:
```js
{
// Rainbows
"unicorn": /* ❤ */ "cake"
}
```
It will replace single-line comments `//` and multi-line comments `/**/` with whitespace. This allows JSON error positions to remain as close as possible to the original source.
Also available as a [Gulp](https://github.com/sindresorhus/gulp-strip-json-comments)/[Grunt](https://github.com/sindresorhus/grunt-strip-json-comments)/[Broccoli](https://github.com/sindresorhus/broccoli-strip-json-comments) plugin.
## Install
```sh
npm install strip-json-comments
```
## Usage
```js
import stripJsonComments from 'strip-json-comments';
const json = `{
// Rainbows
"unicorn": /* ❤ */ "cake"
}`;
JSON.parse(stripJsonComments(json));
//=> {unicorn: 'cake'}
```
## API
### stripJsonComments(jsonString, options?)
#### jsonString
Type: `string`
Accepts a string with JSON and returns a string without comments.
#### options
Type: `object`
##### trailingCommas
Type: `boolean`\
Default: `false`
Strip trailing commas in addition to comments.
##### whitespace
Type: `boolean`\
Default: `true`
Replace comments and trailing commas with whitespace instead of stripping them entirely.
## Benchmark
```sh
npm run bench
```
## Related
- [strip-json-comments-cli](https://github.com/sindresorhus/strip-json-comments-cli) - CLI for this module
- [strip-css-comments](https://github.com/sindresorhus/strip-css-comments) - Strip comments from CSS

View File

@@ -0,0 +1,145 @@
// Type definitions for pino-std-serializers 2.4
// Definitions by: Connor Fitzgerald <https://github.com/connorjayfitzgerald>
// Igor Savin <https://github.com/kibertoad>
// TypeScript Version: 2.7
/// <reference types="node" />
import { IncomingMessage, ServerResponse } from 'http';
export interface SerializedError {
/**
* The name of the object's constructor.
*/
type: string;
/**
* The supplied error message.
*/
message: string;
/**
* The stack when the error was generated.
*/
stack: string;
/**
* Non-enumerable. The original Error object. This will not be included in the logged output.
* This is available for subsequent serializers to use.
*/
raw: Error;
/**
* `cause` is never included in the log output, if you need the `cause`, use {@link raw.cause}
*/
cause?: never;
/**
* Any other extra properties that have been attached to the object will also be present on the serialized object.
*/
[key: string]: any;
[key: number]: any;
}
/**
* Serializes an Error object. Does not serialize "err.cause" fields (will append the err.cause.message to err.message
* and err.cause.stack to err.stack)
*/
export function err(err: Error): SerializedError;
/**
* Serializes an Error object, including full serialization for any err.cause fields recursively.
*/
export function errWithCause(err: Error): SerializedError;
export interface SerializedRequest {
/**
* Defaults to `undefined`, unless there is an `id` property already attached to the `request` object or
* to the `request.info` object. Attach a synchronous function to the `request.id` that returns an
* identifier to have the value filled.
*/
id: string | undefined;
/**
* HTTP method.
*/
method: string;
/**
* Request pathname (as per req.url in core HTTP).
*/
url: string;
/**
* Reference to the `headers` object from the request (as per req.headers in core HTTP).
*/
headers: Record<string, string>;
remoteAddress: string;
remotePort: number;
params: Record<string, string>;
query: Record<string, string>;
/**
* Non-enumerable, i.e. will not be in the output, original request object. This is available for subsequent
* serializers to use. In cases where the `request` input already has a `raw` property this will
* replace the original `request.raw` property.
*/
raw: IncomingMessage;
}
/**
* Serializes a Request object.
*/
export function req(req: IncomingMessage): SerializedRequest;
/**
* Used internally by Pino for general request logging.
*/
export function mapHttpRequest(req: IncomingMessage): {
req: SerializedRequest
};
export interface SerializedResponse {
/**
* HTTP status code.
*/
statusCode: number;
/**
* The headers to be sent in the response.
*/
headers: Record<string, string>;
/**
* Non-enumerable, i.e. will not be in the output, original response object. This is available for subsequent serializers to use.
*/
raw: ServerResponse;
}
/**
* Serializes a Response object.
*/
export function res(res: ServerResponse): SerializedResponse;
/**
* Used internally by Pino for general response logging.
*/
export function mapHttpResponse(res: ServerResponse): {
res: SerializedResponse
};
export type CustomErrorSerializer = (err: SerializedError) => Record<string, any>;
/**
* A utility method for wrapping the default error serializer.
* This allows custom serializers to work with the already serialized object.
* The customSerializer accepts one parameter — the newly serialized error object — and returns the new (or updated) error object.
*/
export function wrapErrorSerializer(customSerializer: CustomErrorSerializer): (err: Error) => Record<string, any>;
export type CustomRequestSerializer = (req: SerializedRequest) => Record<string, any>;
/**
* A utility method for wrapping the default request serializer.
* This allows custom serializers to work with the already serialized object.
* The customSerializer accepts one parameter — the newly serialized request object — and returns the new (or updated) request object.
*/
export function wrapRequestSerializer(customSerializer: CustomRequestSerializer): (req: IncomingMessage) => Record<string, any>;
export type CustomResponseSerializer = (res: SerializedResponse) => Record<string, any>;
/**
* A utility method for wrapping the default response serializer.
* This allows custom serializers to work with the already serialized object.
* The customSerializer accepts one parameter — the newly serialized response object — and returns the new (or updated) response object.
*/
export function wrapResponseSerializer(customSerializer: CustomResponseSerializer): (res: ServerResponse) => Record<string, any>;

View File

@@ -0,0 +1 @@
{"version":3,"file":"commentDirectiveType.enum.d.ts","sourceRoot":"","sources":["../../src/enums/commentDirectiveType.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,oBAAoB;IAC5B,WAAW,IAAI;IACf,MAAM,IAAI;CACb"}

View File

@@ -0,0 +1,93 @@
declare module "colorette" {
type Color = (text: string | number) => string
interface Colorette {
reset: Color
bold: Color
dim: Color
italic: Color
underline: Color
inverse: Color
hidden: Color
strikethrough: Color
black: Color
red: Color
green: Color
yellow: Color
blue: Color
magenta: Color
cyan: Color
white: Color
gray: Color
bgBlack: Color
bgRed: Color
bgGreen: Color
bgYellow: Color
bgBlue: Color
bgMagenta: Color
bgCyan: Color
bgWhite: Color
blackBright: Color
redBright: Color
greenBright: Color
yellowBright: Color
blueBright: Color
magentaBright: Color
cyanBright: Color
whiteBright: Color
bgBlackBright: Color
bgRedBright: Color
bgGreenBright: Color
bgYellowBright: Color
bgBlueBright: Color
bgMagentaBright: Color
bgCyanBright: Color
bgWhiteBright: Color
}
const reset: Color
const bold: Color
const dim: Color
const italic: Color
const underline: Color
const inverse: Color
const hidden: Color
const strikethrough: Color
const black: Color
const red: Color
const green: Color
const yellow: Color
const blue: Color
const magenta: Color
const cyan: Color
const white: Color
const gray: Color
const bgBlack: Color
const bgRed: Color
const bgGreen: Color
const bgYellow: Color
const bgBlue: Color
const bgMagenta: Color
const bgCyan: Color
const bgWhite: Color
const blackBright: Color
const redBright: Color
const greenBright: Color
const yellowBright: Color
const blueBright: Color
const magentaBright: Color
const cyanBright: Color
const whiteBright: Color
const bgBlackBright: Color
const bgRedBright: Color
const bgGreenBright: Color
const bgYellowBright: Color
const bgBlueBright: Color
const bgMagentaBright: Color
const bgCyanBright: Color
const bgWhiteBright: Color
const isColorSupported: boolean
function createColors(options?: { useColor: boolean }): Colorette
}

View File

@@ -0,0 +1,126 @@
import type { $ZodStringFormats } from "../core/checks.js";
import type * as errors from "../core/errors.js";
import * as util from "../core/util.js";
const error: () => errors.$ZodErrorMap = () => {
const Sizable: Record<string, { unit: string; verb: string }> = {
string: { unit: "کاراکتر", verb: "داشته باشد" },
file: { unit: "بایت", verb: "داشته باشد" },
array: { unit: "آیتم", verb: "داشته باشد" },
set: { unit: "آیتم", verb: "داشته باشد" },
};
function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}
const FormatDictionary: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "ورودی",
email: "آدرس ایمیل",
url: "URL",
emoji: "ایموجی",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "تاریخ و زمان ایزو",
date: "تاریخ ایزو",
time: "زمان ایزو",
duration: "مدت زمان ایزو",
ipv4: "IPv4 آدرس",
ipv6: "IPv6 آدرس",
cidrv4: "IPv4 دامنه",
cidrv6: "IPv6 دامنه",
base64: "base64-encoded رشته",
base64url: "base64url-encoded رشته",
json_string: "JSON رشته",
e164: "E.164 عدد",
jwt: "JWT",
template_literal: "ورودی",
};
const TypeDictionary: {
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
} = {
nan: "NaN",
number: "عدد",
array: "آرایه",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `ورودی نامعتبر: می‌بایست instanceof ${issue.expected} می‌بود، ${received} دریافت شد`;
}
return `ورودی نامعتبر: می‌بایست ${expected} می‌بود، ${received} دریافت شد`;
}
case "invalid_value":
if (issue.values.length === 1) {
return `ورودی نامعتبر: می‌بایست ${util.stringifyPrimitive(issue.values[0])} می‌بود`;
}
return `گزینه نامعتبر: می‌بایست یکی از ${util.joinValues(issue.values, "|")} می‌بود`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing) {
return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} ${sizing.unit ?? "عنصر"} باشد`;
}
return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} باشد`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} ${sizing.unit} باشد`;
}
return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} باشد`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") {
return `رشته نامعتبر: باید با "${_issue.prefix}" شروع شود`;
}
if (_issue.format === "ends_with") {
return `رشته نامعتبر: باید با "${_issue.suffix}" تمام شود`;
}
if (_issue.format === "includes") {
return `رشته نامعتبر: باید شامل "${_issue.includes}" باشد`;
}
if (_issue.format === "regex") {
return `رشته نامعتبر: باید با الگوی ${_issue.pattern} مطابقت داشته باشد`;
}
return `${FormatDictionary[_issue.format] ?? issue.format} نامعتبر`;
}
case "not_multiple_of":
return `عدد نامعتبر: باید مضرب ${issue.divisor} باشد`;
case "unrecognized_keys":
return `کلید${issue.keys.length > 1 ? "های" : ""} ناشناس: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `کلید ناشناس در ${issue.origin}`;
case "invalid_union":
return `ورودی نامعتبر`;
case "invalid_element":
return `مقدار نامعتبر در ${issue.origin}`;
default:
return `ورودی نامعتبر`;
}
};
};
export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,91 @@
<p align="center">
<img src="https://github.com/thecodrr/fdir/raw/master/assets/fdir.gif" width="75%"/>
<h1 align="center">The Fastest Directory Crawler & Globber for NodeJS</h1>
<p align="center">
<a href="https://www.npmjs.com/package/fdir"><img src="https://img.shields.io/npm/v/fdir?style=for-the-badge"/></a>
<a href="https://www.npmjs.com/package/fdir"><img src="https://img.shields.io/npm/dw/fdir?style=for-the-badge"/></a>
<a href="https://codeclimate.com/github/thecodrr/fdir/maintainability"><img src="https://img.shields.io/codeclimate/maintainability-percentage/thecodrr/fdir?style=for-the-badge"/></a>
<a href="https://coveralls.io/github/thecodrr/fdir?branch=master"><img src="https://img.shields.io/coveralls/github/thecodrr/fdir?style=for-the-badge"/></a>
<a href="https://www.npmjs.com/package/fdir"><img src="https://img.shields.io/bundlephobia/minzip/fdir?style=for-the-badge"/></a>
<a href="https://www.producthunt.com/posts/fdir-every-millisecond-matters"><img src="https://img.shields.io/badge/ProductHunt-Upvote-red?style=for-the-badge&logo=product-hunt"/></a>
<a href="https://dev.to/thecodrr/how-i-wrote-the-fastest-directory-crawler-ever-3p9c"><img src="https://img.shields.io/badge/dev.to-Read%20Blog-black?style=for-the-badge&logo=dev.to"/></a>
<a href="./LICENSE"><img src="https://img.shields.io/github/license/thecodrr/fdir?style=for-the-badge"/></a>
</p>
</p>
⚡ **The Fastest:** Nothing similar (in the NodeJS world) beats `fdir` in speed. It can easily crawl a directory containing **1 million files in < 1 second.**
💡 **Stupidly Easy:** `fdir` uses expressive Builder pattern to build the crawler increasing code readability.
🤖 **Zero Dependencies\*:** `fdir` only uses NodeJS `fs` & `path` modules.
🕺 **Astonishingly Small:** < 2KB in size gzipped & minified.
🖮 **Hackable:** Extending `fdir` is extremely simple now that the new Builder API is here. Feel free to experiment around.
_\* `picomatch` must be installed manually by the user to support globbing._
## 🚄 Quickstart
### Installation
You can install using `npm`:
```sh
$ npm i fdir
```
or Yarn:
```sh
$ yarn add fdir
```
### Usage
```ts
import { fdir } from "fdir";
// create the builder
const api = new fdir().withFullPaths().crawl("path/to/dir");
// get all files in a directory synchronously
const files = api.sync();
// or asynchronously
api.withPromise().then((files) => {
// do something with the result here.
});
```
## Documentation:
Documentation for all methods is available [here](/documentation.md).
## 📊 Benchmarks:
Please check the benchmark against the latest version [here](/BENCHMARKS.md).
## 🙏Used by:
`fdir` is downloaded over 200k+ times a week by projects around the world. Here's a list of some notable projects using `fdir` in production:
> Note: if you think your project should be here, feel free to open an issue. Notable is anything with a considerable amount of GitHub stars.
1. [rollup/plugins](https://github.com/rollup/plugins)
2. [SuperchupuDev/tinyglobby](https://github.com/SuperchupuDev/tinyglobby)
3. [pulumi/pulumi](https://github.com/pulumi/pulumi)
4. [dotenvx/dotenvx](https://github.com/dotenvx/dotenvx)
5. [mdn/yari](https://github.com/mdn/yari)
6. [streetwriters/notesnook](https://github.com/streetwriters/notesnook)
7. [imba/imba](https://github.com/imba/imba)
8. [moroshko/react-scanner](https://github.com/moroshko/react-scanner)
9. [netlify/build](https://github.com/netlify/build)
10. [yassinedoghri/astro-i18next](https://github.com/yassinedoghri/astro-i18next)
11. [selfrefactor/rambda](https://github.com/selfrefactor/rambda)
12. [whyboris/Video-Hub-App](https://github.com/whyboris/Video-Hub-App)
## 🦮 LICENSE
Copyright &copy; 2024 Abdullah Atta under MIT. [Read full text here.](https://github.com/thecodrr/fdir/raw/master/LICENSE)

View File

@@ -0,0 +1,31 @@
{
"name": "tr46",
"version": "0.0.3",
"description": "An implementation of the Unicode TR46 spec",
"main": "index.js",
"scripts": {
"test": "mocha",
"pretest": "node scripts/getLatestUnicodeTests.js",
"prepublish": "node scripts/generateMappingTable.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Sebmaster/tr46.js.git"
},
"keywords": [
"unicode",
"tr46",
"url",
"whatwg"
],
"author": "Sebastian Mayr <npm@smayr.name>",
"license": "MIT",
"bugs": {
"url": "https://github.com/Sebmaster/tr46.js/issues"
},
"homepage": "https://github.com/Sebmaster/tr46.js#readme",
"devDependencies": {
"mocha": "^2.2.5",
"request": "^2.57.0"
}
}

View File

@@ -0,0 +1 @@
var i=Object.defineProperty;var o=(e,t)=>i(e,"name",{value:t,configurable:!0});const n=o((e,t)=>{const s=e[0]-t[0];if(s===0){const r=e[1]-t[1];return r===0?e[2]>=t[2]:r>0}return s>0},"isVersionGreaterOrEqual"),a=process.versions.node.split(".").map(Number),c=o((e,t=a)=>{for(let s=0;s<e.length;s+=1){const r=e[s];if(s===e.length-1||t[0]===r[0])return n(t,r)}return!1},"isFeatureSupported"),u=[[18,19,0],[20,6,0]],l=[[22,22,3],[24,11,1],[25,1,0],[26,0,0]],m=[[18,19,0],[20,10,0],[21,0,0]],f=[[21,0,0]],p=[[20,11,0],[21,3,0]],d=[[20,11,0],[21,2,0]],R=[[20,19,0],[22,12,0],[23,0,0]];export{u as a,m as b,d as c,p as e,c as i,l as m,R as r,f as t};

View File

@@ -0,0 +1,16 @@
"use strict";
module.exports = function () {
return `
ESLint couldn't find an eslint.config.(js|mjs|cjs) file.
From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:
https://eslint.org/docs/latest/use/configure/migration-guide
If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.
`.trimStart();
};

View File

@@ -0,0 +1,24 @@
const { Argument } = require('./lib/argument.js');
const { Command } = require('./lib/command.js');
const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
const { Help } = require('./lib/help.js');
const { Option } = require('./lib/option.js');
exports.program = new Command();
exports.createCommand = (name) => new Command(name);
exports.createOption = (flags, description) => new Option(flags, description);
exports.createArgument = (name, description) => new Argument(name, description);
/**
* Expose classes
*/
exports.Command = Command;
exports.Option = Option;
exports.Argument = Argument;
exports.Help = Help;
exports.CommanderError = CommanderError;
exports.InvalidArgumentError = InvalidArgumentError;
exports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated

View File

@@ -0,0 +1,8 @@
import arrayWithoutHoles from "./arrayWithoutHoles.js";
import iterableToArray from "./iterableToArray.js";
import unsupportedIterableToArray from "./unsupportedIterableToArray.js";
import nonIterableSpread from "./nonIterableSpread.js";
function _toConsumableArray(r) {
return arrayWithoutHoles(r) || iterableToArray(r) || unsupportedIterableToArray(r) || nonIterableSpread();
}
export { _toConsumableArray as default };

View File

@@ -0,0 +1,109 @@
import * as util from "../core/util.js";
const error = () => {
const Sizable = {
string: { unit: "字符", verb: "包含" },
file: { unit: "字节", verb: "包含" },
array: { unit: "项", verb: "包含" },
set: { unit: "项", verb: "包含" },
};
function getSizing(origin) {
return Sizable[origin] ?? null;
}
const FormatDictionary = {
regex: "输入",
email: "电子邮件",
url: "URL",
emoji: "表情符号",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "ISO日期时间",
date: "ISO日期",
time: "ISO时间",
duration: "ISO时长",
ipv4: "IPv4地址",
ipv6: "IPv6地址",
cidrv4: "IPv4网段",
cidrv6: "IPv6网段",
base64: "base64编码字符串",
base64url: "base64url编码字符串",
json_string: "JSON字符串",
e164: "E.164号码",
jwt: "JWT",
template_literal: "输入",
};
const TypeDictionary = {
nan: "NaN",
number: "数字",
array: "数组",
null: "空值(null)",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `无效输入:期望 instanceof ${issue.expected},实际接收 ${received}`;
}
return `无效输入:期望 ${expected},实际接收 ${received}`;
}
case "invalid_value":
if (issue.values.length === 1)
return `无效输入:期望 ${util.stringifyPrimitive(issue.values[0])}`;
return `无效选项:期望以下之一 ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing)
return `数值过大:期望 ${issue.origin ?? "值"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "个元素"}`;
return `数值过大:期望 ${issue.origin ?? "值"} ${adj}${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `数值过小:期望 ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
}
return `数值过小:期望 ${issue.origin} ${adj}${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue;
if (_issue.format === "starts_with")
return `无效字符串:必须以 "${_issue.prefix}" 开头`;
if (_issue.format === "ends_with")
return `无效字符串:必须以 "${_issue.suffix}" 结尾`;
if (_issue.format === "includes")
return `无效字符串:必须包含 "${_issue.includes}"`;
if (_issue.format === "regex")
return `无效字符串:必须满足正则表达式 ${_issue.pattern}`;
return `无效${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `无效数字:必须是 ${issue.divisor} 的倍数`;
case "unrecognized_keys":
return `出现未知的键(key): ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `${issue.origin} 中的键(key)无效`;
case "invalid_union":
return "无效输入";
case "invalid_element":
return `${issue.origin} 中包含无效值(value)`;
default:
return `无效输入`;
}
};
};
export default function () {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,5 @@
import arrayLikeToArray from "./arrayLikeToArray.js";
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) return arrayLikeToArray(r);
}
export { _arrayWithoutHoles as default };

View File

@@ -0,0 +1,41 @@
/**
* @fileoverview Define the cursor which ignores the first few tokens.
* @author Toru Nagashima
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const DecorativeCursor = require("./decorative-cursor");
//------------------------------------------------------------------------------
// Exports
//------------------------------------------------------------------------------
/**
* The decorative cursor which ignores the first few tokens.
*/
module.exports = class SkipCursor extends DecorativeCursor {
/**
* Initializes this cursor.
* @param {Cursor} cursor The cursor to be decorated.
* @param {number} count The count of tokens this cursor skips.
*/
constructor(cursor, count) {
super(cursor);
this.count = count;
}
/** @inheritdoc */
moveNext() {
while (this.count > 0) {
this.count -= 1;
if (!super.moveNext()) {
return false;
}
}
return super.moveNext();
}
};

View File

@@ -0,0 +1,467 @@
import { ft as __commonJSMin, pt as __require } from "./node.js";
import { t as require_lib } from "./lib.js";
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/format-import-prelude.js
var require_format_import_prelude = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = function formatImportPrelude(layer, media, supports) {
const parts = [];
if (typeof layer !== "undefined") {
let layerParams = "layer";
if (layer) layerParams = `layer(${layer})`;
parts.push(layerParams);
}
if (typeof supports !== "undefined") parts.push(`supports(${supports})`);
if (typeof media !== "undefined") parts.push(media);
return parts.join(" ");
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/base64-encoded-import.js
var require_base64_encoded_import = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const formatImportPrelude = require_format_import_prelude();
module.exports = function base64EncodedConditionalImport(prelude, conditions) {
if (!conditions?.length) return prelude;
conditions.reverse();
const first = conditions.pop();
let params = `${prelude} ${formatImportPrelude(first.layer, first.media, first.supports)}`;
for (const condition of conditions) params = `'data:text/css;base64,${Buffer.from(`@import ${params}`).toString("base64")}' ${formatImportPrelude(condition.layer, condition.media, condition.supports)}`;
return params;
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/apply-conditions.js
var require_apply_conditions = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const base64EncodedConditionalImport = require_base64_encoded_import();
module.exports = function applyConditions(bundle, atRule) {
const firstImportStatementIndex = bundle.findIndex((stmt) => stmt.type === "import");
const lastImportStatementIndex = bundle.findLastIndex((stmt) => stmt.type === "import");
bundle.forEach((stmt, index) => {
if (stmt.type === "charset" || stmt.type === "warning") return;
if (stmt.type === "layer" && (index < lastImportStatementIndex && stmt.conditions?.length || index > firstImportStatementIndex && index < lastImportStatementIndex)) {
stmt.type = "import";
stmt.node = stmt.node.clone({
name: "import",
params: base64EncodedConditionalImport(`'data:text/css;base64,${Buffer.from(stmt.node.toString()).toString("base64")}'`, stmt.conditions)
});
return;
}
if (!stmt.conditions?.length) return;
if (stmt.type === "import") {
stmt.node.params = base64EncodedConditionalImport(stmt.fullUri, stmt.conditions);
return;
}
let nodes;
let parent;
if (stmt.type === "layer") {
nodes = [stmt.node];
parent = stmt.node.parent;
} else {
nodes = stmt.nodes;
parent = nodes[0].parent;
}
const atRules = [];
for (const condition of stmt.conditions) {
if (typeof condition.media !== "undefined") {
const mediaNode = atRule({
name: "media",
params: condition.media,
source: parent.source
});
atRules.push(mediaNode);
}
if (typeof condition.supports !== "undefined") {
const supportsNode = atRule({
name: "supports",
params: `(${condition.supports})`,
source: parent.source
});
atRules.push(supportsNode);
}
if (typeof condition.layer !== "undefined") {
const layerNode = atRule({
name: "layer",
params: condition.layer,
source: parent.source
});
atRules.push(layerNode);
}
}
const outerAtRule = atRules.shift();
const innerAtRule = atRules.reduce((previous, next) => {
previous.append(next);
return next;
}, outerAtRule);
parent.insertBefore(nodes[0], outerAtRule);
nodes.forEach((node) => {
node.parent = void 0;
});
nodes[0].raws.before = nodes[0].raws.before || "\n";
innerAtRule.append(nodes);
stmt.type = "nodes";
stmt.nodes = [outerAtRule];
delete stmt.node;
});
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/apply-raws.js
var require_apply_raws = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = function applyRaws(bundle) {
bundle.forEach((stmt, index) => {
if (index === 0) return;
if (stmt.parent) {
const { before } = stmt.parent.node.raws;
if (stmt.type === "nodes") stmt.nodes[0].raws.before = before;
else stmt.node.raws.before = before;
} else if (stmt.type === "nodes") stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n";
});
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/apply-styles.js
var require_apply_styles = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = function applyStyles(bundle, styles) {
styles.nodes = [];
bundle.forEach((stmt) => {
if ([
"charset",
"import",
"layer"
].includes(stmt.type)) {
stmt.node.parent = void 0;
styles.append(stmt.node);
} else if (stmt.type === "nodes") stmt.nodes.forEach((node) => {
node.parent = void 0;
styles.append(node);
});
});
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/data-url.js
var require_data_url = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const anyDataURLRegexp = /^data:text\/css(?:;(base64|plain))?,/i;
const base64DataURLRegexp = /^data:text\/css;base64,/i;
const plainDataURLRegexp = /^data:text\/css;plain,/i;
function isValid(url) {
return anyDataURLRegexp.test(url);
}
function contents(url) {
if (base64DataURLRegexp.test(url)) return Buffer.from(url.slice(21), "base64").toString();
if (plainDataURLRegexp.test(url)) return decodeURIComponent(url.slice(20));
return decodeURIComponent(url.slice(14));
}
module.exports = {
isValid,
contents
};
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/parse-statements.js
var require_parse_statements = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const valueParser = require_lib();
const { stringify } = valueParser;
module.exports = function parseStatements(result, styles, conditions, from) {
const statements = [];
let nodes = [];
let encounteredNonImportNodes = false;
styles.each((node) => {
let stmt;
if (node.type === "atrule") {
if (node.name === "import") stmt = parseImport(result, node, conditions, from);
else if (node.name === "charset") stmt = parseCharset(result, node, conditions, from);
else if (node.name === "layer" && !encounteredNonImportNodes && !node.nodes) stmt = parseLayer(result, node, conditions, from);
} else if (node.type !== "comment") encounteredNonImportNodes = true;
if (stmt) {
if (nodes.length) {
statements.push({
type: "nodes",
nodes,
conditions: [...conditions],
from
});
nodes = [];
}
statements.push(stmt);
} else nodes.push(node);
});
if (nodes.length) statements.push({
type: "nodes",
nodes,
conditions: [...conditions],
from
});
return statements;
};
function parseCharset(result, atRule, conditions, from) {
if (atRule.prev()) return result.warn("@charset must precede all other statements", { node: atRule });
return {
type: "charset",
node: atRule,
conditions: [...conditions],
from
};
}
function parseImport(result, atRule, conditions, from) {
let prev = atRule.prev();
if (prev) do {
if (prev.type === "comment" || prev.type === "atrule" && prev.name === "import") {
prev = prev.prev();
continue;
}
break;
} while (prev);
if (prev) do {
if (prev.type === "comment" || prev.type === "atrule" && (prev.name === "charset" || prev.name === "layer" && !prev.nodes)) {
prev = prev.prev();
continue;
}
return result.warn("@import must precede all other statements (besides @charset or empty @layer)", { node: atRule });
} while (prev);
if (atRule.nodes) return result.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.", { node: atRule });
const params = valueParser(atRule.params).nodes;
const stmt = {
type: "import",
uri: "",
fullUri: "",
node: atRule,
conditions: [...conditions],
from
};
let layer;
let media;
let supports;
for (let i = 0; i < params.length; i++) {
const node = params[i];
if (node.type === "space" || node.type === "comment") continue;
if (node.type === "string") {
if (stmt.uri) return result.warn(`Multiple url's in '${atRule.toString()}'`, { node: atRule });
if (!node.value) return result.warn(`Unable to find uri in '${atRule.toString()}'`, { node: atRule });
stmt.uri = node.value;
stmt.fullUri = stringify(node);
continue;
}
if (node.type === "function" && /^url$/i.test(node.value)) {
if (stmt.uri) return result.warn(`Multiple url's in '${atRule.toString()}'`, { node: atRule });
if (!node.nodes?.[0]?.value) return result.warn(`Unable to find uri in '${atRule.toString()}'`, { node: atRule });
stmt.uri = node.nodes[0].value;
stmt.fullUri = stringify(node);
continue;
}
if (!stmt.uri) return result.warn(`Unable to find uri in '${atRule.toString()}'`, { node: atRule });
if ((node.type === "word" || node.type === "function") && /^layer$/i.test(node.value)) {
if (typeof layer !== "undefined") return result.warn(`Multiple layers in '${atRule.toString()}'`, { node: atRule });
if (typeof supports !== "undefined") return result.warn(`layers must be defined before support conditions in '${atRule.toString()}'`, { node: atRule });
if (node.nodes) layer = stringify(node.nodes);
else layer = "";
continue;
}
if (node.type === "function" && /^supports$/i.test(node.value)) {
if (typeof supports !== "undefined") return result.warn(`Multiple support conditions in '${atRule.toString()}'`, { node: atRule });
supports = stringify(node.nodes);
continue;
}
media = stringify(params.slice(i));
break;
}
if (!stmt.uri) return result.warn(`Unable to find uri in '${atRule.toString()}'`, { node: atRule });
if (typeof media !== "undefined" || typeof layer !== "undefined" || typeof supports !== "undefined") stmt.conditions.push({
layer,
media,
supports
});
return stmt;
}
function parseLayer(result, atRule, conditions, from) {
return {
type: "layer",
node: atRule,
conditions: [...conditions],
from
};
}
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/process-content.js
var require_process_content = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const path$2 = __require("path");
let sugarss;
module.exports = function processContent(result, content, filename, options, postcss) {
const { plugins } = options;
const ext = path$2.extname(filename);
const parserList = [];
if (ext === ".sss") {
if (!sugarss)
/* c8 ignore next 3 */
try {
sugarss = __require("sugarss");
} catch {}
if (sugarss) return runPostcss(postcss, content, filename, plugins, [sugarss]);
}
if (result.opts.syntax?.parse) parserList.push(result.opts.syntax.parse);
if (result.opts.parser) parserList.push(result.opts.parser);
parserList.push(null);
return runPostcss(postcss, content, filename, plugins, parserList);
};
function runPostcss(postcss, content, filename, plugins, parsers, index) {
if (!index) index = 0;
return postcss(plugins).process(content, {
from: filename,
parser: parsers[index]
}).catch((err) => {
index++;
if (index === parsers.length) throw err;
return runPostcss(postcss, content, filename, plugins, parsers, index);
});
}
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/lib/parse-styles.js
var require_parse_styles = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const path$1 = __require("path");
const dataURL = require_data_url();
const parseStatements = require_parse_statements();
const processContent = require_process_content();
const resolveId = (id) => id;
const formatImportPrelude = require_format_import_prelude();
async function parseStyles(result, styles, options, state, conditions, from, postcss) {
const statements = parseStatements(result, styles, conditions, from);
for (const stmt of statements) {
if (stmt.type !== "import" || !isProcessableURL(stmt.uri)) continue;
if (options.filter && !options.filter(stmt.uri)) continue;
await resolveImportId(result, stmt, options, state, postcss);
}
let charset;
const beforeBundle = [];
const bundle = [];
function handleCharset(stmt) {
if (!charset) charset = stmt;
else if (stmt.node.params.toLowerCase() !== charset.node.params.toLowerCase()) throw stmt.node.error(`Incompatible @charset statements:
${stmt.node.params} specified in ${stmt.node.source.input.file}
${charset.node.params} specified in ${charset.node.source.input.file}`);
}
statements.forEach((stmt) => {
if (stmt.type === "charset") handleCharset(stmt);
else if (stmt.type === "import") if (stmt.children) stmt.children.forEach((child, index) => {
if (child.type === "import") beforeBundle.push(child);
else if (child.type === "layer") beforeBundle.push(child);
else if (child.type === "charset") handleCharset(child);
else bundle.push(child);
if (index === 0) child.parent = stmt;
});
else beforeBundle.push(stmt);
else if (stmt.type === "layer") beforeBundle.push(stmt);
else if (stmt.type === "nodes") bundle.push(stmt);
});
return charset ? [charset, ...beforeBundle.concat(bundle)] : beforeBundle.concat(bundle);
}
async function resolveImportId(result, stmt, options, state, postcss) {
if (dataURL.isValid(stmt.uri)) {
stmt.children = await loadImportContent(result, stmt, stmt.uri, options, state, postcss);
return;
} else if (dataURL.isValid(stmt.from.slice(-1))) throw stmt.node.error(`Unable to import '${stmt.uri}' from a stylesheet that is embedded in a data url`);
const atRule = stmt.node;
let sourceFile;
if (atRule.source?.input?.file) sourceFile = atRule.source.input.file;
const base = sourceFile ? path$1.dirname(atRule.source.input.file) : options.root;
const paths = [await options.resolve(stmt.uri, base, options, atRule)].flat();
const resolved = await Promise.all(paths.map((file) => {
return !path$1.isAbsolute(file) ? resolveId(file, base, options, atRule) : file;
}));
resolved.forEach((file) => {
result.messages.push({
type: "dependency",
plugin: "postcss-import",
file,
parent: sourceFile
});
});
stmt.children = (await Promise.all(resolved.map((file) => {
return loadImportContent(result, stmt, file, options, state, postcss);
}))).flat().filter((x) => !!x);
}
async function loadImportContent(result, stmt, filename, options, state, postcss) {
const atRule = stmt.node;
const { conditions, from } = stmt;
const stmtDuplicateCheckKey = conditions.map((condition) => formatImportPrelude(condition.layer, condition.media, condition.supports)).join(":");
if (options.skipDuplicates) {
if (state.importedFiles[filename]?.[stmtDuplicateCheckKey]) return;
if (!state.importedFiles[filename]) state.importedFiles[filename] = {};
state.importedFiles[filename][stmtDuplicateCheckKey] = true;
}
if (from.includes(filename)) return;
const content = await options.load(filename, options);
if (content.trim() === "" && options.warnOnEmpty) {
result.warn(`${filename} is empty`, { node: atRule });
return;
}
if (options.skipDuplicates && state.hashFiles[content]?.[stmtDuplicateCheckKey]) return;
const importedResult = await processContent(result, content, filename, options, postcss);
const styles = importedResult.root;
result.messages = result.messages.concat(importedResult.messages);
if (options.skipDuplicates) {
if (!styles.some((child) => {
return child.type === "atrule" && child.name === "import";
})) {
if (!state.hashFiles[content]) state.hashFiles[content] = {};
state.hashFiles[content][stmtDuplicateCheckKey] = true;
}
}
return parseStyles(result, styles, options, state, conditions, [...from, filename], postcss);
}
function isProcessableURL(uri) {
if (/^(?:[a-z]+:)?\/\//i.test(uri)) return false;
try {
if (new URL(uri, "https://example.com").search) return false;
} catch {}
return true;
}
module.exports = parseStyles;
}));
//#endregion
//#region ../../node_modules/.pnpm/postcss-import@16.1.1_postcss@8.5.25/node_modules/postcss-import/index.js
var require_postcss_import = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const path = __require("path");
const applyConditions = require_apply_conditions();
const applyRaws = require_apply_raws();
const applyStyles = require_apply_styles();
const loadContent = () => "";
const parseStyles = require_parse_styles();
const resolveId = (id) => id;
function AtImport(options) {
options = {
root: process.cwd(),
path: [],
skipDuplicates: true,
resolve: resolveId,
load: loadContent,
plugins: [],
addModulesDirectories: [],
warnOnEmpty: true,
...options
};
options.root = path.resolve(options.root);
if (typeof options.path === "string") options.path = [options.path];
if (!Array.isArray(options.path)) options.path = [];
options.path = options.path.map((p) => path.resolve(options.root, p));
return {
postcssPlugin: "postcss-import",
async Once(styles, { result, atRule, postcss }) {
const state = {
importedFiles: {},
hashFiles: {}
};
if (styles.source?.input?.file) state.importedFiles[styles.source.input.file] = {};
if (options.plugins && !Array.isArray(options.plugins)) throw new Error("plugins option must be an array");
const bundle = await parseStyles(result, styles, options, state, [], [], postcss);
applyRaws(bundle);
applyConditions(bundle, atRule);
applyStyles(bundle, styles);
}
};
}
AtImport.postcss = true;
module.exports = AtImport;
}));
//#endregion
export default require_postcss_import();
export {};

View File

@@ -0,0 +1,175 @@
/*
Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
Copyright (C) 2013 Alex Seville <hi@alexanderseville.com>
Copyright (C) 2014 Thiago de Arruda <tpadilha84@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Escope (<a href="http://github.com/estools/escope">escope</a>) is an <a
* href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript</a>
* scope analyzer extracted from the <a
* href="http://github.com/estools/esmangle">esmangle project</a/>.
* <p>
* <em>escope</em> finds lexical scopes in a source program, i.e. areas of that
* program where different occurrences of the same identifier refer to the same
* variable. With each scope the contained variables are collected, and each
* identifier reference in code is linked to its corresponding variable (if
* possible).
* <p>
* <em>escope</em> works on a syntax tree of the parsed source code which has
* to adhere to the <a
* href="https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API">
* Mozilla Parser API</a>. E.g. <a href="https://github.com/eslint/espree">espree</a> is a parser
* that produces such syntax trees.
* <p>
* The main interface is the {@link analyze} function.
* @module escope
*/
import { assert } from "./assert.js";
import ScopeManager from "./scope-manager.js";
import Referencer from "./referencer.js";
import Reference from "./reference.js";
import Variable from "./variable.js";
/** @import ESTree from "estree" */
/**
* Set the default options
* @returns {Object} options
*/
function defaultOptions() {
return {
optimistic: false,
nodejsScope: false,
impliedStrict: false,
sourceType: "script", // one of ['script', 'module', 'commonjs']
ecmaVersion: 5,
childVisitorKeys: null,
fallback: "iteration",
};
}
/**
* Preform deep update on option object
* @param {Record<string, unknown>} target Options
* @param {Record<string, unknown>} override Updates
* @returns {Record<string, unknown>} Updated options
*/
function updateDeeply(target, override) {
/**
* Is hash object
* @param {Object} value Test value
* @returns {value is Record<string, unknown>} Result
*/
function isHashObject(value) {
return (
typeof value === "object" &&
value instanceof Object &&
!(value instanceof Array) &&
!(value instanceof RegExp)
);
}
for (const key in override) {
if (Object.hasOwn(override, key)) {
const val = override[key];
if (isHashObject(val)) {
if (isHashObject(target[key])) {
updateDeeply(target[key], val);
} else {
target[key] = updateDeeply({}, val);
}
} else {
target[key] = val;
}
}
}
return target;
}
/**
* Main interface function. Takes an Espree syntax tree and returns the
* analyzed scopes.
* @function analyze
* @param {ESTree.Program} tree Abstract Syntax Tree
* @param {Object} providedOptions Options that tailor the scope analysis
* @param {boolean} [providedOptions.optimistic=false] the optimistic flag
* @param {boolean} [providedOptions.ignoreEval=false] whether to check 'eval()' calls
* @param {boolean} [providedOptions.nodejsScope=false] whether the whole
* script is executed under node.js environment. When enabled, escope adds
* a function scope immediately following the global scope.
* @param {boolean} [providedOptions.impliedStrict=false] implied strict mode
* (if ecmaVersion >= 5).
* @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
* @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
* @param {boolean} [providedOptions.jsx=false] support JSX references
* @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
* @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
* @returns {ScopeManager} ScopeManager
*/
function analyze(tree, providedOptions) {
const options = updateDeeply(defaultOptions(), providedOptions);
const scopeManager = new ScopeManager(options);
const referencer = new Referencer(options, scopeManager);
referencer.visit(tree);
assert(
scopeManager.__currentScope === null,
"currentScope should be null.",
);
return scopeManager;
}
/** @name module:escope.version */
export const version = "9.1.2"; // x-release-please-version
export {
/** @name module:escope.Reference */
Reference,
/** @name module:escope.Variable */
Variable,
/** @name module:escope.ScopeManager */
ScopeManager,
/** @name module:escope.Referencer */
Referencer,
analyze,
};
/** @name module:escope.Definition */
export { Definition } from "./definition.js";
/** @name module:escope.PatternVisitor */
export { default as PatternVisitor } from "./pattern-visitor.js";
/** @name module:escope.Scope */
export { Scope } from "./scope.js";
/* vim: set sw=4 ts=4 et tw=80 : */

View File

@@ -0,0 +1,94 @@
'use strict';
const {Readable} = require('stream');
class FromIterable extends Readable {
constructor(options) {
super(Object.assign({}, options, {objectMode: true}));
this._iterable = null;
this._next = null;
if (options) {
'iterable' in options && (this._iterable = options.iterable);
}
!this._iterable && (this._read = this._readStop);
}
_read() {
if (Symbol.asyncIterator && typeof this._iterable[Symbol.asyncIterator] == 'function') {
this._next = this._iterable[Symbol.asyncIterator]();
this._iterable = null;
this._read = this._readNext;
this._readNext();
return;
}
if (Symbol.iterator && typeof this._iterable[Symbol.iterator] == 'function') {
this._next = this._iterable[Symbol.iterator]();
this._iterable = null;
this._read = this._readNext;
this._readNext();
return;
}
if (typeof this._iterable.next == 'function') {
this._next = this._iterable;
this._iterable = null;
this._read = this._readNext;
this._readNext();
return;
}
const result = this._iterable();
this._iterable = null;
if (result && typeof result.then == 'function') {
result.then(value => this.push(value), error => this.emit('error', error));
this._read = this._readStop;
return;
}
if (result && typeof result.next == 'function') {
this._next = result;
this._read = this._readNext;
this._readNext();
return;
}
this.push(result);
this._read = this._readStop;
}
_readNext() {
for (;;) {
const result = this._next.next();
if (result && typeof result.then == 'function') {
result.then(
value => {
if (value.done || value.value === null) {
this.push(null);
this._next = null;
this._read = this._readStop;
} else {
this.push(value.value);
}
},
error => this.emit('error', error)
);
break;
}
if (result.done || result.value === null) {
this.push(null);
this._next = null;
this._read = this._readStop;
break;
}
if (!this.push(result.value)) break;
}
}
_readStop() {
this.push(null);
}
static make(iterable) {
return new FromIterable(typeof iterable == 'object' && iterable.iterable ? iterable : {iterable});
}
}
FromIterable.fromIterable = FromIterable.make;
FromIterable.make.Constructor = FromIterable;
module.exports = FromIterable;

View File

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

View File

@@ -0,0 +1,42 @@
import { merge, subexp } from "./util";
export function buildExps(isIRI) {
const ALPHA$$ = "[A-Za-z]", CR$ = "[\\x0D]", DIGIT$$ = "[0-9]", DQUOTE$$ = "[\\x22]", HEXDIG$$ = merge(DIGIT$$, "[A-Fa-f]"), //case-insensitive
LF$$ = "[\\x0A]", SP$$ = "[\\x20]", PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)), //expanded
GEN_DELIMS$$ = "[\\:\\/\\?\\#\\[\\]\\@]", SUB_DELIMS$$ = "[\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=]", RESERVED$$ = merge(GEN_DELIMS$$, SUB_DELIMS$$), UCSCHAR$$ = isIRI ? "[\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]" : "[]", //subset, excludes bidi control characters
IPRIVATE$$ = isIRI ? "[\\uE000-\\uF8FF]" : "[]", //subset
UNRESERVED$$ = merge(ALPHA$$, DIGIT$$, "[\\-\\.\\_\\~]", UCSCHAR$$), SCHEME$ = subexp(ALPHA$$ + merge(ALPHA$$, DIGIT$$, "[\\+\\-\\.]") + "*"), USERINFO$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]")) + "*"), DEC_OCTET$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("[1-9]" + DIGIT$$) + "|" + DIGIT$$), DEC_OCTET_RELAXED$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("0?[1-9]" + DIGIT$$) + "|0?0?" + DIGIT$$), //relaxed parsing rules
IPV4ADDRESS$ = subexp(DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$), H16$ = subexp(HEXDIG$$ + "{1,4}"), LS32$ = subexp(subexp(H16$ + "\\:" + H16$) + "|" + IPV4ADDRESS$), IPV6ADDRESS1$ = subexp(subexp(H16$ + "\\:") + "{6}" + LS32$), // 6( h16 ":" ) ls32
IPV6ADDRESS2$ = subexp("\\:\\:" + subexp(H16$ + "\\:") + "{5}" + LS32$), // "::" 5( h16 ":" ) ls32
IPV6ADDRESS3$ = subexp(subexp(H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{4}" + LS32$), //[ h16 ] "::" 4( h16 ":" ) ls32
IPV6ADDRESS4$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,1}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{3}" + LS32$), //[ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
IPV6ADDRESS5$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,2}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{2}" + LS32$), //[ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
IPV6ADDRESS6$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,3}" + H16$) + "?\\:\\:" + H16$ + "\\:" + LS32$), //[ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
IPV6ADDRESS7$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,4}" + H16$) + "?\\:\\:" + LS32$), //[ *4( h16 ":" ) h16 ] "::" ls32
IPV6ADDRESS8$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,5}" + H16$) + "?\\:\\:" + H16$), //[ *5( h16 ":" ) h16 ] "::" h16
IPV6ADDRESS9$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,6}" + H16$) + "?\\:\\:"), //[ *6( h16 ":" ) h16 ] "::"
IPV6ADDRESS$ = subexp([IPV6ADDRESS1$, IPV6ADDRESS2$, IPV6ADDRESS3$, IPV6ADDRESS4$, IPV6ADDRESS5$, IPV6ADDRESS6$, IPV6ADDRESS7$, IPV6ADDRESS8$, IPV6ADDRESS9$].join("|")), ZONEID$ = subexp(subexp(UNRESERVED$$ + "|" + PCT_ENCODED$) + "+"), //RFC 6874
IPV6ADDRZ$ = subexp(IPV6ADDRESS$ + "\\%25" + ZONEID$), //RFC 6874
IPV6ADDRZ_RELAXED$ = subexp(IPV6ADDRESS$ + subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + ZONEID$), //RFC 6874, with relaxed parsing rules
IPVFUTURE$ = subexp("[vV]" + HEXDIG$$ + "+\\." + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]") + "+"), IP_LITERAL$ = subexp("\\[" + subexp(IPV6ADDRZ_RELAXED$ + "|" + IPV6ADDRESS$ + "|" + IPVFUTURE$) + "\\]"), //RFC 6874
REG_NAME$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$)) + "*"), HOST$ = subexp(IP_LITERAL$ + "|" + IPV4ADDRESS$ + "(?!" + REG_NAME$ + ")" + "|" + REG_NAME$), PORT$ = subexp(DIGIT$$ + "*"), AUTHORITY$ = subexp(subexp(USERINFO$ + "@") + "?" + HOST$ + subexp("\\:" + PORT$) + "?"), PCHAR$ = subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@]")), SEGMENT$ = subexp(PCHAR$ + "*"), SEGMENT_NZ$ = subexp(PCHAR$ + "+"), SEGMENT_NZ_NC$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\@]")) + "+"), PATH_ABEMPTY$ = subexp(subexp("\\/" + SEGMENT$) + "*"), PATH_ABSOLUTE$ = subexp("\\/" + subexp(SEGMENT_NZ$ + PATH_ABEMPTY$) + "?"), //simplified
PATH_NOSCHEME$ = subexp(SEGMENT_NZ_NC$ + PATH_ABEMPTY$), //simplified
PATH_ROOTLESS$ = subexp(SEGMENT_NZ$ + PATH_ABEMPTY$), //simplified
PATH_EMPTY$ = "(?!" + PCHAR$ + ")", PATH$ = subexp(PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), QUERY$ = subexp(subexp(PCHAR$ + "|" + merge("[\\/\\?]", IPRIVATE$$)) + "*"), FRAGMENT$ = subexp(subexp(PCHAR$ + "|[\\/\\?]") + "*"), HIER_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), RELATIVE_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$), RELATIVE$ = subexp(RELATIVE_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), URI_REFERENCE$ = subexp(URI$ + "|" + RELATIVE$), ABSOLUTE_URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?"), GENERIC_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", RELATIVE_REF$ = "^(){0}" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", ABSOLUTE_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?$", SAMEDOC_REF$ = "^" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", AUTHORITY_REF$ = "^" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?$";
return {
NOT_SCHEME: new RegExp(merge("[^]", ALPHA$$, DIGIT$$, "[\\+\\-\\.]"), "g"),
NOT_USERINFO: new RegExp(merge("[^\\%\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"),
NOT_HOST: new RegExp(merge("[^\\%\\[\\]\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"),
NOT_PATH: new RegExp(merge("[^\\%\\/\\:\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"),
NOT_PATH_NOSCHEME: new RegExp(merge("[^\\%\\/\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"),
NOT_QUERY: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]", IPRIVATE$$), "g"),
NOT_FRAGMENT: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]"), "g"),
ESCAPE: new RegExp(merge("[^]", UNRESERVED$$, SUB_DELIMS$$), "g"),
UNRESERVED: new RegExp(UNRESERVED$$, "g"),
OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$, RESERVED$$), "g"),
PCT_ENCODED: new RegExp(PCT_ENCODED$, "g"),
IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"),
IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$") //RFC 6874, with relaxed parsing rules
};
}
export default buildExps(false);
//# sourceMappingURL=regexps-uri.js.map

View File

@@ -0,0 +1,497 @@
/**
* Argon2 KDF from RFC 9106. Can be used to create a key from password and salt.
* We suggest to use Scrypt. JS Argon is 2-10x slower than native code because of 64-bitness:
* * argon uses uint64, but JS doesn't have fast uint64array
* * uint64 multiplication is 1/3 of time
* * `P` function would be very nice with u64, because most of value will be in registers,
* hovewer with u32 it will require 32 registers, which is too much.
* * JS arrays do slow bound checks, so reading from `A2_BUF` slows it down
* @module
*/
import { add3H, add3L, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL } from './_u64.ts';
import { blake2b } from './blake2.ts';
import { abytes, clean, kdfInputToBytes, nextTick, u32, u8, type KDFInput } from './utils.ts';
const AT = { Argond2d: 0, Argon2i: 1, Argon2id: 2 } as const;
type Types = (typeof AT)[keyof typeof AT];
const ARGON2_SYNC_POINTS = 4;
const abytesOrZero = (buf?: KDFInput) => {
if (buf === undefined) return Uint8Array.of();
return kdfInputToBytes(buf);
};
// u32 * u32 = u64
function mul(a: number, b: number) {
const aL = a & 0xffff;
const aH = a >>> 16;
const bL = b & 0xffff;
const bH = b >>> 16;
const ll = Math.imul(aL, bL);
const hl = Math.imul(aH, bL);
const lh = Math.imul(aL, bH);
const hh = Math.imul(aH, bH);
const carry = (ll >>> 16) + (hl & 0xffff) + lh;
const high = (hh + (hl >>> 16) + (carry >>> 16)) | 0;
const low = (carry << 16) | (ll & 0xffff);
return { h: high, l: low };
}
function mul2(a: number, b: number) {
// 2 * a * b (via shifts)
const { h, l } = mul(a, b);
return { h: ((h << 1) | (l >>> 31)) & 0xffff_ffff, l: (l << 1) & 0xffff_ffff };
}
// BlaMka permutation for Argon2
// A + B + (2 * u32(A) * u32(B))
function blamka(Ah: number, Al: number, Bh: number, Bl: number) {
const { h: Ch, l: Cl } = mul2(Al, Bl);
// A + B + (2 * A * B)
const Rll = add3L(Al, Bl, Cl);
return { h: add3H(Rll, Ah, Bh, Ch), l: Rll | 0 };
}
// Temporary block buffer
const A2_BUF = new Uint32Array(256); // 1024 bytes (matrix 16x16)
function G(a: number, b: number, c: number, d: number) {
let Al = A2_BUF[2*a], Ah = A2_BUF[2*a + 1]; // prettier-ignore
let Bl = A2_BUF[2*b], Bh = A2_BUF[2*b + 1]; // prettier-ignore
let Cl = A2_BUF[2*c], Ch = A2_BUF[2*c + 1]; // prettier-ignore
let Dl = A2_BUF[2*d], Dh = A2_BUF[2*d + 1]; // prettier-ignore
({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl));
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh, Dl) });
({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl));
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) });
({ h: Ah, l: Al } = blamka(Ah, Al, Bh, Bl));
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) });
({ h: Ch, l: Cl } = blamka(Ch, Cl, Dh, Dl));
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) });
(A2_BUF[2 * a] = Al), (A2_BUF[2 * a + 1] = Ah);
(A2_BUF[2 * b] = Bl), (A2_BUF[2 * b + 1] = Bh);
(A2_BUF[2 * c] = Cl), (A2_BUF[2 * c + 1] = Ch);
(A2_BUF[2 * d] = Dl), (A2_BUF[2 * d + 1] = Dh);
}
// prettier-ignore
function P(
v00: number, v01: number, v02: number, v03: number, v04: number, v05: number, v06: number, v07: number,
v08: number, v09: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number,
) {
G(v00, v04, v08, v12);
G(v01, v05, v09, v13);
G(v02, v06, v10, v14);
G(v03, v07, v11, v15);
G(v00, v05, v10, v15);
G(v01, v06, v11, v12);
G(v02, v07, v08, v13);
G(v03, v04, v09, v14);
}
function block(x: Uint32Array, xPos: number, yPos: number, outPos: number, needXor: boolean) {
for (let i = 0; i < 256; i++) A2_BUF[i] = x[xPos + i] ^ x[yPos + i];
// columns (8)
for (let i = 0; i < 128; i += 16) {
// prettier-ignore
P(
i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7,
i + 8, i + 9, i + 10, i + 11, i + 12, i + 13, i + 14, i + 15
);
}
// rows (8)
for (let i = 0; i < 16; i += 2) {
// prettier-ignore
P(
i, i + 1, i + 16, i + 17, i + 32, i + 33, i + 48, i + 49,
i + 64, i + 65, i + 80, i + 81, i + 96, i + 97, i + 112, i + 113
);
}
if (needXor) for (let i = 0; i < 256; i++) x[outPos + i] ^= A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i];
else for (let i = 0; i < 256; i++) x[outPos + i] = A2_BUF[i] ^ x[xPos + i] ^ x[yPos + i];
clean(A2_BUF);
}
// Variable-Length Hash Function H'
function Hp(A: Uint32Array, dkLen: number) {
const A8 = u8(A);
const T = new Uint32Array(1);
const T8 = u8(T);
T[0] = dkLen;
// Fast path
if (dkLen <= 64) return blake2b.create({ dkLen }).update(T8).update(A8).digest();
const out = new Uint8Array(dkLen);
let V = blake2b.create({}).update(T8).update(A8).digest();
let pos = 0;
// First block
out.set(V.subarray(0, 32));
pos += 32;
// Rest blocks
for (; dkLen - pos > 64; pos += 32) {
const Vh = blake2b.create({}).update(V);
Vh.digestInto(V);
Vh.destroy();
out.set(V.subarray(0, 32), pos);
}
// Last block
out.set(blake2b(V, { dkLen: dkLen - pos }), pos);
clean(V, T);
return u32(out);
}
// Used only inside process block!
function indexAlpha(
r: number,
s: number,
laneLen: number,
segmentLen: number,
index: number,
randL: number,
sameLane: boolean = false
) {
// This is ugly, but close enough to reference implementation.
let area: number;
if (r === 0) {
if (s === 0) area = index - 1;
else if (sameLane) area = s * segmentLen + index - 1;
else area = s * segmentLen + (index == 0 ? -1 : 0);
} else if (sameLane) area = laneLen - segmentLen + index - 1;
else area = laneLen - segmentLen + (index == 0 ? -1 : 0);
const startPos = r !== 0 && s !== ARGON2_SYNC_POINTS - 1 ? (s + 1) * segmentLen : 0;
const rel = area - 1 - mul(area, mul(randL, randL).h).h;
return (startPos + rel) % laneLen;
}
/**
* Argon2 options.
* * t: time cost, m: mem cost in kb, p: parallelization.
* * key: optional key. personalization: arbitrary extra data.
* * dkLen: desired number of output bytes.
*/
export type ArgonOpts = {
t: number; // Time cost, iterations count
m: number; // Memory cost (in KB)
p: number; // Parallelization parameter
version?: number; // Default: 0x13 (19)
key?: KDFInput; // Optional key
personalization?: KDFInput; // Optional arbitrary extra data
dkLen?: number; // Desired number of returned bytes
asyncTick?: number; // Maximum time in ms for which async function can block execution
maxmem?: number;
onProgress?: (progress: number) => void;
};
const maxUint32 = Math.pow(2, 32);
function isU32(num: number) {
return Number.isSafeInteger(num) && num >= 0 && num < maxUint32;
}
function argon2Opts(opts: ArgonOpts) {
const merged: any = {
version: 0x13,
dkLen: 32,
maxmem: maxUint32 - 1,
asyncTick: 10,
};
for (let [k, v] of Object.entries(opts)) if (v != null) merged[k] = v;
const { dkLen, p, m, t, version, onProgress } = merged;
if (!isU32(dkLen) || dkLen < 4) throw new Error('dkLen should be at least 4 bytes');
if (!isU32(p) || p < 1 || p >= Math.pow(2, 24)) throw new Error('p should be 1 <= p < 2^24');
if (!isU32(m)) throw new Error('m should be 0 <= m < 2^32');
if (!isU32(t) || t < 1) throw new Error('t (iterations) should be 1 <= t < 2^32');
if (onProgress !== undefined && typeof onProgress !== 'function')
throw new Error('progressCb should be function');
/*
Memory size m MUST be an integer number of kibibytes from 8*p to 2^(32)-1. The actual number of blocks is m', which is m rounded down to the nearest multiple of 4*p.
*/
if (!isU32(m) || m < 8 * p) throw new Error('memory should be at least 8*p bytes');
if (version !== 0x10 && version !== 0x13) throw new Error('unknown version=' + version);
return merged;
}
function argon2Init(password: KDFInput, salt: KDFInput, type: Types, opts: ArgonOpts) {
password = kdfInputToBytes(password);
salt = kdfInputToBytes(salt);
abytes(password);
abytes(salt);
if (!isU32(password.length)) throw new Error('password should be less than 4 GB');
if (!isU32(salt.length) || salt.length < 8)
throw new Error('salt should be at least 8 bytes and less than 4 GB');
if (!Object.values(AT).includes(type)) throw new Error('invalid type');
let { p, dkLen, m, t, version, key, personalization, maxmem, onProgress, asyncTick } =
argon2Opts(opts);
// Validation
key = abytesOrZero(key);
personalization = abytesOrZero(personalization);
// H_0 = H^(64)(LE32(p) || LE32(T) || LE32(m) || LE32(t) ||
// LE32(v) || LE32(y) || LE32(length(P)) || P ||
// LE32(length(S)) || S || LE32(length(K)) || K ||
// LE32(length(X)) || X)
const h = blake2b.create({});
const BUF = new Uint32Array(1);
const BUF8 = u8(BUF);
for (let item of [p, dkLen, m, t, version, type]) {
BUF[0] = item;
h.update(BUF8);
}
for (let i of [password, salt, key, personalization]) {
BUF[0] = i.length; // BUF is u32 array, this is valid
h.update(BUF8).update(i);
}
const H0 = new Uint32Array(18);
const H0_8 = u8(H0);
h.digestInto(H0_8);
// 256 u32 = 1024 (BLOCK_SIZE), fills A2_BUF on processing
// Params
const lanes = p;
// m' = 4 * p * floor (m / 4p)
const mP = 4 * p * Math.floor(m / (ARGON2_SYNC_POINTS * p));
//q = m' / p columns
const laneLen = Math.floor(mP / p);
const segmentLen = Math.floor(laneLen / ARGON2_SYNC_POINTS);
const memUsed = mP * 256;
if (!isU32(maxmem) || memUsed > maxmem)
throw new Error(
'mem should be less than 2**32, got: maxmem=' + maxmem + ', memused=' + memUsed
);
const B = new Uint32Array(memUsed);
// Fill first blocks
for (let l = 0; l < p; l++) {
const i = 256 * laneLen * l;
// B[i][0] = H'^(1024)(H_0 || LE32(0) || LE32(i))
H0[17] = l;
H0[16] = 0;
B.set(Hp(H0, 1024), i);
// B[i][1] = H'^(1024)(H_0 || LE32(1) || LE32(i))
H0[16] = 1;
B.set(Hp(H0, 1024), i + 256);
}
let perBlock = () => {};
if (onProgress) {
const totalBlock = t * ARGON2_SYNC_POINTS * p * segmentLen;
// Invoke callback if progress changes from 10.01 to 10.02
// Allows to draw smooth progress bar on up to 8K screen
const callbackPer = Math.max(Math.floor(totalBlock / 10000), 1);
let blockCnt = 0;
perBlock = () => {
blockCnt++;
if (onProgress && (!(blockCnt % callbackPer) || blockCnt === totalBlock))
onProgress(blockCnt / totalBlock);
};
}
clean(BUF, H0);
return { type, mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick };
}
function argon2Output(B: Uint32Array, p: number, laneLen: number, dkLen: number) {
const B_final = new Uint32Array(256);
for (let l = 0; l < p; l++)
for (let j = 0; j < 256; j++) B_final[j] ^= B[256 * (laneLen * l + laneLen - 1) + j];
const res = u8(Hp(B_final, dkLen));
clean(B_final);
return res;
}
function processBlock(
B: Uint32Array,
address: Uint32Array,
l: number,
r: number,
s: number,
index: number,
laneLen: number,
segmentLen: number,
lanes: number,
offset: number,
prev: number,
dataIndependent: boolean,
needXor: boolean
) {
if (offset % laneLen) prev = offset - 1;
let randL, randH;
if (dataIndependent) {
let i128 = index % 128;
if (i128 === 0) {
address[256 + 12]++;
block(address, 256, 2 * 256, 0, false);
block(address, 0, 2 * 256, 0, false);
}
randL = address[2 * i128];
randH = address[2 * i128 + 1];
} else {
const T = 256 * prev;
randL = B[T];
randH = B[T + 1];
}
// address block
const refLane = r === 0 && s === 0 ? l : randH % lanes;
const refPos = indexAlpha(r, s, laneLen, segmentLen, index, randL, refLane == l);
const refBlock = laneLen * refLane + refPos;
// B[i][j] = G(B[i][j-1], B[l][z])
block(B, 256 * prev, 256 * refBlock, offset * 256, needXor);
}
function argon2(type: Types, password: KDFInput, salt: KDFInput, opts: ArgonOpts) {
const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock } = argon2Init(
password,
salt,
type,
opts
);
// Pre-loop setup
// [address, input, zero_block] format so we can pass single U32 to block function
const address = new Uint32Array(3 * 256);
address[256 + 6] = mP;
address[256 + 8] = t;
address[256 + 10] = type;
for (let r = 0; r < t; r++) {
const needXor = r !== 0 && version === 0x13;
address[256 + 0] = r;
for (let s = 0; s < ARGON2_SYNC_POINTS; s++) {
address[256 + 4] = s;
const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2);
for (let l = 0; l < p; l++) {
address[256 + 2] = l;
address[256 + 12] = 0;
let startPos = 0;
if (r === 0 && s === 0) {
startPos = 2;
if (dataIndependent) {
address[256 + 12]++;
block(address, 256, 2 * 256, 0, false);
block(address, 0, 2 * 256, 0, false);
}
}
// current block postion
let offset = l * laneLen + s * segmentLen + startPos;
// previous block position
let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1;
for (let index = startPos; index < segmentLen; index++, offset++, prev++) {
perBlock();
processBlock(
B,
address,
l,
r,
s,
index,
laneLen,
segmentLen,
lanes,
offset,
prev,
dataIndependent,
needXor
);
}
}
}
}
clean(address);
return argon2Output(B, p, laneLen, dkLen);
}
/** argon2d GPU-resistant version. */
export const argon2d = (password: KDFInput, salt: KDFInput, opts: ArgonOpts): Uint8Array =>
argon2(AT.Argond2d, password, salt, opts);
/** argon2i side-channel-resistant version. */
export const argon2i = (password: KDFInput, salt: KDFInput, opts: ArgonOpts): Uint8Array =>
argon2(AT.Argon2i, password, salt, opts);
/** argon2id, combining i+d, the most popular version from RFC 9106 */
export const argon2id = (password: KDFInput, salt: KDFInput, opts: ArgonOpts): Uint8Array =>
argon2(AT.Argon2id, password, salt, opts);
async function argon2Async(type: Types, password: KDFInput, salt: KDFInput, opts: ArgonOpts) {
const { mP, p, t, version, B, laneLen, lanes, segmentLen, dkLen, perBlock, asyncTick } =
argon2Init(password, salt, type, opts);
// Pre-loop setup
// [address, input, zero_block] format so we can pass single U32 to block function
const address = new Uint32Array(3 * 256);
address[256 + 6] = mP;
address[256 + 8] = t;
address[256 + 10] = type;
let ts = Date.now();
for (let r = 0; r < t; r++) {
const needXor = r !== 0 && version === 0x13;
address[256 + 0] = r;
for (let s = 0; s < ARGON2_SYNC_POINTS; s++) {
address[256 + 4] = s;
const dataIndependent = type == AT.Argon2i || (type == AT.Argon2id && r === 0 && s < 2);
for (let l = 0; l < p; l++) {
address[256 + 2] = l;
address[256 + 12] = 0;
let startPos = 0;
if (r === 0 && s === 0) {
startPos = 2;
if (dataIndependent) {
address[256 + 12]++;
block(address, 256, 2 * 256, 0, false);
block(address, 0, 2 * 256, 0, false);
}
}
// current block postion
let offset = l * laneLen + s * segmentLen + startPos;
// previous block position
let prev = offset % laneLen ? offset - 1 : offset + laneLen - 1;
for (let index = startPos; index < segmentLen; index++, offset++, prev++) {
perBlock();
processBlock(
B,
address,
l,
r,
s,
index,
laneLen,
segmentLen,
lanes,
offset,
prev,
dataIndependent,
needXor
);
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
const diff = Date.now() - ts;
if (!(diff >= 0 && diff < asyncTick)) {
await nextTick();
ts += diff;
}
}
}
}
}
clean(address);
return argon2Output(B, p, laneLen, dkLen);
}
/** argon2d async GPU-resistant version. */
export const argon2dAsync = (
password: KDFInput,
salt: KDFInput,
opts: ArgonOpts
): Promise<Uint8Array> => argon2Async(AT.Argond2d, password, salt, opts);
/** argon2i async side-channel-resistant version. */
export const argon2iAsync = (
password: KDFInput,
salt: KDFInput,
opts: ArgonOpts
): Promise<Uint8Array> => argon2Async(AT.Argon2i, password, salt, opts);
/** argon2id async, combining i+d, the most popular version from RFC 9106 */
export const argon2idAsync = (
password: KDFInput,
salt: KDFInput,
opts: ArgonOpts
): Promise<Uint8Array> => argon2Async(AT.Argon2id, password, salt, opts);