WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -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;
|
||||
@@ -0,0 +1 @@
|
||||
export declare const xhtmlEntities: Record<string, string>;
|
||||
@@ -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;
|
||||
@@ -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/");'
|
||||
@@ -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;
|
||||
@@ -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"}
|
||||
@@ -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();
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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 }}
|
||||
@@ -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;
|
||||
@@ -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
|
||||
})
|
||||
})
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -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']);
|
||||
}
|
||||
@@ -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;
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user