WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -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';
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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])
|
||||
}
|
||||
@@ -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(),
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
`);
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
@@ -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')
|
||||
@@ -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};`;
|
||||
},
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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(),
|
||||
};
|
||||
}
|
||||
@@ -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",
|
||||
}
|
||||
`);
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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;
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_inherits_loose.js";
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,71 @@
|
||||
bs58
|
||||
====
|
||||
|
||||
[](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:
|
||||
|
||||
[](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
|
||||
@@ -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);
|
||||
File diff suppressed because one or more lines are too long
@@ -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"}
|
||||
@@ -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[];
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -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
|
||||
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
Reference in New Issue
Block a user