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,5 @@
var assertClassBrand = require("./assertClassBrand.js");
function _classPrivateSetter(s, r, a, t) {
return r(assertClassBrand(s, a), t), t;
}
module.exports = _classPrivateSetter, module.exports.__esModule = true, module.exports["default"] = module.exports;

View File

@@ -0,0 +1 @@
export declare const xhtmlEntities: Record<string, string>;

View File

@@ -0,0 +1,190 @@
import process from 'node:process';
import os from 'node:os';
import tty from 'node:tty';
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
const position = argv.indexOf(prefix + flag);
const terminatorPosition = argv.indexOf('--');
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
const {env} = process;
let flagForceColor;
if (
hasFlag('no-color')
|| hasFlag('no-colors')
|| hasFlag('color=false')
|| hasFlag('color=never')
) {
flagForceColor = 0;
} else if (
hasFlag('color')
|| hasFlag('colors')
|| hasFlag('color=true')
|| hasFlag('color=always')
) {
flagForceColor = 1;
}
function envForceColor() {
if ('FORCE_COLOR' in env) {
if (env.FORCE_COLOR === 'true') {
return 1;
}
if (env.FORCE_COLOR === 'false') {
return 0;
}
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
}
}
function translateLevel(level) {
if (level === 0) {
return false;
}
return {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3,
};
}
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
const noFlagForceColor = envForceColor();
if (noFlagForceColor !== undefined) {
flagForceColor = noFlagForceColor;
}
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
if (forceColor === 0) {
return 0;
}
if (sniffFlags) {
if (hasFlag('color=16m')
|| hasFlag('color=full')
|| hasFlag('color=truecolor')) {
return 3;
}
if (hasFlag('color=256')) {
return 2;
}
}
// Check for Azure DevOps pipelines.
// Has to be above the `!streamIsTTY` check.
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
return 1;
}
if (haveStream && !streamIsTTY && forceColor === undefined) {
return 0;
}
const min = forceColor || 0;
if (env.TERM === 'dumb') {
return min;
}
if (process.platform === 'win32') {
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
const osRelease = os.release().split('.');
if (
Number(osRelease[0]) >= 10
&& Number(osRelease[2]) >= 10_586
) {
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
}
return 1;
}
if ('CI' in env) {
if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
return 3;
}
if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
return 1;
}
return min;
}
if ('TEAMCITY_VERSION' in env) {
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
}
if (env.COLORTERM === 'truecolor') {
return 3;
}
if (env.TERM === 'xterm-kitty') {
return 3;
}
if (env.TERM === 'xterm-ghostty') {
return 3;
}
if (env.TERM === 'wezterm') {
return 3;
}
if ('TERM_PROGRAM' in env) {
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
switch (env.TERM_PROGRAM) {
case 'iTerm.app': {
return version >= 3 ? 3 : 2;
}
case 'Apple_Terminal': {
return 2;
}
// No default
}
}
if (/-256(color)?$/i.test(env.TERM)) {
return 2;
}
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
return 1;
}
if ('COLORTERM' in env) {
return 1;
}
return min;
}
export function createSupportsColor(stream, options = {}) {
const level = _supportsColor(stream, {
streamIsTTY: stream && stream.isTTY,
...options,
});
return translateLevel(level);
}
const supportsColor = {
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
};
export default supportsColor;

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env sh
set -e
mkdir -p .browser
echo
echo Preparing browser tests:
find spec -type f -name '*.spec.js' | \
xargs -I {} sh -c \
'export f="{}"; echo $f; browserify $f -t require-globify -t brfs -x ajv -u buffer -o $(echo $f | sed -e "s/spec/.browser/");'

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FunctionTypeScope = void 0;
const ScopeBase_1 = require("./ScopeBase");
const ScopeType_1 = require("./ScopeType");
class FunctionTypeScope extends ScopeBase_1.ScopeBase {
constructor(scopeManager, upperScope, block) {
super(scopeManager, ScopeType_1.ScopeType.functionType, upperScope, block, false);
}
}
exports.FunctionTypeScope = FunctionTypeScope;

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/abstract/utils.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,iCAAiC;AAWjC,oDAAoD;AACvC,QAAA,MAAM,GAAoB,CAAC,CAAC,MAAM,CAAC;AAChD,oDAAoD;AACvC,QAAA,OAAO,GAAqB,CAAC,CAAC,OAAO,CAAC;AACnD,oDAAoD;AACvC,QAAA,UAAU,GAAwB,CAAC,CAAC,UAAU,CAAC;AAC5D,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAC/D,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAC/D,oDAAoD;AACvC,QAAA,UAAU,GAAwB,CAAC,CAAC,UAAU,CAAC;AAC5D,oDAAoD;AACvC,QAAA,OAAO,GAAqB,CAAC,CAAC,OAAO,CAAC;AACnD,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAC/D,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAE/D,oDAAoD;AACvC,QAAA,KAAK,GAAmB,CAAC,CAAC,KAAK,CAAC;AAC7C,oDAAoD;AACvC,QAAA,mBAAmB,GAAiC,CAAC,CAAC,mBAAmB,CAAC;AACvF,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAC/D,oDAAoD;AACvC,QAAA,eAAe,GAA6B,CAAC,CAAC,eAAe,CAAC;AAC3E,oDAAoD;AACvC,QAAA,eAAe,GAA6B,CAAC,CAAC,eAAe,CAAC;AAC3E,oDAAoD;AACvC,QAAA,eAAe,GAA6B,CAAC,CAAC,eAAe,CAAC;AAC3E,oDAAoD;AACvC,QAAA,eAAe,GAA6B,CAAC,CAAC,eAAe,CAAC;AAC3E,oDAAoD;AACvC,QAAA,kBAAkB,GAAgC,CAAC,CAAC,kBAAkB,CAAC;AACpF,oDAAoD;AACvC,QAAA,WAAW,GAAyB,CAAC,CAAC,WAAW,CAAC;AAC/D,oDAAoD;AACvC,QAAA,UAAU,GAAwB,CAAC,CAAC,UAAU,CAAC;AAC5D,oDAAoD;AACvC,QAAA,SAAS,GAAuB,CAAC,CAAC,SAAS,CAAC;AACzD,oDAAoD;AACvC,QAAA,YAAY,GAA0B,CAAC,CAAC,YAAY,CAAC;AAClE,oDAAoD;AACvC,QAAA,OAAO,GAAqB,CAAC,CAAC,OAAO,CAAC;AACnD,oDAAoD;AACvC,QAAA,QAAQ,GAAsB,CAAC,CAAC,QAAQ,CAAC;AACtD,oDAAoD;AACvC,QAAA,MAAM,GAAoB,CAAC,CAAC,MAAM,CAAC;AAChD,oDAAoD;AACvC,QAAA,MAAM,GAAoB,CAAC,CAAC,MAAM,CAAC;AAChD,oDAAoD;AACvC,QAAA,MAAM,GAAoB,CAAC,CAAC,MAAM,CAAC;AAChD,oDAAoD;AACvC,QAAA,OAAO,GAAqB,CAAC,CAAC,OAAO,CAAC;AACnD,oDAAoD;AACvC,QAAA,cAAc,GAA4B,CAAC,CAAC,cAAc,CAAC;AACxE,oDAAoD;AACvC,QAAA,cAAc,GAA4B,CAAC,CAAC,cAAc,CAAC;AACxE,oDAAoD;AACvC,QAAA,QAAQ,GAAsB,CAAC,CAAC,QAAQ,CAAC;AACtD,oDAAoD;AACvC,QAAA,cAAc,GAA4B,CAAC,CAAC,cAAc,CAAC;AACxE,oDAAoD;AACvC,QAAA,MAAM,GAAoB,CAAC,CAAC,MAAM,CAAC"}

View File

@@ -0,0 +1 @@
import{r}from"../register-C9AniqUt.mjs";import"../get-pipe-path-_tAJyU_v.mjs";import"module";import"node:path";import"../temporary-directory-BDDVQOvU.mjs";import"node:os";import"node:module";import"node:url";import"node:fs";import"fs";import"os";import"path";import"../index-DQtFPMc2.mjs";import"esbuild";import"node:crypto";import"../node-features-JeyyvQz6.mjs";import"../client-D_mPDF5S.mjs";import"node:net";import"node:util";import"../index-gbaejti9.mjs";r();

View File

@@ -0,0 +1,93 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// SEE https://typescript-eslint.io/users/configs
//
// For developers working in the typescript-eslint monorepo:
// You can regenerate it using `pnpm run generate-configs`
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const base_1 = __importDefault(require("./base"));
const eslint_recommended_1 = __importDefault(require("./eslint-recommended"));
/**
* A version of `strict` that only contains type-checked rules and disables of any corresponding core ESLint rules.
* @see {@link https://typescript-eslint.io/users/configs#strict-type-checked-only}
*/
exports.default = (plugin, parser) => [
(0, base_1.default)(plugin, parser),
(0, eslint_recommended_1.default)(plugin, parser),
{
name: 'typescript-eslint/strict-type-checked-only',
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-array-delete': 'error',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-deprecated': 'error',
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-for-in-array': 'error',
'no-implied-eval': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-meaningless-void-operator': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-misused-spread': 'error',
'@typescript-eslint/no-mixed-enums': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/no-unnecessary-template-expression': 'error',
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-conversion': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/no-unsafe-unary-minus': 'error',
'@typescript-eslint/no-useless-default-assignment': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/related-getter-setter-pairs': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNullish: false,
allowNumberAndString: false,
allowRegExp: false,
},
],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: false,
allowNever: false,
allowNullish: false,
allowNumber: false,
allowRegExp: false,
},
],
'no-return-await': 'off',
'@typescript-eslint/return-await': [
'error',
'error-handling-correctness-only',
],
'@typescript-eslint/unbound-method': 'error',
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
},
},
];

View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"index.test-d.ts"
]
}

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClassScope = void 0;
const ScopeBase_1 = require("./ScopeBase");
const ScopeType_1 = require("./ScopeType");
class ClassScope extends ScopeBase_1.ScopeBase {
constructor(scopeManager, upperScope, block) {
super(scopeManager, ScopeType_1.ScopeType.class, upperScope, block, false);
}
}
exports.ClassScope = ClassScope;

View File

@@ -0,0 +1,74 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
dependency-review:
name: Dependency Review
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Check out repo
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Dependency review
uses: actions/dependency-review-action@v4
test:
name: Test
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
matrix:
node-version: [20, 22, 24, 26]
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- name: Check out repo
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm i --ignore-scripts
- name: Run tests
run: npm run test:ci
automerge:
name: Automerge Dependabot PRs
if: >
github.event_name == 'pull_request' &&
github.event.pull_request.user.login == 'dependabot[bot]'
needs: test
permissions:
pull-requests: write
contents: write
runs-on: ubuntu-latest
steps:
- uses: fastify/github-action-merge-dependabot@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,4 @@
function _tdzError(e) {
throw new ReferenceError(e + " is not defined - temporal dead zone");
}
module.exports = _tdzError, module.exports.__esModule = true, module.exports["default"] = module.exports;

View File

@@ -0,0 +1,21 @@
'use strict'
// Node v8 throw a `SyntaxError: Unexpected token import`
// even if this branch is never touched in the code,
// by using `eval` we can avoid this issue.
// eslint-disable-next-line
new Function('module', 'return import(module)')('./esm.mjs').catch((err) => {
process.nextTick(() => {
throw err
})
})
// Node v8 throw a `SyntaxError: Unexpected token import`
// even if this branch is never touched in the code,
// by using `eval` we can avoid this issue.
// eslint-disable-next-line
new Function('module', 'return import(module)')('./named-exports.mjs').catch((err) => {
process.nextTick(() => {
throw err
})
})

View File

@@ -0,0 +1,199 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const scope_manager_1 = require("@typescript-eslint/scope-manager");
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'no-redeclare',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow variable redeclaration',
extendsBaseRule: true,
},
messages: {
redeclared: "'{{id}}' is already defined.",
redeclaredAsBuiltin: "'{{id}}' is already defined as a built-in global variable.",
redeclaredBySyntax: "'{{id}}' is already defined by a variable declaration.",
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
builtinGlobals: {
type: 'boolean',
description: 'Whether to report shadowing of built-in global variables.',
},
ignoreDeclarationMerge: {
type: 'boolean',
description: 'Whether to ignore declaration merges between certain TypeScript declaration types.',
},
},
},
],
},
defaultOptions: [
{
builtinGlobals: true,
ignoreDeclarationMerge: true,
},
],
create(context, [options]) {
const CLASS_DECLARATION_MERGE_NODES = new Set([
utils_1.AST_NODE_TYPES.ClassDeclaration,
utils_1.AST_NODE_TYPES.TSInterfaceDeclaration,
utils_1.AST_NODE_TYPES.TSModuleDeclaration,
]);
const FUNCTION_DECLARATION_MERGE_NODES = new Set([
utils_1.AST_NODE_TYPES.FunctionDeclaration,
utils_1.AST_NODE_TYPES.TSModuleDeclaration,
]);
const ENUM_DECLARATION_MERGE_NODES = new Set([
utils_1.AST_NODE_TYPES.TSEnumDeclaration,
utils_1.AST_NODE_TYPES.TSModuleDeclaration,
]);
function* iterateDeclarations(variable) {
if (options.builtinGlobals &&
'eslintImplicitGlobalSetting' in variable &&
(variable.eslintImplicitGlobalSetting === 'readonly' ||
variable.eslintImplicitGlobalSetting === 'writable')) {
yield { type: 'builtin' };
}
if ('eslintExplicitGlobalComments' in variable &&
variable.eslintExplicitGlobalComments) {
for (const comment of variable.eslintExplicitGlobalComments) {
yield {
loc: (0, util_1.getNameLocationInGlobalDirectiveComment)(context.sourceCode, comment, variable.name),
node: comment,
type: 'comment',
};
}
}
const identifiers = variable.identifiers
.map(id => ({
identifier: id,
parent: id.parent,
}))
// ignore function declarations because TS will treat them as an overload
.filter(({ parent }) => parent.type !== utils_1.AST_NODE_TYPES.TSDeclareFunction);
if (options.ignoreDeclarationMerge && identifiers.length > 1) {
if (
// interfaces merging
identifiers.every(({ parent }) => parent.type === utils_1.AST_NODE_TYPES.TSInterfaceDeclaration)) {
return;
}
if (
// namespace/module merging
identifiers.every(({ parent }) => parent.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration)) {
return;
}
if (
// class + interface/namespace merging
identifiers.every(({ parent }) => CLASS_DECLARATION_MERGE_NODES.has(parent.type))) {
const classDecls = identifiers.filter(({ parent }) => parent.type === utils_1.AST_NODE_TYPES.ClassDeclaration);
if (classDecls.length === 1) {
// safe declaration merging
return;
}
// there's more than one class declaration, which needs to be reported
for (const { identifier } of classDecls) {
yield { loc: identifier.loc, node: identifier, type: 'syntax' };
}
return;
}
if (
// class + interface/namespace merging
identifiers.every(({ parent }) => FUNCTION_DECLARATION_MERGE_NODES.has(parent.type))) {
const functionDecls = identifiers.filter(({ parent }) => parent.type === utils_1.AST_NODE_TYPES.FunctionDeclaration);
if (functionDecls.length === 1) {
// safe declaration merging
return;
}
// there's more than one function declaration, which needs to be reported
for (const { identifier } of functionDecls) {
yield { loc: identifier.loc, node: identifier, type: 'syntax' };
}
return;
}
if (
// enum + namespace merging
identifiers.every(({ parent }) => ENUM_DECLARATION_MERGE_NODES.has(parent.type))) {
const enumDecls = identifiers.filter(({ parent }) => parent.type === utils_1.AST_NODE_TYPES.TSEnumDeclaration);
if (enumDecls.length === 1) {
// safe declaration merging
return;
}
// there's more than one enum declaration, which needs to be reported
for (const { identifier } of enumDecls) {
yield { loc: identifier.loc, node: identifier, type: 'syntax' };
}
return;
}
}
for (const { identifier } of identifiers) {
yield { loc: identifier.loc, node: identifier, type: 'syntax' };
}
}
function findVariablesInScope(scope) {
for (const variable of scope.variables) {
const [declaration, ...extraDeclarations] = iterateDeclarations(variable);
if (extraDeclarations.length === 0) {
continue;
}
/*
* If the type of a declaration is different from the type of
* the first declaration, it shows the location of the first
* declaration.
*/
const detailMessageId = declaration.type === 'builtin'
? 'redeclaredAsBuiltin'
: 'redeclaredBySyntax';
const data = { id: variable.name };
// Report extra declarations.
for (const { loc, node, type } of extraDeclarations) {
const messageId = type === declaration.type ? 'redeclared' : detailMessageId;
if (node) {
context.report({ loc, node, messageId, data });
}
else if (loc) {
context.report({ loc, messageId, data });
}
}
}
}
/**
* Find variables in the current scope.
*/
function checkForBlock(node) {
const scope = context.sourceCode.getScope(node);
/*
* In ES5, some node type such as `BlockStatement` doesn't have that scope.
* `scope.block` is a different node in such a case.
*/
if (scope.block === node) {
findVariablesInScope(scope);
}
}
return {
ArrowFunctionExpression: checkForBlock,
BlockStatement: checkForBlock,
ForInStatement: checkForBlock,
ForOfStatement: checkForBlock,
ForStatement: checkForBlock,
FunctionDeclaration: checkForBlock,
FunctionExpression: checkForBlock,
Program(node) {
const scope = context.sourceCode.getScope(node);
findVariablesInScope(scope);
// Node.js or ES modules has a special scope.
if (scope.type === scope_manager_1.ScopeType.global &&
// The special scope's block is the Program node.
scope.block === scope.childScopes[0]?.block) {
findVariablesInScope(scope.childScopes[0]);
}
},
SwitchStatement: checkForBlock,
};
},
});

View File

@@ -0,0 +1,9 @@
import type { TSESTree } from '@typescript-eslint/types';
import type { ScopeManager } from '../ScopeManager';
import type { Scope } from './Scope';
import { ScopeBase } from './ScopeBase';
import { ScopeType } from './ScopeType';
export declare class FunctionExpressionNameScope extends ScopeBase<ScopeType.functionExpressionName, TSESTree.FunctionExpression, Scope> {
readonly functionExpressionScope: true;
constructor(scopeManager: ScopeManager, upperScope: FunctionExpressionNameScope['upper'], block: FunctionExpressionNameScope['block']);
}

View File

@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'no-import-type-side-effects',
meta: {
type: 'problem',
docs: {
description: 'Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers',
},
fixable: 'code',
messages: {
useTopLevelQualifier: 'TypeScript will only remove the inline type specifiers which will leave behind a side effect import at runtime. Convert this to a top-level type qualifier to properly remove the entire import.',
},
schema: [],
},
defaultOptions: [],
create(context) {
return {
'ImportDeclaration[importKind!="type"]'(node) {
if (node.specifiers.length === 0) {
return;
}
const specifiers = [];
for (const specifier of node.specifiers) {
if (specifier.type !== utils_1.AST_NODE_TYPES.ImportSpecifier ||
specifier.importKind !== 'type') {
return;
}
specifiers.push(specifier);
}
context.report({
node,
messageId: 'useTopLevelQualifier',
fix(fixer) {
const fixes = [];
for (const specifier of specifiers) {
const qualifier = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(specifier, util_1.isTypeKeyword), util_1.NullThrowsReasons.MissingToken('type keyword', 'import specifier'));
fixes.push(fixer.removeRange([
qualifier.range[0],
specifier.imported.range[0],
]));
}
const importKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isImportKeyword), util_1.NullThrowsReasons.MissingToken('import keyword', 'import'));
fixes.push(fixer.insertTextAfter(importKeyword, ' type'));
return fixes;
},
});
},
};
},
});

View File

@@ -0,0 +1,9 @@
import md5 from './md5.js';
import v35, { DNS, URL } from './v35.js';
export { DNS, URL } from './v35.js';
function v3(value, namespace, buf, offset) {
return v35(0x30, md5, value, namespace, buf, offset);
}
v3.DNS = DNS;
v3.URL = URL;
export default v3;

View File

@@ -0,0 +1,209 @@
/**
* @fileoverview Rule that warns about used warning comments
* @author Alexander Schmidt <https://github.com/lxanders>
*/
"use strict";
const escapeRegExp = require("escape-string-regexp");
const astUtils = require("./utils/ast-utils");
const CHAR_LIMIT = 40;
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
type: "suggestion",
defaultOptions: [
{
location: "start",
terms: ["todo", "fixme", "xxx"],
},
],
docs: {
description: "Disallow specified warning terms in comments",
recommended: false,
frozen: true,
url: "https://eslint.org/docs/latest/rules/no-warning-comments",
},
schema: [
{
type: "object",
properties: {
terms: {
type: "array",
items: {
type: "string",
},
},
location: {
enum: ["start", "anywhere"],
},
decoration: {
type: "array",
items: {
type: "string",
pattern: "^\\S$",
},
minItems: 1,
uniqueItems: true,
},
},
additionalProperties: false,
},
],
messages: {
unexpectedComment:
"Unexpected '{{matchedTerm}}' comment: '{{comment}}'.",
},
},
create(context) {
const sourceCode = context.sourceCode;
const [{ decoration, location, terms: warningTerms }] = context.options;
const escapedDecoration = escapeRegExp(
decoration ? decoration.join("") : "",
);
const selfConfigRegEx = /\bno-warning-comments\b/u;
/**
* Convert a warning term into a RegExp which will match a comment containing that whole word in the specified
* location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not
* require word boundaries on that side.
* @param {string} term A term to convert to a RegExp
* @returns {RegExp} The term converted to a RegExp
*/
function convertToRegExp(term) {
const escaped = escapeRegExp(term);
/*
* When matching at the start, ignore leading whitespace, and
* there's no need to worry about word boundaries.
*
* These expressions for the prefix and suffix are designed as follows:
* ^ handles any terms at the beginning of a comment.
* e.g. terms ["TODO"] matches `//TODO something`
* $ handles any terms at the end of a comment
* e.g. terms ["TODO"] matches `// something TODO`
* \b handles terms preceded/followed by word boundary
* e.g. terms: ["!FIX", "FIX!"] matches `// FIX!something` or `// something!FIX`
* terms: ["FIX"] matches `// FIX!` or `// !FIX`, but not `// fixed or affix`
*
* For location start:
* [\s]* handles optional leading spaces
* e.g. terms ["TODO"] matches `// TODO something`
* [\s\*]* (where "\*" is the escaped string of decoration)
* handles optional leading spaces or decoration characters (for "start" location only)
* e.g. terms ["TODO"] matches `/**** TODO something ... `
*/
const wordBoundary = "\\b";
let prefix = "";
if (location === "start") {
prefix = `^[\\s${escapedDecoration}]*`;
} else if (/^\w/u.test(term)) {
prefix = wordBoundary;
}
const suffix = /\w$/u.test(term) ? wordBoundary : "";
const flags = "iu"; // Case-insensitive with Unicode case folding.
/*
* For location "start", the typical regex is:
* /^[\s]*ESCAPED_TERM\b/iu.
* Or if decoration characters are specified (e.g. "*"), then any of
* those characters may appear in any order at the start:
* /^[\s\*]*ESCAPED_TERM\b/iu.
*
* For location "anywhere" the typical regex is
* /\bESCAPED_TERM\b/iu
*
* If it starts or ends with non-word character, the prefix and suffix are empty, respectively.
*/
return new RegExp(`${prefix}${escaped}${suffix}`, flags);
}
const warningRegExps = warningTerms.map(convertToRegExp);
/**
* Checks the specified comment for matches of the configured warning terms and returns the matches.
* @param {string} comment The comment which is checked.
* @returns {Array} All matched warning terms for this comment.
*/
function commentContainsWarningTerm(comment) {
const matches = [];
warningRegExps.forEach((regex, index) => {
if (regex.test(comment)) {
matches.push(warningTerms[index]);
}
});
return matches;
}
/**
* Checks the specified node for matching warning comments and reports them.
* @param {ASTNode} node The AST node being checked.
* @returns {void} undefined.
*/
function checkComment(node) {
const comment = node.value;
if (
astUtils.isDirectiveComment(node) &&
selfConfigRegEx.test(comment)
) {
return;
}
const matches = commentContainsWarningTerm(comment);
matches.forEach(matchedTerm => {
let commentToDisplay = "";
let truncated = false;
for (const c of comment.trim().split(/\s+/u)) {
const tmp = commentToDisplay
? `${commentToDisplay} ${c}`
: c;
if (tmp.length <= CHAR_LIMIT) {
commentToDisplay = tmp;
} else {
truncated = true;
break;
}
}
context.report({
node,
messageId: "unexpectedComment",
data: {
matchedTerm,
comment: `${commentToDisplay}${truncated ? "..." : ""}`,
},
});
});
}
return {
Program() {
const comments = sourceCode.getAllComments();
comments
.filter(token => token.type !== "Shebang")
.forEach(checkComment);
},
};
},
};

View File

@@ -0,0 +1,126 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABILITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
interface ProxyHandler<T extends object> {
/**
* A trap method for a function call.
* @param target The original callable object which is being proxied.
*/
apply?(target: T, thisArg: any, argArray: any[]): any;
/**
* A trap for the `new` operator.
* @param target The original object which is being proxied.
* @param newTarget The constructor that was originally called.
*/
construct?(target: T, argArray: any[], newTarget: Function): object;
/**
* A trap for `Object.defineProperty()`.
* @param target The original object which is being proxied.
* @returns A `Boolean` indicating whether or not the property has been defined.
*/
defineProperty?(target: T, property: string | symbol, attributes: PropertyDescriptor): boolean;
/**
* A trap for the `delete` operator.
* @param target The original object which is being proxied.
* @param p The name or `Symbol` of the property to delete.
* @returns A `Boolean` indicating whether or not the property was deleted.
*/
deleteProperty?(target: T, p: string | symbol): boolean;
/**
* A trap for getting a property value.
* @param target The original object which is being proxied.
* @param p The name or `Symbol` of the property to get.
* @param receiver The proxy or an object that inherits from the proxy.
*/
get?(target: T, p: string | symbol, receiver: any): any;
/**
* A trap for `Object.getOwnPropertyDescriptor()`.
* @param target The original object which is being proxied.
* @param p The name of the property whose description should be retrieved.
*/
getOwnPropertyDescriptor?(target: T, p: string | symbol): PropertyDescriptor | undefined;
/**
* A trap for the `[[GetPrototypeOf]]` internal method.
* @param target The original object which is being proxied.
*/
getPrototypeOf?(target: T): object | null;
/**
* A trap for the `in` operator.
* @param target The original object which is being proxied.
* @param p The name or `Symbol` of the property to check for existence.
*/
has?(target: T, p: string | symbol): boolean;
/**
* A trap for `Object.isExtensible()`.
* @param target The original object which is being proxied.
*/
isExtensible?(target: T): boolean;
/**
* A trap for `Reflect.ownKeys()`.
* @param target The original object which is being proxied.
*/
ownKeys?(target: T): ArrayLike<string | symbol>;
/**
* A trap for `Object.preventExtensions()`.
* @param target The original object which is being proxied.
*/
preventExtensions?(target: T): boolean;
/**
* A trap for setting a property value.
* @param target The original object which is being proxied.
* @param p The name or `Symbol` of the property to set.
* @param receiver The object to which the assignment was originally directed.
* @returns A `Boolean` indicating whether or not the property was set.
*/
set?(target: T, p: string | symbol, newValue: any, receiver: any): boolean;
/**
* A trap for `Object.setPrototypeOf()`.
* @param target The original object which is being proxied.
* @param newPrototype The object's new prototype or `null`.
*/
setPrototypeOf?(target: T, v: object | null): boolean;
}
interface ProxyConstructor {
/**
* Creates a revocable Proxy object.
* @param target A target object to wrap with Proxy.
* @param handler An object whose properties define the behavior of Proxy when an operation is attempted on it.
*/
revocable<T extends object>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };
/**
* Creates a Proxy object. The Proxy object allows you to create an object that can be used in place of the
* original object, but which may redefine fundamental Object operations like getting, setting, and defining
* properties. Proxy objects are commonly used to log property accesses, validate, format, or sanitize inputs.
* @param target A target object to wrap with Proxy.
* @param handler An object whose properties define the behavior of Proxy when an operation is attempted on it.
*/
new <T extends object>(target: T, handler: ProxyHandler<T>): T;
}
declare var Proxy: ProxyConstructor;