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,7 @@
export { a as afterAll, b as afterEach, c as aroundAll, d as aroundEach, e as beforeAll, f as beforeEach, p as collectTests, g as createTaskCollector, h as describe, i as getCurrentSuite, j as getCurrentTest, k as getFn, l as getHooks, m as it, o as onTestFailed, n as onTestFinished, r as recordArtifact, s as setFn, q as setHooks, t as startTests, u as suite, v as test, w as updateTask } from './chunk-artifact.js';
import '@vitest/utils/error';
import '@vitest/utils/helpers';
import '@vitest/utils/timers';
import '@vitest/utils/display';
import '@vitest/utils/source-map';
import 'pathe';

View File

@@ -0,0 +1,85 @@
'use strict';
module.exports = function generate_pattern(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || '');
var $valid = 'valid' + $lvl;
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
var $regExpCode = it.opts.regExp ? 'regExp' : 'new RegExp';
if ($isData) {
out += ' var ' + ($valid) + ' = true; try { ' + ($valid) + ' = ' + ($regExpCode) + '(' + ($schemaValue) + ').test(' + ($data) + '); } catch(e) { ' + ($valid) + ' = false; } if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || ';
}
out += ' !' + ($valid) + ') {';
} else {
var $regexp = it.usePattern($schema);
out += ' if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || ';
}
out += ' !' + ($regexp) + '.test(' + ($data) + ') ) {';
}
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('pattern') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { pattern: ';
if ($isData) {
out += '' + ($schemaValue);
} else {
out += '' + (it.util.toQuotedString($schema));
}
out += ' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should match pattern "';
if ($isData) {
out += '\' + ' + ($schemaValue) + ' + \'';
} else {
out += '' + (it.util.escapeQuotes($schema));
}
out += '"\' ';
}
if (it.opts.verbose) {
out += ' , schema: ';
if ($isData) {
out += 'validate.schema' + ($schemaPath);
} else {
out += '' + (it.util.toQuotedString($schema));
}
out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@@ -0,0 +1,64 @@
'use strict'
module.exports = prettifyMessage
const {
LEVELS
} = require('../constants')
const getPropertyValue = require('./get-property-value')
const interpretConditionals = require('./interpret-conditionals')
/**
* @typedef {object} PrettifyMessageParams
* @property {object} log The log object with the message to colorize.
* @property {PrettyContext} context The context object built from parsing
* the options.
*/
/**
* Prettifies a message string if the given `log` has a message property.
*
* @param {PrettifyMessageParams} input
*
* @returns {undefined|string} If the message key is not found, or the message
* key is not a string, then `undefined` will be returned. Otherwise, a string
* that is the prettified message.
*/
function prettifyMessage ({ log, context }) {
const {
colorizer,
customLevels,
levelKey,
levelLabel,
messageFormat,
messageKey,
useOnlyCustomProps
} = context
if (messageFormat && typeof messageFormat === 'string') {
const parsedMessageFormat = interpretConditionals(messageFormat, log)
const message = String(parsedMessageFormat).replace(
/{([^{}]+)}/g,
function (match, p1) {
// return log level as string instead of int
let level
if (p1 === levelLabel && (level = getPropertyValue(log, levelKey)) !== undefined) {
const condition = useOnlyCustomProps ? customLevels === undefined : customLevels[level] === undefined
return condition ? LEVELS[level] : customLevels[level]
}
// Parse nested key access, e.g. `{keyA.subKeyB}`.
const value = getPropertyValue(log, p1)
return value !== undefined ? value : ''
})
return colorizer.message(message)
}
if (messageFormat && typeof messageFormat === 'function') {
const msg = messageFormat(log, messageKey, levelLabel, { colors: colorizer.colors })
return colorizer.message(msg)
}
if (messageKey in log === false) return undefined
if (typeof log[messageKey] !== 'string' && typeof log[messageKey] !== 'number' && typeof log[messageKey] !== 'boolean') return undefined
return colorizer.message(log[messageKey])
}

View File

@@ -0,0 +1,118 @@
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: "karaktrojn", verb: "havi" },
file: { unit: "bajtojn", verb: "havi" },
array: { unit: "elementojn", verb: "havi" },
set: { unit: "elementojn", verb: "havi" },
};
function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}
const FormatDictionary: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "enigo",
email: "retadreso",
url: "URL",
emoji: "emoĝio",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "ISO-datotempo",
date: "ISO-dato",
time: "ISO-tempo",
duration: "ISO-daŭro",
ipv4: "IPv4-adreso",
ipv6: "IPv6-adreso",
cidrv4: "IPv4-rango",
cidrv6: "IPv6-rango",
base64: "64-ume kodita karaktraro",
base64url: "URL-64-ume kodita karaktraro",
json_string: "JSON-karaktraro",
e164: "E.164-nombro",
jwt: "JWT",
template_literal: "enigo",
};
const TypeDictionary: {
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
} = {
nan: "NaN",
number: "nombro",
array: "tabelo",
null: "senvalora",
};
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 `Nevalida enigo: atendiĝis instanceof ${issue.expected}, riceviĝis ${received}`;
}
return `Nevalida enigo: atendiĝis ${expected}, riceviĝis ${received}`;
}
case "invalid_value":
if (issue.values.length === 1) return `Nevalida enigo: atendiĝis ${util.stringifyPrimitive(issue.values[0])}`;
return `Nevalida opcio: atendiĝis unu el ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing)
return `Tro granda: atendiĝis ke ${issue.origin ?? "valoro"} havu ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementojn"}`;
return `Tro granda: atendiĝis ke ${issue.origin ?? "valoro"} havu ${adj}${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `Tro malgranda: atendiĝis ke ${issue.origin} havu ${adj}${issue.minimum.toString()} ${sizing.unit}`;
}
return `Tro malgranda: atendiĝis ke ${issue.origin} estu ${adj}${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") return `Nevalida karaktraro: devas komenciĝi per "${_issue.prefix}"`;
if (_issue.format === "ends_with") return `Nevalida karaktraro: devas finiĝi per "${_issue.suffix}"`;
if (_issue.format === "includes") return `Nevalida karaktraro: devas inkluzivi "${_issue.includes}"`;
if (_issue.format === "regex") return `Nevalida karaktraro: devas kongrui kun la modelo ${_issue.pattern}`;
return `Nevalida ${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `Nevalida nombro: devas esti oblo de ${issue.divisor}`;
case "unrecognized_keys":
return `Nekonata${issue.keys.length > 1 ? "j" : ""} ŝlosilo${issue.keys.length > 1 ? "j" : ""}: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `Nevalida ŝlosilo en ${issue.origin}`;
case "invalid_union":
return "Nevalida enigo";
case "invalid_element":
return `Nevalida valoro en ${issue.origin}`;
default:
return `Nevalida enigo`;
}
};
};
export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,117 @@
import { expect, test } from "vitest";
import * as z from "zod/v4";
const literalTuna = z.literal("tuna");
const literalTunaCustomMessage = z.literal("tuna", {
message: "That's not a tuna",
});
const literalFortyTwo = z.literal(42);
const literalTrue = z.literal(true);
test("passing validations", () => {
literalTuna.parse("tuna");
literalFortyTwo.parse(42);
literalTrue.parse(true);
});
test("failing validations", () => {
expect(() => literalTuna.parse("shark")).toThrow();
expect(() => literalFortyTwo.parse(43)).toThrow();
expect(() => literalTrue.parse(false)).toThrow();
});
test("invalid_literal should have `input` field with data", () => {
const data = "shark";
const result = literalTuna.safeParse(data);
const issue = result.error!.issues[0];
expect(issue.code).toBe("invalid_value");
expect(issue).toMatchInlineSnapshot(`
{
"code": "invalid_value",
"message": "Invalid input: expected "tuna"",
"path": [],
"values": [
"tuna",
],
}
`);
});
test("invalid_literal should return default message", () => {
const data = "shark";
const result = literalTuna.safeParse(data);
const issue = result.error!.issues[0];
expect(issue.message).toEqual(`Invalid input: expected \"tuna\"`);
});
test("invalid_literal should return custom message", () => {
const data = "shark";
const result = literalTunaCustomMessage.safeParse(data);
const issue = result.error!.issues[0];
expect(issue.message).toEqual(`That's not a tuna`);
});
test("literal default error message", () => {
const result = z.literal("Tuna").safeParse("Trout");
expect(result.success).toEqual(false);
expect(result.error!.issues.length).toEqual(1);
expect(result.error).toMatchInlineSnapshot(`
[ZodError: [
{
"code": "invalid_value",
"values": [
"Tuna"
],
"path": [],
"message": "Invalid input: expected \\"Tuna\\""
}
]]
`);
});
test("literal bigint default error message", () => {
const result = z.literal(BigInt(12)).safeParse(BigInt(13));
expect(result.success).toBe(false);
expect(result.error!.issues.length).toEqual(1);
expect(result.error!.issues[0].message).toEqual(`Invalid input: expected 12n`);
});
test(".value getter", () => {
expect(z.literal("tuna").value).toEqual("tuna");
expect(() => z.literal([1, 2, 3]).value).toThrow();
});
test("readonly", () => {
const a = ["asdf"] as const;
z.literal(a);
});
test("literal pattern", () => {
expect(z.literal(1.1)._zod.pattern).toMatchInlineSnapshot(`/\\^\\(1\\\\\\.1\\)\\$/`);
expect(z.templateLiteral([z.literal(1.1)]).safeParse("1.1")).toMatchInlineSnapshot(`
{
"data": "1.1",
"success": true,
}
`);
expect(z.templateLiteral([z.literal(1.1)]).safeParse("1n1")).toMatchInlineSnapshot(`
{
"error": [ZodError: [
{
"code": "invalid_format",
"format": "template_literal",
"pattern": "^(1\\\\.1)$",
"path": [],
"message": "Invalid input"
}
]],
"success": false,
}
`);
});

View File

@@ -0,0 +1,68 @@
'use strict'
const pino = require('..')
const { tmpdir } = require('node:os')
const { join } = require('node:path')
const file = join(tmpdir(), `pino-${process.pid}-example`)
const transport = pino.transport({
targets: [{
level: 'warn',
target: 'pino/file',
options: {
destination: file
}
/*
}, {
level: 'info',
target: 'pino-elasticsearch',
options: {
node: 'http://localhost:9200'
}
*/
}, {
level: 'info',
target: 'pino-pretty'
}]
})
const logger = pino(transport)
logger.info({
file
}, 'logging destination')
logger.info('hello world')
logger.error('this is at error level')
logger.info('the answer is %d', 42)
logger.info({ obj: 42 }, 'hello world')
logger.info({ obj: 42, b: 2 }, 'hello world')
logger.info({ nested: { obj: 42 } }, 'nested')
logger.warn('WARNING!')
setImmediate(() => {
logger.info('after setImmediate')
})
logger.error(new Error('an error'))
const child = logger.child({ a: 'property' })
child.info('hello child!')
const childsChild = child.child({ another: 'property' })
childsChild.info('hello baby..')
logger.debug('this should be mute')
logger.level = 'trace'
logger.debug('this is a debug statement')
logger.child({ another: 'property' }).debug('this is a debug statement via child')
logger.trace('this is a trace statement')
logger.debug('this is a "debug" statement with "')
logger.info(new Error('kaboom'))
logger.info(null)
logger.info(new Error('kaboom'), 'with', 'a', 'message')

View File

@@ -0,0 +1,234 @@
/**
* @fileoverview Helpers to debug for code path analysis.
* @author Toru Nagashima
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const debug = require("debug")("eslint:code-path");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Gets id of a given segment.
* @param {CodePathSegment} segment A segment to get.
* @returns {string} Id of the segment.
*/
/* c8 ignore next */
// eslint-disable-next-line jsdoc/require-jsdoc -- Ignoring
function getId(segment) {
return segment.id + (segment.reachable ? "" : "!");
}
/**
* Get string for the given node and operation.
* @param {ASTNode} node The node to convert.
* @param {"enter" | "exit" | undefined} label The operation label.
* @returns {string} The string representation.
*/
function nodeToString(node, label) {
const suffix = label ? `:${label}` : "";
switch (node.type) {
case "Identifier":
return `${node.type}${suffix} (${node.name})`;
case "Literal":
return `${node.type}${suffix} (${node.value})`;
default:
return `${node.type}${suffix}`;
}
}
/**
* Escape text for use in a DOT label.
* @param {string} value The value to escape.
* @returns {string} The escaped value.
*/
function escapeDotLabelText(value) {
return value.replace(/\\/gu, String.raw`\\`).replace(/"/gu, String.raw`\"`);
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
/**
* A flag that debug dumping is enabled or not.
* @type {boolean}
*/
enabled: debug.enabled,
/**
* Dumps given objects.
* @param {...any} args objects to dump.
* @returns {void}
*/
dump: debug,
/**
* Dumps the current analyzing state.
* @param {ASTNode} node A node to dump.
* @param {CodePathState} state A state to dump.
* @param {boolean} leaving A flag whether or not it's leaving
* @returns {void}
*/
dumpState: !debug.enabled
? debug
: /* c8 ignore next */ function (node, state, leaving) {
for (let i = 0; i < state.currentSegments.length; ++i) {
const segInternal = state.currentSegments[i].internal;
if (leaving) {
const last = segInternal.nodes.length - 1;
if (
last >= 0 &&
segInternal.nodes[last] ===
nodeToString(node, "enter")
) {
segInternal.nodes[last] = nodeToString(
node,
void 0,
);
} else {
segInternal.nodes.push(nodeToString(node, "exit"));
}
} else {
segInternal.nodes.push(nodeToString(node, "enter"));
}
}
debug(
[
`${state.currentSegments.map(getId).join(",")})`,
`${node.type}${leaving ? ":exit" : ""}`,
].join(" "),
);
},
/**
* Dumps a DOT code of a given code path.
* The DOT code can be visualized with Graphvis.
* @param {CodePath} codePath A code path to dump.
* @returns {void}
* @see https://www.graphviz.org
* @see http://www.webgraphviz.com
*/
dumpDot: !debug.enabled
? debug
: /* c8 ignore next */ function (codePath) {
let text =
"\n" +
"digraph {\n" +
'node[shape=box,style="rounded,filled",fillcolor=white];\n' +
'initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n';
if (codePath.returnedSegments.length > 0) {
text +=
'final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n';
}
if (codePath.thrownSegments.length > 0) {
text +=
'thrown[label="✘",shape=circle,width=0.3,height=0.3,fixedsize=true];\n';
}
const traceMap = Object.create(null);
const arrows = this.makeDotArrows(codePath, traceMap);
// eslint-disable-next-line guard-for-in -- Want ability to traverse prototype
for (const id in traceMap) {
const segment = traceMap[id];
text += `${id}[`;
if (segment.reachable) {
text += 'label="';
} else {
text +=
'style="rounded,dashed,filled",fillcolor="#FF9800",label="<<unreachable>>\\n';
}
if (segment.internal.nodes.length > 0) {
text += segment.internal.nodes
.map(escapeDotLabelText)
.join("\\n");
} else {
text += "????";
}
text += '"];\n';
}
text += `${arrows}\n`;
text += "}";
debug("DOT", text);
},
/**
* Makes a DOT code of a given code path.
* The DOT code can be visualized with Graphvis.
* @param {CodePath} codePath A code path to make DOT.
* @param {Object} traceMap Optional. A map to check whether or not segments had been done.
* @returns {string} A DOT code of the code path.
*/
makeDotArrows(codePath, traceMap) {
const stack = [[codePath.initialSegment, 0]];
const done = traceMap || Object.create(null);
let lastId = codePath.initialSegment.id;
let text = `initial->${codePath.initialSegment.id}`;
while (stack.length > 0) {
const item = stack.pop();
const segment = item[0];
const index = item[1];
if (done[segment.id] && index === 0) {
continue;
}
done[segment.id] = segment;
const nextSegment = segment.allNextSegments[index];
if (!nextSegment) {
continue;
}
if (lastId === segment.id) {
text += `->${nextSegment.id}`;
} else {
text += `;\n${segment.id}->${nextSegment.id}`;
}
lastId = nextSegment.id;
stack.unshift([segment, 1 + index]);
stack.push([nextSegment, 0]);
}
codePath.returnedSegments.forEach(finalSegment => {
if (lastId === finalSegment.id) {
text += "->final";
} else {
text += `;\n${finalSegment.id}->final`;
}
lastId = null;
});
codePath.thrownSegments.forEach(finalSegment => {
if (lastId === finalSegment.id) {
text += "->thrown";
} else {
text += `;\n${finalSegment.id}->thrown`;
}
lastId = null;
});
return `${text};`;
},
};

View File

@@ -0,0 +1,155 @@
declare const _default: {
extends: string[];
rules: {
'@typescript-eslint/adjacent-overload-signatures': "error";
'@typescript-eslint/array-type': "error";
'@typescript-eslint/await-thenable': "error";
'@typescript-eslint/ban-ts-comment': "error";
'@typescript-eslint/ban-tslint-comment': "error";
'@typescript-eslint/class-literal-property-style': "error";
'class-methods-use-this': "off";
'@typescript-eslint/class-methods-use-this': "error";
'@typescript-eslint/consistent-generic-constructors': "error";
'@typescript-eslint/consistent-indexed-object-style': "error";
'consistent-return': "off";
'@typescript-eslint/consistent-return': "error";
'@typescript-eslint/consistent-type-assertions': "error";
'@typescript-eslint/consistent-type-definitions': "error";
'@typescript-eslint/consistent-type-exports': "error";
'@typescript-eslint/consistent-type-imports': "error";
'default-param-last': "off";
'@typescript-eslint/default-param-last': "error";
'dot-notation': "off";
'@typescript-eslint/dot-notation': "error";
'@typescript-eslint/explicit-function-return-type': "error";
'@typescript-eslint/explicit-member-accessibility': "error";
'@typescript-eslint/explicit-module-boundary-types': "error";
'init-declarations': "off";
'@typescript-eslint/init-declarations': "error";
'max-params': "off";
'@typescript-eslint/max-params': "error";
'@typescript-eslint/member-ordering': "error";
'@typescript-eslint/method-signature-style': "error";
'@typescript-eslint/naming-convention': "error";
'no-array-constructor': "off";
'@typescript-eslint/no-array-constructor': "error";
'@typescript-eslint/no-array-delete': "error";
'@typescript-eslint/no-base-to-string': "error";
'@typescript-eslint/no-confusing-non-null-assertion': "error";
'@typescript-eslint/no-confusing-void-expression': "error";
'@typescript-eslint/no-deprecated': "error";
'no-dupe-class-members': "off";
'@typescript-eslint/no-dupe-class-members': "error";
'@typescript-eslint/no-duplicate-enum-values': "error";
'@typescript-eslint/no-duplicate-type-constituents': "error";
'@typescript-eslint/no-dynamic-delete': "error";
'no-empty-function': "off";
'@typescript-eslint/no-empty-function': "error";
'@typescript-eslint/no-empty-object-type': "error";
'@typescript-eslint/no-explicit-any': "error";
'@typescript-eslint/no-extra-non-null-assertion': "error";
'@typescript-eslint/no-extraneous-class': "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-import-type-side-effects': "error";
'@typescript-eslint/no-inferrable-types': "error";
'no-invalid-this': "off";
'@typescript-eslint/no-invalid-this': "error";
'@typescript-eslint/no-invalid-void-type': "error";
'no-magic-numbers': "off";
'@typescript-eslint/no-magic-numbers': "error";
'@typescript-eslint/no-meaningless-void-operator': "error";
'@typescript-eslint/no-misused-new': "error";
'@typescript-eslint/no-misused-promises': "error";
'@typescript-eslint/no-misused-spread': "error";
'@typescript-eslint/no-mixed-enums': "error";
'@typescript-eslint/no-namespace': "error";
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': "error";
'@typescript-eslint/no-non-null-asserted-optional-chain': "error";
'@typescript-eslint/no-non-null-assertion': "error";
'no-redeclare': "off";
'@typescript-eslint/no-redeclare': "error";
'@typescript-eslint/no-redundant-type-constituents': "error";
'@typescript-eslint/no-require-imports': "error";
'@typescript-eslint/no-restricted-types': "error";
'no-shadow': "off";
'@typescript-eslint/no-shadow': "error";
'@typescript-eslint/no-this-alias': "error";
'@typescript-eslint/no-unnecessary-boolean-literal-compare': "error";
'@typescript-eslint/no-unnecessary-condition': "error";
'@typescript-eslint/no-unnecessary-parameter-property-assignment': "error";
'@typescript-eslint/no-unnecessary-qualifier': "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-constraint': "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-declaration-merging': "error";
'@typescript-eslint/no-unsafe-enum-comparison': "error";
'@typescript-eslint/no-unsafe-function-type': "error";
'@typescript-eslint/no-unsafe-member-access': "error";
'@typescript-eslint/no-unsafe-return': "error";
'@typescript-eslint/no-unsafe-type-assertion': "error";
'@typescript-eslint/no-unsafe-unary-minus': "error";
'no-unused-expressions': "off";
'@typescript-eslint/no-unused-expressions': "error";
'no-unused-private-class-members': "off";
'@typescript-eslint/no-unused-private-class-members': "error";
'no-unused-vars': "off";
'@typescript-eslint/no-unused-vars': "error";
'no-use-before-define': "off";
'@typescript-eslint/no-use-before-define': "error";
'no-useless-constructor': "off";
'@typescript-eslint/no-useless-constructor': "error";
'@typescript-eslint/no-useless-default-assignment': "error";
'@typescript-eslint/no-useless-empty-export': "error";
'@typescript-eslint/no-wrapper-object-types': "error";
'@typescript-eslint/non-nullable-type-assertion-style': "error";
'no-throw-literal': "off";
'@typescript-eslint/only-throw-error': "error";
'@typescript-eslint/parameter-properties': "error";
'@typescript-eslint/prefer-as-const': "error";
'prefer-destructuring': "off";
'@typescript-eslint/prefer-destructuring': "error";
'@typescript-eslint/prefer-enum-initializers': "error";
'@typescript-eslint/prefer-find': "error";
'@typescript-eslint/prefer-for-of': "error";
'@typescript-eslint/prefer-function-type': "error";
'@typescript-eslint/prefer-includes': "error";
'@typescript-eslint/prefer-literal-enum-member': "error";
'@typescript-eslint/prefer-namespace-keyword': "error";
'@typescript-eslint/prefer-nullish-coalescing': "error";
'@typescript-eslint/prefer-optional-chain': "error";
'prefer-promise-reject-errors': "off";
'@typescript-eslint/prefer-promise-reject-errors': "error";
'@typescript-eslint/prefer-readonly': "error";
'@typescript-eslint/prefer-readonly-parameter-types': "error";
'@typescript-eslint/prefer-reduce-type-parameter': "error";
'@typescript-eslint/prefer-regexp-exec': "error";
'@typescript-eslint/prefer-return-this-type': "error";
'@typescript-eslint/prefer-string-starts-ends-with': "error";
'@typescript-eslint/promise-function-async': "error";
'@typescript-eslint/related-getter-setter-pairs': "error";
'@typescript-eslint/require-array-sort-compare': "error";
'require-await': "off";
'@typescript-eslint/require-await': "error";
'@typescript-eslint/restrict-plus-operands': "error";
'@typescript-eslint/restrict-template-expressions': "error";
'no-return-await': "off";
'@typescript-eslint/return-await': "error";
'@typescript-eslint/strict-boolean-expressions': "error";
'@typescript-eslint/strict-void-return': "error";
'@typescript-eslint/switch-exhaustiveness-check': "error";
'@typescript-eslint/triple-slash-reference': "error";
'@typescript-eslint/unbound-method': "error";
'@typescript-eslint/unified-signatures': "error";
'@typescript-eslint/use-unknown-in-catch-callback-variable': "error";
};
};
export = _default;

View File

@@ -0,0 +1,239 @@
import type { $ZodStringFormats } from "../core/checks.js";
import type * as errors from "../core/errors.js";
import * as util from "../core/util.js";
const capitalizeFirstCharacter = (text: string): string => {
return text.charAt(0).toUpperCase() + text.slice(1);
};
type UnitType = "one" | "few" | "many";
type SizeableComparisonType = "smaller" | "bigger";
function getUnitTypeFromNumber(number: number): UnitType {
const abs = Math.abs(number);
const last = abs % 10;
const last2 = abs % 100;
if ((last2 >= 11 && last2 <= 19) || last === 0) return "many";
if (last === 1) return "one";
return "few";
}
const error: () => errors.$ZodErrorMap = () => {
const Sizable: Record<
string,
{
unit: Record<UnitType, string>;
verb: Record<SizeableComparisonType, { inclusive: string; notInclusive: string }>;
}
> = {
string: {
unit: {
one: "simbolis",
few: "simboliai",
many: "simbolių",
},
verb: {
smaller: {
inclusive: "turi būti ne ilgesnė kaip",
notInclusive: "turi būti trumpesnė kaip",
},
bigger: {
inclusive: "turi būti ne trumpesnė kaip",
notInclusive: "turi būti ilgesnė kaip",
},
},
},
file: {
unit: {
one: "baitas",
few: "baitai",
many: "baitų",
},
verb: {
smaller: {
inclusive: "turi būti ne didesnis kaip",
notInclusive: "turi būti mažesnis kaip",
},
bigger: {
inclusive: "turi būti ne mažesnis kaip",
notInclusive: "turi būti didesnis kaip",
},
},
},
array: {
unit: {
one: "elementą",
few: "elementus",
many: "elementų",
},
verb: {
smaller: {
inclusive: "turi turėti ne daugiau kaip",
notInclusive: "turi turėti mažiau kaip",
},
bigger: {
inclusive: "turi turėti ne mažiau kaip",
notInclusive: "turi turėti daugiau kaip",
},
},
},
set: {
unit: {
one: "elementą",
few: "elementus",
many: "elementų",
},
verb: {
smaller: {
inclusive: "turi turėti ne daugiau kaip",
notInclusive: "turi turėti mažiau kaip",
},
bigger: {
inclusive: "turi turėti ne mažiau kaip",
notInclusive: "turi turėti daugiau kaip",
},
},
},
};
function getSizing(
origin: string,
unitType: UnitType,
inclusive: boolean,
targetShouldBe: SizeableComparisonType
): {
unit: string;
verb: string;
} | null {
const result = Sizable[origin] ?? null;
if (result === null) return result;
return {
unit: result.unit[unitType],
verb: result.verb[targetShouldBe][inclusive ? "inclusive" : "notInclusive"],
};
}
const FormatDictionary: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "įvestis",
email: "el. pašto adresas",
url: "URL",
emoji: "jaustukas",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "ISO data ir laikas",
date: "ISO data",
time: "ISO laikas",
duration: "ISO trukmė",
ipv4: "IPv4 adresas",
ipv6: "IPv6 adresas",
cidrv4: "IPv4 tinklo prefiksas (CIDR)",
cidrv6: "IPv6 tinklo prefiksas (CIDR)",
base64: "base64 užkoduota eilutė",
base64url: "base64url užkoduota eilutė",
json_string: "JSON eilutė",
e164: "E.164 numeris",
jwt: "JWT",
template_literal: "įvestis",
};
const TypeDictionary: {
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
} = {
nan: "NaN",
number: "skaičius",
bigint: "sveikasis skaičius",
string: "eilutė",
boolean: "loginė reikšmė",
undefined: "neapibrėžta reikšmė",
function: "funkcija",
symbol: "simbolis",
array: "masyvas",
object: "objektas",
null: "nulinė reikšmė",
};
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 `Gautas tipas ${received}, o tikėtasi - instanceof ${issue.expected}`;
}
return `Gautas tipas ${received}, o tikėtasi - ${expected}`;
}
case "invalid_value":
if (issue.values.length === 1) return `Privalo būti ${util.stringifyPrimitive(issue.values[0])}`;
return `Privalo būti vienas iš ${util.joinValues(issue.values, "|")} pasirinkimų`;
case "too_big": {
const origin = TypeDictionary[issue.origin] ?? issue.origin;
const sizing = getSizing(
issue.origin,
getUnitTypeFromNumber(Number(issue.maximum)),
issue.inclusive ?? false,
"smaller"
);
if (sizing?.verb)
return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} ${sizing.verb} ${issue.maximum.toString()} ${sizing.unit ?? "elementų"}`;
const adj = issue.inclusive ? "ne didesnis kaip" : "mažesnis kaip";
return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} turi būti ${adj} ${issue.maximum.toString()} ${sizing?.unit}`;
}
case "too_small": {
const origin = TypeDictionary[issue.origin] ?? issue.origin;
const sizing = getSizing(
issue.origin,
getUnitTypeFromNumber(Number(issue.minimum)),
issue.inclusive ?? false,
"bigger"
);
if (sizing?.verb)
return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} ${sizing.verb} ${issue.minimum.toString()} ${sizing.unit ?? "elementų"}`;
const adj = issue.inclusive ? "ne mažesnis kaip" : "didesnis kaip";
return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} turi būti ${adj} ${issue.minimum.toString()} ${sizing?.unit}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") {
return `Eilutė privalo prasidėti "${_issue.prefix}"`;
}
if (_issue.format === "ends_with") return `Eilutė privalo pasibaigti "${_issue.suffix}"`;
if (_issue.format === "includes") return `Eilutė privalo įtraukti "${_issue.includes}"`;
if (_issue.format === "regex") return `Eilutė privalo atitikti ${_issue.pattern}`;
return `Neteisingas ${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `Skaičius privalo būti ${issue.divisor} kartotinis.`;
case "unrecognized_keys":
return `Neatpažint${issue.keys.length > 1 ? "i" : "as"} rakt${issue.keys.length > 1 ? "ai" : "as"}: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return "Rastas klaidingas raktas";
case "invalid_union":
return "Klaidinga įvestis";
case "invalid_element": {
const origin = TypeDictionary[issue.origin] ?? issue.origin;
return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} turi klaidingą įvestį`;
}
default:
return "Klaidinga įvestis";
}
};
};
export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,134 @@
import { expect, test } from "vitest";
import * as z from "zod/v4";
test("length checks", async () => {
const schema = z.string();
const result = await schema["~standard"].validate(12);
expect(result).toMatchInlineSnapshot(`
{
"issues": [
{
"code": "invalid_type",
"expected": "string",
"message": "Invalid input: expected string, received number",
"path": [],
},
],
}
`);
});
test("length checks", async () => {
const schema = z.string();
const result = await schema["~standard"].validate("asdf");
expect(result).toMatchInlineSnapshot(`
{
"value": "asdf",
}
`);
});
test("length checks", async () => {
const schema = z.string().refine(async (val) => val.length > 5);
const result = await schema["~standard"].validate(12);
expect(result).toMatchInlineSnapshot(`
{
"issues": [
{
"code": "invalid_type",
"expected": "string",
"message": "Invalid input: expected string, received number",
"path": [],
},
],
}
`);
});
test("length checks", async () => {
const schema = z.string().refine(async (val) => val.length > 5);
const result = await schema["~standard"].validate("234134134");
expect(result).toMatchInlineSnapshot(`
{
"value": "234134134",
}
`);
});
test("schemas conform to StandardJSONSchemaV1", async () => {
const schema = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseFloat(str),
encode: (num) => num.toString(),
});
expect(schema["~standard"].validate).toBeTypeOf("function");
expect(await schema["~standard"].validate("42")).toMatchInlineSnapshot(`
{
"value": 42,
}
`);
expect(schema["~standard"].jsonSchema.input({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string",
}
`);
expect(schema["~standard"].jsonSchema.output({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "number",
}
`);
});
test(".toJSONSchema() returns StandardJSONSchemaV1", async () => {
const codec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseFloat(str),
encode: (num) => num.toString(),
});
const result = codec.toJSONSchema();
expect(result["~standard"].validate).toBeTypeOf("function");
expect(await result["~standard"].validate("42")).toMatchInlineSnapshot(`
{
"value": 42,
}
`);
expect(result["~standard"].jsonSchema.input({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string",
}
`);
expect(result["~standard"].jsonSchema.output({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "number",
}
`);
});
test("z.toJSONSchema() returns StandardJSONSchemaV1", async () => {
const codec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseFloat(str),
encode: (num) => num.toString(),
});
const result = z.toJSONSchema(codec);
expect(result["~standard"].validate).toBeTypeOf("function");
expect(await result["~standard"].validate("42")).toMatchInlineSnapshot(`
{
"value": 42,
}
`);
expect(result["~standard"].jsonSchema.input({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string",
}
`);
expect(result["~standard"].jsonSchema.output({ target: "draft-2020-12" })).toMatchInlineSnapshot(`
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "number",
}
`);
});

View File

@@ -0,0 +1,368 @@
/**
* @fileoverview enforce consistent line breaks inside function parentheses
* @author Teddy Katz
* @deprecated in ESLint v8.53.0
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
deprecated: {
message: "Formatting rules are being moved out of ESLint core.",
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
deprecatedSince: "8.53.0",
availableUntil: "11.0.0",
replacedBy: [
{
message:
"ESLint Stylistic now maintains deprecated stylistic core rules.",
url: "https://eslint.style/guide/migration",
plugin: {
name: "@stylistic/eslint-plugin",
url: "https://eslint.style",
},
rule: {
name: "function-paren-newline",
url: "https://eslint.style/rules/function-paren-newline",
},
},
],
},
type: "layout",
docs: {
description:
"Enforce consistent line breaks inside function parentheses",
recommended: false,
url: "https://eslint.org/docs/latest/rules/function-paren-newline",
},
fixable: "whitespace",
schema: [
{
oneOf: [
{
enum: [
"always",
"never",
"consistent",
"multiline",
"multiline-arguments",
],
},
{
type: "object",
properties: {
minItems: {
type: "integer",
minimum: 0,
},
},
additionalProperties: false,
},
],
},
],
messages: {
expectedBefore: "Expected newline before ')'.",
expectedAfter: "Expected newline after '('.",
expectedBetween: "Expected newline between arguments/params.",
unexpectedBefore: "Unexpected newline before ')'.",
unexpectedAfter: "Unexpected newline after '('.",
},
},
create(context) {
const sourceCode = context.sourceCode;
const rawOption = context.options[0] || "multiline";
const multilineOption = rawOption === "multiline";
const multilineArgumentsOption = rawOption === "multiline-arguments";
const consistentOption = rawOption === "consistent";
let minItems;
if (typeof rawOption === "object") {
minItems = rawOption.minItems;
} else if (rawOption === "always") {
minItems = 0;
} else if (rawOption === "never") {
minItems = Infinity;
} else {
minItems = null;
}
//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
/**
* Determines whether there should be newlines inside function parens
* @param {ASTNode[]} elements The arguments or parameters in the list
* @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code.
* @returns {boolean} `true` if there should be newlines inside the function parens
*/
function shouldHaveNewlines(elements, hasLeftNewline) {
if (multilineArgumentsOption && elements.length === 1) {
return hasLeftNewline;
}
if (multilineOption || multilineArgumentsOption) {
return elements.some(
(element, index) =>
index !== elements.length - 1 &&
element.loc.end.line !==
elements[index + 1].loc.start.line,
);
}
if (consistentOption) {
return hasLeftNewline;
}
return elements.length >= minItems;
}
/**
* Validates parens
* @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token
* @param {ASTNode[]} elements The arguments or parameters in the list
* @returns {void}
*/
function validateParens(parens, elements) {
const leftParen = parens.leftParen;
const rightParen = parens.rightParen;
const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen);
const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen);
const hasLeftNewline = !astUtils.isTokenOnSameLine(
leftParen,
tokenAfterLeftParen,
);
const hasRightNewline = !astUtils.isTokenOnSameLine(
tokenBeforeRightParen,
rightParen,
);
const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline);
if (hasLeftNewline && !needsNewlines) {
context.report({
node: leftParen,
messageId: "unexpectedAfter",
fix(fixer) {
return sourceCode
.getText()
.slice(
leftParen.range[1],
tokenAfterLeftParen.range[0],
)
.trim()
? // If there is a comment between the ( and the first element, don't do a fix.
null
: fixer.removeRange([
leftParen.range[1],
tokenAfterLeftParen.range[0],
]);
},
});
} else if (!hasLeftNewline && needsNewlines) {
context.report({
node: leftParen,
messageId: "expectedAfter",
fix: fixer => fixer.insertTextAfter(leftParen, "\n"),
});
}
if (hasRightNewline && !needsNewlines) {
context.report({
node: rightParen,
messageId: "unexpectedBefore",
fix(fixer) {
return sourceCode
.getText()
.slice(
tokenBeforeRightParen.range[1],
rightParen.range[0],
)
.trim()
? // If there is a comment between the last element and the ), don't do a fix.
null
: fixer.removeRange([
tokenBeforeRightParen.range[1],
rightParen.range[0],
]);
},
});
} else if (!hasRightNewline && needsNewlines) {
context.report({
node: rightParen,
messageId: "expectedBefore",
fix: fixer => fixer.insertTextBefore(rightParen, "\n"),
});
}
}
/**
* Validates a list of arguments or parameters
* @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token
* @param {ASTNode[]} elements The arguments or parameters in the list
* @returns {void}
*/
function validateArguments(parens, elements) {
const leftParen = parens.leftParen;
const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen);
const hasLeftNewline = !astUtils.isTokenOnSameLine(
leftParen,
tokenAfterLeftParen,
);
const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline);
for (let i = 0; i <= elements.length - 2; i++) {
const currentElement = elements[i];
const nextElement = elements[i + 1];
const hasNewLine =
currentElement.loc.end.line !== nextElement.loc.start.line;
if (!hasNewLine && needsNewlines) {
context.report({
node: currentElement,
messageId: "expectedBetween",
fix: fixer => fixer.insertTextBefore(nextElement, "\n"),
});
}
}
}
/**
* Gets the left paren and right paren tokens of a node.
* @param {ASTNode} node The node with parens
* @throws {TypeError} Unexpected node type.
* @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token.
* Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression
* with a single parameter)
*/
function getParenTokens(node) {
switch (node.type) {
case "NewExpression":
if (
!node.arguments.length &&
!(
astUtils.isOpeningParenToken(
sourceCode.getLastToken(node, { skip: 1 }),
) &&
astUtils.isClosingParenToken(
sourceCode.getLastToken(node),
) &&
node.callee.range[1] < node.range[1]
)
) {
// If the NewExpression does not have parens (e.g. `new Foo`), return null.
return null;
}
// falls through
case "CallExpression":
return {
leftParen: sourceCode.getTokenAfter(
node.callee,
astUtils.isOpeningParenToken,
),
rightParen: sourceCode.getLastToken(node),
};
case "FunctionDeclaration":
case "FunctionExpression": {
const leftParen = sourceCode.getFirstToken(
node,
astUtils.isOpeningParenToken,
);
const rightParen = node.params.length
? sourceCode.getTokenAfter(
node.params.at(-1),
astUtils.isClosingParenToken,
)
: sourceCode.getTokenAfter(leftParen);
return { leftParen, rightParen };
}
case "ArrowFunctionExpression": {
const firstToken = sourceCode.getFirstToken(node, {
skip: node.async ? 1 : 0,
});
if (!astUtils.isOpeningParenToken(firstToken)) {
// If the ArrowFunctionExpression has a single param without parens, return null.
return null;
}
const rightParen = node.params.length
? sourceCode.getTokenAfter(
node.params.at(-1),
astUtils.isClosingParenToken,
)
: sourceCode.getTokenAfter(firstToken);
return {
leftParen: firstToken,
rightParen,
};
}
case "ImportExpression": {
const leftParen = sourceCode.getFirstToken(node, 1);
const rightParen = sourceCode.getLastToken(node);
return { leftParen, rightParen };
}
default:
throw new TypeError(
`unexpected node with type ${node.type}`,
);
}
}
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
[[
"ArrowFunctionExpression",
"CallExpression",
"FunctionDeclaration",
"FunctionExpression",
"ImportExpression",
"NewExpression",
]](node) {
const parens = getParenTokens(node);
let params;
if (node.type === "ImportExpression") {
params = [node.source];
} else if (astUtils.isFunction(node)) {
params = node.params;
} else {
params = node.arguments;
}
if (parens) {
validateParens(parens, params);
if (multilineArgumentsOption) {
validateArguments(parens, params);
}
}
},
};
},
};

View File

@@ -0,0 +1,134 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const util = __importStar(require("../core/util.cjs"));
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: "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",
};
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 `無法識別的鍵值${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 `無效的輸入值`;
}
};
};
function default_1() {
return {
localeError: error(),
};
}
module.exports = exports.default;

View File

@@ -0,0 +1,71 @@
bs58
====
[![build status](https://travis-ci.org/cryptocoinjs/bs58.svg)](https://travis-ci.org/cryptocoinjs/bs58)
JavaScript component to compute base 58 encoding. This encoding is typically used for crypto currencies such as Bitcoin.
**Note:** If you're looking for **base 58 check** encoding, see: [https://github.com/bitcoinjs/bs58check](https://github.com/bitcoinjs/bs58check), which depends upon this library.
Install
-------
npm i --save bs58
API
---
### encode(input)
`input` must be a [Buffer](https://nodejs.org/api/buffer.html) or an `Array`. It returns a `string`.
**example**:
```js
const bs58 = require('bs58')
const bytes = Buffer.from('003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187', 'hex')
const address = bs58.encode(bytes)
console.log(address)
// => 16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS
```
### decode(input)
`input` must be a base 58 encoded string. Returns a [Buffer](https://nodejs.org/api/buffer.html).
**example**:
```js
const bs58 = require('bs58')
const address = '16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS'
const bytes = bs58.decode(address)
console.log(out.toString('hex'))
// => 003c176e659bea0f29a3e9bf7880c112b1b31b4dc826268187
```
Hack / Test
-----------
Uses JavaScript standard style. Read more:
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
Credits
-------
- [Mike Hearn](https://github.com/mikehearn) for original Java implementation
- [Stefan Thomas](https://github.com/justmoon) for porting to JavaScript
- [Stephan Pair](https://github.com/gasteve) for buffer improvements
- [Daniel Cousens](https://github.com/dcousens) for cleanup and merging improvements from bitcoinjs-lib
- [Jared Deckard](https://github.com/deckar01) for killing `bigi` as a dependency
License
-------
MIT

View File

@@ -0,0 +1,690 @@
"use strict";
var _TRAILING_WILD_CARD_R;
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
// A simple implementation of make-array
function makeArray(subject) {
return Array.isArray(subject) ? subject : [subject];
}
var UNDEFINED = undefined;
var EMPTY = '';
var SPACE = ' ';
var ESCAPE = '\\';
var REGEX_TEST_BLANK_LINE = /^\s+$/;
var REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
var REGEX_SPLITALL_CRLF = /\r?\n/g;
// Invalid:
// - /foo,
// - ./foo,
// - ../foo,
// - .
// - ..
// Valid:
// - .foo
var REGEX_TEST_INVALID_PATH = /^\.{0,2}\/|^\.{1,2}$/;
var REGEX_TEST_TRAILING_SLASH = /\/$/;
var SLASH = '/';
// Do not use ternary expression here, since "istanbul ignore next" is buggy
var TMP_KEY_IGNORE = 'node-ignore';
/* istanbul ignore else */
if (typeof Symbol !== 'undefined') {
TMP_KEY_IGNORE = Symbol["for"]('node-ignore');
}
var KEY_IGNORE = TMP_KEY_IGNORE;
var define = function define(object, key, value) {
Object.defineProperty(object, key, {
value: value
});
return value;
};
var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
var RETURN_FALSE = function RETURN_FALSE() {
return false;
};
// Sanitize the range of a regular expression
// The cases are complicated, see test cases for details
var sanitizeRange = function sanitizeRange(range) {
return range.replace(REGEX_REGEXP_RANGE, function (match, from, to) {
return from.charCodeAt(0) <= to.charCodeAt(0) ? match
// Invalid range (out of order) which is ok for gitignore rules but
// fatal for JavaScript regular expression, so eliminate it.
: EMPTY;
});
};
// > An optional `!` or `^` at the start of a class negates it, so that it
// > matches any character not in the set. (gitignore(5), fnmatch(3))
// The leading `^` has already been escaped to `\^` by the metacharacter
// escaper, so we strip the literal `!` or escaped `^` and emit a single
// regex `^` which is the JavaScript negation token.
var negateRange = function negateRange(range) {
return range.startsWith('!') || range.startsWith('\\^') ? "^".concat(range.slice(range[0] === '!' ? 1 : 2)) : range;
};
// See fixtures #59
var cleanRangeBackSlash = function cleanRangeBackSlash(slashes) {
var length = slashes.length;
return slashes.slice(0, length - length % 2);
};
// > If the pattern ends with a slash,
// > it is removed for the purpose of the following description,
// > but it would only find a match with a directory.
// > In other words, foo/ will match a directory foo and paths underneath it,
// > but will not match a regular file or a symbolic link foo
// > (this is consistent with the way how pathspec works in general in Git).
// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
// you could use option `mark: true` with `glob`
// '`foo/`' should not continue with the '`..`'
var REPLACERS = [[
// Remove BOM
// TODO:
// Other similar zero-width characters?
/^\uFEFF/, function () {
return EMPTY;
}],
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
[
// (a\ ) -> (a )
// (a ) -> (a)
// (a ) -> (a)
// (a \ ) -> (a )
/((?:\\\\)*?)(\\?\s+)$/, function (_, m1, m2) {
return m1 + (m2.indexOf('\\') === 0 ? SPACE : EMPTY);
}],
// Replace (\ ) with ' '
// (\ ) -> ' '
// (\\ ) -> '\\ '
// (\\\ ) -> '\\ '
[/(\\+?)\s/g, function (_, m1) {
var length = m1.length;
return m1.slice(0, length - length % 2) + SPACE;
}],
// Escape metacharacters
// which is written down by users but means special for regular expressions.
// > There are 12 characters with special meanings:
// > - the backslash \,
// > - the caret ^,
// > - the dollar sign $,
// > - the period or dot .,
// > - the vertical bar or pipe symbol |,
// > - the question mark ?,
// > - the asterisk or star *,
// > - the plus sign +,
// > - the opening parenthesis (,
// > - the closing parenthesis ),
// > - and the opening square bracket [,
// > - the opening curly brace {,
// > These special characters are often called "metacharacters".
[/[\\$.|*+(){^]/g, function (match) {
return "\\".concat(match);
}], [
// > a question mark (?) matches a single character
/(?!\\)\?/g, function () {
return '[^/]';
}],
// leading slash
[
// > A leading slash matches the beginning of the pathname.
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
// A leading slash matches the beginning of the pathname
/^\//, function () {
return '^';
}],
// replace special metacharacter slash after the leading slash
[/\//g, function () {
return '\\/';
}], [
// > A leading "**" followed by a slash means match in all directories.
// > For example, "**/foo" matches file or directory "foo" anywhere,
// > the same as pattern "foo".
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
// > under directory "foo".
// Notice that the '*'s have been replaced as '\\*'
/^\^*(?:\\\*\\\*\\\/)+/,
// '**/foo' <-> 'foo'
function () {
return '^(?:.*\\/)?';
}],
// starting
[
// there will be no leading '/'
// (which has been replaced by section "leading slash")
// If starts with '**', adding a '^' to the regular expression also works
/^(?=[^^])/, function startingReplacer() {
// If has a slash `/` at the beginning or middle
return !/\/(?!$)/.test(this)
// > Prior to 2.22.1
// > If the pattern does not contain a slash /,
// > Git treats it as a shell glob pattern
// Actually, if there is only a trailing slash,
// git also treats it as a shell glob pattern
// After 2.22.1 (compatible but clearer)
// > If there is a separator at the beginning or middle (or both)
// > of the pattern, then the pattern is relative to the directory
// > level of the particular .gitignore file itself.
// > Otherwise the pattern may also match at any level below
// > the .gitignore level.
? '(?:^|\\/)'
// > Otherwise, Git treats the pattern as a shell glob suitable for
// > consumption by fnmatch(3)
: '^';
}],
// two globstars
[
// Use lookahead assertions so that we could match more than one `'/**'`
/\\\/\\\*\\\*(?=\\\/|$)/g,
// Zero, one or several directories
// should not use '*', or it will be replaced by the next replacer
// Check if it is not the last `'/**'`
function (_, index, str) {
return index + 6 < str.length
// case: /**/
// > A slash followed by two consecutive asterisks then a slash matches
// > zero or more directories.
// > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
// '/**/'
? '(?:\\/[^\\/]+)*'
// case: /**
// > A trailing `"/**"` matches everything inside.
// #21: everything inside but it should not include the current folder
: '\\/.+';
}],
// normal intermediate wildcards
[
// Never replace escaped '*'
// ignore rule '\*' will match the path '*'
// 'abc.*/' -> go
// 'abc.*' -> skip this rule,
// coz trailing single wildcard will be handed by [trailing wildcard]
/(^|[^\\]+)(\\\*)+(?=.+)/g,
// '*.js' matches '.js'
// '*.js' doesn't match 'abc'
function (_, p1, p2) {
// 1.
// > An asterisk "*" matches anything except a slash.
// 2.
// > Other consecutive asterisks are considered regular asterisks
// > and will match according to the previous rules.
var unescaped = p2.replace(/\\\*/g, '[^\\/]*');
return p1 + unescaped;
}], [
// unescape, revert step 3 except for back slash
// For example, if a user escape a '\\*',
// after step 3, the result will be '\\\\\\*'
/\\\\\\(?=[$.|*+(){^])/g, function () {
return ESCAPE;
}], [
// '\\\\' -> '\\'
/\\\\/g, function () {
return ESCAPE;
}], [
// > The range notation, e.g. [a-zA-Z],
// > can be used to match one of the characters in a range.
// `\` is escaped by step 3
/(\\)?\[([^\]/]*?)(\\*)($|\])/g, function (match, leadEscape, range, endEscape, close) {
return leadEscape === ESCAPE
// '\\[bar]' -> '\\\\[bar\\]'
? "\\[".concat(range).concat(cleanRangeBackSlash(endEscape)).concat(close) : close === ']' ? endEscape.length % 2 === 0
// A normal case, and it is a range notation
// '[bar]'
// '[bar\\\\]'
? "[".concat(negateRange(sanitizeRange(range))).concat(endEscape, "]") // Invalid range notaton
// '[bar\\]' -> '[bar\\\\]'
: '[]' : '[]';
}],
// ending
[
// 'js' will not match 'js.'
// 'ab' will not match 'abc'
/(?:[^*])$/,
// WTF!
// https://git-scm.com/docs/gitignore
// changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
// which re-fixes #24, #38
// > If there is a separator at the end of the pattern then the pattern
// > will only match directories, otherwise the pattern can match both
// > files and directories.
// 'js*' will not match 'a.js'
// 'js/' will not match 'a.js'
// 'js' will match 'a.js' and 'a.js/'
function (match) {
return /\/$/.test(match)
// foo/ will not match 'foo'
? "".concat(match, "$") // foo matches 'foo' and 'foo/'
: "".concat(match, "(?=$|\\/$)");
}]];
var REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\/)?\\\*$/;
var MODE_IGNORE = 'regex';
var MODE_CHECK_IGNORE = 'checkRegex';
var UNDERSCORE = '_';
var TRAILING_WILD_CARD_REPLACERS = (_TRAILING_WILD_CARD_R = {}, _defineProperty(_TRAILING_WILD_CARD_R, MODE_IGNORE, function (_, p1) {
var prefix = p1
// '\^':
// '/*' does not match EMPTY
// '/*' does not match everything
// '\\\/':
// 'abc/*' does not match 'abc/'
? "".concat(p1, "[^/]+") // 'a*' matches 'a'
// 'a*' matches 'aa'
: '[^/]*';
return "".concat(prefix, "(?=$|\\/$)");
}), _defineProperty(_TRAILING_WILD_CARD_R, MODE_CHECK_IGNORE, function (_, p1) {
// When doing `git check-ignore`
var prefix = p1
// '\\\/':
// 'abc/*' DOES match 'abc/' !
? "".concat(p1, "[^/]*") // 'a*' matches 'a'
// 'a*' matches 'aa'
: '[^/]*';
return "".concat(prefix, "(?=$|\\/$)");
}), _TRAILING_WILD_CARD_R);
// @param {pattern}
var makeRegexPrefix = function makeRegexPrefix(pattern) {
return REPLACERS.reduce(function (prev, _ref) {
var _ref2 = _slicedToArray(_ref, 2),
matcher = _ref2[0],
replacer = _ref2[1];
return prev.replace(matcher, replacer.bind(pattern));
}, pattern);
};
var isString = function isString(subject) {
return typeof subject === 'string';
};
// > A blank line matches no files, so it can serve as a separator for readability.
var checkPattern = function checkPattern(pattern) {
return pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)
// > A line starting with # serves as a comment.
&& pattern.indexOf('#') !== 0;
};
var splitPattern = function splitPattern(pattern) {
return pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
};
var IgnoreRule = /*#__PURE__*/function () {
function IgnoreRule(pattern, mark, body, ignoreCase, negative, prefix) {
_classCallCheck(this, IgnoreRule);
this.pattern = pattern;
this.mark = mark;
this.negative = negative;
define(this, 'body', body);
define(this, 'ignoreCase', ignoreCase);
define(this, 'regexPrefix', prefix);
}
_createClass(IgnoreRule, [{
key: "regex",
get: function get() {
var key = UNDERSCORE + MODE_IGNORE;
if (this[key]) {
return this[key];
}
return this._make(MODE_IGNORE, key);
}
}, {
key: "checkRegex",
get: function get() {
var key = UNDERSCORE + MODE_CHECK_IGNORE;
if (this[key]) {
return this[key];
}
return this._make(MODE_CHECK_IGNORE, key);
}
}, {
key: "_make",
value: function _make(mode, key) {
var str = this.regexPrefix.replace(REGEX_REPLACE_TRAILING_WILDCARD,
// It does not need to bind pattern
TRAILING_WILD_CARD_REPLACERS[mode]);
var regex = this.ignoreCase ? new RegExp(str, 'i') : new RegExp(str);
return define(this, key, regex);
}
}]);
return IgnoreRule;
}();
var createRule = function createRule(_ref3, ignoreCase) {
var pattern = _ref3.pattern,
mark = _ref3.mark;
var negative = false;
var body = pattern;
// > An optional prefix "!" which negates the pattern;
if (body.indexOf('!') === 0) {
negative = true;
body = body.substr(1);
}
body = body
// > Put a backslash ("\") in front of the first "!" for patterns that
// > begin with a literal "!", for example, `"\!important!.txt"`.
.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')
// > Put a backslash ("\") in front of the first hash for patterns that
// > begin with a hash.
.replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#');
var regexPrefix = makeRegexPrefix(body);
return new IgnoreRule(pattern, mark, body, ignoreCase, negative, regexPrefix);
};
var RuleManager = /*#__PURE__*/function () {
function RuleManager(ignoreCase) {
_classCallCheck(this, RuleManager);
this._ignoreCase = ignoreCase;
this._rules = [];
}
_createClass(RuleManager, [{
key: "_add",
value: function _add(pattern) {
// #32
if (pattern && pattern[KEY_IGNORE]) {
this._rules = this._rules.concat(pattern._rules._rules);
this._added = true;
return;
}
if (isString(pattern)) {
pattern = {
pattern: pattern
};
}
if (checkPattern(pattern.pattern)) {
var rule = createRule(pattern, this._ignoreCase);
this._added = true;
this._rules.push(rule);
}
}
// @param {Array<string> | string | Ignore} pattern
}, {
key: "add",
value: function add(pattern) {
this._added = false;
makeArray(isString(pattern) ? splitPattern(pattern) : pattern).forEach(this._add, this);
return this._added;
}
// Test one single path without recursively checking parent directories
//
// - checkUnignored `boolean` whether should check if the path is unignored,
// setting `checkUnignored` to `false` could reduce additional
// path matching.
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
// @returns {TestResult} true if a file is ignored
}, {
key: "test",
value: function test(path, checkUnignored, mode) {
var ignored = false;
var unignored = false;
var matchedRule;
this._rules.forEach(function (rule) {
var negative = rule.negative;
// | ignored : unignored
// -------- | ---------------------------------------
// negative | 0:0 | 0:1 | 1:0 | 1:1
// -------- | ------- | ------- | ------- | --------
// 0 | TEST | TEST | SKIP | X
// 1 | TESTIF | SKIP | TEST | X
// - SKIP: always skip
// - TEST: always test
// - TESTIF: only test if checkUnignored
// - X: that never happen
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
return;
}
var matched = rule[mode].test(path);
if (!matched) {
return;
}
ignored = !negative;
unignored = negative;
matchedRule = negative ? UNDEFINED : rule;
});
var ret = {
ignored: ignored,
unignored: unignored
};
if (matchedRule) {
ret.rule = matchedRule;
}
return ret;
}
}]);
return RuleManager;
}();
var throwError = function throwError(message, Ctor) {
throw new Ctor(message);
};
var checkPath = function checkPath(path, originalPath, doThrow) {
if (!isString(path)) {
return doThrow("path must be a string, but got `".concat(originalPath, "`"), TypeError);
}
// We don't know if we should ignore EMPTY, so throw
if (!path) {
return doThrow("path must not be empty", TypeError);
}
// Check if it is a relative path
if (checkPath.isNotRelative(path)) {
var r = '`path.relative()`d';
return doThrow("path should be a ".concat(r, " string, but got \"").concat(originalPath, "\""), RangeError);
}
return true;
};
var isNotRelative = function isNotRelative(path) {
return REGEX_TEST_INVALID_PATH.test(path);
};
checkPath.isNotRelative = isNotRelative;
// On windows, the following function will be replaced
/* istanbul ignore next */
checkPath.convert = function (p) {
return p;
};
var Ignore = /*#__PURE__*/function () {
function Ignore() {
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref4$ignorecase = _ref4.ignorecase,
ignorecase = _ref4$ignorecase === void 0 ? true : _ref4$ignorecase,
_ref4$ignoreCase = _ref4.ignoreCase,
ignoreCase = _ref4$ignoreCase === void 0 ? ignorecase : _ref4$ignoreCase,
_ref4$allowRelativePa = _ref4.allowRelativePaths,
allowRelativePaths = _ref4$allowRelativePa === void 0 ? false : _ref4$allowRelativePa;
_classCallCheck(this, Ignore);
define(this, KEY_IGNORE, true);
this._rules = new RuleManager(ignoreCase);
this._strictPathCheck = !allowRelativePaths;
this._initCache();
}
_createClass(Ignore, [{
key: "_initCache",
value: function _initCache() {
// A cache for the result of `.ignores()`
this._ignoreCache = Object.create(null);
// A cache for the result of `.test()`
this._testCache = Object.create(null);
}
}, {
key: "add",
value: function add(pattern) {
if (this._rules.add(pattern)) {
// Some rules have just added to the ignore,
// making the behavior changed,
// so we need to re-initialize the result cache
this._initCache();
}
return this;
}
// legacy
}, {
key: "addPattern",
value: function addPattern(pattern) {
return this.add(pattern);
}
// @returns {TestResult}
}, {
key: "_test",
value: function _test(originalPath, cache, checkUnignored, slices) {
var path = originalPath
// Supports nullable path
&& checkPath.convert(originalPath);
checkPath(path, originalPath, this._strictPathCheck ? throwError : RETURN_FALSE);
return this._t(path, cache, checkUnignored, slices);
}
}, {
key: "checkIgnore",
value: function checkIgnore(path) {
// If the path doest not end with a slash, `.ignores()` is much equivalent
// to `git check-ignore`
if (!REGEX_TEST_TRAILING_SLASH.test(path)) {
return this.test(path);
}
var slices = path.split(SLASH).filter(Boolean);
slices.pop();
if (slices.length) {
var parent = this._t(slices.join(SLASH) + SLASH, this._testCache, true, slices);
if (parent.ignored) {
return parent;
}
}
return this._rules.test(path, false, MODE_CHECK_IGNORE);
}
}, {
key: "_t",
value: function _t(
// The path to be tested
path,
// The cache for the result of a certain checking
cache,
// Whether should check if the path is unignored
checkUnignored,
// The path slices
slices) {
if (path in cache) {
return cache[path];
}
if (!slices) {
// path/to/a.js
// ['path', 'to', 'a.js']
slices = path.split(SLASH).filter(Boolean);
}
slices.pop();
// If the path has no parent directory, just test it
if (!slices.length) {
return cache[path] = this._rules.test(path, checkUnignored, MODE_IGNORE);
}
var parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices);
// If the path contains a parent directory, check the parent first
return cache[path] = parent.ignored
// > It is not possible to re-include a file if a parent directory of
// > that file is excluded.
? parent : this._rules.test(path, checkUnignored, MODE_IGNORE);
}
}, {
key: "ignores",
value: function ignores(path) {
return this._test(path, this._ignoreCache, false).ignored;
}
}, {
key: "createFilter",
value: function createFilter() {
var _this = this;
return function (path) {
return !_this.ignores(path);
};
}
}, {
key: "filter",
value: function filter(paths) {
return makeArray(paths).filter(this.createFilter());
}
// @returns {TestResult}
}, {
key: "test",
value: function test(path) {
return this._test(path, this._testCache, true);
}
}]);
return Ignore;
}();
var factory = function factory(options) {
return new Ignore(options);
};
var isPathValid = function isPathValid(path) {
return checkPath(path && checkPath.convert(path), path, RETURN_FALSE);
};
/* istanbul ignore next */
var setupWindows = function setupWindows() {
/* eslint no-control-regex: "off" */
var makePosix = function makePosix(str) {
return /^\\\\\?\\/.test(str) || /[\0-\x1F"<>\|]+/.test(str) ? str : str.replace(/\\/g, '/');
};
checkPath.convert = makePosix;
// 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/'
// 'd:\\foo'
var REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
checkPath.isNotRelative = function (path) {
return REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path);
};
};
// Windows
// --------------------------------------------------------------
/* istanbul ignore next */
if (
// Detect `process` so that it can run in browsers.
typeof process !== 'undefined' && process.platform === 'win32') {
setupWindows();
}
// COMMONJS_EXPORTS ////////////////////////////////////////////////////////////
module.exports = factory;
// Although it is an anti-pattern,
// it is still widely misused by a lot of libraries in github
// Ref: https://github.com/search?q=ignore.default%28%29&type=code
factory["default"] = factory;
module.exports.isPathValid = isPathValid;
// For testing purposes
define(module.exports, Symbol["for"]('setupWindows'), setupWindows);

View File

@@ -0,0 +1 @@
{"version":3,"file":"nodeFlags.js","sourceRoot":"","sources":["../../src/enums/nodeFlags.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,CAAC,IAAI,SAAc,CAAC;AAC1B,CAAC,UAAU,SAAS;IAChB,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC1C,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IACxC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC;IAC5C,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC;IAC5C,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;IAClD,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,GAAG,aAAa,CAAC;IACzD,SAAS,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC;IAC7D,SAAS,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC;IAC7D,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,GAAG,cAAc,CAAC;IAC5D,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,GAAG,mBAAmB,CAAC;IACtE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,GAAG,mBAAmB,CAAC;IACtE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,GAAG,mBAAmB,CAAC;IACvE,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,GAAG,cAAc,CAAC;IAC7D,SAAS,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,GAAG,kBAAkB,CAAC;IACrE,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,GAAG,cAAc,CAAC;IAC7D,SAAS,CAAC,SAAS,CAAC,iCAAiC,CAAC,GAAG,KAAK,CAAC,GAAG,iCAAiC,CAAC;IACpG,SAAS,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,GAAG,kBAAkB,CAAC;IACtE,SAAS,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAC,GAAG,gBAAgB,CAAC;IAClE,SAAS,CAAC,SAAS,CAAC,+BAA+B,CAAC,GAAG,MAAM,CAAC,GAAG,+BAA+B,CAAC;IACjG,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,MAAM,CAAC,GAAG,mBAAmB,CAAC;IACzE,SAAS,CAAC,SAAS,CAAC,+BAA+B,CAAC,GAAG,MAAM,CAAC,GAAG,+BAA+B,CAAC;IACjG,SAAS,CAAC,SAAS,CAAC,4BAA4B,CAAC,GAAG,OAAO,CAAC,GAAG,4BAA4B,CAAC;IAC5F,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,GAAG,UAAU,CAAC;IACxD,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC;IAClD,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC;IACtD,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG,QAAQ,CAAC,GAAG,iBAAiB,CAAC;IACvE,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,UAAU,CAAC;IACzD,SAAS,CAAC,SAAS,CAAC,+BAA+B,CAAC,GAAG,QAAQ,CAAC,GAAG,+BAA+B,CAAC;IACnG,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC,GAAG,aAAa,CAAC;IAChE,SAAS,CAAC,SAAS,CAAC,4BAA4B,CAAC,GAAG,SAAS,CAAC,GAAG,4BAA4B,CAAC;IAC9F,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC;IACxD,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;IAClD,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC;IACtD,SAAS,CAAC,SAAS,CAAC,wBAAwB,CAAC,GAAG,GAAG,CAAC,GAAG,wBAAwB,CAAC;IAChF,SAAS,CAAC,SAAS,CAAC,0BAA0B,CAAC,GAAG,MAAM,CAAC,GAAG,0BAA0B,CAAC;IACvF,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,GAAG,cAAc,CAAC;IACjE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,GAAG,mBAAmB,CAAC;IACxE,SAAS,CAAC,SAAS,CAAC,gCAAgC,CAAC,GAAG,OAAO,CAAC,GAAG,gCAAgC,CAAC;IACpG,SAAS,CAAC,SAAS,CAAC,oCAAoC,CAAC,GAAG,GAAG,CAAC,GAAG,oCAAoC,CAAC;IACxG,SAAS,CAAC,SAAS,CAAC,8BAA8B,CAAC,GAAG,MAAM,CAAC,GAAG,8BAA8B,CAAC;IAC/F,SAAS,CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC,GAAG,iBAAiB,CAAC;AACrE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC"}

View File

@@ -0,0 +1,31 @@
/*! *****************************************************************************
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,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference no-default-lib="true"/>
declare namespace Intl {
/**
* The `Intl.getCanonicalLocales()` method returns an array containing
* the canonical locale names. Duplicates will be omitted and elements
* will be validated as structurally valid language tags.
*
* [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales)
*
* @param locale A list of String values for which to get the canonical locale names
* @returns An array containing the canonical and validated locale names.
*/
function getCanonicalLocales(locale?: string | readonly string[]): string[];
}

View File

@@ -0,0 +1,324 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const ts = __importStar(require("typescript"));
const util_1 = require("../util");
exports.default = (0, util_1.createRule)({
name: 'no-useless-default-assignment',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow default values that will never be used',
recommended: 'strict',
requiresTypeChecking: true,
},
fixable: 'code',
messages: {
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
preferOptionalSyntax: 'Using `= undefined` to make a parameter optional adds unnecessary runtime logic. Use the `?` optional syntax instead.',
uselessDefaultAssignment: 'Default value is useless because the {{ type }} is not optional.',
uselessUndefined: 'Default value is useless because it is undefined. Optional {{ type }}s are already undefined by default.',
},
schema: [
{
type: 'object',
additionalProperties: false,
properties: {
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
type: 'boolean',
description: 'Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`.',
},
},
},
],
},
defaultOptions: [
{
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
},
],
create(context, [{ allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing }]) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
const compilerOptions = services.program.getCompilerOptions();
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
if (!isStrictNullChecks &&
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
context.report({
loc: {
start: { column: 0, line: 0 },
end: { column: 0, line: 0 },
},
messageId: 'noStrictNullCheck',
});
}
function canBeUndefined(type) {
if ((0, util_1.isTypeAnyType)(type) || (0, util_1.isTypeUnknownType)(type)) {
return true;
}
return tsutils
.unionConstituents(type)
.some(part => (0, util_1.isTypeFlagSet)(part, ts.TypeFlags.Undefined));
}
function getArrayElementType(arrayType, elementIndex) {
if (checker.isTupleType(arrayType)) {
const tupleArgs = checker.getTypeArguments(arrayType);
if (elementIndex < tupleArgs.length) {
return tupleArgs[elementIndex];
}
}
return arrayType.getNumberIndexType() ?? null;
}
function checkAssignmentPattern(node) {
if (node.right.type === utils_1.AST_NODE_TYPES.Identifier &&
node.right.name === 'undefined') {
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
if (ts.isParameter(tsNode) &&
tsNode.type &&
canBeUndefined(checker.getTypeFromTypeNode(tsNode.type))) {
reportPreferOptionalSyntax(node);
return;
}
const type = node.parent.type === utils_1.AST_NODE_TYPES.Property ||
node.parent.type === utils_1.AST_NODE_TYPES.ArrayPattern
? 'property'
: 'parameter';
reportUselessUndefined(node, type);
return;
}
const parent = node.parent;
if (parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
parent.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
const paramIndex = parent.params.indexOf(node);
if (paramIndex !== -1) {
const tsFunc = services.esTreeNodeToTSNodeMap.get(parent);
// tsFunc is already a FunctionLike subtype; defensive runtime check
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (ts.isFunctionLike(tsFunc)) {
const contextualType = checker.getContextualType(tsFunc);
if (!contextualType) {
return;
}
const signatures = contextualType.getCallSignatures();
if (signatures.length === 0 ||
signatures[0].getDeclaration() === tsFunc) {
return;
}
const defaultCanBeUsed = signatures.some(signature => {
const params = signature.getParameters();
if (paramIndex >= params.length) {
return true;
}
const paramSymbol = params[paramIndex];
if (paramSymbol.valueDeclaration &&
(0, util_1.isRestParameterDeclaration)(paramSymbol.valueDeclaration)) {
return true;
}
if (tsutils.isSymbolFlagSet(paramSymbol, ts.SymbolFlags.Optional)) {
return true;
}
const paramType = checker.getTypeOfSymbol(paramSymbol);
return (tsutils.isTypeParameter(paramType) || canBeUndefined(paramType));
});
if (!defaultCanBeUsed) {
reportUselessDefaultAssignment(node, 'parameter');
}
}
}
return;
}
if (parent.type === utils_1.AST_NODE_TYPES.Property) {
const propertyType = getTypeOfProperty(parent);
if (!propertyType) {
return;
}
if (!canBeUndefined(propertyType)) {
reportUselessDefaultAssignment(node, 'property');
}
}
else if (parent.type === utils_1.AST_NODE_TYPES.ArrayPattern) {
const sourceType = getSourceTypeForPattern(parent);
if (!sourceType) {
return;
}
if (!checker.isTupleType(sourceType)) {
return;
}
const tupleArgs = checker.getTypeArguments(sourceType);
const elementIndex = parent.elements.indexOf(node);
if (elementIndex < 0 || elementIndex >= tupleArgs.length) {
return;
}
const elementType = tupleArgs[elementIndex];
if (!canBeUndefined(elementType)) {
reportUselessDefaultAssignment(node, 'property');
}
}
}
function getTypeOfProperty(node) {
const objectPattern = node.parent;
const sourceType = getSourceTypeForPattern(objectPattern);
if (!sourceType) {
return null;
}
const propertyName = getPropertyName(node.key);
if (!propertyName) {
return null;
}
const symbol = sourceType.getProperty(propertyName);
if (!symbol) {
return null;
}
if (tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Optional)) {
const parent = objectPattern.parent;
if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
parent.init &&
hasConditionalInitializer(objectPattern)) {
const propertyName = getPropertyName(node.key);
if (!propertyName ||
!hasPropertyInAllBranches(parent.init, propertyName)) {
return null;
}
}
}
return checker.getTypeOfSymbol(symbol);
}
function hasConditionalInitializer(node) {
const parent = node.parent;
if (!parent) {
return false;
}
if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator && parent.init) {
return (parent.init.type === utils_1.AST_NODE_TYPES.ConditionalExpression ||
parent.init.type === utils_1.AST_NODE_TYPES.LogicalExpression);
}
return hasConditionalInitializer(parent);
}
function getSourceTypeForPattern(pattern) {
const parent = (0, util_1.nullThrows)(pattern.parent, util_1.NullThrowsReasons.MissingParent);
if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator && parent.init) {
const tsNode = services.esTreeNodeToTSNodeMap.get(parent.init);
return checker.getTypeAtLocation(tsNode);
}
if ((0, util_1.isFunction)(parent)) {
let paramIndex = parent.params.indexOf(pattern);
const tsFunc = services.esTreeNodeToTSNodeMap.get(parent);
const signature = (0, util_1.nullThrows)(checker.getSignatureFromDeclaration(tsFunc), util_1.NullThrowsReasons.MissingToken('signature', 'function'));
const params = signature.getParameters();
if (signature.thisParameter) {
paramIndex--;
}
if (paramIndex < 0 || paramIndex >= params.length) {
return null;
}
return checker.getTypeOfSymbol(params[paramIndex]);
}
if (parent.type === utils_1.AST_NODE_TYPES.AssignmentPattern) {
return getSourceTypeForPattern(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.Property) {
return getTypeOfProperty(parent);
}
if (parent.type === utils_1.AST_NODE_TYPES.ArrayPattern) {
const arrayType = getSourceTypeForPattern(parent);
if (!arrayType) {
return null;
}
const elementIndex = parent.elements.indexOf(pattern);
return getArrayElementType(arrayType, elementIndex);
}
return null;
}
function getPropertyName(key) {
switch (key.type) {
case utils_1.AST_NODE_TYPES.Identifier:
return key.name;
case utils_1.AST_NODE_TYPES.Literal:
return String(key.value);
case utils_1.AST_NODE_TYPES.TemplateLiteral:
return key.expressions.length ? null : key.quasis[0].value.cooked;
default:
return null;
}
}
function reportUselessDefaultAssignment(node, type) {
context.report({
node: node.right,
messageId: 'uselessDefaultAssignment',
data: { type },
fix: fixer => removeDefault(fixer, node),
});
}
function reportUselessUndefined(node, type) {
context.report({
node: node.right,
messageId: 'uselessUndefined',
data: { type },
fix: fixer => removeDefault(fixer, node),
});
}
function reportPreferOptionalSyntax(node) {
context.report({
node: node.right,
messageId: 'preferOptionalSyntax',
*fix(fixer) {
yield removeDefault(fixer, node);
const { left } = node;
if (left.type === utils_1.AST_NODE_TYPES.Identifier) {
yield fixer.insertTextAfterRange([left.range[0], left.range[0] + left.name.length], '?');
}
},
});
}
function removeDefault(fixer, node) {
const start = node.left.range[1];
const end = node.range[1];
return fixer.removeRange([start, end]);
}
function hasPropertyInAllBranches(expression, propertyName) {
return ((expression.type === utils_1.AST_NODE_TYPES.ObjectExpression &&
expression.properties.some(prop => prop.type === utils_1.AST_NODE_TYPES.Property &&
getPropertyName(prop.key) === propertyName)) ||
(expression.type === utils_1.AST_NODE_TYPES.ConditionalExpression &&
hasPropertyInAllBranches(expression.consequent, propertyName) &&
hasPropertyInAllBranches(expression.alternate, propertyName)));
}
return {
AssignmentPattern: checkAssignmentPattern,
};
},
});

View File

@@ -0,0 +1,4 @@
// Code generated by _scripts/generate-ts-ast.ts. DO NOT EDIT.
import { SyntaxKind } from "#enums/syntaxKind";
import { TokenFlags } from "#enums/tokenFlags";
//# sourceMappingURL=ast.generated.js.map

View File

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

View File

@@ -0,0 +1,361 @@
'use strict';
const scan = require('./scan');
const parse = require('./parse');
const utils = require('./utils');
const constants = require('./constants');
const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
/**
* Creates a matcher function from one or more glob patterns. The
* returned function takes a string to match as its first argument,
* and returns true if the string is a match. The returned matcher
* function also takes a boolean as the second argument that, when true,
* returns an object with additional information.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch(glob[, options]);
*
* const isMatch = picomatch('*.!(*a)');
* console.log(isMatch('a.a')); //=> false
* console.log(isMatch('a.b')); //=> true
*
* // For environments without `node.js`, `picomatch/posix` provides you a dependency-free matcher, without automatic OS detection.
* const picomatch = require('picomatch/posix');
* // the same API, defaulting to posix paths
* const isMatch = picomatch('a/*');
* console.log(isMatch('a\\b')); //=> false
* console.log(isMatch('a/b')); //=> true
*
* // you can still configure the matcher function to accept windows paths
* const isMatch = picomatch('a/*', { options: windows });
* console.log(isMatch('a\\b')); //=> true
* console.log(isMatch('a/b')); //=> true
* ```
* @name picomatch
* @param {String|Array} `globs` One or more glob patterns.
* @param {Object=} `options`
* @return {Function=} Returns a matcher function.
* @api public
*/
const picomatch = (glob, options, returnState = false) => {
if (Array.isArray(glob)) {
const fns = glob.map(input => picomatch(input, options, returnState));
const arrayMatcher = str => {
for (const isMatch of fns) {
const state = isMatch(str);
if (state) return state;
}
return false;
};
return arrayMatcher;
}
const isState = isObject(glob) && glob.tokens && glob.input;
if (glob === '' || (typeof glob !== 'string' && !isState)) {
throw new TypeError('Expected pattern to be a non-empty string');
}
const opts = options || {};
const posix = opts.windows;
const regex = isState
? picomatch.compileRe(glob, options)
: picomatch.makeRe(glob, options, false, true);
const state = regex.state;
delete regex.state;
let isIgnored = () => false;
if (opts.ignore) {
const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
}
const matcher = (input, returnObject = false) => {
const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
const result = { glob, state, regex, posix, input, output, match, isMatch };
if (typeof opts.onResult === 'function') {
opts.onResult(result);
}
if (isMatch === false) {
result.isMatch = false;
return returnObject ? result : false;
}
if (isIgnored(input)) {
if (typeof opts.onIgnore === 'function') {
opts.onIgnore(result);
}
result.isMatch = false;
return returnObject ? result : false;
}
if (typeof opts.onMatch === 'function') {
opts.onMatch(result);
}
return returnObject ? result : true;
};
if (returnState) {
matcher.state = state;
}
return matcher;
};
/**
* Test `input` with the given `regex`. This is used by the main
* `picomatch()` function to test the input string.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.test(input, regex[, options]);
*
* console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
* // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
* ```
* @param {String} `input` String to test.
* @param {RegExp} `regex`
* @return {Object} Returns an object with matching info.
* @api public
*/
picomatch.test = (input, regex, options, { glob, posix } = {}) => {
if (typeof input !== 'string') {
throw new TypeError('Expected input to be a string');
}
if (input === '') {
return { isMatch: false, output: '' };
}
const opts = options || {};
const format = opts.format || (posix ? utils.toPosixSlashes : null);
let match = input === glob;
let output = (match && format) ? format(input) : input;
if (match === false) {
output = format ? format(input) : input;
match = output === glob;
}
if (match === false || opts.capture === true) {
if (opts.matchBase === true || opts.basename === true) {
match = picomatch.matchBase(input, regex, options, posix);
} else {
match = regex.exec(output);
}
}
return { isMatch: Boolean(match), match, output };
};
/**
* Match the basename of a filepath.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.matchBase(input, glob[, options]);
* console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
* ```
* @param {String} `input` String to test.
* @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
* @return {Boolean}
* @api public
*/
picomatch.matchBase = (input, glob, options, posix = options && options.windows) => {
const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
return regex.test(utils.basename(input, { windows: posix }));
};
/**
* Returns true if **any** of the given glob `patterns` match the specified `string`.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.isMatch(string, patterns[, options]);
*
* console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
* console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
* ```
* @param {String|Array} str The string to test.
* @param {String|Array} patterns One or more glob patterns to use for matching.
* @param {Object} [options] See available [options](#options).
* @return {Boolean} Returns true if any patterns match `str`
* @api public
*/
picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
/**
* Parse a glob pattern to create the source string for a regular
* expression.
*
* ```js
* const picomatch = require('picomatch');
* const result = picomatch.parse(pattern[, options]);
* ```
* @param {String} `pattern`
* @param {Object} `options`
* @return {Object} Returns an object with useful properties and output to be used as a regex source string.
* @api public
*/
picomatch.parse = (pattern, options) => {
if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
return parse(pattern, { ...options, fastpaths: false });
};
/**
* Scan a glob pattern to separate the pattern into segments.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.scan(input[, options]);
*
* const result = picomatch.scan('!./foo/*.js');
* console.log(result);
* { prefix: '!./',
* input: '!./foo/*.js',
* start: 3,
* base: 'foo',
* glob: '*.js',
* isBrace: false,
* isBracket: false,
* isGlob: true,
* isExtglob: false,
* isGlobstar: false,
* negated: true }
* ```
* @param {String} `input` Glob pattern to scan.
* @param {Object} `options`
* @return {Object} Returns an object with
* @api public
*/
picomatch.scan = (input, options) => scan(input, options);
/**
* Compile a regular expression from the `state` object returned by the
* [parse()](#parse) method.
*
* ```js
* const picomatch = require('picomatch');
* const state = picomatch.parse('*.js');
* // picomatch.compileRe(state[, options]);
*
* console.log(picomatch.compileRe(state));
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {Object} `state`
* @param {Object} `options`
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
* @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
* @return {RegExp}
* @api public
*/
picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
if (returnOutput === true) {
return state.output;
}
const opts = options || {};
const prepend = opts.contains ? '' : '^';
const append = opts.contains ? '' : '$';
let source = `${prepend}(?:${state.output})${append}`;
if (state && state.negated === true) {
source = `^(?!${source}).*$`;
}
const regex = picomatch.toRegex(source, options);
if (returnState === true) {
regex.state = state;
}
return regex;
};
/**
* Create a regular expression from a parsed glob pattern.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.makeRe(state[, options]);
*
* const result = picomatch.makeRe('*.js');
* console.log(result);
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {String} `state` The object returned from the `.parse` method.
* @param {Object} `options`
* @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
* @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
* @return {RegExp} Returns a regex created from the given pattern.
* @api public
*/
picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
if (!input || typeof input !== 'string') {
throw new TypeError('Expected a non-empty string');
}
let parsed = { negated: false, fastpaths: true };
if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
parsed.output = parse.fastpaths(input, options);
}
if (!parsed.output) {
parsed = parse(input, options);
}
return picomatch.compileRe(parsed, options, returnOutput, returnState);
};
/**
* Create a regular expression from the given regex source string.
*
* ```js
* const picomatch = require('picomatch');
* // picomatch.toRegex(source[, options]);
*
* const { output } = picomatch.parse('*.js');
* console.log(picomatch.toRegex(output));
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
* ```
* @param {String} `source` Regular expression source string.
* @param {Object} `options`
* @return {RegExp}
* @api public
*/
picomatch.toRegex = (source, options) => {
try {
const opts = options || {};
return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
} catch (err) {
if (options && options.debug === true) throw err;
return /$^/;
}
};
/**
* Picomatch constants.
* @return {Object}
*/
picomatch.constants = constants;
/**
* Expose "picomatch"
*/
module.exports = picomatch;

View File

@@ -0,0 +1,164 @@
"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: 'parameter-properties',
meta: {
type: 'problem',
docs: {
description: 'Require or disallow parameter properties in class constructors',
},
messages: {
preferClassProperty: 'Property {{parameter}} should be declared as a class property.',
preferParameterProperty: 'Property {{parameter}} should be declared as a parameter property.',
},
schema: [
{
type: 'object',
$defs: {
modifier: {
type: 'string',
enum: [
'readonly',
'private',
'protected',
'public',
'private readonly',
'protected readonly',
'public readonly',
],
},
},
additionalProperties: false,
properties: {
allow: {
type: 'array',
description: 'Whether to allow certain kinds of properties to be ignored.',
items: {
$ref: '#/items/0/$defs/modifier',
},
},
prefer: {
type: 'string',
description: 'Whether to prefer class properties or parameter properties.',
enum: ['class-property', 'parameter-property'],
},
},
},
],
},
defaultOptions: [
{
allow: [],
prefer: 'class-property',
},
],
create(context, [{ allow = [], prefer = 'class-property' }]) {
/**
* Gets the modifiers of `node`.
* @param node the node to be inspected.
*/
function getModifiers(node) {
const modifiers = [];
if (node.accessibility) {
modifiers.push(node.accessibility);
}
if (node.readonly) {
modifiers.push('readonly');
}
return modifiers.filter(Boolean).join(' ');
}
if (prefer === 'class-property') {
return {
TSParameterProperty(node) {
const modifiers = getModifiers(node);
if (!allow.includes(modifiers)) {
const name = node.parameter.type === utils_1.AST_NODE_TYPES.Identifier
? node.parameter.name
: node.parameter.left.name;
context.report({
node,
messageId: 'preferClassProperty',
data: {
parameter: name,
},
});
}
},
};
}
const propertyNodesByNameStack = [];
function getNodesByName(name) {
const propertyNodesByName = propertyNodesByNameStack[propertyNodesByNameStack.length - 1];
const existing = propertyNodesByName.get(name);
if (existing) {
return existing;
}
const created = {};
propertyNodesByName.set(name, created);
return created;
}
function typeAnnotationsMatch(classProperty, constructorParameter) {
if (!classProperty.typeAnnotation ||
!constructorParameter.typeAnnotation) {
return (classProperty.typeAnnotation === constructorParameter.typeAnnotation);
}
return (context.sourceCode.getText(classProperty.typeAnnotation) ===
context.sourceCode.getText(constructorParameter.typeAnnotation));
}
return {
':matches(ClassDeclaration, ClassExpression):exit'() {
const propertyNodesByName = (0, util_1.nullThrows)(propertyNodesByNameStack.pop(), 'Stack should exist on class exit');
for (const [name, nodes] of propertyNodesByName) {
if (nodes.classProperty &&
nodes.constructorAssignment &&
nodes.constructorParameter &&
typeAnnotationsMatch(nodes.classProperty, nodes.constructorParameter)) {
context.report({
node: nodes.classProperty,
messageId: 'preferParameterProperty',
data: {
parameter: name,
},
});
}
}
},
ClassBody(node) {
for (const element of node.body) {
if (element.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
element.key.type === utils_1.AST_NODE_TYPES.Identifier &&
!element.value &&
!allow.includes(getModifiers(element))) {
getNodesByName(element.key.name).classProperty = element;
}
}
},
'ClassDeclaration, ClassExpression'() {
propertyNodesByNameStack.push(new Map());
},
'MethodDefinition[kind="constructor"]'(node) {
for (const parameter of node.value.params) {
if (parameter.type === utils_1.AST_NODE_TYPES.Identifier) {
getNodesByName(parameter.name).constructorParameter = parameter;
}
}
for (const statement of node.value.body?.body ?? []) {
if (statement.type !== utils_1.AST_NODE_TYPES.ExpressionStatement ||
statement.expression.type !== utils_1.AST_NODE_TYPES.AssignmentExpression ||
statement.expression.left.type !==
utils_1.AST_NODE_TYPES.MemberExpression ||
statement.expression.left.object.type !==
utils_1.AST_NODE_TYPES.ThisExpression ||
statement.expression.left.property.type !==
utils_1.AST_NODE_TYPES.Identifier ||
statement.expression.right.type !== utils_1.AST_NODE_TYPES.Identifier) {
break;
}
getNodesByName(statement.expression.right.name).constructorAssignment = statement.expression;
}
},
};
},
});

View File

@@ -0,0 +1,422 @@
/**
* @fileoverview Rule to flag non-camelcased identifiers
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
type: "suggestion",
defaultOptions: [
{
allow: [],
ignoreDestructuring: false,
ignoreGlobals: false,
ignoreImports: false,
properties: "always",
},
],
docs: {
description: "Enforce camelcase naming convention",
recommended: false,
frozen: true,
url: "https://eslint.org/docs/latest/rules/camelcase",
},
schema: [
{
type: "object",
properties: {
ignoreDestructuring: {
type: "boolean",
},
ignoreImports: {
type: "boolean",
},
ignoreGlobals: {
type: "boolean",
},
properties: {
enum: ["always", "never"],
},
allow: {
type: "array",
items: {
type: "string",
},
minItems: 0,
uniqueItems: true,
},
},
additionalProperties: false,
},
],
messages: {
notCamelCase: "Identifier '{{name}}' is not in camel case.",
notCamelCasePrivate: "#{{name}} is not in camel case.",
},
},
create(context) {
const [
{
allow,
ignoreDestructuring,
ignoreGlobals,
ignoreImports,
properties,
},
] = context.options;
const sourceCode = context.sourceCode;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
// contains reported nodes to avoid reporting twice on destructuring with shorthand notation
const reported = new Set();
/**
* Checks if a string contains an underscore and isn't all upper-case
* @param {string} name The string to check.
* @returns {boolean} if the string is underscored
* @private
*/
function isUnderscored(name) {
const nameBody = name.replace(/^_+|_+$/gu, "");
// if there's an underscore, it might be A_CONSTANT, which is okay
return (
nameBody.includes("_") && nameBody !== nameBody.toUpperCase()
);
}
/**
* Checks if a string match the ignore list
* @param {string} name The string to check.
* @returns {boolean} if the string is ignored
* @private
*/
function isAllowed(name) {
return allow.some(
entry => name === entry || name.match(new RegExp(entry, "u")),
);
}
/**
* Checks if a given name is good or not.
* @param {string} name The name to check.
* @returns {boolean} `true` if the name is good.
* @private
*/
function isGoodName(name) {
return !isUnderscored(name) || isAllowed(name);
}
/**
* Checks if a given identifier reference or member expression is an assignment
* target.
* @param {ASTNode} node The node to check.
* @returns {boolean} `true` if the node is an assignment target.
*/
function isAssignmentTarget(node) {
const parent = node.parent;
switch (parent.type) {
case "AssignmentExpression":
case "AssignmentPattern":
return parent.left === node;
case "Property":
return (
parent.parent.type === "ObjectPattern" &&
parent.value === node
);
case "ArrayPattern":
case "RestElement":
return true;
default:
return false;
}
}
/**
* Checks if a given binding identifier uses the original name as-is.
* - If it's in object destructuring or object expression, the original name is its property name.
* - If it's in import declaration, the original name is its exported name.
* @param {ASTNode} node The `Identifier` node to check.
* @returns {boolean} `true` if the identifier uses the original name as-is.
*/
function equalsToOriginalName(node) {
const localName = node.name;
const valueNode =
node.parent.type === "AssignmentPattern" ? node.parent : node;
const parent = valueNode.parent;
switch (parent.type) {
case "Property":
return (
(parent.parent.type === "ObjectPattern" ||
parent.parent.type === "ObjectExpression") &&
parent.value === valueNode &&
!parent.computed &&
parent.key.type === "Identifier" &&
parent.key.name === localName
);
case "ImportSpecifier":
return (
parent.local === node &&
astUtils.getModuleExportName(parent.imported) ===
localName
);
default:
return false;
}
}
/**
* Reports an AST node as a rule violation.
* @param {ASTNode} node The node to report.
* @returns {void}
* @private
*/
function report(node) {
if (reported.has(node.range[0])) {
return;
}
reported.add(node.range[0]);
// Report it.
context.report({
node,
messageId:
node.type === "PrivateIdentifier"
? "notCamelCasePrivate"
: "notCamelCase",
data: { name: node.name },
});
}
/**
* Reports an identifier reference or a binding identifier.
* @param {ASTNode} node The `Identifier` node to report.
* @returns {void}
*/
function reportReferenceId(node) {
/*
* For backward compatibility, if it's in callings then ignore it.
* Not sure why it is.
*/
if (
node.parent.type === "CallExpression" ||
node.parent.type === "NewExpression"
) {
return;
}
/*
* For backward compatibility, if it's a default value of
* destructuring/parameters then ignore it.
* Not sure why it is.
*/
if (
node.parent.type === "AssignmentPattern" &&
node.parent.right === node
) {
return;
}
/*
* The `ignoreDestructuring` flag skips the identifiers that uses
* the property name as-is.
*/
if (ignoreDestructuring && equalsToOriginalName(node)) {
return;
}
/*
* Import attribute keys are always ignored
*/
if (astUtils.isImportAttributeKey(node)) {
return;
}
report(node);
}
return {
// Report camelcase of global variable references ------------------
Program(node) {
const scope = sourceCode.getScope(node);
if (!ignoreGlobals) {
// Defined globals in config files or directive comments.
for (const variable of scope.variables) {
if (
variable.identifiers.length > 0 ||
isGoodName(variable.name)
) {
continue;
}
for (const reference of variable.references) {
/*
* For backward compatibility, this rule reports read-only
* references as well.
*/
reportReferenceId(reference.identifier);
}
}
}
// Undefined globals.
for (const reference of scope.through) {
const id = reference.identifier;
if (
isGoodName(id.name) ||
astUtils.isImportAttributeKey(id)
) {
continue;
}
/*
* For backward compatibility, this rule reports read-only
* references as well.
*/
reportReferenceId(id);
}
},
// Report camelcase of declared variables --------------------------
[[
"VariableDeclaration",
"FunctionDeclaration",
"FunctionExpression",
"ArrowFunctionExpression",
"ClassDeclaration",
"ClassExpression",
"CatchClause",
]](node) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (isGoodName(variable.name)) {
continue;
}
const id = variable.identifiers[0];
// Report declaration.
if (!(ignoreDestructuring && equalsToOriginalName(id))) {
report(id);
}
/*
* For backward compatibility, report references as well.
* It looks unnecessary because declarations are reported.
*/
for (const reference of variable.references) {
if (reference.init) {
continue; // Skip the write references of initializers.
}
reportReferenceId(reference.identifier);
}
}
},
// Report camelcase in properties ----------------------------------
[[
"ObjectExpression > Property[computed!=true] > Identifier.key",
"MethodDefinition[computed!=true] > Identifier.key",
"PropertyDefinition[computed!=true] > Identifier.key",
"MethodDefinition > PrivateIdentifier.key",
"PropertyDefinition > PrivateIdentifier.key",
]](node) {
if (
properties === "never" ||
astUtils.isImportAttributeKey(node) ||
isGoodName(node.name)
) {
return;
}
report(node);
},
"MemberExpression[computed!=true] > Identifier.property"(node) {
if (
properties === "never" ||
!isAssignmentTarget(node.parent) || // ← ignore read-only references.
isGoodName(node.name)
) {
return;
}
report(node);
},
// Report camelcase in import --------------------------------------
ImportDeclaration(node) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (isGoodName(variable.name)) {
continue;
}
const id = variable.identifiers[0];
// Report declaration.
if (!(ignoreImports && equalsToOriginalName(id))) {
report(id);
}
/*
* For backward compatibility, report references as well.
* It looks unnecessary because declarations are reported.
*/
for (const reference of variable.references) {
reportReferenceId(reference.identifier);
}
}
},
// Report camelcase in re-export -----------------------------------
[[
"ExportAllDeclaration > Identifier.exported",
"ExportSpecifier > Identifier.exported",
]](node) {
if (isGoodName(node.name)) {
return;
}
report(node);
},
// Report camelcase in labels --------------------------------------
[[
"LabeledStatement > Identifier.label",
/*
* For backward compatibility, report references as well.
* It looks unnecessary because declarations are reported.
*/
"BreakStatement > Identifier.label",
"ContinueStatement > Identifier.label",
]](node) {
if (isGoodName(node.name)) {
return;
}
report(node);
},
};
},
};

View File

@@ -0,0 +1,19 @@
'use strict'
const { Writable } = require('stream')
const { parentPort } = require('worker_threads')
async function run () {
parentPort.postMessage({
internal: 'watch-mode'
})
return new Writable({
autoDestroy: true,
write (chunk, enc, cb) {
cb()
}
})
}
module.exports = run

View File

@@ -0,0 +1,14 @@
import type { TSESTreeOptions } from '../parser-options';
/**
* ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
* such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
* on a file in an IDE).
*
* When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
* is important because there is significant overhead to managing the so called Watch Programs
* needed for the long-running use-case. We therefore use the following logic to figure out which
* of these contexts applies to the current execution.
*
* @returns Whether this is part of a single run, rather than a long-running process.
*/
export declare function inferSingleRun(options: TSESTreeOptions | undefined): boolean;