WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
declare const _default: {
|
||||
parserOptions: {
|
||||
program: null;
|
||||
project: false;
|
||||
projectService: false;
|
||||
};
|
||||
rules: {
|
||||
'@typescript-eslint/await-thenable': "off";
|
||||
'@typescript-eslint/consistent-return': "off";
|
||||
'@typescript-eslint/consistent-type-exports': "off";
|
||||
'@typescript-eslint/dot-notation': "off";
|
||||
'@typescript-eslint/naming-convention': "off";
|
||||
'@typescript-eslint/no-array-delete': "off";
|
||||
'@typescript-eslint/no-base-to-string': "off";
|
||||
'@typescript-eslint/no-confusing-void-expression': "off";
|
||||
'@typescript-eslint/no-deprecated': "off";
|
||||
'@typescript-eslint/no-duplicate-type-constituents': "off";
|
||||
'@typescript-eslint/no-floating-promises': "off";
|
||||
'@typescript-eslint/no-for-in-array': "off";
|
||||
'@typescript-eslint/no-implied-eval': "off";
|
||||
'@typescript-eslint/no-meaningless-void-operator': "off";
|
||||
'@typescript-eslint/no-misused-promises': "off";
|
||||
'@typescript-eslint/no-misused-spread': "off";
|
||||
'@typescript-eslint/no-mixed-enums': "off";
|
||||
'@typescript-eslint/no-redundant-type-constituents': "off";
|
||||
'@typescript-eslint/no-unnecessary-boolean-literal-compare': "off";
|
||||
'@typescript-eslint/no-unnecessary-condition': "off";
|
||||
'@typescript-eslint/no-unnecessary-qualifier': "off";
|
||||
'@typescript-eslint/no-unnecessary-template-expression': "off";
|
||||
'@typescript-eslint/no-unnecessary-type-arguments': "off";
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': "off";
|
||||
'@typescript-eslint/no-unnecessary-type-conversion': "off";
|
||||
'@typescript-eslint/no-unnecessary-type-parameters': "off";
|
||||
'@typescript-eslint/no-unsafe-argument': "off";
|
||||
'@typescript-eslint/no-unsafe-assignment': "off";
|
||||
'@typescript-eslint/no-unsafe-call': "off";
|
||||
'@typescript-eslint/no-unsafe-enum-comparison': "off";
|
||||
'@typescript-eslint/no-unsafe-member-access': "off";
|
||||
'@typescript-eslint/no-unsafe-return': "off";
|
||||
'@typescript-eslint/no-unsafe-type-assertion': "off";
|
||||
'@typescript-eslint/no-unsafe-unary-minus': "off";
|
||||
'@typescript-eslint/no-useless-default-assignment': "off";
|
||||
'@typescript-eslint/non-nullable-type-assertion-style': "off";
|
||||
'@typescript-eslint/only-throw-error': "off";
|
||||
'@typescript-eslint/prefer-destructuring': "off";
|
||||
'@typescript-eslint/prefer-find': "off";
|
||||
'@typescript-eslint/prefer-includes': "off";
|
||||
'@typescript-eslint/prefer-nullish-coalescing': "off";
|
||||
'@typescript-eslint/prefer-optional-chain': "off";
|
||||
'@typescript-eslint/prefer-promise-reject-errors': "off";
|
||||
'@typescript-eslint/prefer-readonly': "off";
|
||||
'@typescript-eslint/prefer-readonly-parameter-types': "off";
|
||||
'@typescript-eslint/prefer-reduce-type-parameter': "off";
|
||||
'@typescript-eslint/prefer-regexp-exec': "off";
|
||||
'@typescript-eslint/prefer-return-this-type': "off";
|
||||
'@typescript-eslint/prefer-string-starts-ends-with': "off";
|
||||
'@typescript-eslint/promise-function-async': "off";
|
||||
'@typescript-eslint/related-getter-setter-pairs': "off";
|
||||
'@typescript-eslint/require-array-sort-compare': "off";
|
||||
'@typescript-eslint/require-await': "off";
|
||||
'@typescript-eslint/restrict-plus-operands': "off";
|
||||
'@typescript-eslint/restrict-template-expressions': "off";
|
||||
'@typescript-eslint/return-await': "off";
|
||||
'@typescript-eslint/strict-boolean-expressions': "off";
|
||||
'@typescript-eslint/strict-void-return': "off";
|
||||
'@typescript-eslint/switch-exhaustiveness-check': "off";
|
||||
'@typescript-eslint/unbound-method': "off";
|
||||
'@typescript-eslint/use-unknown-in-catch-callback-variable': "off";
|
||||
};
|
||||
};
|
||||
export = _default;
|
||||
@@ -0,0 +1,47 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const sleep = require('.')
|
||||
|
||||
test('blocks event loop for given amount of milliseconds', ({ is, end }) => {
|
||||
const now = Date.now()
|
||||
setTimeout(() => {
|
||||
const delta = Date.now() - now
|
||||
const fuzzyDelta = Math.floor(delta / 10) * 10 // allow up to 10ms of execution lag
|
||||
is(fuzzyDelta, 1000)
|
||||
end()
|
||||
}, 100)
|
||||
sleep(1000)
|
||||
})
|
||||
|
||||
if (typeof BigInt !== 'undefined') {
|
||||
|
||||
test('allows ms to be supplied as a BigInt number', ({ is, end }) => {
|
||||
const now = Date.now()
|
||||
setTimeout(() => {
|
||||
const delta = Date.now() - now
|
||||
const fuzzyDelta = Math.floor(delta / 10) * 10 // allow up to 10ms of execution lag
|
||||
is(fuzzyDelta, 1000)
|
||||
end()
|
||||
}, 100)
|
||||
sleep(BigInt(1000)) // avoiding n notation as this will error on legacy node/browsers
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
test('throws range error if ms less than 0', ({ throws, end }) => {
|
||||
throws(() => sleep(-1), RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity'))
|
||||
end()
|
||||
})
|
||||
|
||||
test('throws range error if ms is Infinity', ({ throws, end }) => {
|
||||
throws(() => sleep(Infinity), RangeError('sleep: ms must be a number that is greater than 0 but less than Infinity'))
|
||||
end()
|
||||
})
|
||||
|
||||
test('throws range error if ms is not a number or bigint', ({ throws, end }) => {
|
||||
throws(() => sleep('Infinity'), TypeError('sleep: ms must be a number'))
|
||||
throws(() => sleep('foo'), TypeError('sleep: ms must be a number'))
|
||||
throws(() => sleep({a: 1}), TypeError('sleep: ms must be a number'))
|
||||
throws(() => sleep([1,2,3]), TypeError('sleep: ms must be a number'))
|
||||
end()
|
||||
})
|
||||
@@ -0,0 +1,107 @@
|
||||
import * as util from "../core/util.js";
|
||||
const error = () => {
|
||||
const Sizable = {
|
||||
string: { unit: "àmi", verb: "ní" },
|
||||
file: { unit: "bytes", verb: "ní" },
|
||||
array: { unit: "nkan", verb: "ní" },
|
||||
set: { unit: "nkan", verb: "ní" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "ẹ̀rọ ìbáwọlé",
|
||||
email: "àdírẹ́sì ìmẹ́lì",
|
||||
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: "àkókò ISO",
|
||||
date: "ọjọ́ ISO",
|
||||
time: "àkókò ISO",
|
||||
duration: "àkókò tó pé ISO",
|
||||
ipv4: "àdírẹ́sì IPv4",
|
||||
ipv6: "àdírẹ́sì IPv6",
|
||||
cidrv4: "àgbègbè IPv4",
|
||||
cidrv6: "àgbègbè IPv6",
|
||||
base64: "ọ̀rọ̀ tí a kọ́ ní base64",
|
||||
base64url: "ọ̀rọ̀ base64url",
|
||||
json_string: "ọ̀rọ̀ JSON",
|
||||
e164: "nọ́mbà E.164",
|
||||
jwt: "JWT",
|
||||
template_literal: "ẹ̀rọ ìbáwọlé",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
number: "nọ́mbà",
|
||||
array: "akopọ",
|
||||
};
|
||||
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 `Ìbáwọlé aṣìṣe: a ní láti fi instanceof ${issue.expected}, àmọ̀ a rí ${received}`;
|
||||
}
|
||||
return `Ìbáwọlé aṣìṣe: a ní láti fi ${expected}, àmọ̀ a rí ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Ìbáwọlé aṣìṣe: a ní láti fi ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Àṣàyàn aṣìṣe: yan ọ̀kan lára ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `Tó pọ̀ jù: a ní láti jẹ́ pé ${issue.origin ?? "iye"} ${sizing.verb} ${adj}${issue.maximum} ${sizing.unit}`;
|
||||
return `Tó pọ̀ jù: a ní láti jẹ́ ${adj}${issue.maximum}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `Kéré ju: a ní láti jẹ́ pé ${issue.origin} ${sizing.verb} ${adj}${issue.minimum} ${sizing.unit}`;
|
||||
return `Kéré ju: a ní láti jẹ́ ${adj}${issue.minimum}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with")
|
||||
return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bẹ̀rẹ̀ pẹ̀lú "${_issue.prefix}"`;
|
||||
if (_issue.format === "ends_with")
|
||||
return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ parí pẹ̀lú "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ ní "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bá àpẹẹrẹ mu ${_issue.pattern}`;
|
||||
return `Aṣìṣe: ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Nọ́mbà aṣìṣe: gbọ́dọ̀ jẹ́ èyà pípín ti ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `Bọtìnì àìmọ̀: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Bọtìnì aṣìṣe nínú ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Ìbáwọlé aṣìṣe";
|
||||
case "invalid_element":
|
||||
return `Iye aṣìṣe nínú ${issue.origin}`;
|
||||
default:
|
||||
return "Ìbáwọlé aṣìṣe";
|
||||
}
|
||||
};
|
||||
};
|
||||
export default function () {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var stringify = require('../');
|
||||
|
||||
test('custom comparison function', function (t) {
|
||||
t.plan(1);
|
||||
var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };
|
||||
var s = stringify(obj, function (a, b) {
|
||||
return a.key < b.key ? 1 : -1;
|
||||
});
|
||||
t.equal(s, '{"c":8,"b":[{"z":6,"y":5,"x":4},7],"a":3}');
|
||||
});
|
||||
@@ -0,0 +1,604 @@
|
||||
/**
|
||||
* @fileoverview A class to track messages reported by the linter for a file.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const assert = require("../shared/assert");
|
||||
const { RuleFixer } = require("./rule-fixer");
|
||||
const { interpolate } = require("./interpolate");
|
||||
const ruleReplacements = require("../../conf/replacements.json");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("../types").Linter.LintMessage} LintMessage */
|
||||
/** @typedef {import("../types").Linter.LintSuggestion} SuggestionResult */
|
||||
/** @typedef {import("@eslint/core").Language} Language */
|
||||
/** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
|
||||
|
||||
/**
|
||||
* An error message description
|
||||
* @typedef {Object} MessageDescriptor
|
||||
* @property {ASTNode} [node] The reported node
|
||||
* @property {Location} loc The location of the problem.
|
||||
* @property {string} message The problem message.
|
||||
* @property {Object} [data] Optional data to use to fill in placeholders in the
|
||||
* message.
|
||||
* @property {Function} [fix] The function to call that creates a fix command.
|
||||
* @property {Array<{desc?: string, messageId?: string, fix: Function}>} suggest Suggestion descriptions and functions to create a the associated fixes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} LintProblem
|
||||
* @property {string} ruleId The rule ID that reported the problem.
|
||||
* @property {string} message The problem message.
|
||||
* @property {SourceLocation} loc The location of the problem.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const DEFAULT_ERROR_LOC = {
|
||||
start: { line: 1, column: 0 },
|
||||
end: { line: 1, column: 1 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a given location based on the language offsets. This allows us to
|
||||
* change 0-based locations to 1-based locations. We always want ESLint
|
||||
* reporting lines and columns starting from 1.
|
||||
* @todo Potentially this should be moved into a shared utility file.
|
||||
* @param {Object} location The location to update.
|
||||
* @param {number} location.line The starting line number.
|
||||
* @param {number} location.column The starting column number.
|
||||
* @param {number} [location.endLine] The ending line number.
|
||||
* @param {number} [location.endColumn] The ending column number.
|
||||
* @param {Language} language The language to use to adjust the location information.
|
||||
* @returns {Object} The updated location.
|
||||
*/
|
||||
function updateLocationInformation(
|
||||
{ line, column, endLine, endColumn },
|
||||
language,
|
||||
) {
|
||||
const columnOffset = language.columnStart === 1 ? 0 : 1;
|
||||
const lineOffset = language.lineStart === 1 ? 0 : 1;
|
||||
|
||||
// calculate separately to account for undefined
|
||||
const finalEndLine = endLine === void 0 ? endLine : endLine + lineOffset;
|
||||
const finalEndColumn =
|
||||
endColumn === void 0 ? endColumn : endColumn + columnOffset;
|
||||
|
||||
return {
|
||||
line: line + lineOffset,
|
||||
column: column + columnOffset,
|
||||
endLine: finalEndLine,
|
||||
endColumn: finalEndColumn,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a missing-rule message.
|
||||
* @param {string} ruleId the ruleId to create
|
||||
* @returns {string} created error message
|
||||
* @private
|
||||
*/
|
||||
function createMissingRuleMessage(ruleId) {
|
||||
return Object.hasOwn(ruleReplacements.rules, ruleId)
|
||||
? `Rule '${ruleId}' was removed and replaced by: ${ruleReplacements.rules[ruleId].join(", ")}`
|
||||
: `Definition for rule '${ruleId}' was not found.`;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a linting problem
|
||||
* @param {LintProblem} options to create linting error
|
||||
* @param {RuleSeverity} severity the error message to report
|
||||
* @param {Language} language the language to use to adjust the location information.
|
||||
* @returns {LintMessage} created problem, returns a missing-rule problem if only provided ruleId.
|
||||
* @private
|
||||
*/
|
||||
function createLintingProblem(options, severity, language) {
|
||||
const {
|
||||
ruleId = null,
|
||||
loc = DEFAULT_ERROR_LOC,
|
||||
message = createMissingRuleMessage(options.ruleId),
|
||||
} = options;
|
||||
|
||||
return {
|
||||
ruleId,
|
||||
message,
|
||||
...updateLocationInformation(
|
||||
{
|
||||
line: loc.start.line,
|
||||
column: loc.start.column,
|
||||
endLine: loc.end.line,
|
||||
endColumn: loc.end.column,
|
||||
},
|
||||
language,
|
||||
),
|
||||
severity,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a multi-argument context.report() call into a single object argument call
|
||||
* @param {...*} args A list of arguments passed to `context.report`
|
||||
* @returns {MessageDescriptor} A normalized object containing report information
|
||||
*/
|
||||
function normalizeMultiArgReportCall(...args) {
|
||||
// If there is one argument, it is considered to be a new-style call already.
|
||||
if (args.length === 1) {
|
||||
// Shallow clone the object to avoid surprises if reusing the descriptor
|
||||
return Object.assign({}, args[0]);
|
||||
}
|
||||
|
||||
// If the second argument is a string, the arguments are interpreted as [node, message, data, fix].
|
||||
if (typeof args[1] === "string") {
|
||||
return {
|
||||
node: args[0],
|
||||
message: args[1],
|
||||
data: args[2],
|
||||
fix: args[3],
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise, the arguments are interpreted as [node, loc, message, data, fix].
|
||||
return {
|
||||
node: args[0],
|
||||
loc: args[1],
|
||||
message: args[2],
|
||||
data: args[3],
|
||||
fix: args[4],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that either a loc or a node was provided, and the node is valid if it was provided.
|
||||
* @param {MessageDescriptor} descriptor A descriptor to validate
|
||||
* @returns {void}
|
||||
* @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object
|
||||
*/
|
||||
function assertValidNodeInfo(descriptor) {
|
||||
if (descriptor.node) {
|
||||
assert(typeof descriptor.node === "object", "Node must be an object");
|
||||
} else {
|
||||
assert(
|
||||
descriptor.loc,
|
||||
"Node must be provided when reporting error if location is not provided",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties
|
||||
* @param {MessageDescriptor} descriptor A descriptor for the report from a rule.
|
||||
* @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties
|
||||
* from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor.
|
||||
*/
|
||||
function normalizeReportLoc(descriptor) {
|
||||
if (descriptor.loc.start) {
|
||||
return descriptor.loc;
|
||||
}
|
||||
return { start: descriptor.loc, end: null };
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the given fix object.
|
||||
* @param {Fix|null} fix The fix to clone.
|
||||
* @returns {Fix|null} Deep cloned fix object or `null` if `null` or `undefined` was passed in.
|
||||
*/
|
||||
function cloneFix(fix) {
|
||||
if (!fix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
range: [fix.range[0], fix.range[1]],
|
||||
text: fix.text,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a fix has a valid range.
|
||||
* @param {Fix|null} fix The fix to validate.
|
||||
* @returns {void}
|
||||
*/
|
||||
function assertValidFix(fix) {
|
||||
if (fix) {
|
||||
assert(
|
||||
fix.range &&
|
||||
typeof fix.range[0] === "number" &&
|
||||
typeof fix.range[1] === "number",
|
||||
`Fix has invalid range: ${JSON.stringify(fix, null, 2)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares items in a fixes array by range.
|
||||
* @param {Fix} a The first message.
|
||||
* @param {Fix} b The second message.
|
||||
* @returns {number} -1 if a comes before b, 1 if a comes after b, 0 if equal.
|
||||
* @private
|
||||
*/
|
||||
function compareFixesByRange(a, b) {
|
||||
return a.range[0] - b.range[0] || a.range[1] - b.range[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the given fixes array into one.
|
||||
* @param {Fix[]} fixes The fixes to merge.
|
||||
* @param {SourceCode} sourceCode The source code object to get the text between fixes.
|
||||
* @returns {{text: string, range: number[]}} The merged fixes
|
||||
*/
|
||||
function mergeFixes(fixes, sourceCode) {
|
||||
for (const fix of fixes) {
|
||||
assertValidFix(fix);
|
||||
}
|
||||
|
||||
if (fixes.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (fixes.length === 1) {
|
||||
return cloneFix(fixes[0]);
|
||||
}
|
||||
|
||||
fixes.sort(compareFixesByRange);
|
||||
|
||||
const originalText = sourceCode.text;
|
||||
const start = fixes[0].range[0];
|
||||
const end = fixes.at(-1).range[1];
|
||||
let text = "";
|
||||
let lastPos = Number.MIN_SAFE_INTEGER;
|
||||
|
||||
for (const fix of fixes) {
|
||||
assert(
|
||||
fix.range[0] >= lastPos,
|
||||
"Fix objects must not be overlapped in a report.",
|
||||
);
|
||||
|
||||
if (fix.range[0] >= 0) {
|
||||
text += originalText.slice(
|
||||
Math.max(0, start, lastPos),
|
||||
fix.range[0],
|
||||
);
|
||||
}
|
||||
text += fix.text;
|
||||
lastPos = fix.range[1];
|
||||
}
|
||||
text += originalText.slice(Math.max(0, start, lastPos), end);
|
||||
|
||||
return { range: [start, end], text };
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one fix object from the given descriptor.
|
||||
* If the descriptor retrieves multiple fixes, this merges those to one.
|
||||
* @param {MessageDescriptor} descriptor The report descriptor.
|
||||
* @param {SourceCode} sourceCode The source code object to get text between fixes.
|
||||
* @returns {({text: string, range: number[]}|null)} The fix for the descriptor
|
||||
*/
|
||||
function normalizeFixes(descriptor, sourceCode) {
|
||||
if (typeof descriptor.fix !== "function") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const ruleFixer = new RuleFixer({ sourceCode });
|
||||
|
||||
// @type {null | Fix | Fix[] | IterableIterator<Fix>}
|
||||
const fix = descriptor.fix(ruleFixer);
|
||||
|
||||
// Merge to one.
|
||||
if (fix && Symbol.iterator in fix) {
|
||||
return mergeFixes(Array.from(fix), sourceCode);
|
||||
}
|
||||
|
||||
assertValidFix(fix);
|
||||
return cloneFix(fix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of suggestion objects from the given descriptor.
|
||||
* @param {MessageDescriptor} descriptor The report descriptor.
|
||||
* @param {SourceCode} sourceCode The source code object to get text between fixes.
|
||||
* @param {Object} messages Object of meta messages for the rule.
|
||||
* @returns {Array<SuggestionResult>} The suggestions for the descriptor
|
||||
*/
|
||||
function mapSuggestions(descriptor, sourceCode, messages) {
|
||||
if (!descriptor.suggest || !Array.isArray(descriptor.suggest)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (
|
||||
descriptor.suggest
|
||||
.map(suggestInfo => {
|
||||
const computedDesc =
|
||||
suggestInfo.desc || messages[suggestInfo.messageId];
|
||||
|
||||
return {
|
||||
...suggestInfo,
|
||||
desc: interpolate(computedDesc, suggestInfo.data),
|
||||
fix: normalizeFixes(suggestInfo, sourceCode),
|
||||
};
|
||||
})
|
||||
|
||||
// Remove suggestions that didn't provide a fix
|
||||
.filter(({ fix }) => fix)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates information about the report from a descriptor
|
||||
* @param {Object} options Information about the problem
|
||||
* @param {string} options.ruleId Rule ID
|
||||
* @param {(0|1|2)} options.severity Rule severity
|
||||
* @param {string} options.message Error message
|
||||
* @param {string} [options.messageId] The error message ID.
|
||||
* @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
|
||||
* @param {{text: string, range: (number[]|null)}} options.fix The fix object
|
||||
* @param {Array<{text: string, range: (number[]|null)}>} options.suggestions The array of suggestions objects
|
||||
* @param {Language} [options.language] The language to use to adjust line and column offsets.
|
||||
* @returns {LintMessage} Information about the report
|
||||
*/
|
||||
function createProblem(options) {
|
||||
const { language } = options;
|
||||
|
||||
// calculate offsets based on the language in use
|
||||
const columnOffset = language.columnStart === 1 ? 0 : 1;
|
||||
const lineOffset = language.lineStart === 1 ? 0 : 1;
|
||||
|
||||
const problem = {
|
||||
ruleId: options.ruleId,
|
||||
severity: options.severity,
|
||||
message: options.message,
|
||||
line: options.loc.start.line + lineOffset,
|
||||
column: options.loc.start.column + columnOffset,
|
||||
};
|
||||
|
||||
/*
|
||||
* If this isn’t in the conditional, some of the tests fail
|
||||
* because `messageId` is present in the problem object
|
||||
*/
|
||||
if (options.messageId) {
|
||||
problem.messageId = options.messageId;
|
||||
}
|
||||
|
||||
if (options.loc.end) {
|
||||
problem.endLine = options.loc.end.line + lineOffset;
|
||||
problem.endColumn = options.loc.end.column + columnOffset;
|
||||
}
|
||||
|
||||
if (options.fix) {
|
||||
problem.fix = options.fix;
|
||||
}
|
||||
|
||||
if (options.suggestions && options.suggestions.length > 0) {
|
||||
problem.suggestions = options.suggestions;
|
||||
}
|
||||
|
||||
return problem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that suggestions are properly defined. Throws if an error is detected.
|
||||
* @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data.
|
||||
* @param {Object} messages Object of meta messages for the rule.
|
||||
* @returns {void}
|
||||
*/
|
||||
function validateSuggestions(suggest, messages) {
|
||||
if (suggest && Array.isArray(suggest)) {
|
||||
suggest.forEach(suggestion => {
|
||||
if (suggestion.messageId) {
|
||||
const { messageId } = suggestion;
|
||||
|
||||
if (!messages) {
|
||||
throw new TypeError(
|
||||
`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!messages[messageId]) {
|
||||
throw new TypeError(
|
||||
`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (suggestion.desc) {
|
||||
throw new TypeError(
|
||||
"context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one.",
|
||||
);
|
||||
}
|
||||
} else if (!suggestion.desc) {
|
||||
throw new TypeError(
|
||||
"context.report() called with a suggest option that doesn't have either a `desc` or `messageId`",
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof suggestion.fix !== "function") {
|
||||
throw new TypeError(
|
||||
`context.report() called with a suggest option without a fix function. See: ${JSON.stringify(suggestion, null, 2)}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the message from a report descriptor.
|
||||
* @param {MessageDescriptor} descriptor The report descriptor.
|
||||
* @param {Object} messages Object of meta messages for the rule.
|
||||
* @returns {string} The computed message.
|
||||
* @throws {TypeError} If messageId is not found or both message and messageId are provided.
|
||||
*/
|
||||
function computeMessageFromDescriptor(descriptor, messages) {
|
||||
if (descriptor.messageId) {
|
||||
if (!messages) {
|
||||
throw new TypeError(
|
||||
"context.report() called with a messageId, but no messages were present in the rule metadata.",
|
||||
);
|
||||
}
|
||||
const id = descriptor.messageId;
|
||||
|
||||
if (descriptor.message) {
|
||||
throw new TypeError(
|
||||
"context.report() called with a message and a messageId. Please only pass one.",
|
||||
);
|
||||
}
|
||||
if (!messages || !Object.hasOwn(messages, id)) {
|
||||
throw new TypeError(
|
||||
`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`,
|
||||
);
|
||||
}
|
||||
return messages[id];
|
||||
}
|
||||
|
||||
if (descriptor.message) {
|
||||
return descriptor.message;
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
"Missing `message` property in report() call; add a message that describes the linting problem.",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A report object that contains the messages reported the linter
|
||||
* for a file.
|
||||
*/
|
||||
class FileReport {
|
||||
/**
|
||||
* The messages reported by the linter for this file.
|
||||
* @type {LintMessage[]}
|
||||
*/
|
||||
messages = [];
|
||||
|
||||
/**
|
||||
* A rule mapper that maps rule IDs to their metadata.
|
||||
* @type {(string) => RuleDefinition}
|
||||
*/
|
||||
#ruleMapper;
|
||||
|
||||
/**
|
||||
* The source code object for the file.
|
||||
* @type {SourceCode}
|
||||
*/
|
||||
#sourceCode;
|
||||
|
||||
/**
|
||||
* The language to use to adjust line and column offsets.
|
||||
* @type {Language}
|
||||
*/
|
||||
#language;
|
||||
|
||||
/**
|
||||
* Whether to disable fixes for this report.
|
||||
* @type {boolean}
|
||||
*/
|
||||
#disableFixes;
|
||||
|
||||
/**
|
||||
* Creates a new FileReport instance.
|
||||
* @param {Object} options The options for the file report
|
||||
* @param {(string) => RuleDefinition} options.ruleMapper A rule mapper that maps rule IDs to their metadata.
|
||||
* @param {SourceCode} options.sourceCode The source code object for the file.
|
||||
* @param {Language} options.language The language to use to adjust line and column offsets.
|
||||
* @param {boolean} [options.disableFixes=false] Whether to disable fixes for this report.
|
||||
*/
|
||||
constructor({ ruleMapper, sourceCode, language, disableFixes = false }) {
|
||||
this.#ruleMapper = ruleMapper;
|
||||
this.#sourceCode = sourceCode;
|
||||
this.#language = language;
|
||||
this.#disableFixes = disableFixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rule-generated message to the report.
|
||||
* @param {string} ruleId The rule ID that reported the problem.
|
||||
* @param {0|1|2} severity The severity of the problem (0 = off, 1 = warning, 2 = error).
|
||||
* @param {...*} args The arguments passed to `context.report()`.
|
||||
* @returns {LintMessage} The created message object.
|
||||
* @throws {TypeError} If the messageId is not found or both message and messageId are provided.
|
||||
* @throws {AssertionError} If the node is not an object or neither a node nor a loc is provided.
|
||||
*/
|
||||
addRuleMessage(ruleId, severity, ...args) {
|
||||
const descriptor = normalizeMultiArgReportCall(...args);
|
||||
const ruleDefinition = this.#ruleMapper(ruleId);
|
||||
const messages = ruleDefinition?.meta?.messages;
|
||||
|
||||
assertValidNodeInfo(descriptor);
|
||||
|
||||
const computedMessage = computeMessageFromDescriptor(
|
||||
descriptor,
|
||||
messages,
|
||||
);
|
||||
|
||||
validateSuggestions(descriptor.suggest, messages);
|
||||
|
||||
this.messages.push(
|
||||
createProblem({
|
||||
ruleId,
|
||||
severity,
|
||||
message: interpolate(computedMessage, descriptor.data),
|
||||
messageId: descriptor.messageId,
|
||||
loc: descriptor.loc
|
||||
? normalizeReportLoc(descriptor)
|
||||
: this.#sourceCode.getLoc(descriptor.node),
|
||||
fix: this.#disableFixes
|
||||
? null
|
||||
: normalizeFixes(descriptor, this.#sourceCode),
|
||||
suggestions: this.#disableFixes
|
||||
? []
|
||||
: mapSuggestions(descriptor, this.#sourceCode, messages),
|
||||
language: this.#language,
|
||||
}),
|
||||
);
|
||||
|
||||
return this.messages.at(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error message to the report. Meant to be called outside of rules.
|
||||
* @param {LintProblem} descriptor The descriptor for the error message.
|
||||
* @returns {LintMessage} The created message object.
|
||||
*/
|
||||
addError(descriptor) {
|
||||
const message = createLintingProblem(descriptor, 2, this.#language);
|
||||
this.messages.push(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a fatal error message to the report. Meant to be called outside of rules.
|
||||
* @param {LintProblem} descriptor The descriptor for the fatal error message.
|
||||
* @returns {LintMessage} The created message object.
|
||||
*/
|
||||
addFatal(descriptor) {
|
||||
const message = createLintingProblem(descriptor, 2, this.#language);
|
||||
message.fatal = true;
|
||||
this.messages.push(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a warning message to the report. Meant to be called outside of rules.
|
||||
* @param {LintProblem} descriptor The descriptor for the warning message.
|
||||
* @returns {LintMessage} The created message object.
|
||||
*/
|
||||
addWarning(descriptor) {
|
||||
const message = createLintingProblem(descriptor, 1, this.#language);
|
||||
this.messages.push(message);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FileReport,
|
||||
updateLocationInformation,
|
||||
};
|
||||
@@ -0,0 +1,926 @@
|
||||
import WebSocketImpl, { WebSocketServer } from 'ws';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import url from 'url';
|
||||
import { v1 } from 'uuid';
|
||||
|
||||
// src/lib/client/websocket.ts
|
||||
function WebSocket(address, options) {
|
||||
return new WebSocketImpl(address, options);
|
||||
}
|
||||
|
||||
// src/lib/utils.ts
|
||||
var DefaultDataPack = class {
|
||||
encode(value) {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
decode(value) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
};
|
||||
|
||||
// src/lib/client.ts
|
||||
var CommonClient = class extends EventEmitter {
|
||||
address;
|
||||
rpc_id;
|
||||
queue;
|
||||
options;
|
||||
autoconnect;
|
||||
ready;
|
||||
reconnect;
|
||||
reconnect_timer_id;
|
||||
reconnect_interval;
|
||||
max_reconnects;
|
||||
rest_options;
|
||||
current_reconnects;
|
||||
generate_request_id;
|
||||
socket;
|
||||
webSocketFactory;
|
||||
dataPack;
|
||||
/**
|
||||
* Instantiate a Client class.
|
||||
* @constructor
|
||||
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
|
||||
* @param {String} address - url to a websocket server
|
||||
* @param {Object} options - ws options object with reconnect parameters
|
||||
* @param {Function} generate_request_id - custom generation request Id
|
||||
* @param {DataPack} dataPack - data pack contains encoder and decoder
|
||||
* @return {CommonClient}
|
||||
*/
|
||||
constructor(webSocketFactory, address = "ws://localhost:8080", {
|
||||
autoconnect = true,
|
||||
reconnect = true,
|
||||
reconnect_interval = 1e3,
|
||||
max_reconnects = 5,
|
||||
...rest_options
|
||||
} = {}, generate_request_id, dataPack) {
|
||||
super();
|
||||
this.webSocketFactory = webSocketFactory;
|
||||
this.queue = {};
|
||||
this.rpc_id = 0;
|
||||
this.address = address;
|
||||
this.autoconnect = autoconnect;
|
||||
this.ready = false;
|
||||
this.reconnect = reconnect;
|
||||
this.reconnect_timer_id = void 0;
|
||||
this.reconnect_interval = reconnect_interval;
|
||||
this.max_reconnects = max_reconnects;
|
||||
this.rest_options = rest_options;
|
||||
this.current_reconnects = 0;
|
||||
this.generate_request_id = generate_request_id || (() => typeof this.rpc_id === "number" ? ++this.rpc_id : Number(this.rpc_id) + 1);
|
||||
if (!dataPack) this.dataPack = new DefaultDataPack();
|
||||
else this.dataPack = dataPack;
|
||||
if (this.autoconnect)
|
||||
this._connect(this.address, {
|
||||
autoconnect: this.autoconnect,
|
||||
reconnect: this.reconnect,
|
||||
reconnect_interval: this.reconnect_interval,
|
||||
max_reconnects: this.max_reconnects,
|
||||
...this.rest_options
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Connects to a defined server if not connected already.
|
||||
* @method
|
||||
* @return {Undefined}
|
||||
*/
|
||||
connect() {
|
||||
if (this.socket) return;
|
||||
this._connect(this.address, {
|
||||
autoconnect: this.autoconnect,
|
||||
reconnect: this.reconnect,
|
||||
reconnect_interval: this.reconnect_interval,
|
||||
max_reconnects: this.max_reconnects,
|
||||
...this.rest_options
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Calls a registered RPC method on server.
|
||||
* @method
|
||||
* @param {String} method - RPC method name
|
||||
* @param {Object|Array} params - optional method parameters
|
||||
* @param {Number} timeout - RPC reply timeout value
|
||||
* @param {Object} ws_opts - options passed to ws
|
||||
* @return {Promise}
|
||||
*/
|
||||
call(method, params, timeout, ws_opts) {
|
||||
if (!ws_opts && "object" === typeof timeout) {
|
||||
ws_opts = timeout;
|
||||
timeout = null;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.ready) return reject(new Error("socket not ready"));
|
||||
const rpc_id = this.generate_request_id(method, params);
|
||||
const message = {
|
||||
jsonrpc: "2.0",
|
||||
method,
|
||||
params: params || void 0,
|
||||
id: rpc_id
|
||||
};
|
||||
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
|
||||
if (error) return reject(error);
|
||||
this.queue[rpc_id] = { promise: [resolve, reject] };
|
||||
if (timeout) {
|
||||
this.queue[rpc_id].timeout = setTimeout(() => {
|
||||
delete this.queue[rpc_id];
|
||||
reject(new Error("reply timeout"));
|
||||
}, timeout);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Logins with the other side of the connection.
|
||||
* @method
|
||||
* @param {Object} params - Login credentials object
|
||||
* @return {Promise}
|
||||
*/
|
||||
async login(params) {
|
||||
const resp = await this.call("rpc.login", params);
|
||||
if (!resp) throw new Error("authentication failed");
|
||||
return resp;
|
||||
}
|
||||
/**
|
||||
* Fetches a list of client's methods registered on server.
|
||||
* @method
|
||||
* @return {Array}
|
||||
*/
|
||||
async listMethods() {
|
||||
return await this.call("__listMethods");
|
||||
}
|
||||
/**
|
||||
* Sends a JSON-RPC 2.0 notification to server.
|
||||
* @method
|
||||
* @param {String} method - RPC method name
|
||||
* @param {Object} params - optional method parameters
|
||||
* @return {Promise}
|
||||
*/
|
||||
notify(method, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.ready) return reject(new Error("socket not ready"));
|
||||
const message = {
|
||||
jsonrpc: "2.0",
|
||||
method,
|
||||
params
|
||||
};
|
||||
this.socket.send(this.dataPack.encode(message), (error) => {
|
||||
if (error) return reject(error);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Subscribes for a defined event.
|
||||
* @method
|
||||
* @param {String|Array} event - event name
|
||||
* @return {Undefined}
|
||||
* @throws {Error}
|
||||
*/
|
||||
async subscribe(event) {
|
||||
if (typeof event === "string") event = [event];
|
||||
const result = await this.call("rpc.on", event);
|
||||
if (typeof event === "string" && result[event] !== "ok")
|
||||
throw new Error(
|
||||
"Failed subscribing to an event '" + event + "' with: " + result[event]
|
||||
);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Unsubscribes from a defined event.
|
||||
* @method
|
||||
* @param {String|Array} event - event name
|
||||
* @return {Undefined}
|
||||
* @throws {Error}
|
||||
*/
|
||||
async unsubscribe(event) {
|
||||
if (typeof event === "string") event = [event];
|
||||
const result = await this.call("rpc.off", event);
|
||||
if (typeof event === "string" && result[event] !== "ok")
|
||||
throw new Error("Failed unsubscribing from an event with: " + result);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Closes a WebSocket connection gracefully.
|
||||
* @method
|
||||
* @param {Number} code - socket close code
|
||||
* @param {String} data - optional data to be sent before closing
|
||||
* @return {Undefined}
|
||||
*/
|
||||
close(code, data) {
|
||||
if (this.socket) this.socket.close(code || 1e3, data);
|
||||
}
|
||||
/**
|
||||
* Enable / disable automatic reconnection.
|
||||
* @method
|
||||
* @param {Boolean} reconnect - enable / disable reconnection
|
||||
* @return {Undefined}
|
||||
*/
|
||||
setAutoReconnect(reconnect) {
|
||||
this.reconnect = reconnect;
|
||||
}
|
||||
/**
|
||||
* Set the interval between reconnection attempts.
|
||||
* @method
|
||||
* @param {Number} interval - reconnection interval in milliseconds
|
||||
* @return {Undefined}
|
||||
*/
|
||||
setReconnectInterval(interval) {
|
||||
this.reconnect_interval = interval;
|
||||
}
|
||||
/**
|
||||
* Set the maximum number of reconnection attempts.
|
||||
* @method
|
||||
* @param {Number} max_reconnects - maximum reconnection attempts
|
||||
* @return {Undefined}
|
||||
*/
|
||||
setMaxReconnects(max_reconnects) {
|
||||
this.max_reconnects = max_reconnects;
|
||||
}
|
||||
/**
|
||||
* Get the current number of reconnection attempts made.
|
||||
* @method
|
||||
* @return {Number} current reconnection attempts
|
||||
*/
|
||||
getCurrentReconnects() {
|
||||
return this.current_reconnects;
|
||||
}
|
||||
/**
|
||||
* Get the maximum number of reconnection attempts.
|
||||
* @method
|
||||
* @return {Number} maximum reconnection attempts
|
||||
*/
|
||||
getMaxReconnects() {
|
||||
return this.max_reconnects;
|
||||
}
|
||||
/**
|
||||
* Check if the client is currently attempting to reconnect.
|
||||
* @method
|
||||
* @return {Boolean} true if reconnection is in progress
|
||||
*/
|
||||
isReconnecting() {
|
||||
return this.reconnect_timer_id !== void 0;
|
||||
}
|
||||
/**
|
||||
* Check if the client will attempt to reconnect on the next close event.
|
||||
* @method
|
||||
* @return {Boolean} true if reconnection will be attempted
|
||||
*/
|
||||
willReconnect() {
|
||||
return this.reconnect && (this.max_reconnects === 0 || this.current_reconnects < this.max_reconnects);
|
||||
}
|
||||
/**
|
||||
* Connection/Message handler.
|
||||
* @method
|
||||
* @private
|
||||
* @param {String} address - WebSocket API address
|
||||
* @param {Object} options - ws options object
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_connect(address, options) {
|
||||
clearTimeout(this.reconnect_timer_id);
|
||||
this.socket = this.webSocketFactory(address, options);
|
||||
this.socket.addEventListener("open", () => {
|
||||
this.ready = true;
|
||||
this.emit("open");
|
||||
this.current_reconnects = 0;
|
||||
});
|
||||
this.socket.addEventListener("message", ({ data: message }) => {
|
||||
if (message instanceof ArrayBuffer)
|
||||
message = Buffer.from(message).toString();
|
||||
try {
|
||||
message = this.dataPack.decode(message);
|
||||
} catch (_error) {
|
||||
return;
|
||||
}
|
||||
if (message.notification && this.listeners(message.notification).length) {
|
||||
if (!Object.keys(message.params).length)
|
||||
return this.emit(message.notification);
|
||||
const args = [message.notification];
|
||||
if (message.params.constructor === Object) args.push(message.params);
|
||||
else
|
||||
for (let i = 0; i < message.params.length; i++)
|
||||
args.push(message.params[i]);
|
||||
return Promise.resolve().then(() => {
|
||||
this.emit.apply(this, args);
|
||||
});
|
||||
}
|
||||
if (!this.queue[message.id]) {
|
||||
if (message.method) {
|
||||
return Promise.resolve().then(() => {
|
||||
this.emit(message.method, message?.params);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ("error" in message === "result" in message)
|
||||
this.queue[message.id].promise[1](
|
||||
new Error(
|
||||
'Server response malformed. Response must include either "result" or "error", but not both.'
|
||||
)
|
||||
);
|
||||
if (this.queue[message.id].timeout)
|
||||
clearTimeout(this.queue[message.id].timeout);
|
||||
if (message.error) this.queue[message.id].promise[1](message.error);
|
||||
else this.queue[message.id].promise[0](message.result);
|
||||
delete this.queue[message.id];
|
||||
});
|
||||
this.socket.addEventListener("error", (error) => this.emit("error", error));
|
||||
this.socket.addEventListener("close", ({ code, reason }) => {
|
||||
if (this.ready)
|
||||
setTimeout(() => this.emit("close", code, reason), 0);
|
||||
this.ready = false;
|
||||
this.socket = void 0;
|
||||
if (code === 1e3) return;
|
||||
this.current_reconnects++;
|
||||
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
|
||||
this.reconnect_timer_id = setTimeout(
|
||||
() => this._connect(address, options),
|
||||
this.reconnect_interval
|
||||
);
|
||||
else if (this.reconnect && this.max_reconnects > 0 && this.current_reconnects >= this.max_reconnects) {
|
||||
setTimeout(() => this.emit("max_reconnects_reached", code, reason), 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
var Server = class extends EventEmitter {
|
||||
namespaces;
|
||||
dataPack;
|
||||
wss;
|
||||
/**
|
||||
* Instantiate a Server class.
|
||||
* @constructor
|
||||
* @param {Object} options - ws constructor's parameters with rpc
|
||||
* @param {DataPack} dataPack - data pack contains encoder and decoder
|
||||
* @return {Server} - returns a new Server instance
|
||||
*/
|
||||
constructor(options, dataPack) {
|
||||
super();
|
||||
this.namespaces = {};
|
||||
if (!dataPack) this.dataPack = new DefaultDataPack();
|
||||
else this.dataPack = dataPack;
|
||||
this.wss = new WebSocketServer(options);
|
||||
this.wss.on("listening", () => this.emit("listening"));
|
||||
this.wss.on("connection", (socket, request) => {
|
||||
const u = url.parse(request.url, true);
|
||||
const ns = u.pathname;
|
||||
if (u.query.socket_id) socket._id = u.query.socket_id;
|
||||
else socket._id = v1();
|
||||
socket["_authenticated"] = false;
|
||||
socket.on("error", (error) => this.emit("socket-error", socket, error));
|
||||
socket.on("close", () => {
|
||||
this.namespaces[ns].clients.delete(socket._id);
|
||||
for (const event of Object.keys(this.namespaces[ns].events)) {
|
||||
const index = this.namespaces[ns].events[event].sockets.indexOf(
|
||||
socket._id
|
||||
);
|
||||
if (index >= 0)
|
||||
this.namespaces[ns].events[event].sockets.splice(index, 1);
|
||||
}
|
||||
this.emit("disconnection", socket);
|
||||
});
|
||||
if (!this.namespaces[ns]) this._generateNamespace(ns);
|
||||
this.namespaces[ns].clients.set(socket._id, socket);
|
||||
this.emit("connection", socket, request);
|
||||
return this._handleRPC(socket, ns);
|
||||
});
|
||||
this.wss.on("error", (error) => this.emit("error", error));
|
||||
}
|
||||
/**
|
||||
* Registers an RPC method.
|
||||
* @method
|
||||
* @param {String} name - method name
|
||||
* @param {Function} fn - a callee function
|
||||
* @param {String} ns - namespace identifier
|
||||
* @throws {TypeError}
|
||||
* @return {Object} - returns an IMethod object
|
||||
*/
|
||||
register(name, fn, ns = "/") {
|
||||
if (!this.namespaces[ns]) this._generateNamespace(ns);
|
||||
this.namespaces[ns].rpc_methods[name] = {
|
||||
fn,
|
||||
protected: false
|
||||
};
|
||||
return {
|
||||
protected: () => this._makeProtectedMethod(name, ns),
|
||||
public: () => this._makePublicMethod(name, ns)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Sets an auth method.
|
||||
* @method
|
||||
* @param {Function} fn - an arbitrary auth method
|
||||
* @param {String} ns - namespace identifier
|
||||
* @throws {TypeError}
|
||||
* @return {Undefined}
|
||||
*/
|
||||
setAuth(fn, ns = "/") {
|
||||
this.register("rpc.login", fn, ns);
|
||||
}
|
||||
/**
|
||||
* Marks an RPC method as protected.
|
||||
* @method
|
||||
* @param {String} name - method name
|
||||
* @param {String} ns - namespace identifier
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_makeProtectedMethod(name, ns = "/") {
|
||||
this.namespaces[ns].rpc_methods[name].protected = true;
|
||||
}
|
||||
/**
|
||||
* Marks an RPC method as public.
|
||||
* @method
|
||||
* @param {String} name - method name
|
||||
* @param {String} ns - namespace identifier
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_makePublicMethod(name, ns = "/") {
|
||||
this.namespaces[ns].rpc_methods[name].protected = false;
|
||||
}
|
||||
/**
|
||||
* Marks an event as protected.
|
||||
* @method
|
||||
* @param {String} name - event name
|
||||
* @param {String} ns - namespace identifier
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_makeProtectedEvent(name, ns = "/") {
|
||||
this.namespaces[ns].events[name].protected = true;
|
||||
}
|
||||
/**
|
||||
* Marks an event as public.
|
||||
* @method
|
||||
* @param {String} name - event name
|
||||
* @param {String} ns - namespace identifier
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_makePublicEvent(name, ns = "/") {
|
||||
this.namespaces[ns].events[name].protected = false;
|
||||
}
|
||||
/**
|
||||
* Removes a namespace and closes all connections
|
||||
* @method
|
||||
* @param {String} ns - namespace identifier
|
||||
* @throws {TypeError}
|
||||
* @return {Undefined}
|
||||
*/
|
||||
closeNamespace(ns) {
|
||||
const namespace = this.namespaces[ns];
|
||||
if (namespace) {
|
||||
delete namespace.rpc_methods;
|
||||
delete namespace.events;
|
||||
for (const socket of namespace.clients.values()) socket.close();
|
||||
delete this.namespaces[ns];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new event that can be emitted to clients.
|
||||
* @method
|
||||
* @param {String} name - event name
|
||||
* @param {String} ns - namespace identifier
|
||||
* @throws {TypeError}
|
||||
* @return {Object} - returns an IEvent object
|
||||
*/
|
||||
event(name, ns = "/") {
|
||||
if (!this.namespaces[ns]) this._generateNamespace(ns);
|
||||
else {
|
||||
const index = this.namespaces[ns].events[name];
|
||||
if (index !== void 0)
|
||||
throw new Error(`Already registered event ${ns}${name}`);
|
||||
}
|
||||
this.namespaces[ns].events[name] = {
|
||||
sockets: [],
|
||||
protected: false
|
||||
};
|
||||
this.on(name, (...params) => {
|
||||
if (params.length === 1 && params[0] instanceof Object)
|
||||
params = params[0];
|
||||
for (const socket_id of this.namespaces[ns].events[name].sockets) {
|
||||
const socket = this.namespaces[ns].clients.get(socket_id);
|
||||
if (!socket) continue;
|
||||
socket.send(
|
||||
this.dataPack.encode({
|
||||
notification: name,
|
||||
params
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
return {
|
||||
protected: () => this._makeProtectedEvent(name, ns),
|
||||
public: () => this._makePublicEvent(name, ns)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Returns a requested namespace object
|
||||
* @method
|
||||
* @param {String} name - namespace identifier
|
||||
* @throws {TypeError}
|
||||
* @return {Object} - namespace object
|
||||
*/
|
||||
of(name) {
|
||||
if (!this.namespaces[name]) this._generateNamespace(name);
|
||||
const self = this;
|
||||
return {
|
||||
// self.register convenience method
|
||||
register(fn_name, fn) {
|
||||
if (arguments.length !== 2)
|
||||
throw new Error("must provide exactly two arguments");
|
||||
if (typeof fn_name !== "string")
|
||||
throw new Error("name must be a string");
|
||||
if (typeof fn !== "function")
|
||||
throw new Error("handler must be a function");
|
||||
return self.register(fn_name, fn, name);
|
||||
},
|
||||
// self.event convenience method
|
||||
event(ev_name) {
|
||||
if (arguments.length !== 1)
|
||||
throw new Error("must provide exactly one argument");
|
||||
if (typeof ev_name !== "string")
|
||||
throw new Error("name must be a string");
|
||||
return self.event(ev_name, name);
|
||||
},
|
||||
// self.eventList convenience method
|
||||
get eventList() {
|
||||
return Object.keys(self.namespaces[name].events);
|
||||
},
|
||||
/**
|
||||
* Emits a specified event to this namespace.
|
||||
* @inner
|
||||
* @method
|
||||
* @param {String} event - event name
|
||||
* @param {Array} params - event parameters
|
||||
* @return {Undefined}
|
||||
*/
|
||||
emit(event, ...params) {
|
||||
const nsEvent = self.namespaces[name].events[event];
|
||||
if (nsEvent)
|
||||
for (const socket_id of nsEvent.sockets) {
|
||||
const socket = self.namespaces[name].clients.get(socket_id);
|
||||
if (!socket) continue;
|
||||
socket.send(
|
||||
self.dataPack.encode({
|
||||
notification: event,
|
||||
params
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Returns a name of this namespace.
|
||||
* @inner
|
||||
* @method
|
||||
* @kind constant
|
||||
* @return {String}
|
||||
*/
|
||||
get name() {
|
||||
return name;
|
||||
},
|
||||
/**
|
||||
* Returns a hash of websocket objects connected to this namespace.
|
||||
* @inner
|
||||
* @method
|
||||
* @return {Object}
|
||||
*/
|
||||
connected() {
|
||||
const socket_ids = [...self.namespaces[name].clients.keys()];
|
||||
return socket_ids.reduce(
|
||||
(acc, curr) => ({
|
||||
...acc,
|
||||
[curr]: self.namespaces[name].clients.get(curr)
|
||||
}),
|
||||
{}
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Returns a list of client unique identifiers connected to this namespace.
|
||||
* @inner
|
||||
* @method
|
||||
* @return {Array}
|
||||
*/
|
||||
clients() {
|
||||
return self.namespaces[name];
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Lists all created events in a given namespace. Defaults to "/".
|
||||
* @method
|
||||
* @param {String} ns - namespaces identifier
|
||||
* @readonly
|
||||
* @return {Array} - returns a list of created events
|
||||
*/
|
||||
eventList(ns = "/") {
|
||||
if (!this.namespaces[ns]) return [];
|
||||
return Object.keys(this.namespaces[ns].events);
|
||||
}
|
||||
/**
|
||||
* Creates a JSON-RPC 2.0 compliant error
|
||||
* @method
|
||||
* @param {Number} code - indicates the error type that occurred
|
||||
* @param {String} message - provides a short description of the error
|
||||
* @param {String|Object} data - details containing additional information about the error
|
||||
* @return {Object}
|
||||
*/
|
||||
createError(code, message, data) {
|
||||
return {
|
||||
code,
|
||||
message,
|
||||
data: data || null
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Closes the server and terminates all clients.
|
||||
* @method
|
||||
* @return {Promise}
|
||||
*/
|
||||
close() {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
this.wss.close();
|
||||
this.emit("close");
|
||||
resolve();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handles all WebSocket JSON RPC 2.0 requests.
|
||||
* @private
|
||||
* @param {Object} socket - ws socket instance
|
||||
* @param {String} ns - namespaces identifier
|
||||
* @return {Undefined}
|
||||
*/
|
||||
_handleRPC(socket, ns = "/") {
|
||||
socket.on("message", async (data) => {
|
||||
const msg_options = {};
|
||||
if (data instanceof ArrayBuffer) {
|
||||
msg_options.binary = true;
|
||||
data = Buffer.from(data).toString();
|
||||
}
|
||||
if (socket.readyState !== 1) return;
|
||||
let parsedData;
|
||||
try {
|
||||
parsedData = this.dataPack.decode(data);
|
||||
} catch (error) {
|
||||
return socket.send(
|
||||
this.dataPack.encode({
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32700, error.toString()),
|
||||
id: null
|
||||
}),
|
||||
msg_options
|
||||
);
|
||||
}
|
||||
if (Array.isArray(parsedData)) {
|
||||
if (!parsedData.length)
|
||||
return socket.send(
|
||||
this.dataPack.encode({
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32600, "Invalid array"),
|
||||
id: null
|
||||
}),
|
||||
msg_options
|
||||
);
|
||||
const responses = [];
|
||||
for (const message of parsedData) {
|
||||
const response2 = await this._runMethod(message, socket._id, ns);
|
||||
if (!response2) continue;
|
||||
responses.push(response2);
|
||||
}
|
||||
if (!responses.length) return;
|
||||
return socket.send(this.dataPack.encode(responses), msg_options);
|
||||
}
|
||||
const response = await this._runMethod(parsedData, socket._id, ns);
|
||||
if (!response) return;
|
||||
return socket.send(this.dataPack.encode(response), msg_options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Runs a defined RPC method.
|
||||
* @private
|
||||
* @param {Object} message - a message received
|
||||
* @param {Object} socket_id - user's socket id
|
||||
* @param {String} ns - namespaces identifier
|
||||
* @return {Object|undefined}
|
||||
*/
|
||||
async _runMethod(message, socket_id, ns = "/") {
|
||||
if (typeof message !== "object" || message === null)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32600),
|
||||
id: null
|
||||
};
|
||||
if (message.jsonrpc !== "2.0")
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32600, "Invalid JSON RPC version"),
|
||||
id: message.id || null
|
||||
};
|
||||
if (!message.method)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32602, "Method not specified"),
|
||||
id: message.id || null
|
||||
};
|
||||
if (typeof message.method !== "string")
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32600, "Invalid method name"),
|
||||
id: message.id || null
|
||||
};
|
||||
if (message.params && typeof message.params === "string")
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32600),
|
||||
id: message.id || null
|
||||
};
|
||||
if (message.method === "rpc.on") {
|
||||
if (!message.params)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32e3),
|
||||
id: message.id || null
|
||||
};
|
||||
const results = {};
|
||||
const event_names = Object.keys(this.namespaces[ns].events);
|
||||
for (const name of message.params) {
|
||||
const index = event_names.indexOf(name);
|
||||
const namespace = this.namespaces[ns];
|
||||
if (index === -1) {
|
||||
results[name] = "provided event invalid";
|
||||
continue;
|
||||
}
|
||||
if (namespace.events[event_names[index]].protected === true && namespace.clients.get(socket_id)["_authenticated"] === false) {
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32606),
|
||||
id: message.id || null
|
||||
};
|
||||
}
|
||||
const socket_index = namespace.events[event_names[index]].sockets.indexOf(socket_id);
|
||||
if (socket_index >= 0) {
|
||||
results[name] = "socket has already been subscribed to event";
|
||||
continue;
|
||||
}
|
||||
namespace.events[event_names[index]].sockets.push(socket_id);
|
||||
results[name] = "ok";
|
||||
}
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
result: results,
|
||||
id: message.id || null
|
||||
};
|
||||
} else if (message.method === "rpc.off") {
|
||||
if (!message.params)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32e3),
|
||||
id: message.id || null
|
||||
};
|
||||
const results = {};
|
||||
for (const name of message.params) {
|
||||
if (!this.namespaces[ns].events[name]) {
|
||||
results[name] = "provided event invalid";
|
||||
continue;
|
||||
}
|
||||
const index = this.namespaces[ns].events[name].sockets.indexOf(socket_id);
|
||||
if (index === -1) {
|
||||
results[name] = "not subscribed";
|
||||
continue;
|
||||
}
|
||||
this.namespaces[ns].events[name].sockets.splice(index, 1);
|
||||
results[name] = "ok";
|
||||
}
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
result: results,
|
||||
id: message.id || null
|
||||
};
|
||||
} else if (message.method === "rpc.login") {
|
||||
if (!message.params)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32604),
|
||||
id: message.id || null
|
||||
};
|
||||
}
|
||||
if (!this.namespaces[ns].rpc_methods[message.method]) {
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32601),
|
||||
id: message.id || null
|
||||
};
|
||||
}
|
||||
let response = null;
|
||||
if (this.namespaces[ns].rpc_methods[message.method].protected === true && this.namespaces[ns].clients.get(socket_id)["_authenticated"] === false) {
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: createError(-32605),
|
||||
id: message.id || null
|
||||
};
|
||||
}
|
||||
try {
|
||||
response = await this.namespaces[ns].rpc_methods[message.method].fn(
|
||||
message.params,
|
||||
socket_id
|
||||
);
|
||||
} catch (error) {
|
||||
if (!message.id) return;
|
||||
if (error instanceof Error)
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error: {
|
||||
code: -32e3,
|
||||
message: error.name,
|
||||
data: error.message
|
||||
},
|
||||
id: message.id
|
||||
};
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
error,
|
||||
id: message.id
|
||||
};
|
||||
}
|
||||
if (!message.id) return;
|
||||
if (message.method === "rpc.login" && response === true) {
|
||||
const s = this.namespaces[ns].clients.get(socket_id);
|
||||
if (s) {
|
||||
s["_authenticated"] = true;
|
||||
this.namespaces[ns].clients.set(socket_id, s);
|
||||
}
|
||||
}
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
result: response,
|
||||
id: message.id
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate a new namespace store.
|
||||
* Also preregister some special namespace methods.
|
||||
* @private
|
||||
* @param {String} name - namespaces identifier
|
||||
* @return {undefined}
|
||||
*/
|
||||
_generateNamespace(name) {
|
||||
this.namespaces[name] = {
|
||||
rpc_methods: {
|
||||
__listMethods: {
|
||||
fn: () => Object.keys(this.namespaces[name].rpc_methods),
|
||||
protected: false
|
||||
}
|
||||
},
|
||||
clients: /* @__PURE__ */ new Map(),
|
||||
events: {}
|
||||
};
|
||||
}
|
||||
};
|
||||
var RPC_ERRORS = /* @__PURE__ */ new Map([
|
||||
[-32e3, "Event not provided"],
|
||||
[-32600, "Invalid Request"],
|
||||
[-32601, "Method not found"],
|
||||
[-32602, "Invalid params"],
|
||||
[-32603, "Internal error"],
|
||||
[-32604, "Params not found"],
|
||||
[-32605, "Method forbidden"],
|
||||
[-32606, "Event forbidden"],
|
||||
[-32700, "Parse error"]
|
||||
]);
|
||||
function createError(code, details) {
|
||||
const error = {
|
||||
code,
|
||||
message: RPC_ERRORS.get(code) || "Internal Server Error"
|
||||
};
|
||||
if (details) error["data"] = details;
|
||||
return error;
|
||||
}
|
||||
|
||||
// src/index.ts
|
||||
var Client = class extends CommonClient {
|
||||
constructor(address = "ws://localhost:8080", {
|
||||
autoconnect = true,
|
||||
reconnect = true,
|
||||
reconnect_interval = 1e3,
|
||||
max_reconnects = 5,
|
||||
...rest_options
|
||||
} = {}, generate_request_id) {
|
||||
super(
|
||||
WebSocket,
|
||||
address,
|
||||
{
|
||||
autoconnect,
|
||||
reconnect,
|
||||
reconnect_interval,
|
||||
max_reconnects,
|
||||
...rest_options
|
||||
},
|
||||
generate_request_id
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export { Client, CommonClient, DefaultDataPack, Server, WebSocket, createError };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
@@ -0,0 +1,259 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const JSONB = require('json-buffer');
|
||||
|
||||
const loadStore = options => {
|
||||
const adapters = {
|
||||
redis: '@keyv/redis',
|
||||
rediss: '@keyv/redis',
|
||||
mongodb: '@keyv/mongo',
|
||||
mongo: '@keyv/mongo',
|
||||
sqlite: '@keyv/sqlite',
|
||||
postgresql: '@keyv/postgres',
|
||||
postgres: '@keyv/postgres',
|
||||
mysql: '@keyv/mysql',
|
||||
etcd: '@keyv/etcd',
|
||||
offline: '@keyv/offline',
|
||||
tiered: '@keyv/tiered',
|
||||
};
|
||||
if (options.adapter || options.uri) {
|
||||
const adapter = options.adapter || /^[^:+]*/.exec(options.uri)[0];
|
||||
return new (require(adapters[adapter]))(options);
|
||||
}
|
||||
|
||||
return new Map();
|
||||
};
|
||||
|
||||
const iterableAdapters = [
|
||||
'sqlite',
|
||||
'postgres',
|
||||
'mysql',
|
||||
'mongo',
|
||||
'redis',
|
||||
'tiered',
|
||||
];
|
||||
|
||||
class Keyv extends EventEmitter {
|
||||
constructor(uri, {emitErrors = true, ...options} = {}) {
|
||||
super();
|
||||
this.opts = {
|
||||
namespace: 'keyv',
|
||||
serialize: JSONB.stringify,
|
||||
deserialize: JSONB.parse,
|
||||
...((typeof uri === 'string') ? {uri} : uri),
|
||||
...options,
|
||||
};
|
||||
|
||||
if (!this.opts.store) {
|
||||
const adapterOptions = {...this.opts};
|
||||
this.opts.store = loadStore(adapterOptions);
|
||||
}
|
||||
|
||||
if (this.opts.compression) {
|
||||
const compression = this.opts.compression;
|
||||
this.opts.serialize = compression.serialize.bind(compression);
|
||||
this.opts.deserialize = compression.deserialize.bind(compression);
|
||||
}
|
||||
|
||||
if (typeof this.opts.store.on === 'function' && emitErrors) {
|
||||
this.opts.store.on('error', error => this.emit('error', error));
|
||||
}
|
||||
|
||||
this.opts.store.namespace = this.opts.namespace;
|
||||
|
||||
const generateIterator = iterator => async function * () {
|
||||
for await (const [key, raw] of typeof iterator === 'function'
|
||||
? iterator(this.opts.store.namespace)
|
||||
: iterator) {
|
||||
const data = await this.opts.deserialize(raw);
|
||||
if (this.opts.store.namespace && !key.includes(this.opts.store.namespace)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof data.expires === 'number' && Date.now() > data.expires) {
|
||||
this.delete(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
yield [this._getKeyUnprefix(key), data.value];
|
||||
}
|
||||
};
|
||||
|
||||
// Attach iterators
|
||||
if (typeof this.opts.store[Symbol.iterator] === 'function' && this.opts.store instanceof Map) {
|
||||
this.iterator = generateIterator(this.opts.store);
|
||||
} else if (typeof this.opts.store.iterator === 'function' && this.opts.store.opts
|
||||
&& this._checkIterableAdaptar()) {
|
||||
this.iterator = generateIterator(this.opts.store.iterator.bind(this.opts.store));
|
||||
}
|
||||
}
|
||||
|
||||
_checkIterableAdaptar() {
|
||||
return iterableAdapters.includes(this.opts.store.opts.dialect)
|
||||
|| iterableAdapters.findIndex(element => this.opts.store.opts.url.includes(element)) >= 0;
|
||||
}
|
||||
|
||||
_getKeyPrefix(key) {
|
||||
return `${this.opts.namespace}:${key}`;
|
||||
}
|
||||
|
||||
_getKeyPrefixArray(keys) {
|
||||
return keys.map(key => `${this.opts.namespace}:${key}`);
|
||||
}
|
||||
|
||||
_getKeyUnprefix(key) {
|
||||
return key
|
||||
.split(':')
|
||||
.splice(1)
|
||||
.join(':');
|
||||
}
|
||||
|
||||
get(key, options) {
|
||||
const {store} = this.opts;
|
||||
const isArray = Array.isArray(key);
|
||||
const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
|
||||
if (isArray && store.getMany === undefined) {
|
||||
const promises = [];
|
||||
for (const key of keyPrefixed) {
|
||||
promises.push(Promise.resolve()
|
||||
.then(() => store.get(key))
|
||||
.then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data))
|
||||
.then(data => {
|
||||
if (data === undefined || data === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof data.expires === 'number' && Date.now() > data.expires) {
|
||||
return this.delete(key).then(() => undefined);
|
||||
}
|
||||
|
||||
return (options && options.raw) ? data : data.value;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.allSettled(promises)
|
||||
.then(values => {
|
||||
const data = [];
|
||||
for (const value of values) {
|
||||
data.push(value.value);
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => isArray ? store.getMany(keyPrefixed) : store.get(keyPrefixed))
|
||||
.then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data))
|
||||
.then(data => {
|
||||
if (data === undefined || data === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isArray) {
|
||||
return data.map((row, index) => {
|
||||
if ((typeof row === 'string')) {
|
||||
row = this.opts.deserialize(row);
|
||||
}
|
||||
|
||||
if (row === undefined || row === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof row.expires === 'number' && Date.now() > row.expires) {
|
||||
this.delete(key[index]).then(() => undefined);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (options && options.raw) ? row : row.value;
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof data.expires === 'number' && Date.now() > data.expires) {
|
||||
return this.delete(key).then(() => undefined);
|
||||
}
|
||||
|
||||
return (options && options.raw) ? data : data.value;
|
||||
});
|
||||
}
|
||||
|
||||
set(key, value, ttl) {
|
||||
const keyPrefixed = this._getKeyPrefix(key);
|
||||
if (typeof ttl === 'undefined') {
|
||||
ttl = this.opts.ttl;
|
||||
}
|
||||
|
||||
if (ttl === 0) {
|
||||
ttl = undefined;
|
||||
}
|
||||
|
||||
const {store} = this.opts;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null;
|
||||
if (typeof value === 'symbol') {
|
||||
this.emit('error', 'symbol cannot be serialized');
|
||||
}
|
||||
|
||||
value = {value, expires};
|
||||
return this.opts.serialize(value);
|
||||
})
|
||||
.then(value => store.set(keyPrefixed, value, ttl))
|
||||
.then(() => true);
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
const {store} = this.opts;
|
||||
if (Array.isArray(key)) {
|
||||
const keyPrefixed = this._getKeyPrefixArray(key);
|
||||
if (store.deleteMany === undefined) {
|
||||
const promises = [];
|
||||
for (const key of keyPrefixed) {
|
||||
promises.push(store.delete(key));
|
||||
}
|
||||
|
||||
return Promise.allSettled(promises)
|
||||
.then(values => values.every(x => x.value === true));
|
||||
}
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => store.deleteMany(keyPrefixed));
|
||||
}
|
||||
|
||||
const keyPrefixed = this._getKeyPrefix(key);
|
||||
return Promise.resolve()
|
||||
.then(() => store.delete(keyPrefixed));
|
||||
}
|
||||
|
||||
clear() {
|
||||
const {store} = this.opts;
|
||||
return Promise.resolve()
|
||||
.then(() => store.clear());
|
||||
}
|
||||
|
||||
has(key) {
|
||||
const keyPrefixed = this._getKeyPrefix(key);
|
||||
const {store} = this.opts;
|
||||
return Promise.resolve()
|
||||
.then(async () => {
|
||||
if (typeof store.has === 'function') {
|
||||
return store.has(keyPrefixed);
|
||||
}
|
||||
|
||||
const value = await store.get(keyPrefixed);
|
||||
return value !== undefined;
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
const {store} = this.opts;
|
||||
if (typeof store.disconnect === 'function') {
|
||||
return store.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Keyv;
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"keys-while": {
|
||||
"name": "keys-while",
|
||||
"browser": "Safari 10.0.1 (Mac OS X 10.12.1)",
|
||||
"suite": "iter",
|
||||
"hz": 37350.5774949858,
|
||||
"success": true,
|
||||
"fastest": true,
|
||||
"rme": 0.00603595175796559,
|
||||
"rhz": 1,
|
||||
"sampleSize": 178
|
||||
},
|
||||
"keys-for": {
|
||||
"name": "keys-for",
|
||||
"browser": "Safari 10.0.1 (Mac OS X 10.12.1)",
|
||||
"suite": "iter",
|
||||
"hz": 34798.70521653226,
|
||||
"success": true,
|
||||
"fastest": true,
|
||||
"rme": 0.025579700229008188,
|
||||
"rhz": 0.9316778360710454,
|
||||
"sampleSize": 165
|
||||
},
|
||||
"incr-for": {
|
||||
"name": "incr-for",
|
||||
"browser": "Safari 10.0.1 (Mac OS X 10.12.1)",
|
||||
"suite": "iter",
|
||||
"hz": 17731.809750745466,
|
||||
"success": true,
|
||||
"fastest": false,
|
||||
"rme": 0.011567636716923044,
|
||||
"rhz": 0.4747399087236578,
|
||||
"sampleSize": 176
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import * as core from "../core/index.js";
|
||||
import { ZodRealError } from "./errors.js";
|
||||
export const parse = /* @__PURE__ */ core._parse(ZodRealError);
|
||||
export const parseAsync = /* @__PURE__ */ core._parseAsync(ZodRealError);
|
||||
export const safeParse = /* @__PURE__ */ core._safeParse(ZodRealError);
|
||||
export const safeParseAsync = /* @__PURE__ */ core._safeParseAsync(ZodRealError);
|
||||
// Codec functions
|
||||
export const encode = /* @__PURE__ */ core._encode(ZodRealError);
|
||||
export const decode = /* @__PURE__ */ core._decode(ZodRealError);
|
||||
export const encodeAsync = /* @__PURE__ */ core._encodeAsync(ZodRealError);
|
||||
export const decodeAsync = /* @__PURE__ */ core._decodeAsync(ZodRealError);
|
||||
export const safeEncode = /* @__PURE__ */ core._safeEncode(ZodRealError);
|
||||
export const safeDecode = /* @__PURE__ */ core._safeDecode(ZodRealError);
|
||||
export const safeEncodeAsync = /* @__PURE__ */ core._safeEncodeAsync(ZodRealError);
|
||||
export const safeDecodeAsync = /* @__PURE__ */ core._safeDecodeAsync(ZodRealError);
|
||||
@@ -0,0 +1,176 @@
|
||||
import type { $ZodStringFormats } from "../core/checks.js";
|
||||
import type * as errors from "../core/errors.js";
|
||||
import * as util from "../core/util.js";
|
||||
|
||||
function getBelarusianPlural(count: number, one: string, few: string, many: string): string {
|
||||
const absCount = Math.abs(count);
|
||||
const lastDigit = absCount % 10;
|
||||
const lastTwoDigits = absCount % 100;
|
||||
|
||||
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
|
||||
return many;
|
||||
}
|
||||
|
||||
if (lastDigit === 1) {
|
||||
return one;
|
||||
}
|
||||
|
||||
if (lastDigit >= 2 && lastDigit <= 4) {
|
||||
return few;
|
||||
}
|
||||
|
||||
return many;
|
||||
}
|
||||
|
||||
interface BelarusianSizable {
|
||||
unit: {
|
||||
one: string;
|
||||
few: string;
|
||||
many: string;
|
||||
};
|
||||
verb: string;
|
||||
}
|
||||
const error: () => errors.$ZodErrorMap = () => {
|
||||
const Sizable: Record<string, BelarusianSizable> = {
|
||||
string: {
|
||||
unit: {
|
||||
one: "сімвал",
|
||||
few: "сімвалы",
|
||||
many: "сімвалаў",
|
||||
},
|
||||
verb: "мець",
|
||||
},
|
||||
array: {
|
||||
unit: {
|
||||
one: "элемент",
|
||||
few: "элементы",
|
||||
many: "элементаў",
|
||||
},
|
||||
verb: "мець",
|
||||
},
|
||||
set: {
|
||||
unit: {
|
||||
one: "элемент",
|
||||
few: "элементы",
|
||||
many: "элементаў",
|
||||
},
|
||||
verb: "мець",
|
||||
},
|
||||
file: {
|
||||
unit: {
|
||||
one: "байт",
|
||||
few: "байты",
|
||||
many: "байтаў",
|
||||
},
|
||||
verb: "мець",
|
||||
},
|
||||
};
|
||||
|
||||
function getSizing(origin: string): BelarusianSizable | null {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
|
||||
const FormatDictionary: {
|
||||
[k in $ZodStringFormats | (string & {})]?: string;
|
||||
} = {
|
||||
regex: "увод",
|
||||
email: "email адрас",
|
||||
url: "URL",
|
||||
emoji: "эмодзі",
|
||||
uuid: "UUID",
|
||||
uuidv4: "UUIDv4",
|
||||
uuidv6: "UUIDv6",
|
||||
nanoid: "nanoid",
|
||||
guid: "GUID",
|
||||
cuid: "cuid",
|
||||
cuid2: "cuid2",
|
||||
ulid: "ULID",
|
||||
xid: "XID",
|
||||
ksuid: "KSUID",
|
||||
datetime: "ISO дата і час",
|
||||
date: "ISO дата",
|
||||
time: "ISO час",
|
||||
duration: "ISO працягласць",
|
||||
ipv4: "IPv4 адрас",
|
||||
ipv6: "IPv6 адрас",
|
||||
cidrv4: "IPv4 дыяпазон",
|
||||
cidrv6: "IPv6 дыяпазон",
|
||||
base64: "радок у фармаце base64",
|
||||
base64url: "радок у фармаце base64url",
|
||||
json_string: "JSON радок",
|
||||
e164: "нумар E.164",
|
||||
jwt: "JWT",
|
||||
template_literal: "увод",
|
||||
};
|
||||
|
||||
const TypeDictionary: {
|
||||
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
|
||||
} = {
|
||||
nan: "NaN",
|
||||
number: "лік",
|
||||
array: "масіў",
|
||||
};
|
||||
|
||||
return (issue) => {
|
||||
switch (issue.code) {
|
||||
case "invalid_type": {
|
||||
const expected = TypeDictionary[issue.expected] ?? issue.expected;
|
||||
const receivedType = util.parsedType(issue.input);
|
||||
const received = TypeDictionary[receivedType] ?? receivedType;
|
||||
if (/^[A-Z]/.test(issue.expected)) {
|
||||
return `Няправільны ўвод: чакаўся instanceof ${issue.expected}, атрымана ${received}`;
|
||||
}
|
||||
return `Няправільны ўвод: чакаўся ${expected}, атрымана ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1) return `Няправільны ўвод: чакалася ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Няправільны варыянт: чакаўся адзін з ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) {
|
||||
const maxValue = Number(issue.maximum);
|
||||
const unit = getBelarusianPlural(maxValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);
|
||||
return `Занадта вялікі: чакалася, што ${issue.origin ?? "значэнне"} павінна ${sizing.verb} ${adj}${issue.maximum.toString()} ${unit}`;
|
||||
}
|
||||
return `Занадта вялікі: чакалася, што ${issue.origin ?? "значэнне"} павінна быць ${adj}${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) {
|
||||
const minValue = Number(issue.minimum);
|
||||
const unit = getBelarusianPlural(minValue, sizing.unit.one, sizing.unit.few, sizing.unit.many);
|
||||
return `Занадта малы: чакалася, што ${issue.origin} павінна ${sizing.verb} ${adj}${issue.minimum.toString()} ${unit}`;
|
||||
}
|
||||
return `Занадта малы: чакалася, што ${issue.origin} павінна быць ${adj}${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue as errors.$ZodStringFormatIssues;
|
||||
if (_issue.format === "starts_with") return `Няправільны радок: павінен пачынацца з "${_issue.prefix}"`;
|
||||
if (_issue.format === "ends_with") return `Няправільны радок: павінен заканчвацца на "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes") return `Няправільны радок: павінен змяшчаць "${_issue.includes}"`;
|
||||
if (_issue.format === "regex") return `Няправільны радок: павінен адпавядаць шаблону ${_issue.pattern}`;
|
||||
return `Няправільны ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Няправільны лік: павінен быць кратным ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `Нераспазнаны ${issue.keys.length > 1 ? "ключы" : "ключ"}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Няправільны ключ у ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Няправільны ўвод";
|
||||
case "invalid_element":
|
||||
return `Няправільнае значэнне ў ${issue.origin}`;
|
||||
default:
|
||||
return `Няправільны ўвод`;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default function (): { localeError: errors.$ZodErrorMap } {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts"
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
"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: "caracteres", verb: "tener" },
|
||||
file: { unit: "bytes", verb: "tener" },
|
||||
array: { unit: "elementos", verb: "tener" },
|
||||
set: { unit: "elementos", verb: "tener" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "entrada",
|
||||
email: "dirección de correo electrónico",
|
||||
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: "fecha y hora ISO",
|
||||
date: "fecha ISO",
|
||||
time: "hora ISO",
|
||||
duration: "duración ISO",
|
||||
ipv4: "dirección IPv4",
|
||||
ipv6: "dirección IPv6",
|
||||
cidrv4: "rango IPv4",
|
||||
cidrv6: "rango IPv6",
|
||||
base64: "cadena codificada en base64",
|
||||
base64url: "URL codificada en base64",
|
||||
json_string: "cadena JSON",
|
||||
e164: "número E.164",
|
||||
jwt: "JWT",
|
||||
template_literal: "entrada",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
string: "texto",
|
||||
number: "número",
|
||||
boolean: "booleano",
|
||||
array: "arreglo",
|
||||
object: "objeto",
|
||||
set: "conjunto",
|
||||
file: "archivo",
|
||||
date: "fecha",
|
||||
bigint: "número grande",
|
||||
symbol: "símbolo",
|
||||
undefined: "indefinido",
|
||||
null: "nulo",
|
||||
function: "función",
|
||||
map: "mapa",
|
||||
record: "registro",
|
||||
tuple: "tupla",
|
||||
enum: "enumeración",
|
||||
union: "unión",
|
||||
literal: "literal",
|
||||
promise: "promesa",
|
||||
void: "vacío",
|
||||
never: "nunca",
|
||||
unknown: "desconocido",
|
||||
any: "cualquiera",
|
||||
};
|
||||
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 `Entrada inválida: se esperaba instanceof ${issue.expected}, recibido ${received}`;
|
||||
}
|
||||
return `Entrada inválida: se esperaba ${expected}, recibido ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Entrada inválida: se esperaba ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Opción inválida: se esperaba una de ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
const origin = TypeDictionary[issue.origin] ?? issue.origin;
|
||||
if (sizing)
|
||||
return `Demasiado grande: se esperaba que ${origin ?? "valor"} tuviera ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementos"}`;
|
||||
return `Demasiado grande: se esperaba que ${origin ?? "valor"} fuera ${adj}${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
const origin = TypeDictionary[issue.origin] ?? issue.origin;
|
||||
if (sizing) {
|
||||
return `Demasiado pequeño: se esperaba que ${origin} tuviera ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
||||
}
|
||||
return `Demasiado pequeño: se esperaba que ${origin} fuera ${adj}${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with")
|
||||
return `Cadena inválida: debe comenzar con "${_issue.prefix}"`;
|
||||
if (_issue.format === "ends_with")
|
||||
return `Cadena inválida: debe terminar en "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Cadena inválida: debe incluir "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Cadena inválida: debe coincidir con el patrón ${_issue.pattern}`;
|
||||
return `Inválido ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Número inválido: debe ser múltiplo de ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `Llave${issue.keys.length > 1 ? "s" : ""} desconocida${issue.keys.length > 1 ? "s" : ""}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Llave inválida en ${TypeDictionary[issue.origin] ?? issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Entrada inválida";
|
||||
case "invalid_element":
|
||||
return `Valor inválido en ${TypeDictionary[issue.origin] ?? issue.origin}`;
|
||||
default:
|
||||
return `Entrada inválida`;
|
||||
}
|
||||
};
|
||||
};
|
||||
function default_1() {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
module.exports = exports.default;
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/messages.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAoOH,eAAe,EAClB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC;KAGtC,CAAC,IAAI,eAAe,GAAG,MAAM;CACjC,CA2XA,CAAC"}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { TSESTree } from '@typescript-eslint/types';
|
||||
import type { ScopeManager } from '../ScopeManager';
|
||||
import type { Scope } from './Scope';
|
||||
import { ScopeBase } from './ScopeBase';
|
||||
import { ScopeType } from './ScopeType';
|
||||
export declare class FunctionTypeScope extends ScopeBase<ScopeType.functionType, TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructorType | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSFunctionType | TSESTree.TSMethodSignature, Scope> {
|
||||
constructor(scopeManager: ScopeManager, upperScope: FunctionTypeScope['upper'], block: FunctionTypeScope['block']);
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
"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 scope_manager_1 = require("@typescript-eslint/scope-manager");
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const util_1 = require("../util");
|
||||
var AllowedType;
|
||||
(function (AllowedType) {
|
||||
AllowedType[AllowedType["Number"] = 0] = "Number";
|
||||
AllowedType[AllowedType["String"] = 1] = "String";
|
||||
AllowedType[AllowedType["Unknown"] = 2] = "Unknown";
|
||||
})(AllowedType || (AllowedType = {}));
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-mixed-enums',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow enums from having both number and string members',
|
||||
recommended: 'strict',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
mixed: `Mixing number and string enums can be confusing.`,
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
defaultOptions: [],
|
||||
create(context) {
|
||||
const parserServices = (0, util_1.getParserServices)(context);
|
||||
const typeChecker = parserServices.program.getTypeChecker();
|
||||
function collectNodeDefinitions(node) {
|
||||
const { name } = node.id;
|
||||
const found = {
|
||||
imports: [],
|
||||
previousSibling: undefined,
|
||||
};
|
||||
let scope = context.sourceCode.getScope(node);
|
||||
for (const definition of scope.upper?.set.get(name)?.defs ?? []) {
|
||||
if (definition.node.type === utils_1.AST_NODE_TYPES.TSEnumDeclaration &&
|
||||
definition.node.range[0] < node.range[0] &&
|
||||
definition.node.body.members.length > 0) {
|
||||
found.previousSibling = definition.node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (scope) {
|
||||
scope.set.get(name)?.defs.forEach(definition => {
|
||||
if (definition.type === scope_manager_1.DefinitionType.ImportBinding) {
|
||||
found.imports.push(definition.node);
|
||||
}
|
||||
});
|
||||
scope = scope.upper;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
function getAllowedTypeForNode(node) {
|
||||
return tsutils.isTypeFlagSet(typeChecker.getTypeAtLocation(node), ts.TypeFlags.StringLike)
|
||||
? AllowedType.String
|
||||
: AllowedType.Number;
|
||||
}
|
||||
function getTypeFromImported(imported) {
|
||||
const type = typeChecker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(imported));
|
||||
const valueDeclaration = type.getSymbol()?.valueDeclaration;
|
||||
if (!valueDeclaration ||
|
||||
!ts.isEnumDeclaration(valueDeclaration) ||
|
||||
valueDeclaration.members.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return getAllowedTypeForNode(valueDeclaration.members[0]);
|
||||
}
|
||||
function getMemberType(member) {
|
||||
if (!member.initializer) {
|
||||
return AllowedType.Number;
|
||||
}
|
||||
switch (member.initializer.type) {
|
||||
case utils_1.AST_NODE_TYPES.Literal:
|
||||
switch (typeof member.initializer.value) {
|
||||
case 'number':
|
||||
return AllowedType.Number;
|
||||
case 'string':
|
||||
return AllowedType.String;
|
||||
default:
|
||||
return AllowedType.Unknown;
|
||||
}
|
||||
case utils_1.AST_NODE_TYPES.TemplateLiteral:
|
||||
return AllowedType.String;
|
||||
default:
|
||||
return getAllowedTypeForNode(parserServices.esTreeNodeToTSNodeMap.get(member.initializer));
|
||||
}
|
||||
}
|
||||
function getDesiredTypeForDefinition(node) {
|
||||
const { imports, previousSibling } = collectNodeDefinitions(node);
|
||||
// Case: Merged ambiently via module augmentation
|
||||
// import { MyEnum } from 'other-module';
|
||||
// declare module 'other-module' {
|
||||
// enum MyEnum { A }
|
||||
// }
|
||||
for (const imported of imports) {
|
||||
const typeFromImported = getTypeFromImported(imported);
|
||||
if (typeFromImported != null) {
|
||||
return typeFromImported;
|
||||
}
|
||||
}
|
||||
// Case: Multiple enum declarations in the same file
|
||||
// enum MyEnum { A }
|
||||
// enum MyEnum { B }
|
||||
if (previousSibling) {
|
||||
return getMemberType(previousSibling.body.members[0]);
|
||||
}
|
||||
// Case: Namespace declaration merging
|
||||
// namespace MyNamespace {
|
||||
// export enum MyEnum { A }
|
||||
// }
|
||||
// namespace MyNamespace {
|
||||
// export enum MyEnum { B }
|
||||
// }
|
||||
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration &&
|
||||
node.parent.parent.type === utils_1.AST_NODE_TYPES.TSModuleBlock) {
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/8352
|
||||
// TODO: We don't need to dip into the TypeScript type checker here!
|
||||
// Merged namespaces must all exist in the same file.
|
||||
// We could instead compare this file's nodes to find the merges.
|
||||
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node.id);
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const declarations = typeChecker
|
||||
.getSymbolAtLocation(tsNode)
|
||||
.getDeclarations();
|
||||
const [{ initializer }] = declarations[0]
|
||||
.members;
|
||||
return initializer &&
|
||||
tsutils.isTypeFlagSet(typeChecker.getTypeAtLocation(initializer), ts.TypeFlags.StringLike)
|
||||
? AllowedType.String
|
||||
: AllowedType.Number;
|
||||
}
|
||||
// Finally, we default to the type of the first enum member
|
||||
return getMemberType(node.body.members[0]);
|
||||
}
|
||||
return {
|
||||
TSEnumDeclaration(node) {
|
||||
if (!node.body.members.length) {
|
||||
return;
|
||||
}
|
||||
let desiredType = getDesiredTypeForDefinition(node);
|
||||
if (desiredType === ts.TypeFlags.Unknown) {
|
||||
return;
|
||||
}
|
||||
for (const member of node.body.members) {
|
||||
const currentType = getMemberType(member);
|
||||
if (currentType === AllowedType.Unknown) {
|
||||
return;
|
||||
}
|
||||
if (currentType === AllowedType.Number) {
|
||||
desiredType ??= currentType;
|
||||
}
|
||||
if (currentType !== desiredType) {
|
||||
context.report({
|
||||
node: member.initializer ?? member,
|
||||
messageId: 'mixed',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"encoder.generated.js","sourceRoot":"","sources":["../../../src/api/node/encoder.generated.ts"],"names":[],"mappings":"AAAA,+DAA+D;AA0B/D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACH,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,GACxB,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,UAAU,CAAC,UAAU,CAAC;QAC3B,KAAK,UAAU,CAAC,iBAAiB,CAAC;QAClC,KAAK,UAAU,CAAC,OAAO,CAAC;QACxB,KAAK,UAAU,CAAC,SAAS,CAAC;QAC1B,KAAK,UAAU,CAAC,SAAS,CAAC;QAC1B,KAAK,UAAU,CAAC,cAAc,CAAC;QAC/B,KAAK,UAAU,CAAC,aAAa;YACzB,OAAO,qBAAqB,CAAC;QACjC,KAAK,UAAU,CAAC,aAAa,CAAC;QAC9B,KAAK,UAAU,CAAC,cAAc,CAAC;QAC/B,KAAK,UAAU,CAAC,aAAa,CAAC;QAC9B,KAAK,UAAU,CAAC,wBAAwB,CAAC;QACzC,KAAK,UAAU,CAAC,6BAA6B,CAAC;QAC9C,KAAK,UAAU,CAAC,YAAY,CAAC;QAC7B,KAAK,UAAU,CAAC,cAAc,CAAC;QAC/B,KAAK,UAAU,CAAC,YAAY,CAAC;QAC7B,KAAK,UAAU,CAAC,UAAU;YACtB,OAAO,uBAAuB,CAAC;QACnC;YACI,OAAO,uBAAuB,CAAC;IACvC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAU;IACxC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,UAAU,CAAC,KAAK;YACjB,OAAO,CAAE,IAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,UAAU,CAAC,cAAc;YAC1B,OAAO,CAAE,IAAuB,CAAC,KAAK,KAAK,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3F,KAAK,UAAU,CAAC,gBAAgB;YAC5B,OAAO,CAAE,IAAyB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,KAAK,UAAU,CAAC,eAAe;YAC3B,OAAO,CAAE,IAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,KAAK,UAAU,CAAC,qBAAqB;YACjC,OAAO,CAAE,IAA8B,CAAC,QAAQ,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAA8B,CAAC,QAAQ,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAA8B,CAAC,QAAQ,KAAK,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAA8B,CAAC,QAAQ,KAAK,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAA8B,CAAC,QAAQ,KAAK,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChZ,KAAK,UAAU,CAAC,sBAAsB;YAClC,OAAO,CAAE,IAA+B,CAAC,QAAQ,KAAK,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpG,KAAK,UAAU,CAAC,YAAY;YACxB,OAAO,CAAE,IAAqB,CAAC,YAAY,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzF,KAAK,UAAU,CAAC,sBAAsB;YAClC,OAAO,CAAE,IAA+B,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,KAAK,UAAU,CAAC,uBAAuB;YACnC,OAAO,CAAE,IAAgC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvE,KAAK,UAAU,CAAC,YAAY;YACxB,OAAO,CAAE,IAAyB,CAAC,QAAQ,KAAK,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAAyB,CAAC,QAAQ,KAAK,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrK,KAAK,UAAU,CAAC,gBAAgB;YAC5B,OAAO,CAAE,IAAyB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAE,IAAyB,CAAC,KAAK,KAAK,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChJ,KAAK,UAAU,CAAC,OAAO;YACnB,OAAO,CAAE,IAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,KAAK,UAAU,CAAC,iBAAiB;YAC7B,OAAO,CAAE,IAA0B,CAAC,OAAO,KAAK,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/F,KAAK,UAAU,CAAC,uBAAuB;YACnC,OAAO,CAAE,IAAgC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxE,KAAK,UAAU,CAAC,iBAAiB;YAC7B,OAAO,CAAE,IAA0B,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClE,KAAK,UAAU,CAAC,UAAU;YACtB,OAAO,CAAE,IAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,KAAK,UAAU,CAAC,YAAY;YACxB,OAAO,CAAE,IAAqB,CAAC,aAAa,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAAqB,CAAC,aAAa,KAAK,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClK,KAAK,UAAU,CAAC,eAAe;YAC3B,OAAO,CAAE,IAAwB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,KAAK,UAAU,CAAC,gBAAgB;YAC5B,OAAO,CAAE,IAAyB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClE,KAAK,UAAU,CAAC,iBAAiB,CAAC;QAClC,KAAK,UAAU,CAAC,gBAAgB;YAC5B,OAAO,CAAE,IAAoC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAE,IAAoC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrJ,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC"}
|
||||
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
|
||||
function _class_apply_descriptor_update(receiver, descriptor) {
|
||||
if (descriptor.set) {
|
||||
if (!descriptor.get) throw new TypeError("attempted to read set only private field");
|
||||
|
||||
if (!("__destrWrapper" in descriptor)) {
|
||||
descriptor.__destrWrapper = {
|
||||
set value(v) {
|
||||
descriptor.set.call(receiver, v);
|
||||
},
|
||||
get value() {
|
||||
return descriptor.get.call(receiver);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return descriptor.__destrWrapper;
|
||||
} else {
|
||||
if (!descriptor.writable) {
|
||||
// This should only throw in strict mode, but class bodies are
|
||||
// always strict and private fields can only be used inside
|
||||
// class bodies.
|
||||
throw new TypeError("attempted to set read only private field");
|
||||
}
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
exports._ = _class_apply_descriptor_update;
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* @fileoverview Rule to check the spacing around the * in yield* expressions.
|
||||
* @author Bryan Smith
|
||||
* @deprecated in ESLint v8.53.0
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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: "yield-star-spacing",
|
||||
url: "https://eslint.style/rules/yield-star-spacing",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "layout",
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Require or disallow spacing around the `*` in `yield*` expressions",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/yield-star-spacing",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
|
||||
schema: [
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
enum: ["before", "after", "both", "neither"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
before: { type: "boolean" },
|
||||
after: { type: "boolean" },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
missingBefore: "Missing space before *.",
|
||||
missingAfter: "Missing space after *.",
|
||||
unexpectedBefore: "Unexpected space before *.",
|
||||
unexpectedAfter: "Unexpected space after *.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
const mode = (function (option) {
|
||||
if (!option || typeof option === "string") {
|
||||
return {
|
||||
before: { before: true, after: false },
|
||||
after: { before: false, after: true },
|
||||
both: { before: true, after: true },
|
||||
neither: { before: false, after: false },
|
||||
}[option || "after"];
|
||||
}
|
||||
return option;
|
||||
})(context.options[0]);
|
||||
|
||||
/**
|
||||
* Checks the spacing between two tokens before or after the star token.
|
||||
* @param {string} side Either "before" or "after".
|
||||
* @param {Token} leftToken `function` keyword token if side is "before", or
|
||||
* star token if side is "after".
|
||||
* @param {Token} rightToken Star token if side is "before", or identifier
|
||||
* token if side is "after".
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkSpacing(side, leftToken, rightToken) {
|
||||
if (
|
||||
sourceCode.isSpaceBetween(leftToken, rightToken) !== mode[side]
|
||||
) {
|
||||
const after = leftToken.value === "*";
|
||||
const spaceRequired = mode[side];
|
||||
const node = after ? leftToken : rightToken;
|
||||
let messageId;
|
||||
|
||||
if (spaceRequired) {
|
||||
messageId =
|
||||
side === "before" ? "missingBefore" : "missingAfter";
|
||||
} else {
|
||||
messageId =
|
||||
side === "before"
|
||||
? "unexpectedBefore"
|
||||
: "unexpectedAfter";
|
||||
}
|
||||
|
||||
context.report({
|
||||
node,
|
||||
messageId,
|
||||
fix(fixer) {
|
||||
if (spaceRequired) {
|
||||
if (after) {
|
||||
return fixer.insertTextAfter(node, " ");
|
||||
}
|
||||
return fixer.insertTextBefore(node, " ");
|
||||
}
|
||||
return fixer.removeRange([
|
||||
leftToken.range[1],
|
||||
rightToken.range[0],
|
||||
]);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the spacing around the star if node is a yield* expression.
|
||||
* @param {ASTNode} node A yield expression node.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkExpression(node) {
|
||||
if (!node.delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tokens = sourceCode.getFirstTokens(node, 3);
|
||||
const yieldToken = tokens[0];
|
||||
const starToken = tokens[1];
|
||||
const nextToken = tokens[2];
|
||||
|
||||
checkSpacing("before", yieldToken, starToken);
|
||||
checkSpacing("after", starToken, nextToken);
|
||||
}
|
||||
|
||||
return {
|
||||
YieldExpression: checkExpression,
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "../index.js";
|
||||
|
||||
test("basic apply (number)", () => {
|
||||
const setCommonNumberChecks = <T extends z.ZodMiniNumber>(schema: T) => {
|
||||
return schema.check(z.minimum(0), z.maximum(100));
|
||||
};
|
||||
|
||||
const schema = z.nullable(z.number().apply(setCommonNumberChecks));
|
||||
|
||||
expect(() => z.parse(schema, -1)).toThrowError();
|
||||
expect(() => z.parse(schema, 101)).toThrowError();
|
||||
expect(z.parse(schema, 0)).toBe(0);
|
||||
expect(z.parse(schema, null)).toBe(null);
|
||||
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<number | null>();
|
||||
});
|
||||
|
||||
test("The callback's return value becomes the apply's return value.", () => {
|
||||
const symbol = Symbol();
|
||||
const result = z.number().apply(() => symbol);
|
||||
|
||||
expect(result).toBe(symbol);
|
||||
expectTypeOf<typeof result>().toEqualTypeOf<symbol>();
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
export type Formatter = (input: string | number | null | undefined) => string
|
||||
|
||||
export interface Colors {
|
||||
isColorSupported: boolean
|
||||
|
||||
reset: Formatter
|
||||
bold: Formatter
|
||||
dim: Formatter
|
||||
italic: Formatter
|
||||
underline: Formatter
|
||||
inverse: Formatter
|
||||
hidden: Formatter
|
||||
strikethrough: Formatter
|
||||
|
||||
black: Formatter
|
||||
red: Formatter
|
||||
green: Formatter
|
||||
yellow: Formatter
|
||||
blue: Formatter
|
||||
magenta: Formatter
|
||||
cyan: Formatter
|
||||
white: Formatter
|
||||
gray: Formatter
|
||||
|
||||
bgBlack: Formatter
|
||||
bgRed: Formatter
|
||||
bgGreen: Formatter
|
||||
bgYellow: Formatter
|
||||
bgBlue: Formatter
|
||||
bgMagenta: Formatter
|
||||
bgCyan: Formatter
|
||||
bgWhite: Formatter
|
||||
|
||||
blackBright: Formatter
|
||||
redBright: Formatter
|
||||
greenBright: Formatter
|
||||
yellowBright: Formatter
|
||||
blueBright: Formatter
|
||||
magentaBright: Formatter
|
||||
cyanBright: Formatter
|
||||
whiteBright: Formatter
|
||||
|
||||
bgBlackBright: Formatter
|
||||
bgRedBright: Formatter
|
||||
bgGreenBright: Formatter
|
||||
bgYellowBright: Formatter
|
||||
bgBlueBright: Formatter
|
||||
bgMagentaBright: Formatter
|
||||
bgCyanBright: Formatter
|
||||
bgWhiteBright: Formatter
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
||||
* @todo re-check https://issues.chromium.org/issues/42212588
|
||||
* @module
|
||||
*/
|
||||
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
||||
const _32n = /* @__PURE__ */ BigInt(32);
|
||||
|
||||
function fromBig(
|
||||
n: bigint,
|
||||
le = false
|
||||
): {
|
||||
h: number;
|
||||
l: number;
|
||||
} {
|
||||
if (le) return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
||||
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
||||
}
|
||||
|
||||
function split(lst: bigint[], le = false): Uint32Array[] {
|
||||
const len = lst.length;
|
||||
let Ah = new Uint32Array(len);
|
||||
let Al = new Uint32Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
const { h, l } = fromBig(lst[i], le);
|
||||
[Ah[i], Al[i]] = [h, l];
|
||||
}
|
||||
return [Ah, Al];
|
||||
}
|
||||
|
||||
const toBig = (h: number, l: number): bigint => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
|
||||
// for Shift in [0, 32)
|
||||
const shrSH = (h: number, _l: number, s: number): number => h >>> s;
|
||||
const shrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);
|
||||
// Right rotate for Shift in [1, 32)
|
||||
const rotrSH = (h: number, l: number, s: number): number => (h >>> s) | (l << (32 - s));
|
||||
const rotrSL = (h: number, l: number, s: number): number => (h << (32 - s)) | (l >>> s);
|
||||
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
||||
const rotrBH = (h: number, l: number, s: number): number => (h << (64 - s)) | (l >>> (s - 32));
|
||||
const rotrBL = (h: number, l: number, s: number): number => (h >>> (s - 32)) | (l << (64 - s));
|
||||
// Right rotate for shift===32 (just swaps l&h)
|
||||
const rotr32H = (_h: number, l: number): number => l;
|
||||
const rotr32L = (h: number, _l: number): number => h;
|
||||
// Left rotate for Shift in [1, 32)
|
||||
const rotlSH = (h: number, l: number, s: number): number => (h << s) | (l >>> (32 - s));
|
||||
const rotlSL = (h: number, l: number, s: number): number => (l << s) | (h >>> (32 - s));
|
||||
// Left rotate for Shift in (32, 64), NOTE: 32 is special case.
|
||||
const rotlBH = (h: number, l: number, s: number): number => (l << (s - 32)) | (h >>> (64 - s));
|
||||
const rotlBL = (h: number, l: number, s: number): number => (h << (s - 32)) | (l >>> (64 - s));
|
||||
|
||||
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
||||
// simple take carry out of low bit sum by shift, we need to use division.
|
||||
function add(
|
||||
Ah: number,
|
||||
Al: number,
|
||||
Bh: number,
|
||||
Bl: number
|
||||
): {
|
||||
h: number;
|
||||
l: number;
|
||||
} {
|
||||
const l = (Al >>> 0) + (Bl >>> 0);
|
||||
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
||||
}
|
||||
// Addition with more than 2 elements
|
||||
const add3L = (Al: number, Bl: number, Cl: number): number => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
||||
const add3H = (low: number, Ah: number, Bh: number, Ch: number): number =>
|
||||
(Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
||||
const add4L = (Al: number, Bl: number, Cl: number, Dl: number): number =>
|
||||
(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
||||
const add4H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number): number =>
|
||||
(Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
||||
const add5L = (Al: number, Bl: number, Cl: number, Dl: number, El: number): number =>
|
||||
(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
||||
const add5H = (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number): number =>
|
||||
(Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
||||
|
||||
// prettier-ignore
|
||||
export {
|
||||
add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig
|
||||
};
|
||||
// prettier-ignore
|
||||
const u64: { fromBig: typeof fromBig; split: typeof split; toBig: (h: number, l: number) => bigint; shrSH: (h: number, _l: number, s: number) => number; shrSL: (h: number, l: number, s: number) => number; rotrSH: (h: number, l: number, s: number) => number; rotrSL: (h: number, l: number, s: number) => number; rotrBH: (h: number, l: number, s: number) => number; rotrBL: (h: number, l: number, s: number) => number; rotr32H: (_h: number, l: number) => number; rotr32L: (h: number, _l: number) => number; rotlSH: (h: number, l: number, s: number) => number; rotlSL: (h: number, l: number, s: number) => number; rotlBH: (h: number, l: number, s: number) => number; rotlBL: (h: number, l: number, s: number) => number; add: typeof add; add3L: (Al: number, Bl: number, Cl: number) => number; add3H: (low: number, Ah: number, Bh: number, Ch: number) => number; add4L: (Al: number, Bl: number, Cl: number, Dl: number) => number; add4H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number) => number; add5H: (low: number, Ah: number, Bh: number, Ch: number, Dh: number, Eh: number) => number; add5L: (Al: number, Bl: number, Cl: number, Dl: number, El: number) => number; } = {
|
||||
fromBig, split, toBig,
|
||||
shrSH, shrSL,
|
||||
rotrSH, rotrSL, rotrBH, rotrBL,
|
||||
rotr32H, rotr32L,
|
||||
rotlSH, rotlSL, rotlBH, rotlBL,
|
||||
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
||||
};
|
||||
export default u64;
|
||||
@@ -0,0 +1,57 @@
|
||||
# balanced-match
|
||||
|
||||
Match balanced string pairs, like `{` and `}` or `<b>` and
|
||||
`</b>`. Supports regular expressions as well!
|
||||
|
||||
## Example
|
||||
|
||||
Get the first matching pair of braces:
|
||||
|
||||
```js
|
||||
import { balanced } from 'balanced-match'
|
||||
|
||||
console.log(balanced('{', '}', 'pre{in{nested}}post'))
|
||||
console.log(balanced('{', '}', 'pre{first}between{second}post'))
|
||||
console.log(
|
||||
balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'),
|
||||
)
|
||||
```
|
||||
|
||||
The matches are:
|
||||
|
||||
```bash
|
||||
$ node example.js
|
||||
{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
|
||||
{ start: 3,
|
||||
end: 9,
|
||||
pre: 'pre',
|
||||
body: 'first',
|
||||
post: 'between{second}post' }
|
||||
{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### const m = balanced(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
object with those keys:
|
||||
|
||||
- **start** the index of the first match of `a`
|
||||
- **end** the index of the matching `b`
|
||||
- **pre** the preamble, `a` and `b` not included
|
||||
- **body** the match, `a` and `b` not included
|
||||
- **post** the postscript, `a` and `b` not included
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
|
||||
|
||||
### const r = balanced.range(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
array with indexes: `[ <a index>, <b index> ]`.
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"unescape.js","sourceRoot":"","sources":["../../src/unescape.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAS,EACT,EACE,oBAAoB,GAAG,KAAK,EAC5B,aAAa,GAAG,IAAI,MACgD,EAAE,EACxE,EAAE;IACF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,oBAAoB,CAAC,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC;YAClC,CAAC,CAAC,CAAC;iBACE,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC;iBAC3C,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,oBAAoB,CAAC,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC;QACpC,CAAC,CAAC,CAAC;aACE,OAAO,CAAC,4BAA4B,EAAE,MAAM,CAAC;aAC7C,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC,CAAA","sourcesContent":["import type { MinimatchOptions } from './index.js'\n\n/**\n * Un-escape a string that has been escaped with {@link escape}.\n *\n * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then\n * square-bracket escapes are removed, but not backslash escapes.\n *\n * For example, it will turn the string `'[*]'` into `*`, but it will not\n * turn `'\\\\*'` into `'*'`, because `\\` is a path separator in\n * `windowsPathsNoEscape` mode.\n *\n * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and\n * backslash escapes are removed.\n *\n * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped\n * or unescaped.\n *\n * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be\n * unescaped.\n */\n\nexport const unescape = (\n s: string,\n {\n windowsPathsNoEscape = false,\n magicalBraces = true,\n }: Pick<MinimatchOptions, 'windowsPathsNoEscape' | 'magicalBraces'> = {},\n) => {\n if (magicalBraces) {\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\])\\]/g, '$1$2')\n .replace(/\\\\([^/])/g, '$1')\n }\n return windowsPathsNoEscape ?\n s.replace(/\\[([^/\\\\{}])\\]/g, '$1')\n : s\n .replace(/((?!\\\\).|^)\\[([^/\\\\{}])\\]/g, '$1$2')\n .replace(/\\\\([^/{}])/g, '$1')\n}\n"]}
|
||||
@@ -0,0 +1,228 @@
|
||||
'use strict';
|
||||
module.exports = function generate_custom(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 $errorKeyword;
|
||||
var $data = 'data' + ($dataLvl || '');
|
||||
var $valid = 'valid' + $lvl;
|
||||
var $errs = 'errs__' + $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 $rule = this,
|
||||
$definition = 'definition' + $lvl,
|
||||
$rDef = $rule.definition,
|
||||
$closingBraces = '';
|
||||
var $compile, $inline, $macro, $ruleValidate, $validateCode;
|
||||
if ($isData && $rDef.$data) {
|
||||
$validateCode = 'keywordValidate' + $lvl;
|
||||
var $validateSchema = $rDef.validateSchema;
|
||||
out += ' var ' + ($definition) + ' = RULES.custom[\'' + ($keyword) + '\'].definition; var ' + ($validateCode) + ' = ' + ($definition) + '.validate;';
|
||||
} else {
|
||||
$ruleValidate = it.useCustomRule($rule, $schema, it.schema, it);
|
||||
if (!$ruleValidate) return;
|
||||
$schemaValue = 'validate.schema' + $schemaPath;
|
||||
$validateCode = $ruleValidate.code;
|
||||
$compile = $rDef.compile;
|
||||
$inline = $rDef.inline;
|
||||
$macro = $rDef.macro;
|
||||
}
|
||||
var $ruleErrs = $validateCode + '.errors',
|
||||
$i = 'i' + $lvl,
|
||||
$ruleErr = 'ruleErr' + $lvl,
|
||||
$asyncKeyword = $rDef.async;
|
||||
if ($asyncKeyword && !it.async) throw new Error('async keyword in sync schema');
|
||||
if (!($inline || $macro)) {
|
||||
out += '' + ($ruleErrs) + ' = null;';
|
||||
}
|
||||
out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';';
|
||||
if ($isData && $rDef.$data) {
|
||||
$closingBraces += '}';
|
||||
out += ' if (' + ($schemaValue) + ' === undefined) { ' + ($valid) + ' = true; } else { ';
|
||||
if ($validateSchema) {
|
||||
$closingBraces += '}';
|
||||
out += ' ' + ($valid) + ' = ' + ($definition) + '.validateSchema(' + ($schemaValue) + '); if (' + ($valid) + ') { ';
|
||||
}
|
||||
}
|
||||
if ($inline) {
|
||||
if ($rDef.statements) {
|
||||
out += ' ' + ($ruleValidate.validate) + ' ';
|
||||
} else {
|
||||
out += ' ' + ($valid) + ' = ' + ($ruleValidate.validate) + '; ';
|
||||
}
|
||||
} else if ($macro) {
|
||||
var $it = it.util.copy(it);
|
||||
var $closingBraces = '';
|
||||
$it.level++;
|
||||
var $nextValid = 'valid' + $it.level;
|
||||
$it.schema = $ruleValidate.validate;
|
||||
$it.schemaPath = '';
|
||||
var $wasComposite = it.compositeRule;
|
||||
it.compositeRule = $it.compositeRule = true;
|
||||
var $code = it.validate($it).replace(/validate\.schema/g, $validateCode);
|
||||
it.compositeRule = $it.compositeRule = $wasComposite;
|
||||
out += ' ' + ($code);
|
||||
} else {
|
||||
var $$outStack = $$outStack || [];
|
||||
$$outStack.push(out);
|
||||
out = '';
|
||||
out += ' ' + ($validateCode) + '.call( ';
|
||||
if (it.opts.passContext) {
|
||||
out += 'this';
|
||||
} else {
|
||||
out += 'self';
|
||||
}
|
||||
if ($compile || $rDef.schema === false) {
|
||||
out += ' , ' + ($data) + ' ';
|
||||
} else {
|
||||
out += ' , ' + ($schemaValue) + ' , ' + ($data) + ' , validate.schema' + (it.schemaPath) + ' ';
|
||||
}
|
||||
out += ' , (dataPath || \'\')';
|
||||
if (it.errorPath != '""') {
|
||||
out += ' + ' + (it.errorPath);
|
||||
}
|
||||
var $parentData = $dataLvl ? 'data' + (($dataLvl - 1) || '') : 'parentData',
|
||||
$parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty';
|
||||
out += ' , ' + ($parentData) + ' , ' + ($parentDataProperty) + ' , rootData ) ';
|
||||
var def_callRuleValidate = out;
|
||||
out = $$outStack.pop();
|
||||
if ($rDef.errors === false) {
|
||||
out += ' ' + ($valid) + ' = ';
|
||||
if ($asyncKeyword) {
|
||||
out += 'await ';
|
||||
}
|
||||
out += '' + (def_callRuleValidate) + '; ';
|
||||
} else {
|
||||
if ($asyncKeyword) {
|
||||
$ruleErrs = 'customErrors' + $lvl;
|
||||
out += ' var ' + ($ruleErrs) + ' = null; try { ' + ($valid) + ' = await ' + (def_callRuleValidate) + '; } catch (e) { ' + ($valid) + ' = false; if (e instanceof ValidationError) ' + ($ruleErrs) + ' = e.errors; else throw e; } ';
|
||||
} else {
|
||||
out += ' ' + ($ruleErrs) + ' = null; ' + ($valid) + ' = ' + (def_callRuleValidate) + '; ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($rDef.modifying) {
|
||||
out += ' if (' + ($parentData) + ') ' + ($data) + ' = ' + ($parentData) + '[' + ($parentDataProperty) + '];';
|
||||
}
|
||||
out += '' + ($closingBraces);
|
||||
if ($rDef.valid) {
|
||||
if ($breakOnError) {
|
||||
out += ' if (true) { ';
|
||||
}
|
||||
} else {
|
||||
out += ' if ( ';
|
||||
if ($rDef.valid === undefined) {
|
||||
out += ' !';
|
||||
if ($macro) {
|
||||
out += '' + ($nextValid);
|
||||
} else {
|
||||
out += '' + ($valid);
|
||||
}
|
||||
} else {
|
||||
out += ' ' + (!$rDef.valid) + ' ';
|
||||
}
|
||||
out += ') { ';
|
||||
$errorKeyword = $rule.keyword;
|
||||
var $$outStack = $$outStack || [];
|
||||
$$outStack.push(out);
|
||||
out = '';
|
||||
var $$outStack = $$outStack || [];
|
||||
$$outStack.push(out);
|
||||
out = ''; /* istanbul ignore else */
|
||||
if (it.createErrors !== false) {
|
||||
out += ' { keyword: \'' + ($errorKeyword || 'custom') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { keyword: \'' + ($rule.keyword) + '\' } ';
|
||||
if (it.opts.messages !== false) {
|
||||
out += ' , message: \'should pass "' + ($rule.keyword) + '" keyword validation\' ';
|
||||
}
|
||||
if (it.opts.verbose) {
|
||||
out += ' , schema: validate.schema' + ($schemaPath) + ' , 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++; ';
|
||||
}
|
||||
var def_customError = out;
|
||||
out = $$outStack.pop();
|
||||
if ($inline) {
|
||||
if ($rDef.errors) {
|
||||
if ($rDef.errors != 'full') {
|
||||
out += ' for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; if (' + ($ruleErr) + '.schemaPath === undefined) { ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; } ';
|
||||
if (it.opts.verbose) {
|
||||
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
|
||||
}
|
||||
out += ' } ';
|
||||
}
|
||||
} else {
|
||||
if ($rDef.errors === false) {
|
||||
out += ' ' + (def_customError) + ' ';
|
||||
} else {
|
||||
out += ' if (' + ($errs) + ' == errors) { ' + (def_customError) + ' } else { for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; if (' + ($ruleErr) + '.schemaPath === undefined) { ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; } ';
|
||||
if (it.opts.verbose) {
|
||||
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
|
||||
}
|
||||
out += ' } } ';
|
||||
}
|
||||
}
|
||||
} else if ($macro) {
|
||||
out += ' var err = '; /* istanbul ignore else */
|
||||
if (it.createErrors !== false) {
|
||||
out += ' { keyword: \'' + ($errorKeyword || 'custom') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { keyword: \'' + ($rule.keyword) + '\' } ';
|
||||
if (it.opts.messages !== false) {
|
||||
out += ' , message: \'should pass "' + ($rule.keyword) + '" keyword validation\' ';
|
||||
}
|
||||
if (it.opts.verbose) {
|
||||
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
|
||||
}
|
||||
out += ' } ';
|
||||
} else {
|
||||
out += ' {} ';
|
||||
}
|
||||
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
|
||||
if (!it.compositeRule && $breakOnError) {
|
||||
/* istanbul ignore if */
|
||||
if (it.async) {
|
||||
out += ' throw new ValidationError(vErrors); ';
|
||||
} else {
|
||||
out += ' validate.errors = vErrors; return false; ';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($rDef.errors === false) {
|
||||
out += ' ' + (def_customError) + ' ';
|
||||
} else {
|
||||
out += ' if (Array.isArray(' + ($ruleErrs) + ')) { if (vErrors === null) vErrors = ' + ($ruleErrs) + '; else vErrors = vErrors.concat(' + ($ruleErrs) + '); errors = vErrors.length; for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + '<errors; ' + ($i) + '++) { var ' + ($ruleErr) + ' = vErrors[' + ($i) + ']; if (' + ($ruleErr) + '.dataPath === undefined) ' + ($ruleErr) + '.dataPath = (dataPath || \'\') + ' + (it.errorPath) + '; ' + ($ruleErr) + '.schemaPath = "' + ($errSchemaPath) + '"; ';
|
||||
if (it.opts.verbose) {
|
||||
out += ' ' + ($ruleErr) + '.schema = ' + ($schemaValue) + '; ' + ($ruleErr) + '.data = ' + ($data) + '; ';
|
||||
}
|
||||
out += ' } } else { ' + (def_customError) + ' } ';
|
||||
}
|
||||
}
|
||||
out += ' } ';
|
||||
if ($breakOnError) {
|
||||
out += ' else { ';
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2016_array_include = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2016_array_include = {
|
||||
libs: [],
|
||||
variables: [
|
||||
['Array', base_config_1.TYPE],
|
||||
['ReadonlyArray', base_config_1.TYPE],
|
||||
['Int8Array', base_config_1.TYPE],
|
||||
['Uint8Array', base_config_1.TYPE],
|
||||
['Uint8ClampedArray', base_config_1.TYPE],
|
||||
['Int16Array', base_config_1.TYPE],
|
||||
['Uint16Array', base_config_1.TYPE],
|
||||
['Int32Array', base_config_1.TYPE],
|
||||
['Uint32Array', base_config_1.TYPE],
|
||||
['Float32Array', base_config_1.TYPE],
|
||||
['Float64Array', base_config_1.TYPE],
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
export interface Thenable <R> {
|
||||
then <U> (onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
|
||||
then <U> (onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => void): Thenable<U>;
|
||||
}
|
||||
|
||||
export class Promise <R> implements Thenable <R> {
|
||||
/**
|
||||
* If you call resolve in the body of the callback passed to the constructor,
|
||||
* your promise is fulfilled with result object passed to resolve.
|
||||
* If you call reject your promise is rejected with the object passed to resolve.
|
||||
* For consistency and debugging (eg stack traces), obj should be an instanceof Error.
|
||||
* Any errors thrown in the constructor callback will be implicitly passed to reject().
|
||||
*/
|
||||
constructor (callback: (resolve : (value?: R | Thenable<R>) => void, reject: (error?: any) => void) => void);
|
||||
|
||||
/**
|
||||
* onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects.
|
||||
* Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called.
|
||||
* Both callbacks have a single parameter , the fulfillment value or rejection reason.
|
||||
* "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve.
|
||||
* If an error is thrown in the callback, the returned promise rejects with that error.
|
||||
*
|
||||
* @param onFulfilled called when/if "promise" resolves
|
||||
* @param onRejected called when/if "promise" rejects
|
||||
*/
|
||||
then <U> (onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
||||
then <U> (onFulfilled?: (value: R) => U | Thenable<U>, onRejected?: (error: any) => void): Promise<U>;
|
||||
|
||||
/**
|
||||
* Sugar for promise.then(undefined, onRejected)
|
||||
*
|
||||
* @param onRejected called when/if "promise" rejects
|
||||
*/
|
||||
catch <U> (onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
||||
|
||||
/**
|
||||
* onSettled is invoked when/if the "promise" settles (either rejects or fulfills).
|
||||
* The returned promise is settled when the `Thenable` returned by `onFinally` settles;
|
||||
* it is rejected if `onFinally` throws or rejects; otherwise it assumes the state of the
|
||||
* original Promise.
|
||||
*
|
||||
* @param onFinally called when/if "promise" settles
|
||||
|
||||
*/
|
||||
finally (onFinally?: () => any | Thenable<any>): Promise<R>;
|
||||
|
||||
/**
|
||||
* Make a new promise from the thenable.
|
||||
* A thenable is promise-like in as far as it has a "then" method.
|
||||
*/
|
||||
static resolve (): Promise<void>;
|
||||
static resolve <R> (value: R | Thenable<R>): Promise<R>;
|
||||
|
||||
/**
|
||||
* Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error
|
||||
*/
|
||||
static reject <R> (error: any): Promise<R>;
|
||||
|
||||
/**
|
||||
* Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects.
|
||||
* the array passed to all can be a mixture of promise-like objects and other objects.
|
||||
* The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value.
|
||||
*/
|
||||
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>, T10 | Thenable<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
|
||||
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
|
||||
static all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
|
||||
static all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>;
|
||||
static all<T1, T2, T3, T4, T5, T6>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>;
|
||||
static all<T1, T2, T3, T4, T5>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>]): Promise<[T1, T2, T3, T4, T5]>;
|
||||
static all<T1, T2, T3, T4>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>]): Promise<[T1, T2, T3, T4]>;
|
||||
static all<T1, T2, T3>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>]): Promise<[T1, T2, T3]>;
|
||||
static all<T1, T2>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>]): Promise<[T1, T2]>;
|
||||
static all<T1>(values: [T1 | Thenable<T1>]): Promise<[T1]>;
|
||||
static all<TAll>(values: Array<TAll | Thenable<TAll>>): Promise<TAll[]>;
|
||||
|
||||
/**
|
||||
* Make a Promise that fulfills when any item fulfills, and rejects if any item rejects.
|
||||
*/
|
||||
static race <R> (promises: (R | Thenable<R>)[]): Promise<R>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The polyfill method will patch the global environment (in this case to the Promise name) when called.
|
||||
*/
|
||||
export function polyfill (): void;
|
||||
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.errorUtil = void 0;
|
||||
var errorUtil;
|
||||
(function (errorUtil) {
|
||||
errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
||||
// biome-ignore lint:
|
||||
errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
|
||||
})(errorUtil || (exports.errorUtil = errorUtil = {}));
|
||||
@@ -0,0 +1,8 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '4'
|
||||
- '6'
|
||||
- '8'
|
||||
- '9'
|
||||
- '10'
|
||||
@@ -0,0 +1,31 @@
|
||||
import * as core from "../core/index.js";
|
||||
import { type ZodError } from "./errors.js";
|
||||
export type ZodSafeParseResult<T> = ZodSafeParseSuccess<T> | ZodSafeParseError<T>;
|
||||
export type ZodSafeParseSuccess<T> = {
|
||||
success: true;
|
||||
data: T;
|
||||
error?: never;
|
||||
};
|
||||
export type ZodSafeParseError<T> = {
|
||||
success: false;
|
||||
data?: never;
|
||||
error: ZodError<T>;
|
||||
};
|
||||
export declare const parse: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => core.output<T>;
|
||||
export declare const parseAsync: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => Promise<core.output<T>>;
|
||||
export declare const safeParse: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.output<T>>;
|
||||
export declare const safeParseAsync: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.output<T>>>;
|
||||
export declare const encode: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => core.input<T>;
|
||||
export declare const decode: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => core.output<T>;
|
||||
export declare const encodeAsync: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<core.input<T>>;
|
||||
export declare const decodeAsync: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<core.output<T>>;
|
||||
export declare const safeEncode: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.input<T>>;
|
||||
export declare const safeDecode: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.output<T>>;
|
||||
export declare const safeEncodeAsync: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.input<T>>>;
|
||||
export declare const safeDecodeAsync: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.output<T>>>;
|
||||
@@ -0,0 +1,27 @@
|
||||
declare module "node:string_decoder" {
|
||||
class StringDecoder {
|
||||
constructor(encoding?: BufferEncoding);
|
||||
/**
|
||||
* Returns a decoded string, ensuring that any incomplete multibyte characters at
|
||||
* the end of the `Buffer`, or `TypedArray`, or `DataView` are omitted from the
|
||||
* returned string and stored in an internal buffer for the next call to `stringDecoder.write()` or `stringDecoder.end()`.
|
||||
* @since v0.1.99
|
||||
* @param buffer The bytes to decode.
|
||||
*/
|
||||
write(buffer: string | NodeJS.ArrayBufferView): string;
|
||||
/**
|
||||
* Returns any remaining input stored in the internal buffer as a string. Bytes
|
||||
* representing incomplete UTF-8 and UTF-16 characters will be replaced with
|
||||
* substitution characters appropriate for the character encoding.
|
||||
*
|
||||
* If the `buffer` argument is provided, one final call to `stringDecoder.write()` is performed before returning the remaining input.
|
||||
* After `end()` is called, the `stringDecoder` object can be reused for new input.
|
||||
* @since v0.9.3
|
||||
* @param buffer The bytes to decode.
|
||||
*/
|
||||
end(buffer?: string | NodeJS.ArrayBufferView): string;
|
||||
}
|
||||
}
|
||||
declare module "string_decoder" {
|
||||
export * from "node:string_decoder";
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
||||
import ansiStyles from '#ansi-styles';
|
||||
import supportsColor from '#supports-color';
|
||||
import { // eslint-disable-line import/order
|
||||
stringReplaceAll,
|
||||
stringEncaseCRLFWithFirstIndex,
|
||||
} from './utilities.js';
|
||||
|
||||
const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
|
||||
|
||||
const GENERATOR = Symbol('GENERATOR');
|
||||
const STYLER = Symbol('STYLER');
|
||||
const IS_EMPTY = Symbol('IS_EMPTY');
|
||||
|
||||
// `supportsColor.level` → `ansiStyles.color[name]` mapping
|
||||
const levelMapping = [
|
||||
'ansi',
|
||||
'ansi',
|
||||
'ansi256',
|
||||
'ansi16m',
|
||||
];
|
||||
|
||||
const styles = Object.create(null);
|
||||
|
||||
const applyOptions = (object, options = {}) => {
|
||||
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
||||
throw new Error('The `level` option should be an integer from 0 to 3');
|
||||
}
|
||||
|
||||
// Detect level if not set manually
|
||||
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
||||
object.level = options.level === undefined ? colorLevel : options.level;
|
||||
};
|
||||
|
||||
export class Chalk {
|
||||
constructor(options) {
|
||||
// eslint-disable-next-line no-constructor-return
|
||||
return chalkFactory(options);
|
||||
}
|
||||
}
|
||||
|
||||
const chalkFactory = options => {
|
||||
const chalk = (...strings) => strings.join(' ');
|
||||
applyOptions(chalk, options);
|
||||
|
||||
Object.setPrototypeOf(chalk, createChalk.prototype);
|
||||
|
||||
return chalk;
|
||||
};
|
||||
|
||||
function createChalk(options) {
|
||||
return chalkFactory(options);
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
||||
|
||||
for (const [styleName, style] of Object.entries(ansiStyles)) {
|
||||
styles[styleName] = {
|
||||
get() {
|
||||
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
||||
Object.defineProperty(this, styleName, {value: builder});
|
||||
return builder;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
styles.visible = {
|
||||
get() {
|
||||
const builder = createBuilder(this, this[STYLER], true);
|
||||
Object.defineProperty(this, 'visible', {value: builder});
|
||||
return builder;
|
||||
},
|
||||
};
|
||||
|
||||
const getModelAnsi = (model, level, type, ...arguments_) => {
|
||||
if (model === 'rgb') {
|
||||
if (level === 'ansi16m') {
|
||||
return ansiStyles[type].ansi16m(...arguments_);
|
||||
}
|
||||
|
||||
if (level === 'ansi256') {
|
||||
return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
|
||||
}
|
||||
|
||||
return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
|
||||
}
|
||||
|
||||
if (model === 'hex') {
|
||||
return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));
|
||||
}
|
||||
|
||||
return ansiStyles[type][model](...arguments_);
|
||||
};
|
||||
|
||||
const usedModels = ['rgb', 'hex', 'ansi256'];
|
||||
|
||||
for (const model of usedModels) {
|
||||
styles[model] = {
|
||||
get() {
|
||||
const {level} = this;
|
||||
return function (...arguments_) {
|
||||
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);
|
||||
return createBuilder(this, styler, this[IS_EMPTY]);
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
|
||||
styles[bgModel] = {
|
||||
get() {
|
||||
const {level} = this;
|
||||
return function (...arguments_) {
|
||||
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
|
||||
return createBuilder(this, styler, this[IS_EMPTY]);
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const proto = Object.defineProperties(() => {}, {
|
||||
...styles,
|
||||
level: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this[GENERATOR].level;
|
||||
},
|
||||
set(level) {
|
||||
this[GENERATOR].level = level;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createStyler = (open, close, parent) => {
|
||||
let openAll;
|
||||
let closeAll;
|
||||
if (parent === undefined) {
|
||||
openAll = open;
|
||||
closeAll = close;
|
||||
} else {
|
||||
openAll = parent.openAll + open;
|
||||
closeAll = close + parent.closeAll;
|
||||
}
|
||||
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
openAll,
|
||||
closeAll,
|
||||
parent,
|
||||
};
|
||||
};
|
||||
|
||||
const createBuilder = (self, _styler, _isEmpty) => {
|
||||
// Single argument is hot path, implicit coercion is faster than anything
|
||||
// eslint-disable-next-line no-implicit-coercion
|
||||
const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
|
||||
|
||||
// We alter the prototype because we must return a function, but there is
|
||||
// no way to create a function with a different prototype
|
||||
Object.setPrototypeOf(builder, proto);
|
||||
|
||||
builder[GENERATOR] = self;
|
||||
builder[STYLER] = _styler;
|
||||
builder[IS_EMPTY] = _isEmpty;
|
||||
|
||||
return builder;
|
||||
};
|
||||
|
||||
const applyStyle = (self, string) => {
|
||||
if (self.level <= 0 || !string) {
|
||||
return self[IS_EMPTY] ? '' : string;
|
||||
}
|
||||
|
||||
let styler = self[STYLER];
|
||||
|
||||
if (styler === undefined) {
|
||||
return string;
|
||||
}
|
||||
|
||||
const {openAll, closeAll} = styler;
|
||||
if (string.includes('\u001B')) {
|
||||
while (styler !== undefined) {
|
||||
// Replace any instances already present with a re-opening code
|
||||
// otherwise only the part of the string until said closing code
|
||||
// will be colored, and the rest will simply be 'plain'.
|
||||
string = stringReplaceAll(string, styler.close, styler.open);
|
||||
|
||||
styler = styler.parent;
|
||||
}
|
||||
}
|
||||
|
||||
// We can move both next actions out of loop, because remaining actions in loop won't have
|
||||
// any/visible effect on parts we add here. Close the styling before a linebreak and reopen
|
||||
// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
|
||||
const lfIndex = string.indexOf('\n');
|
||||
if (lfIndex !== -1) {
|
||||
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
||||
}
|
||||
|
||||
return openAll + string + closeAll;
|
||||
};
|
||||
|
||||
Object.defineProperties(createChalk.prototype, styles);
|
||||
|
||||
const chalk = createChalk();
|
||||
export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});
|
||||
|
||||
export {
|
||||
modifierNames,
|
||||
foregroundColorNames,
|
||||
backgroundColorNames,
|
||||
colorNames,
|
||||
|
||||
// TODO: Remove these aliases in the next major version
|
||||
modifierNames as modifiers,
|
||||
foregroundColorNames as foregroundColors,
|
||||
backgroundColorNames as backgroundColors,
|
||||
colorNames as colors,
|
||||
} from './vendor/ansi-styles/index.js';
|
||||
|
||||
export {
|
||||
stdoutColor as supportsColor,
|
||||
stderrColor as supportsColorStderr,
|
||||
};
|
||||
|
||||
export default chalk;
|
||||
@@ -0,0 +1,11 @@
|
||||
# @influxdata/influxdb-client
|
||||
|
||||
The reference javascript client for InfluxDB 2.x. Both node and browser environments are supported. The package.json
|
||||
|
||||
- **main** points to node.js CJS distribution
|
||||
- **module** points to node.js ESM distribution
|
||||
- **browser** points to browser (UMD) distribution
|
||||
|
||||
Node.js distributions do not work in browser and vice versa, because different platform APIs are used. Use `@influxdata/influxdb-client-browser` to import browser ESM module. See https://github.com/influxdata/influxdb-client-js to know more.
|
||||
|
||||
**Note: This library is for use with InfluxDB 2.x or 1.8+. For connecting to InfluxDB 1.x instances, see [node-influx](https://github.com/node-influx/node-influx).**
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag assignment of the exception parameter
|
||||
* @author Stephen Murray <spmurrayzzz>
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
|
||||
docs: {
|
||||
description: "Disallow reassigning exceptions in `catch` clauses",
|
||||
recommended: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-ex-assign",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
unexpected: "Do not assign to the exception parameter.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* Finds and reports references that are non initializer and writable.
|
||||
* @param {Variable} variable A variable to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function checkVariable(variable) {
|
||||
astUtils
|
||||
.getModifyingReferences(variable.references)
|
||||
.forEach(reference => {
|
||||
context.report({
|
||||
node: reference.identifier,
|
||||
messageId: "unexpected",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
CatchClause(node) {
|
||||
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user