WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,652 @@
|
||||
/**
|
||||
* @fileoverview enforce a particular style for multiline comments
|
||||
* @author Teddy Katz
|
||||
* @deprecated in ESLint v9.3.0
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
deprecated: {
|
||||
message: "Formatting rules are being moved out of ESLint core.",
|
||||
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
||||
deprecatedSince: "9.3.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: "multiline-comment-style",
|
||||
url: "https://eslint.style/rules/multiline-comment-style",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
type: "suggestion",
|
||||
docs: {
|
||||
description: "Enforce a particular style for multiline comments",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/multiline-comment-style",
|
||||
},
|
||||
|
||||
fixable: "whitespace",
|
||||
schema: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "array",
|
||||
items: [
|
||||
{
|
||||
enum: ["starred-block", "bare-block"],
|
||||
},
|
||||
],
|
||||
additionalItems: false,
|
||||
},
|
||||
{
|
||||
type: "array",
|
||||
items: [
|
||||
{
|
||||
enum: ["separate-lines"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
checkJSDoc: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
additionalItems: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
messages: {
|
||||
expectedBlock:
|
||||
"Expected a block comment instead of consecutive line comments.",
|
||||
expectedBareBlock:
|
||||
"Expected a block comment without padding stars.",
|
||||
startNewline: "Expected a linebreak after '/*'.",
|
||||
endNewline: "Expected a linebreak before '*/'.",
|
||||
missingStar: "Expected a '*' at the start of this line.",
|
||||
alignment:
|
||||
"Expected this line to be aligned with the start of the comment.",
|
||||
expectedLines:
|
||||
"Expected multiple line comments instead of a block comment.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const sourceCode = context.sourceCode;
|
||||
const option = context.options[0] || "starred-block";
|
||||
const params = context.options[1] || {};
|
||||
const checkJSDoc = !!params.checkJSDoc;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helpers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if a comment line is starred.
|
||||
* @param {string} line A string representing a comment line.
|
||||
* @returns {boolean} Whether or not the comment line is starred.
|
||||
*/
|
||||
function isStarredCommentLine(line) {
|
||||
return /^\s*\*/u.test(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a comment group is in starred-block form.
|
||||
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment.
|
||||
* @returns {boolean} Whether or not the comment group is in starred block form.
|
||||
*/
|
||||
function isStarredBlockComment([firstComment]) {
|
||||
if (firstComment.type !== "Block") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER);
|
||||
|
||||
// The first and last lines can only contain whitespace.
|
||||
return (
|
||||
lines.length > 0 &&
|
||||
lines.every((line, i) =>
|
||||
(i === 0 || i === lines.length - 1
|
||||
? /^\s*$/u
|
||||
: /^\s*\*/u
|
||||
).test(line),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a comment group is in JSDoc form.
|
||||
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment.
|
||||
* @returns {boolean} Whether or not the comment group is in JSDoc form.
|
||||
*/
|
||||
function isJSDocComment([firstComment]) {
|
||||
if (firstComment.type !== "Block") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER);
|
||||
|
||||
return (
|
||||
/^\*\s*$/u.test(lines[0]) &&
|
||||
lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
|
||||
/^\s*$/u.test(lines.at(-1))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a comment group that is currently in separate-line form, calculating the offset for each line.
|
||||
* @param {Token[]} commentGroup A group of comments containing multiple line comments.
|
||||
* @returns {string[]} An array of the processed lines.
|
||||
*/
|
||||
function processSeparateLineComments(commentGroup) {
|
||||
const allLinesHaveLeadingSpace = commentGroup
|
||||
.map(({ value }) => value)
|
||||
.filter(line => line.trim().length)
|
||||
.every(line => line.startsWith(" "));
|
||||
|
||||
return commentGroup.map(({ value }) =>
|
||||
allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a comment group that is currently in starred-block form, calculating the offset for each line.
|
||||
* @param {Token} comment A single block comment token in starred-block form.
|
||||
* @returns {string[]} An array of the processed lines.
|
||||
*/
|
||||
function processStarredBlockComment(comment) {
|
||||
const lines = comment.value
|
||||
.split(astUtils.LINEBREAK_MATCHER)
|
||||
.filter(
|
||||
(line, i, linesArr) =>
|
||||
!(i === 0 || i === linesArr.length - 1),
|
||||
)
|
||||
.map(line => line.replace(/^\s*$/u, ""));
|
||||
const allLinesHaveLeadingSpace = lines
|
||||
.map(line => line.replace(/\s*\*/u, ""))
|
||||
.filter(line => line.trim().length)
|
||||
.every(line => line.startsWith(" "));
|
||||
|
||||
return lines.map(line =>
|
||||
line.replace(
|
||||
allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u,
|
||||
"",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a comment group that is currently in bare-block form, calculating the offset for each line.
|
||||
* @param {Token} comment A single block comment token in bare-block form.
|
||||
* @returns {string[]} An array of the processed lines.
|
||||
*/
|
||||
function processBareBlockComment(comment) {
|
||||
const lines = comment.value
|
||||
.split(astUtils.LINEBREAK_MATCHER)
|
||||
.map(line => line.replace(/^\s*$/u, ""));
|
||||
const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])} `;
|
||||
let offset = "";
|
||||
|
||||
/*
|
||||
* Calculate the offset of the least indented line and use that as the basis for offsetting all the lines.
|
||||
* The first line should not be checked because it is inline with the opening block comment delimiter.
|
||||
*/
|
||||
for (const [i, line] of lines.entries()) {
|
||||
if (!line.trim().length || i === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const [, lineOffset] = line.match(/^(\s*\*?\s*)/u);
|
||||
|
||||
if (lineOffset.length < leadingWhitespace.length) {
|
||||
const newOffset = leadingWhitespace.slice(
|
||||
lineOffset.length - leadingWhitespace.length,
|
||||
);
|
||||
|
||||
if (newOffset.length > offset.length) {
|
||||
offset = newOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lines.map(line => {
|
||||
const match = line.match(/^(\s*\*?\s*)(.*)/u);
|
||||
const [, lineOffset, lineContents] = match;
|
||||
|
||||
if (lineOffset.length > leadingWhitespace.length) {
|
||||
return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`;
|
||||
}
|
||||
|
||||
if (lineOffset.length < leadingWhitespace.length) {
|
||||
return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`;
|
||||
}
|
||||
|
||||
return lineContents;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of comment lines in a group, formatting leading whitespace as necessary.
|
||||
* @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment.
|
||||
* @returns {string[]} A list of comment lines.
|
||||
*/
|
||||
function getCommentLines(commentGroup) {
|
||||
const [firstComment] = commentGroup;
|
||||
|
||||
if (firstComment.type === "Line") {
|
||||
return processSeparateLineComments(commentGroup);
|
||||
}
|
||||
|
||||
if (isStarredBlockComment(commentGroup)) {
|
||||
return processStarredBlockComment(firstComment);
|
||||
}
|
||||
|
||||
return processBareBlockComment(firstComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the initial offset (whitespace) from the beginning of a line to a given comment token.
|
||||
* @param {Token} comment The token to check.
|
||||
* @returns {string} The offset from the beginning of a line to the token.
|
||||
*/
|
||||
function getInitialOffset(comment) {
|
||||
return sourceCode.text.slice(
|
||||
comment.range[0] - comment.loc.start.column,
|
||||
comment.range[0],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comment into starred-block form
|
||||
* @param {Token} firstComment The first comment of the group being converted
|
||||
* @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment
|
||||
* @returns {string} A representation of the comment value in starred-block form, excluding start and end markers
|
||||
*/
|
||||
function convertToStarredBlock(firstComment, commentLinesList) {
|
||||
const initialOffset = getInitialOffset(firstComment);
|
||||
|
||||
return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comment into separate-line form
|
||||
* @param {Token} firstComment The first comment of the group being converted
|
||||
* @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment
|
||||
* @returns {string} A representation of the comment value in separate-line form
|
||||
*/
|
||||
function convertToSeparateLines(firstComment, commentLinesList) {
|
||||
return commentLinesList
|
||||
.map(line => `// ${line}`)
|
||||
.join(`\n${getInitialOffset(firstComment)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a comment into bare-block form
|
||||
* @param {Token} firstComment The first comment of the group being converted
|
||||
* @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment
|
||||
* @returns {string} A representation of the comment value in bare-block form
|
||||
*/
|
||||
function convertToBlock(firstComment, commentLinesList) {
|
||||
return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)} `)} */`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each method checks a group of comments to see if it's valid according to the given option.
|
||||
* @param {Token[]} commentGroup A list of comments that appear together. This will either contain a single
|
||||
* block comment or multiple line comments.
|
||||
* @returns {void}
|
||||
*/
|
||||
const commentGroupCheckers = {
|
||||
"starred-block"(commentGroup) {
|
||||
const [firstComment] = commentGroup;
|
||||
const commentLines = getCommentLines(commentGroup);
|
||||
|
||||
if (commentLines.some(value => value.includes("*/"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (commentGroup.length > 1) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: firstComment.loc.start,
|
||||
end: commentGroup.at(-1).loc.end,
|
||||
},
|
||||
messageId: "expectedBlock",
|
||||
fix(fixer) {
|
||||
const range = [
|
||||
firstComment.range[0],
|
||||
commentGroup.at(-1).range[1],
|
||||
];
|
||||
|
||||
return commentLines.some(value =>
|
||||
value.startsWith("/"),
|
||||
)
|
||||
? null
|
||||
: fixer.replaceTextRange(
|
||||
range,
|
||||
convertToStarredBlock(
|
||||
firstComment,
|
||||
commentLines,
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const lines = firstComment.value.split(
|
||||
astUtils.LINEBREAK_MATCHER,
|
||||
);
|
||||
const expectedLeadingWhitespace =
|
||||
getInitialOffset(firstComment);
|
||||
const expectedLinePrefix = `${expectedLeadingWhitespace} *`;
|
||||
|
||||
if (!/^\*?\s*$/u.test(lines[0])) {
|
||||
const start = firstComment.value.startsWith("*")
|
||||
? firstComment.range[0] + 1
|
||||
: firstComment.range[0];
|
||||
|
||||
context.report({
|
||||
loc: {
|
||||
start: firstComment.loc.start,
|
||||
end: {
|
||||
line: firstComment.loc.start.line,
|
||||
column: firstComment.loc.start.column + 2,
|
||||
},
|
||||
},
|
||||
messageId: "startNewline",
|
||||
fix: fixer =>
|
||||
fixer.insertTextAfterRange(
|
||||
[start, start + 2],
|
||||
`\n${expectedLinePrefix}`,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
if (!/^\s*$/u.test(lines.at(-1))) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: {
|
||||
line: firstComment.loc.end.line,
|
||||
column: firstComment.loc.end.column - 2,
|
||||
},
|
||||
end: firstComment.loc.end,
|
||||
},
|
||||
messageId: "endNewline",
|
||||
fix: fixer =>
|
||||
fixer.replaceTextRange(
|
||||
[
|
||||
firstComment.range[1] - 2,
|
||||
firstComment.range[1],
|
||||
],
|
||||
`\n${expectedLinePrefix}/`,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
for (
|
||||
let lineNumber = firstComment.loc.start.line + 1;
|
||||
lineNumber <= firstComment.loc.end.line;
|
||||
lineNumber++
|
||||
) {
|
||||
const lineText = sourceCode.lines[lineNumber - 1];
|
||||
const errorType = isStarredCommentLine(lineText)
|
||||
? "alignment"
|
||||
: "missingStar";
|
||||
|
||||
if (!lineText.startsWith(expectedLinePrefix)) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: { line: lineNumber, column: 0 },
|
||||
end: {
|
||||
line: lineNumber,
|
||||
column: lineText.length,
|
||||
},
|
||||
},
|
||||
messageId: errorType,
|
||||
fix(fixer) {
|
||||
const lineStartIndex =
|
||||
sourceCode.getIndexFromLoc({
|
||||
line: lineNumber,
|
||||
column: 0,
|
||||
});
|
||||
|
||||
if (errorType === "alignment") {
|
||||
const [, commentTextPrefix = ""] =
|
||||
lineText.match(/^(\s*\*)/u) || [];
|
||||
const commentTextStartIndex =
|
||||
lineStartIndex +
|
||||
commentTextPrefix.length;
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
[
|
||||
lineStartIndex,
|
||||
commentTextStartIndex,
|
||||
],
|
||||
expectedLinePrefix,
|
||||
);
|
||||
}
|
||||
|
||||
const [, commentTextPrefix = ""] =
|
||||
lineText.match(/^(\s*)/u) || [];
|
||||
const commentTextStartIndex =
|
||||
lineStartIndex +
|
||||
commentTextPrefix.length;
|
||||
let offset;
|
||||
|
||||
for (const [idx, line] of lines.entries()) {
|
||||
if (!/\S+/u.test(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const lineTextToAlignWith =
|
||||
sourceCode.lines[
|
||||
firstComment.loc.start.line -
|
||||
1 +
|
||||
idx
|
||||
];
|
||||
const [
|
||||
,
|
||||
prefix = "",
|
||||
initialOffset = "",
|
||||
] =
|
||||
lineTextToAlignWith.match(
|
||||
/^(\s*(?:\/?\*)?(\s*))/u,
|
||||
) || [];
|
||||
|
||||
offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`;
|
||||
|
||||
if (
|
||||
/^\s*\//u.test(lineText) &&
|
||||
offset.length === 0
|
||||
) {
|
||||
offset += " ";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return fixer.replaceTextRange(
|
||||
[lineStartIndex, commentTextStartIndex],
|
||||
`${expectedLinePrefix}${offset}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"separate-lines"(commentGroup) {
|
||||
const [firstComment] = commentGroup;
|
||||
|
||||
const isJSDoc = isJSDocComment(commentGroup);
|
||||
|
||||
if (firstComment.type !== "Block" || (!checkJSDoc && isJSDoc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let commentLines = getCommentLines(commentGroup);
|
||||
|
||||
if (isJSDoc) {
|
||||
commentLines = commentLines.slice(
|
||||
1,
|
||||
commentLines.length - 1,
|
||||
);
|
||||
}
|
||||
|
||||
const tokenAfter = sourceCode.getTokenAfter(firstComment, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
if (
|
||||
tokenAfter &&
|
||||
firstComment.loc.end.line === tokenAfter.loc.start.line
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report({
|
||||
loc: {
|
||||
start: firstComment.loc.start,
|
||||
end: {
|
||||
line: firstComment.loc.start.line,
|
||||
column: firstComment.loc.start.column + 2,
|
||||
},
|
||||
},
|
||||
messageId: "expectedLines",
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(
|
||||
firstComment,
|
||||
convertToSeparateLines(firstComment, commentLines),
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
"bare-block"(commentGroup) {
|
||||
if (isJSDocComment(commentGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [firstComment] = commentGroup;
|
||||
const commentLines = getCommentLines(commentGroup);
|
||||
|
||||
// Disallows consecutive line comments in favor of using a block comment.
|
||||
if (
|
||||
firstComment.type === "Line" &&
|
||||
commentLines.length > 1 &&
|
||||
!commentLines.some(value => value.includes("*/"))
|
||||
) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: firstComment.loc.start,
|
||||
end: commentGroup.at(-1).loc.end,
|
||||
},
|
||||
messageId: "expectedBlock",
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[
|
||||
firstComment.range[0],
|
||||
commentGroup.at(-1).range[1],
|
||||
],
|
||||
convertToBlock(firstComment, commentLines),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Prohibits block comments from having a * at the beginning of each line.
|
||||
if (isStarredBlockComment(commentGroup)) {
|
||||
context.report({
|
||||
loc: {
|
||||
start: firstComment.loc.start,
|
||||
end: {
|
||||
line: firstComment.loc.start.line,
|
||||
column: firstComment.loc.start.column + 2,
|
||||
},
|
||||
},
|
||||
messageId: "expectedBareBlock",
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(
|
||||
firstComment,
|
||||
convertToBlock(firstComment, commentLines),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
Program() {
|
||||
return sourceCode
|
||||
.getAllComments()
|
||||
.filter(comment => comment.type !== "Shebang")
|
||||
.filter(
|
||||
comment =>
|
||||
!astUtils.COMMENTS_IGNORE_PATTERN.test(
|
||||
comment.value,
|
||||
),
|
||||
)
|
||||
.filter(comment => {
|
||||
const tokenBefore = sourceCode.getTokenBefore(comment, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
return (
|
||||
!tokenBefore ||
|
||||
tokenBefore.loc.end.line < comment.loc.start.line
|
||||
);
|
||||
})
|
||||
.reduce((commentGroups, comment, index, commentList) => {
|
||||
const tokenBefore = sourceCode.getTokenBefore(comment, {
|
||||
includeComments: true,
|
||||
});
|
||||
|
||||
if (
|
||||
comment.type === "Line" &&
|
||||
index &&
|
||||
commentList[index - 1].type === "Line" &&
|
||||
tokenBefore &&
|
||||
tokenBefore.loc.end.line ===
|
||||
comment.loc.start.line - 1 &&
|
||||
tokenBefore === commentList[index - 1]
|
||||
) {
|
||||
commentGroups.at(-1).push(comment);
|
||||
} else {
|
||||
commentGroups.push([comment]);
|
||||
}
|
||||
|
||||
return commentGroups;
|
||||
}, [])
|
||||
.filter(
|
||||
commentGroup =>
|
||||
!(
|
||||
commentGroup.length === 1 &&
|
||||
commentGroup[0].loc.start.line ===
|
||||
commentGroup[0].loc.end.line
|
||||
),
|
||||
)
|
||||
.forEach(commentGroupCheckers[option]);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,161 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// SEE https://typescript-eslint.io/users/configs
|
||||
//
|
||||
// For developers working in the typescript-eslint monorepo:
|
||||
// You can regenerate it using `pnpm run generate-configs`
|
||||
module.exports = {
|
||||
extends: ['./configs/eslintrc/base', './configs/eslintrc/eslint-recommended'],
|
||||
rules: {
|
||||
'@typescript-eslint/adjacent-overload-signatures': 'error',
|
||||
'@typescript-eslint/array-type': 'error',
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
'@typescript-eslint/ban-ts-comment': 'error',
|
||||
'@typescript-eslint/ban-tslint-comment': 'error',
|
||||
'@typescript-eslint/class-literal-property-style': 'error',
|
||||
'class-methods-use-this': 'off',
|
||||
'@typescript-eslint/class-methods-use-this': 'error',
|
||||
'@typescript-eslint/consistent-generic-constructors': 'error',
|
||||
'@typescript-eslint/consistent-indexed-object-style': 'error',
|
||||
'consistent-return': 'off',
|
||||
'@typescript-eslint/consistent-return': 'error',
|
||||
'@typescript-eslint/consistent-type-assertions': 'error',
|
||||
'@typescript-eslint/consistent-type-definitions': 'error',
|
||||
'@typescript-eslint/consistent-type-exports': 'error',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'default-param-last': 'off',
|
||||
'@typescript-eslint/default-param-last': 'error',
|
||||
'dot-notation': 'off',
|
||||
'@typescript-eslint/dot-notation': 'error',
|
||||
'@typescript-eslint/explicit-function-return-type': 'error',
|
||||
'@typescript-eslint/explicit-member-accessibility': 'error',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'error',
|
||||
'init-declarations': 'off',
|
||||
'@typescript-eslint/init-declarations': 'error',
|
||||
'max-params': 'off',
|
||||
'@typescript-eslint/max-params': 'error',
|
||||
'@typescript-eslint/member-ordering': 'error',
|
||||
'@typescript-eslint/method-signature-style': 'error',
|
||||
'@typescript-eslint/naming-convention': 'error',
|
||||
'no-array-constructor': 'off',
|
||||
'@typescript-eslint/no-array-constructor': 'error',
|
||||
'@typescript-eslint/no-array-delete': 'error',
|
||||
'@typescript-eslint/no-base-to-string': 'error',
|
||||
'@typescript-eslint/no-confusing-non-null-assertion': 'error',
|
||||
'@typescript-eslint/no-confusing-void-expression': 'error',
|
||||
'@typescript-eslint/no-deprecated': 'error',
|
||||
'no-dupe-class-members': 'off',
|
||||
'@typescript-eslint/no-dupe-class-members': 'error',
|
||||
'@typescript-eslint/no-duplicate-enum-values': 'error',
|
||||
'@typescript-eslint/no-duplicate-type-constituents': 'error',
|
||||
'@typescript-eslint/no-dynamic-delete': 'error',
|
||||
'no-empty-function': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'error',
|
||||
'@typescript-eslint/no-empty-object-type': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-extra-non-null-assertion': 'error',
|
||||
'@typescript-eslint/no-extraneous-class': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-for-in-array': 'error',
|
||||
'no-implied-eval': 'off',
|
||||
'@typescript-eslint/no-implied-eval': 'error',
|
||||
'@typescript-eslint/no-import-type-side-effects': 'error',
|
||||
'@typescript-eslint/no-inferrable-types': 'error',
|
||||
'no-invalid-this': 'off',
|
||||
'@typescript-eslint/no-invalid-this': 'error',
|
||||
'@typescript-eslint/no-invalid-void-type': 'error',
|
||||
'no-magic-numbers': 'off',
|
||||
'@typescript-eslint/no-magic-numbers': 'error',
|
||||
'@typescript-eslint/no-meaningless-void-operator': 'error',
|
||||
'@typescript-eslint/no-misused-new': 'error',
|
||||
'@typescript-eslint/no-misused-promises': 'error',
|
||||
'@typescript-eslint/no-misused-spread': 'error',
|
||||
'@typescript-eslint/no-mixed-enums': 'error',
|
||||
'@typescript-eslint/no-namespace': 'error',
|
||||
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'error',
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'error',
|
||||
'@typescript-eslint/no-require-imports': 'error',
|
||||
'@typescript-eslint/no-restricted-types': 'error',
|
||||
'no-shadow': 'off',
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
'@typescript-eslint/no-this-alias': 'error',
|
||||
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
|
||||
'@typescript-eslint/no-unnecessary-condition': 'error',
|
||||
'@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
|
||||
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
||||
'@typescript-eslint/no-unnecessary-template-expression': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-conversion': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
|
||||
'@typescript-eslint/no-unsafe-argument': 'error',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'error',
|
||||
'@typescript-eslint/no-unsafe-call': 'error',
|
||||
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
|
||||
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
|
||||
'@typescript-eslint/no-unsafe-function-type': 'error',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'error',
|
||||
'@typescript-eslint/no-unsafe-return': 'error',
|
||||
'@typescript-eslint/no-unsafe-type-assertion': 'error',
|
||||
'@typescript-eslint/no-unsafe-unary-minus': 'error',
|
||||
'no-unused-expressions': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'error',
|
||||
'no-unused-private-class-members': 'off',
|
||||
'@typescript-eslint/no-unused-private-class-members': 'error',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'no-use-before-define': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'error',
|
||||
'no-useless-constructor': 'off',
|
||||
'@typescript-eslint/no-useless-constructor': 'error',
|
||||
'@typescript-eslint/no-useless-default-assignment': 'error',
|
||||
'@typescript-eslint/no-useless-empty-export': 'error',
|
||||
'@typescript-eslint/no-wrapper-object-types': 'error',
|
||||
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
|
||||
'no-throw-literal': 'off',
|
||||
'@typescript-eslint/only-throw-error': 'error',
|
||||
'@typescript-eslint/parameter-properties': 'error',
|
||||
'@typescript-eslint/prefer-as-const': 'error',
|
||||
'prefer-destructuring': 'off',
|
||||
'@typescript-eslint/prefer-destructuring': 'error',
|
||||
'@typescript-eslint/prefer-enum-initializers': 'error',
|
||||
'@typescript-eslint/prefer-find': 'error',
|
||||
'@typescript-eslint/prefer-for-of': 'error',
|
||||
'@typescript-eslint/prefer-function-type': 'error',
|
||||
'@typescript-eslint/prefer-includes': 'error',
|
||||
'@typescript-eslint/prefer-literal-enum-member': 'error',
|
||||
'@typescript-eslint/prefer-namespace-keyword': 'error',
|
||||
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
||||
'@typescript-eslint/prefer-optional-chain': 'error',
|
||||
'prefer-promise-reject-errors': 'off',
|
||||
'@typescript-eslint/prefer-promise-reject-errors': 'error',
|
||||
'@typescript-eslint/prefer-readonly': 'error',
|
||||
'@typescript-eslint/prefer-readonly-parameter-types': 'error',
|
||||
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
|
||||
'@typescript-eslint/prefer-regexp-exec': 'error',
|
||||
'@typescript-eslint/prefer-return-this-type': 'error',
|
||||
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
|
||||
'@typescript-eslint/promise-function-async': 'error',
|
||||
'@typescript-eslint/related-getter-setter-pairs': 'error',
|
||||
'@typescript-eslint/require-array-sort-compare': 'error',
|
||||
'require-await': 'off',
|
||||
'@typescript-eslint/require-await': 'error',
|
||||
'@typescript-eslint/restrict-plus-operands': 'error',
|
||||
'@typescript-eslint/restrict-template-expressions': 'error',
|
||||
'no-return-await': 'off',
|
||||
'@typescript-eslint/return-await': 'error',
|
||||
'@typescript-eslint/strict-boolean-expressions': 'error',
|
||||
'@typescript-eslint/strict-void-return': 'error',
|
||||
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
||||
'@typescript-eslint/triple-slash-reference': 'error',
|
||||
'@typescript-eslint/unbound-method': 'error',
|
||||
'@typescript-eslint/unified-signatures': 'error',
|
||||
'@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,333 @@
|
||||
// @ts-ignore TS6133
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test(".optional()", () => {
|
||||
const schema = z.string().optional();
|
||||
expect(schema.parse("adsf")).toEqual("adsf");
|
||||
expect(schema.parse(undefined)).toEqual(undefined);
|
||||
expect(schema.safeParse(null).success).toEqual(false);
|
||||
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<string | undefined>();
|
||||
});
|
||||
|
||||
test("unwrap", () => {
|
||||
const unwrapped = z.string().optional().unwrap();
|
||||
expect(unwrapped).toBeInstanceOf(z.ZodString);
|
||||
});
|
||||
|
||||
test("optionality", () => {
|
||||
const a = z.string();
|
||||
expect(a._zod.optin).toEqual(undefined);
|
||||
expect(a._zod.optout).toEqual(undefined);
|
||||
|
||||
const b = z.string().optional();
|
||||
expect(b._zod.optin).toEqual("optional");
|
||||
expect(b._zod.optout).toEqual("optional");
|
||||
|
||||
const c = z.string().default("asdf");
|
||||
expect(c._zod.optin).toEqual("optional");
|
||||
expect(c._zod.optout).toEqual(undefined);
|
||||
|
||||
const d = z.string().optional().nullable();
|
||||
expect(d._zod.optin).toEqual("optional");
|
||||
expect(d._zod.optout).toEqual("optional");
|
||||
|
||||
const e = z.string().default("asdf").nullable();
|
||||
expect(e._zod.optin).toEqual("optional");
|
||||
expect(e._zod.optout).toEqual(undefined);
|
||||
|
||||
// z.undefined should NOT be optional
|
||||
const f = z.undefined();
|
||||
expect(f._zod.optin).toEqual(undefined);
|
||||
expect(f._zod.optout).toEqual(undefined);
|
||||
expectTypeOf<typeof f._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof f._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
// z.union should be optional if any of the types are optional
|
||||
const g = z.union([z.string(), z.undefined()]);
|
||||
expect(g._zod.optin).toEqual(undefined);
|
||||
expect(g._zod.optout).toEqual(undefined);
|
||||
expectTypeOf<typeof g._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof g._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
const h = z.union([z.string(), z.optional(z.string())]);
|
||||
expect(h._zod.optin).toEqual("optional");
|
||||
expect(h._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof h._zod.optin>().toEqualTypeOf<"optional">();
|
||||
expectTypeOf<typeof h._zod.optout>().toEqualTypeOf<"optional">();
|
||||
});
|
||||
|
||||
test("pipe optionality", () => {
|
||||
z.string().optional()._zod.optin;
|
||||
const a = z.string().optional().pipe(z.string());
|
||||
expect(a._zod.optin).toEqual("optional");
|
||||
expect(a._zod.optout).toEqual(undefined);
|
||||
expectTypeOf<typeof a._zod.optin>().toEqualTypeOf<"optional">();
|
||||
expectTypeOf<typeof a._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
const b = z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().optional());
|
||||
expect(b._zod.optin).toEqual(undefined);
|
||||
expect(b._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof b._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof b._zod.optout>().toEqualTypeOf<"optional">();
|
||||
|
||||
const c = z.string().default("asdf").pipe(z.string());
|
||||
expect(c._zod.optin).toEqual("optional");
|
||||
expect(c._zod.optout).toEqual(undefined);
|
||||
|
||||
const d = z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().default("asdf"));
|
||||
expect(d._zod.optin).toEqual(undefined);
|
||||
expect(d._zod.optout).toEqual(undefined);
|
||||
});
|
||||
|
||||
test("pipe optionality inside objects", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().optional(),
|
||||
b: z.string().optional().pipe(z.string()),
|
||||
c: z.string().default("asdf").pipe(z.string()),
|
||||
d: z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().optional()),
|
||||
e: z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().default("asdf")),
|
||||
});
|
||||
|
||||
type SchemaIn = z.input<typeof schema>;
|
||||
expectTypeOf<SchemaIn>().toEqualTypeOf<{
|
||||
a?: string | undefined;
|
||||
b?: string | undefined;
|
||||
c?: string | undefined;
|
||||
d: string;
|
||||
e: string;
|
||||
}>();
|
||||
|
||||
type SchemaOut = z.output<typeof schema>;
|
||||
expectTypeOf<SchemaOut>().toEqualTypeOf<{
|
||||
a?: string | undefined;
|
||||
b: string;
|
||||
c: string;
|
||||
d?: string | undefined;
|
||||
e: string;
|
||||
}>();
|
||||
});
|
||||
|
||||
test("optional prop with pipe", () => {
|
||||
const schema = z.object({
|
||||
id: z
|
||||
.union([z.number(), z.string().nullish()])
|
||||
.transform((val) => (val === null || val === undefined ? val : Number(val)))
|
||||
.pipe(z.number())
|
||||
.optional(),
|
||||
});
|
||||
|
||||
schema.parse({});
|
||||
schema.parse({}, { jitless: true });
|
||||
});
|
||||
|
||||
test("object absent keys require optin optional", () => {
|
||||
const valueUndefined = z.object({
|
||||
value: z.undefined(),
|
||||
union: z.union([z.string(), z.undefined()]),
|
||||
});
|
||||
|
||||
expect(valueUndefined.safeParse({}).error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "nonoptional",
|
||||
"message": "Invalid input: expected nonoptional, received undefined",
|
||||
"path": [
|
||||
"value",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "nonoptional",
|
||||
"message": "Invalid input: expected nonoptional, received undefined",
|
||||
"path": [
|
||||
"union",
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(valueUndefined.safeParse({}, { jitless: true }).success).toEqual(false);
|
||||
expect(valueUndefined.parse({ value: undefined, union: undefined })).toEqual({
|
||||
value: undefined,
|
||||
union: undefined,
|
||||
});
|
||||
|
||||
const optionalOutOnly = z.object({
|
||||
value: z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().optional()),
|
||||
});
|
||||
expect(optionalOutOnly.safeParse({}).success).toEqual(false);
|
||||
expect(optionalOutOnly.safeParse({}, { jitless: true }).success).toEqual(false);
|
||||
|
||||
const defaulted = z.object({ value: z.string().default("fallback") });
|
||||
expect(defaulted.parse({})).toEqual({ value: "fallback" });
|
||||
expect(defaulted.parse({}, { jitless: true })).toEqual({ value: "fallback" });
|
||||
});
|
||||
|
||||
// exactOptional tests
|
||||
test(".exactOptional()", () => {
|
||||
const schema = z.string().exactOptional();
|
||||
expect(schema.parse("asdf")).toEqual("asdf");
|
||||
expect(schema.safeParse(undefined).success).toEqual(false);
|
||||
expect(schema.safeParse(null).success).toEqual(false);
|
||||
|
||||
// Type should NOT include undefined
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<string>();
|
||||
expectTypeOf<typeof schema._input>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("exactOptional unwrap", () => {
|
||||
const unwrapped = z.string().exactOptional().unwrap();
|
||||
expect(unwrapped).toBeInstanceOf(z.ZodString);
|
||||
});
|
||||
|
||||
test("exactOptional optionality", () => {
|
||||
const a = z.string().exactOptional();
|
||||
expect(a._zod.optin).toEqual("optional");
|
||||
expect(a._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof a._zod.optin>().toEqualTypeOf<"optional">();
|
||||
expectTypeOf<typeof a._zod.optout>().toEqualTypeOf<"optional">();
|
||||
});
|
||||
|
||||
test("exactOptional in objects - absent keys", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().exactOptional(),
|
||||
});
|
||||
|
||||
// Absent key should pass
|
||||
expect(schema.parse({})).toEqual({});
|
||||
expect(schema.parse({}, { jitless: true })).toEqual({});
|
||||
|
||||
// Present key with valid value should pass
|
||||
expect(schema.parse({ a: "hello" })).toEqual({ a: "hello" });
|
||||
expect(schema.parse({ a: "hello" }, { jitless: true })).toEqual({ a: "hello" });
|
||||
});
|
||||
|
||||
test("exactOptional in objects - explicit undefined rejected", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().exactOptional(),
|
||||
});
|
||||
|
||||
// Explicit undefined should fail
|
||||
expect(schema.safeParse({ a: undefined }).success).toEqual(false);
|
||||
expect(schema.safeParse({ a: undefined }, { jitless: true }).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("exactOptional type inference in objects", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().exactOptional(),
|
||||
b: z.string().optional(),
|
||||
});
|
||||
|
||||
type SchemaIn = z.input<typeof schema>;
|
||||
expectTypeOf<SchemaIn>().toEqualTypeOf<{
|
||||
a?: string;
|
||||
b?: string | undefined;
|
||||
}>();
|
||||
|
||||
type SchemaOut = z.output<typeof schema>;
|
||||
expectTypeOf<SchemaOut>().toEqualTypeOf<{
|
||||
a?: string;
|
||||
b?: string | undefined;
|
||||
}>();
|
||||
});
|
||||
|
||||
test("exactOptional vs optional comparison", () => {
|
||||
const optionalSchema = z.object({ a: z.string().optional() });
|
||||
const exactOptionalSchema = z.object({ a: z.string().exactOptional() });
|
||||
|
||||
// Both accept absent keys
|
||||
expect(optionalSchema.parse({})).toEqual({});
|
||||
expect(exactOptionalSchema.parse({})).toEqual({});
|
||||
|
||||
// Both accept valid values
|
||||
expect(optionalSchema.parse({ a: "hi" })).toEqual({ a: "hi" });
|
||||
expect(exactOptionalSchema.parse({ a: "hi" })).toEqual({ a: "hi" });
|
||||
|
||||
// optional() accepts explicit undefined
|
||||
expect(optionalSchema.parse({ a: undefined })).toEqual({ a: undefined });
|
||||
|
||||
// exactOptional() rejects explicit undefined
|
||||
expect(exactOptionalSchema.safeParse({ a: undefined }).success).toEqual(false);
|
||||
});
|
||||
|
||||
// Defensive inference coverage: every schema that propagates `optout` participates
|
||||
// in object-key optionality inference. If anyone ever changes the set of values that
|
||||
// `optout` can take (or how OptionalOutSchema matches them), these assertions must
|
||||
// continue to hold or downstream `z.infer<typeof obj>` types silently flip required keys.
|
||||
test("object key optionality through optout propagation", () => {
|
||||
const direct = z.object({ k: z.string().optional() });
|
||||
expectTypeOf<z.infer<typeof direct>>().toEqualTypeOf<{ k?: string | undefined }>();
|
||||
|
||||
const exact = z.object({ k: z.string().exactOptional() });
|
||||
expectTypeOf<z.infer<typeof exact>>().toEqualTypeOf<{ k?: string }>();
|
||||
|
||||
// nullable() preserves the inner type's optout
|
||||
const nullableOpt = z.object({ k: z.string().optional().nullable() });
|
||||
expectTypeOf<z.infer<typeof nullableOpt>>().toEqualTypeOf<{ k?: string | null | undefined }>();
|
||||
|
||||
// optional() wrapping nullable() — still optional out
|
||||
const optNullable = z.object({ k: z.string().nullable().optional() });
|
||||
expectTypeOf<z.infer<typeof optNullable>>().toEqualTypeOf<{ k?: string | null | undefined }>();
|
||||
|
||||
// union containing an optional member must mark the key as optional
|
||||
const unionWithOpt = z.object({ k: z.union([z.string(), z.string().optional()]) });
|
||||
expectTypeOf<z.infer<typeof unionWithOpt>>().toEqualTypeOf<{ k?: string | undefined }>();
|
||||
|
||||
// pipe ending in optional()
|
||||
const pipedToOpt = z.object({
|
||||
k: z
|
||||
.string()
|
||||
.transform((v) => (Math.random() ? v : undefined))
|
||||
.pipe(z.string().optional()),
|
||||
});
|
||||
expectTypeOf<z.output<typeof pipedToOpt>>().toEqualTypeOf<{ k?: string | undefined }>();
|
||||
|
||||
// mixed shape pinning required vs optional keys end-to-end
|
||||
const mixed = z.object({
|
||||
req: z.string(),
|
||||
opt: z.string().optional(),
|
||||
exact: z.string().exactOptional(),
|
||||
def: z.string().default("x"),
|
||||
nullableOpt: z.string().optional().nullable(),
|
||||
});
|
||||
expectTypeOf<z.output<typeof mixed>>().toEqualTypeOf<{
|
||||
req: string;
|
||||
opt?: string | undefined;
|
||||
exact?: string;
|
||||
def: string;
|
||||
nullableOpt?: string | null | undefined;
|
||||
}>();
|
||||
});
|
||||
|
||||
// Defensive: tuple optional-tail inference also reads optout. The PR that introduced
|
||||
// `"includeUndefined"` had to update TupleOutputTypeWithOptionals; pin the result so
|
||||
// any future flag change has to keep this contract.
|
||||
test("tuple tail optionality through optout propagation", () => {
|
||||
const trailingOptional = z.tuple([z.string(), z.number().optional()]);
|
||||
expectTypeOf<z.output<typeof trailingOptional>>().toEqualTypeOf<[string, (number | undefined)?]>();
|
||||
|
||||
const trailingExact = z.tuple([z.string(), z.number().exactOptional()]);
|
||||
expectTypeOf<z.output<typeof trailingExact>>().toEqualTypeOf<[string, number?]>();
|
||||
|
||||
// Interior optional must NOT make the tail optional
|
||||
const interiorOptional = z.tuple([z.string(), z.number().optional(), z.string()]);
|
||||
expectTypeOf<z.output<typeof interiorOptional>>().toEqualTypeOf<[string, number | undefined, string]>();
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import parse from './parse.js';
|
||||
import { unsafeStringify } from './stringify.js';
|
||||
export function stringToBytes(str) {
|
||||
str = unescape(encodeURIComponent(str));
|
||||
const bytes = new Uint8Array(str.length);
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
bytes[i] = str.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
||||
export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
|
||||
export default function v35(version, hash, value, namespace, buf, offset) {
|
||||
const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;
|
||||
const namespaceBytes = typeof namespace === 'string' ? parse(namespace) : namespace;
|
||||
if (typeof namespace === 'string') {
|
||||
namespace = parse(namespace);
|
||||
}
|
||||
if (namespace?.length !== 16) {
|
||||
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
|
||||
}
|
||||
let bytes = new Uint8Array(16 + valueBytes.length);
|
||||
bytes.set(namespaceBytes);
|
||||
bytes.set(valueBytes, namespaceBytes.length);
|
||||
bytes = hash(bytes);
|
||||
bytes[6] = (bytes[6] & 0x0f) | version;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
if (buf) {
|
||||
offset ??= 0;
|
||||
if (offset < 0 || offset + 16 > buf.length) {
|
||||
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
||||
}
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = bytes[i];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
return unsafeStringify(bytes);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import * as util from "../core/util.js";
|
||||
const error = () => {
|
||||
const Sizable = {
|
||||
string: { unit: "tegn", verb: "havde" },
|
||||
file: { unit: "bytes", verb: "havde" },
|
||||
array: { unit: "elementer", verb: "indeholdt" },
|
||||
set: { unit: "elementer", verb: "indeholdt" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "input",
|
||||
email: "e-mailadresse",
|
||||
url: "URL",
|
||||
emoji: "emoji",
|
||||
uuid: "UUID",
|
||||
uuidv4: "UUIDv4",
|
||||
uuidv6: "UUIDv6",
|
||||
nanoid: "nanoid",
|
||||
guid: "GUID",
|
||||
cuid: "cuid",
|
||||
cuid2: "cuid2",
|
||||
ulid: "ULID",
|
||||
xid: "XID",
|
||||
ksuid: "KSUID",
|
||||
datetime: "ISO dato- og klokkeslæt",
|
||||
date: "ISO-dato",
|
||||
time: "ISO-klokkeslæt",
|
||||
duration: "ISO-varighed",
|
||||
ipv4: "IPv4-område",
|
||||
ipv6: "IPv6-område",
|
||||
cidrv4: "IPv4-spektrum",
|
||||
cidrv6: "IPv6-spektrum",
|
||||
base64: "base64-kodet streng",
|
||||
base64url: "base64url-kodet streng",
|
||||
json_string: "JSON-streng",
|
||||
e164: "E.164-nummer",
|
||||
jwt: "JWT",
|
||||
template_literal: "input",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
string: "streng",
|
||||
number: "tal",
|
||||
boolean: "boolean",
|
||||
array: "liste",
|
||||
object: "objekt",
|
||||
set: "sæt",
|
||||
file: "fil",
|
||||
};
|
||||
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 `Ugyldigt input: forventede instanceof ${issue.expected}, fik ${received}`;
|
||||
}
|
||||
return `Ugyldigt input: forventede ${expected}, fik ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Ugyldig værdi: forventede ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Ugyldigt valg: forventede en af følgende ${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 `For stor: forventede ${origin ?? "value"} ${sizing.verb} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "elementer"}`;
|
||||
return `For stor: forventede ${origin ?? "value"} havde ${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 `For lille: forventede ${origin} ${sizing.verb} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
|
||||
}
|
||||
return `For lille: forventede ${origin} havde ${adj} ${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with")
|
||||
return `Ugyldig streng: skal starte med "${_issue.prefix}"`;
|
||||
if (_issue.format === "ends_with")
|
||||
return `Ugyldig streng: skal ende med "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Ugyldig streng: skal indeholde "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Ugyldig streng: skal matche mønsteret ${_issue.pattern}`;
|
||||
return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Ugyldigt tal: skal være deleligt med ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `${issue.keys.length > 1 ? "Ukendte nøgler" : "Ukendt nøgle"}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Ugyldig nøgle i ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Ugyldigt input: matcher ingen af de tilladte typer";
|
||||
case "invalid_element":
|
||||
return `Ugyldig værdi i ${issue.origin}`;
|
||||
default:
|
||||
return `Ugyldigt input`;
|
||||
}
|
||||
};
|
||||
};
|
||||
export default function () {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
Copyright 2011 Gary Court. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY GARY COURT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Gary Court.
|
||||
@@ -0,0 +1,10 @@
|
||||
const { Writable } = require('node:stream')
|
||||
|
||||
module.exports = () => {
|
||||
return new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
cb()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
"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 });
|
||||
exports.getTypeName = getTypeName;
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
/**
|
||||
* Get the type name of a given type.
|
||||
* @param typeChecker The context sensitive TypeScript TypeChecker.
|
||||
* @param type The type to get the name of.
|
||||
*/
|
||||
function getTypeName(typeChecker, type) {
|
||||
// It handles `string` and string literal types as string.
|
||||
if (tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike)) {
|
||||
return 'string';
|
||||
}
|
||||
// If the type is a type parameter which extends primitive string types,
|
||||
// but it was not recognized as a string like. So check the constraint
|
||||
// type of the type parameter.
|
||||
if (tsutils.isTypeFlagSet(type, ts.TypeFlags.TypeParameter)) {
|
||||
// `type.getConstraint()` method doesn't return the constraint type of
|
||||
// the type parameter for some reason. So this gets the constraint type
|
||||
// via AST.
|
||||
const symbol = type.getSymbol();
|
||||
const decls = symbol?.getDeclarations();
|
||||
const typeParamDecl = decls?.[0];
|
||||
if (typeParamDecl != null &&
|
||||
ts.isTypeParameterDeclaration(typeParamDecl) &&
|
||||
typeParamDecl.constraint != null) {
|
||||
return getTypeName(typeChecker, typeChecker.getTypeFromTypeNode(typeParamDecl.constraint));
|
||||
}
|
||||
}
|
||||
// If the type is a union and all types in the union are string like,
|
||||
// return `string`. For example:
|
||||
// - `"a" | "b"` is string.
|
||||
// - `string | string[]` is not string.
|
||||
if (type.isUnion() &&
|
||||
type.types
|
||||
.map(value => getTypeName(typeChecker, value))
|
||||
.every(t => t === 'string')) {
|
||||
return 'string';
|
||||
}
|
||||
// If the type is an intersection and a type in the intersection is string
|
||||
// like, return `string`. For example: `string & {__htmlEscaped: void}`
|
||||
if (type.isIntersection() &&
|
||||
type.types
|
||||
.map(value => getTypeName(typeChecker, value))
|
||||
.some(t => t === 'string')) {
|
||||
return 'string';
|
||||
}
|
||||
return typeChecker.typeToString(type);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import * as util from "../core/util.js";
|
||||
const error = () => {
|
||||
const Sizable = {
|
||||
string: { unit: "znakov", verb: "imeti" },
|
||||
file: { unit: "bajtov", verb: "imeti" },
|
||||
array: { unit: "elementov", verb: "imeti" },
|
||||
set: { unit: "elementov", verb: "imeti" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "vnos",
|
||||
email: "e-poštni naslov",
|
||||
url: "URL",
|
||||
emoji: "emoji",
|
||||
uuid: "UUID",
|
||||
uuidv4: "UUIDv4",
|
||||
uuidv6: "UUIDv6",
|
||||
nanoid: "nanoid",
|
||||
guid: "GUID",
|
||||
cuid: "cuid",
|
||||
cuid2: "cuid2",
|
||||
ulid: "ULID",
|
||||
xid: "XID",
|
||||
ksuid: "KSUID",
|
||||
datetime: "ISO datum in čas",
|
||||
date: "ISO datum",
|
||||
time: "ISO čas",
|
||||
duration: "ISO trajanje",
|
||||
ipv4: "IPv4 naslov",
|
||||
ipv6: "IPv6 naslov",
|
||||
cidrv4: "obseg IPv4",
|
||||
cidrv6: "obseg IPv6",
|
||||
base64: "base64 kodiran niz",
|
||||
base64url: "base64url kodiran niz",
|
||||
json_string: "JSON niz",
|
||||
e164: "E.164 številka",
|
||||
jwt: "JWT",
|
||||
template_literal: "vnos",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
number: "število",
|
||||
array: "tabela",
|
||||
};
|
||||
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 `Neveljaven vnos: pričakovano instanceof ${issue.expected}, prejeto ${received}`;
|
||||
}
|
||||
return `Neveljaven vnos: pričakovano ${expected}, prejeto ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Neveljaven vnos: pričakovano ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Neveljavna možnost: pričakovano eno izmed ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `Preveliko: pričakovano, da bo ${issue.origin ?? "vrednost"} imelo ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementov"}`;
|
||||
return `Preveliko: pričakovano, da bo ${issue.origin ?? "vrednost"} ${adj}${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) {
|
||||
return `Premajhno: pričakovano, da bo ${issue.origin} imelo ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
||||
}
|
||||
return `Premajhno: pričakovano, da bo ${issue.origin} ${adj}${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with") {
|
||||
return `Neveljaven niz: mora se začeti z "${_issue.prefix}"`;
|
||||
}
|
||||
if (_issue.format === "ends_with")
|
||||
return `Neveljaven niz: mora se končati z "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Neveljaven niz: mora vsebovati "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Neveljaven niz: mora ustrezati vzorcu ${_issue.pattern}`;
|
||||
return `Neveljaven ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Neveljavno število: mora biti večkratnik ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `Neprepoznan${issue.keys.length > 1 ? "i ključi" : " ključ"}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Neveljaven ključ v ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Neveljaven vnos";
|
||||
case "invalid_element":
|
||||
return `Neveljavna vrednost v ${issue.origin}`;
|
||||
default:
|
||||
return "Neveljaven vnos";
|
||||
}
|
||||
};
|
||||
};
|
||||
export default function () {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{{# def.definitions }}
|
||||
{{# def.errors }}
|
||||
{{# def.setupKeyword }}
|
||||
{{# def.setupNextLevel }}
|
||||
|
||||
{{? {{# def.nonEmptySchema:$schema }} }}
|
||||
{{
|
||||
$it.schema = $schema;
|
||||
$it.schemaPath = $schemaPath;
|
||||
$it.errSchemaPath = $errSchemaPath;
|
||||
}}
|
||||
|
||||
var {{=$errs}} = errors;
|
||||
|
||||
{{# def.setCompositeRule }}
|
||||
|
||||
{{
|
||||
$it.createErrors = false;
|
||||
var $allErrorsOption;
|
||||
if ($it.opts.allErrors) {
|
||||
$allErrorsOption = $it.opts.allErrors;
|
||||
$it.opts.allErrors = false;
|
||||
}
|
||||
}}
|
||||
{{= it.validate($it) }}
|
||||
{{
|
||||
$it.createErrors = true;
|
||||
if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption;
|
||||
}}
|
||||
|
||||
{{# def.resetCompositeRule }}
|
||||
|
||||
if ({{=$nextValid}}) {
|
||||
{{# def.error:'not' }}
|
||||
} else {
|
||||
{{# def.resetErrors }}
|
||||
{{? it.opts.allErrors }} } {{?}}
|
||||
{{??}}
|
||||
{{# def.addError:'not' }}
|
||||
{{? $breakOnError}}
|
||||
if (false) {
|
||||
{{?}}
|
||||
{{?}}
|
||||
@@ -0,0 +1,112 @@
|
||||
declare module 'vm' {
|
||||
interface Context {
|
||||
[key: string]: any;
|
||||
}
|
||||
interface BaseOptions {
|
||||
/**
|
||||
* Specifies the filename used in stack traces produced by this script.
|
||||
* Default: `''`.
|
||||
*/
|
||||
filename?: string | undefined;
|
||||
/**
|
||||
* Specifies the line number offset that is displayed in stack traces produced by this script.
|
||||
* Default: `0`.
|
||||
*/
|
||||
lineOffset?: number | undefined;
|
||||
/**
|
||||
* Specifies the column number offset that is displayed in stack traces produced by this script.
|
||||
* @default 0
|
||||
*/
|
||||
columnOffset?: number | undefined;
|
||||
}
|
||||
interface ScriptOptions extends BaseOptions {
|
||||
displayErrors?: boolean | undefined;
|
||||
timeout?: number | undefined;
|
||||
cachedData?: Buffer | undefined;
|
||||
/** @deprecated in favor of `script.createCachedData()` */
|
||||
produceCachedData?: boolean | undefined;
|
||||
}
|
||||
interface RunningScriptOptions extends BaseOptions {
|
||||
/**
|
||||
* When `true`, if an `Error` occurs while compiling the `code`, the line of code causing the error is attached to the stack trace.
|
||||
* Default: `true`.
|
||||
*/
|
||||
displayErrors?: boolean | undefined;
|
||||
/**
|
||||
* Specifies the number of milliseconds to execute code before terminating execution.
|
||||
* If execution is terminated, an `Error` will be thrown. This value must be a strictly positive integer.
|
||||
*/
|
||||
timeout?: number | undefined;
|
||||
/**
|
||||
* If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received.
|
||||
* Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that.
|
||||
* If execution is terminated, an `Error` will be thrown.
|
||||
* Default: `false`.
|
||||
*/
|
||||
breakOnSigint?: boolean | undefined;
|
||||
}
|
||||
interface CompileFunctionOptions extends BaseOptions {
|
||||
/**
|
||||
* Provides an optional data with V8's code cache data for the supplied source.
|
||||
*/
|
||||
cachedData?: Buffer | undefined;
|
||||
/**
|
||||
* Specifies whether to produce new cache data.
|
||||
* Default: `false`,
|
||||
*/
|
||||
produceCachedData?: boolean | undefined;
|
||||
/**
|
||||
* The sandbox/context in which the said function should be compiled in.
|
||||
*/
|
||||
parsingContext?: Context | undefined;
|
||||
|
||||
/**
|
||||
* An array containing a collection of context extensions (objects wrapping the current scope) to be applied while compiling
|
||||
*/
|
||||
contextExtensions?: Object[] | undefined;
|
||||
}
|
||||
|
||||
interface CreateContextOptions {
|
||||
/**
|
||||
* Human-readable name of the newly created context.
|
||||
* @default 'VM Context i' Where i is an ascending numerical index of the created context.
|
||||
*/
|
||||
name?: string | undefined;
|
||||
/**
|
||||
* Corresponds to the newly created context for display purposes.
|
||||
* The origin should be formatted like a `URL`, but with only the scheme, host, and port (if necessary),
|
||||
* like the value of the `url.origin` property of a URL object.
|
||||
* Most notably, this string should omit the trailing slash, as that denotes a path.
|
||||
* @default ''
|
||||
*/
|
||||
origin?: string | undefined;
|
||||
codeGeneration?: {
|
||||
/**
|
||||
* If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc)
|
||||
* will throw an EvalError.
|
||||
* @default true
|
||||
*/
|
||||
strings?: boolean | undefined;
|
||||
/**
|
||||
* If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError.
|
||||
* @default true
|
||||
*/
|
||||
wasm?: boolean | undefined;
|
||||
} | undefined;
|
||||
}
|
||||
|
||||
class Script {
|
||||
constructor(code: string, options?: ScriptOptions);
|
||||
runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any;
|
||||
runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any;
|
||||
runInThisContext(options?: RunningScriptOptions): any;
|
||||
createCachedData(): Buffer;
|
||||
cachedDataRejected?: boolean | undefined;
|
||||
}
|
||||
function createContext(sandbox?: Context, options?: CreateContextOptions): Context;
|
||||
function isContext(sandbox: Context): boolean;
|
||||
function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions | string): any;
|
||||
function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions | string): any;
|
||||
function runInThisContext(code: string, options?: RunningScriptOptions | string): any;
|
||||
function compileFunction(code: string, params?: ReadonlyArray<string>, options?: CompileFunctionOptions): Function;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
function _regeneratorKeys(e) {
|
||||
var n = Object(e),
|
||||
r = [];
|
||||
for (var t in n) r.unshift(t);
|
||||
return function e() {
|
||||
for (; r.length;) if ((t = r.pop()) in n) return e.value = t, e.done = !1, e;
|
||||
return e.done = !0, e;
|
||||
};
|
||||
}
|
||||
module.exports = _regeneratorKeys, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code generated by Herebyfile.mjs generate:enums from internal/ast/tokenflags.go. DO NOT EDIT.
|
||||
export var TokenFlags;
|
||||
(function (TokenFlags) {
|
||||
TokenFlags[TokenFlags["None"] = 0] = "None";
|
||||
TokenFlags[TokenFlags["PrecedingLineBreak"] = 1] = "PrecedingLineBreak";
|
||||
TokenFlags[TokenFlags["PrecedingJSDocComment"] = 2] = "PrecedingJSDocComment";
|
||||
TokenFlags[TokenFlags["Unterminated"] = 4] = "Unterminated";
|
||||
TokenFlags[TokenFlags["ExtendedUnicodeEscape"] = 8] = "ExtendedUnicodeEscape";
|
||||
TokenFlags[TokenFlags["Scientific"] = 16] = "Scientific";
|
||||
TokenFlags[TokenFlags["Octal"] = 32] = "Octal";
|
||||
TokenFlags[TokenFlags["HexSpecifier"] = 64] = "HexSpecifier";
|
||||
TokenFlags[TokenFlags["BinarySpecifier"] = 128] = "BinarySpecifier";
|
||||
TokenFlags[TokenFlags["OctalSpecifier"] = 256] = "OctalSpecifier";
|
||||
TokenFlags[TokenFlags["ContainsSeparator"] = 512] = "ContainsSeparator";
|
||||
TokenFlags[TokenFlags["UnicodeEscape"] = 1024] = "UnicodeEscape";
|
||||
TokenFlags[TokenFlags["ContainsInvalidEscape"] = 2048] = "ContainsInvalidEscape";
|
||||
TokenFlags[TokenFlags["HexEscape"] = 4096] = "HexEscape";
|
||||
TokenFlags[TokenFlags["ContainsLeadingZero"] = 8192] = "ContainsLeadingZero";
|
||||
TokenFlags[TokenFlags["ContainsInvalidSeparator"] = 16384] = "ContainsInvalidSeparator";
|
||||
TokenFlags[TokenFlags["PrecedingJSDocLeadingAsterisks"] = 32768] = "PrecedingJSDocLeadingAsterisks";
|
||||
TokenFlags[TokenFlags["SingleQuote"] = 65536] = "SingleQuote";
|
||||
TokenFlags[TokenFlags["PrecedingJSDocWithDeprecated"] = 131072] = "PrecedingJSDocWithDeprecated";
|
||||
TokenFlags[TokenFlags["PrecedingJSDocWithSeeOrLink"] = 262144] = "PrecedingJSDocWithSeeOrLink";
|
||||
TokenFlags[TokenFlags["BinaryOrOctalSpecifier"] = 384] = "BinaryOrOctalSpecifier";
|
||||
TokenFlags[TokenFlags["WithSpecifier"] = 448] = "WithSpecifier";
|
||||
TokenFlags[TokenFlags["StringLiteralFlags"] = 72716] = "StringLiteralFlags";
|
||||
TokenFlags[TokenFlags["NumericLiteralFlags"] = 25584] = "NumericLiteralFlags";
|
||||
TokenFlags[TokenFlags["TemplateLiteralLikeFlags"] = 7180] = "TemplateLiteralLikeFlags";
|
||||
TokenFlags[TokenFlags["RegularExpressionLiteralFlags"] = 4] = "RegularExpressionLiteralFlags";
|
||||
TokenFlags[TokenFlags["IsInvalid"] = 26656] = "IsInvalid";
|
||||
})(TokenFlags || (TokenFlags = {}));
|
||||
//# sourceMappingURL=tokenFlags.js.map
|
||||
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path')
|
||||
, fs = require('fs')
|
||||
, helper = require('./helper.js')
|
||||
;
|
||||
|
||||
|
||||
module.exports = function(connInfo, cb) {
|
||||
var file = helper.getFileName();
|
||||
|
||||
fs.stat(file, function(err, stat){
|
||||
if (err || !helper.usePgPass(stat, file)) {
|
||||
return cb(undefined);
|
||||
}
|
||||
|
||||
var st = fs.createReadStream(file);
|
||||
|
||||
helper.getPassword(connInfo, st, cb);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.warnTo = helper.warnTo;
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/api/async/client.ts"],"names":[],"mappings":"AAeA,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAG1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAKH,eAAe,EACf,KAAK,UAAU,EAClB,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;AAEvE;;;GAGG;AACH,qBAAa,MAAM;IACf,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAA8B;gBAEhC,OAAO,EAAE,aAAa;IAO5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAWhB,eAAe;YAiDf,gBAAgB;IAmB9B,OAAO,CAAC,mBAAmB;IAoBrB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAgC3D,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAOzF;;;;;OAKG;IACH,kBAAkB,IAAI,eAAe,GAAG,SAAS;IAIjD;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IAYpC,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAUxB,iBAAiB;IAUzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB/B"}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { TSESLint } from '@typescript-eslint/utils';
|
||||
export type MessageId = 'await' | 'awaitUsingOfNonAsyncDisposable' | 'convertToOrdinaryFor' | 'forAwaitOfNonAsyncIterable' | 'invalidPromiseAggregatorInput' | 'removeAwait';
|
||||
declare const _default: TSESLint.RuleModule<MessageId, [], import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,334 @@
|
||||
/**
|
||||
* @fileoverview A class of the code path.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const CodePathState = require("./code-path-state");
|
||||
const IdGenerator = require("./id-generator");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A code path.
|
||||
*/
|
||||
class CodePath {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options Options for the function (see below).
|
||||
* @param {string} options.id An identifier.
|
||||
* @param {string} options.origin The type of code path origin.
|
||||
* @param {CodePath|null} options.upper The code path of the upper function scope.
|
||||
* @param {Function} options.onLooped A callback function to notify looping.
|
||||
*/
|
||||
constructor({ id, origin, upper, onLooped }) {
|
||||
/**
|
||||
* The identifier of this code path.
|
||||
* Rules use it to store additional information of each rule.
|
||||
* @type {string}
|
||||
*/
|
||||
this.id = id;
|
||||
|
||||
/**
|
||||
* The reason that this code path was started. May be "program",
|
||||
* "function", "class-field-initializer", or "class-static-block".
|
||||
* @type {string}
|
||||
*/
|
||||
this.origin = origin;
|
||||
|
||||
/**
|
||||
* The code path of the upper function scope.
|
||||
* @type {CodePath|null}
|
||||
*/
|
||||
this.upper = upper;
|
||||
|
||||
/**
|
||||
* The code paths of nested function scopes.
|
||||
* @type {CodePath[]}
|
||||
*/
|
||||
this.childCodePaths = [];
|
||||
|
||||
// Initializes internal state.
|
||||
Object.defineProperty(this, "internal", {
|
||||
value: new CodePathState(new IdGenerator(`${id}_`), onLooped),
|
||||
});
|
||||
|
||||
// Adds this into `childCodePaths` of `upper`.
|
||||
if (upper) {
|
||||
upper.childCodePaths.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of a given code path.
|
||||
* @param {CodePath} codePath A code path to get.
|
||||
* @returns {CodePathState} The state of the code path.
|
||||
*/
|
||||
static getState(codePath) {
|
||||
return codePath.internal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial code path segment. This is the segment that is at the head
|
||||
* of the code path.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment}
|
||||
*/
|
||||
get initialSegment() {
|
||||
return this.internal.initialSegment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments. These are the terminal (tail) segments in the
|
||||
* code path, which is the combination of `returnedSegments` and `thrownSegments`.
|
||||
* All segments in this array are reachable.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get finalSegments() {
|
||||
return this.internal.finalSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments that represent normal completion of the code path.
|
||||
* For functions, this means both explicit `return` statements and implicit returns,
|
||||
* such as the last reachable segment in a function that does not have an
|
||||
* explicit `return` as this implicitly returns `undefined`, as well as
|
||||
* return-like exits from suspended `yield` expressions. For scripts, modules,
|
||||
* class field initializers, and class static blocks, this means all lines of
|
||||
* code have been executed.
|
||||
* These segments are also present in `finalSegments`.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get returnedSegments() {
|
||||
return this.internal.returnedForkContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments that represent `throw` statements and throw-like
|
||||
* exits from suspended `yield` expressions.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* These segments are also present in `finalSegments`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get thrownSegments() {
|
||||
return this.internal.thrownForkContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses all segments in this code path.
|
||||
*
|
||||
* codePath.traverseSegments((segment, controller) => {
|
||||
* // do something.
|
||||
* });
|
||||
*
|
||||
* This method enumerates segments in order from the head.
|
||||
*
|
||||
* The `controller` argument has two methods:
|
||||
*
|
||||
* - `skip()` - skips the following segments in this branch
|
||||
* - `break()` - skips all following segments in the traversal
|
||||
*
|
||||
* A note on the parameters: the `options` argument is optional. This means
|
||||
* the first argument might be an options object or the callback function.
|
||||
* @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
|
||||
* @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
|
||||
* @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
|
||||
* @param {Function} callback A callback function.
|
||||
* @returns {void}
|
||||
*/
|
||||
traverseSegments(optionsOrCallback, callback) {
|
||||
// normalize the arguments into a callback and options
|
||||
let resolvedOptions;
|
||||
let resolvedCallback;
|
||||
|
||||
if (typeof optionsOrCallback === "function") {
|
||||
resolvedCallback = optionsOrCallback;
|
||||
resolvedOptions = {};
|
||||
} else {
|
||||
resolvedOptions = optionsOrCallback || {};
|
||||
resolvedCallback = callback;
|
||||
}
|
||||
|
||||
// determine where to start traversing from based on the options
|
||||
const startSegment =
|
||||
resolvedOptions.first || this.internal.initialSegment;
|
||||
const lastSegment = resolvedOptions.last;
|
||||
|
||||
// set up initial location information
|
||||
let record;
|
||||
let index;
|
||||
let end;
|
||||
let segment = null;
|
||||
|
||||
// segments that have already been visited during traversal
|
||||
const visited = new Set();
|
||||
|
||||
// tracks the traversal steps
|
||||
const stack = [[startSegment, 0]];
|
||||
|
||||
// segments that have been skipped during traversal
|
||||
const skipped = new Set();
|
||||
|
||||
// indicates if we exited early from the traversal
|
||||
let broken = false;
|
||||
|
||||
/**
|
||||
* Maintains traversal state.
|
||||
*/
|
||||
const controller = {
|
||||
/**
|
||||
* Skip the following segments in this branch.
|
||||
* @returns {void}
|
||||
*/
|
||||
skip() {
|
||||
skipped.add(segment);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop traversal completely - do not traverse to any
|
||||
* other segments.
|
||||
* @returns {void}
|
||||
*/
|
||||
break() {
|
||||
broken = true;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a given previous segment has been visited.
|
||||
* @param {CodePathSegment} prevSegment A previous segment to check.
|
||||
* @returns {boolean} `true` if the segment has been visited.
|
||||
*/
|
||||
function isVisited(prevSegment) {
|
||||
return (
|
||||
visited.has(prevSegment) ||
|
||||
segment.isLoopedPrevSegment(prevSegment)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given previous segment has been skipped.
|
||||
* @param {CodePathSegment} prevSegment A previous segment to check.
|
||||
* @returns {boolean} `true` if the segment has been skipped.
|
||||
*/
|
||||
function isSkipped(prevSegment) {
|
||||
return (
|
||||
skipped.has(prevSegment) ||
|
||||
segment.isLoopedPrevSegment(prevSegment)
|
||||
);
|
||||
}
|
||||
|
||||
// the traversal
|
||||
while (stack.length > 0) {
|
||||
/*
|
||||
* This isn't a pure stack. We use the top record all the time
|
||||
* but don't always pop it off. The record is popped only if
|
||||
* one of the following is true:
|
||||
*
|
||||
* 1) We have already visited the segment.
|
||||
* 2) We have not visited *all* of the previous segments.
|
||||
* 3) We have traversed past the available next segments.
|
||||
*
|
||||
* Otherwise, we just read the value and sometimes modify the
|
||||
* record as we traverse.
|
||||
*/
|
||||
record = stack.at(-1);
|
||||
segment = record[0];
|
||||
index = record[1];
|
||||
|
||||
if (index === 0) {
|
||||
// Skip if this segment has been visited already.
|
||||
if (visited.has(segment)) {
|
||||
stack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if all previous segments have not been visited.
|
||||
if (
|
||||
segment !== startSegment &&
|
||||
segment.prevSegments.length > 0 &&
|
||||
!segment.prevSegments.every(isVisited)
|
||||
) {
|
||||
stack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.add(segment);
|
||||
|
||||
// Skips the segment if all previous segments have been skipped.
|
||||
const shouldSkip =
|
||||
skipped.size > 0 &&
|
||||
segment.prevSegments.length > 0 &&
|
||||
segment.prevSegments.every(isSkipped);
|
||||
|
||||
/*
|
||||
* If the most recent segment hasn't been skipped, then we call
|
||||
* the callback, passing in the segment and the controller.
|
||||
*/
|
||||
if (!shouldSkip) {
|
||||
resolvedCallback.call(this, segment, controller);
|
||||
|
||||
// exit if we're at the last segment
|
||||
if (segment === lastSegment) {
|
||||
controller.skip();
|
||||
}
|
||||
|
||||
/*
|
||||
* If the previous statement was executed, or if the callback
|
||||
* called a method on the controller, we might need to exit the
|
||||
* loop, so check for that and break accordingly.
|
||||
*/
|
||||
if (broken) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// If the most recent segment has been skipped, then mark it as skipped.
|
||||
skipped.add(segment);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the stack.
|
||||
end = segment.nextSegments.length - 1;
|
||||
if (index < end) {
|
||||
/*
|
||||
* If we haven't yet visited all of the next segments, update
|
||||
* the current top record on the stack to the next index to visit
|
||||
* and then push a record for the current segment on top.
|
||||
*
|
||||
* Setting the current top record's index lets us know how many
|
||||
* times we've been here and ensures that the segment won't be
|
||||
* reprocessed (because we only process segments with an index
|
||||
* of 0).
|
||||
*/
|
||||
record[1] += 1;
|
||||
stack.push([segment.nextSegments[index], 0]);
|
||||
} else if (index === end) {
|
||||
/*
|
||||
* If we are at the last next segment, then reset the top record
|
||||
* in the stack to next segment and set its index to 0 so it will
|
||||
* be processed next.
|
||||
*/
|
||||
record[0] = segment.nextSegments[index];
|
||||
record[1] = 0;
|
||||
} else {
|
||||
/*
|
||||
* If index > end, that means we have no more segments that need
|
||||
* processing. So, we pop that record off of the stack in order to
|
||||
* continue traversing at the next level up.
|
||||
*/
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CodePath;
|
||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
declare function stringify(
|
||||
value: any,
|
||||
replacer?: (key: string, value: any) => any,
|
||||
space?: string | number,
|
||||
options?: { depthLimit: number | undefined; edgesLimit: number | undefined }
|
||||
): string;
|
||||
|
||||
declare namespace stringify {
|
||||
export function stable(
|
||||
value: any,
|
||||
replacer?: (key: string, value: any) => any,
|
||||
space?: string | number,
|
||||
options?: { depthLimit: number | undefined; edgesLimit: number | undefined }
|
||||
): string;
|
||||
export function stableStringify(
|
||||
value: any,
|
||||
replacer?: (key: string, value: any) => any,
|
||||
space?: string | number,
|
||||
options?: { depthLimit: number | undefined; edgesLimit: number | undefined }
|
||||
): string;
|
||||
}
|
||||
|
||||
export default stringify;
|
||||
@@ -0,0 +1,39 @@
|
||||
import Client from './client'
|
||||
import TPoolStats from './pool-stats'
|
||||
import { URL } from 'node:url'
|
||||
import Dispatcher from './dispatcher'
|
||||
|
||||
export default RoundRobinPool
|
||||
|
||||
type RoundRobinPoolConnectOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
|
||||
|
||||
declare class RoundRobinPool extends Dispatcher {
|
||||
constructor (url: string | URL, options?: RoundRobinPool.Options)
|
||||
/** `true` after `pool.close()` has been called. */
|
||||
closed: boolean
|
||||
/** `true` after `pool.destroyed()` has been called or `pool.close()` has been called and the pool shutdown has completed. */
|
||||
destroyed: boolean
|
||||
/** Aggregate stats for a RoundRobinPool. */
|
||||
readonly stats: TPoolStats
|
||||
|
||||
// Override dispatcher APIs.
|
||||
override connect (
|
||||
options: RoundRobinPoolConnectOptions
|
||||
): Promise<Dispatcher.ConnectData>
|
||||
override connect (
|
||||
options: RoundRobinPoolConnectOptions,
|
||||
callback: (err: Error | null, data: Dispatcher.ConnectData) => void
|
||||
): void
|
||||
}
|
||||
|
||||
declare namespace RoundRobinPool {
|
||||
export type RoundRobinPoolStats = TPoolStats
|
||||
export interface Options extends Client.Options {
|
||||
/** Default: `(origin, opts) => new Client(origin, opts)`. */
|
||||
factory?(origin: URL, opts: object): Dispatcher;
|
||||
/** The max number of clients to create. `null` if no limit. Default `null`. */
|
||||
connections?: number | null;
|
||||
/** The amount of time before a client is removed from the pool and closed. `null` if no time limit. Default `null` */
|
||||
clientTtl?: number | null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"newLineKind.js","sourceRoot":"","sources":["../../src/enums/newLineKind.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,MAAM,CAAC,IAAI,WAAgB,CAAC;AAC5B,CAAC,UAAU,WAAW;IAClB,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC9C,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC9C,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;AAC9C,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC"}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "../../cjs/_class_private_field_init.cjs",
|
||||
"module": "../../esm/_class_private_field_init.js"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const SemVer = require('../classes/semver')
|
||||
const compareBuild = (a, b, loose) => {
|
||||
const versionA = new SemVer(a, loose)
|
||||
const versionB = new SemVer(b, loose)
|
||||
return versionA.compare(versionB) || versionA.compareBuild(versionB)
|
||||
}
|
||||
module.exports = compareBuild
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* @fileoverview Utility functions to locate the source text of each code unit in the value of a string literal or template token.
|
||||
* @author Francesco Trotta
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Represents a code unit produced by the evaluation of a JavaScript common token like a string
|
||||
* literal or template token.
|
||||
*/
|
||||
class CodeUnit {
|
||||
constructor(start, source) {
|
||||
this.start = start;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
get end() {
|
||||
return this.start + this.length;
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this.source.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object used to keep track of the position in a source text where the next characters will be read.
|
||||
*/
|
||||
class TextReader {
|
||||
constructor(source) {
|
||||
this.source = source;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the reading position of the specified number of characters.
|
||||
* @param {number} length Number of characters to advance.
|
||||
* @returns {void}
|
||||
*/
|
||||
advance(length) {
|
||||
this.pos += length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads characters from the source.
|
||||
* @param {number} [offset=0] The offset where reading starts, relative to the current position.
|
||||
* @param {number} [length=1] Number of characters to read.
|
||||
* @returns {string} A substring of source characters.
|
||||
*/
|
||||
read(offset = 0, length = 1) {
|
||||
const start = offset + this.pos;
|
||||
|
||||
return this.source.slice(start, start + length);
|
||||
}
|
||||
}
|
||||
|
||||
const SIMPLE_ESCAPE_SEQUENCES = {
|
||||
__proto__: null,
|
||||
b: "\b",
|
||||
f: "\f",
|
||||
n: "\n",
|
||||
r: "\r",
|
||||
t: "\t",
|
||||
v: "\v",
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads a hex escape sequence.
|
||||
* @param {TextReader} reader The reader should be positioned on the first hexadecimal digit.
|
||||
* @param {number} length The number of hexadecimal digits.
|
||||
* @returns {string} A code unit.
|
||||
*/
|
||||
function readHexSequence(reader, length) {
|
||||
const str = reader.read(0, length);
|
||||
const charCode = parseInt(str, 16);
|
||||
|
||||
reader.advance(length);
|
||||
return String.fromCharCode(charCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a Unicode escape sequence.
|
||||
* @param {TextReader} reader The reader should be positioned after the "u".
|
||||
* @returns {string} A code unit.
|
||||
*/
|
||||
function readUnicodeSequence(reader) {
|
||||
const regExp = /\{(?<hexDigits>[\dA-F]+)\}/iuy;
|
||||
|
||||
regExp.lastIndex = reader.pos;
|
||||
const match = regExp.exec(reader.source);
|
||||
|
||||
if (match) {
|
||||
const codePoint = parseInt(match.groups.hexDigits, 16);
|
||||
|
||||
reader.pos = regExp.lastIndex;
|
||||
return String.fromCodePoint(codePoint);
|
||||
}
|
||||
return readHexSequence(reader, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an octal escape sequence.
|
||||
* @param {TextReader} reader The reader should be positioned after the first octal digit.
|
||||
* @param {number} maxLength The maximum number of octal digits.
|
||||
* @returns {string} A code unit.
|
||||
*/
|
||||
function readOctalSequence(reader, maxLength) {
|
||||
const [octalStr] = reader.read(-1, maxLength).match(/^[0-7]+/u);
|
||||
|
||||
reader.advance(octalStr.length - 1);
|
||||
const octal = parseInt(octalStr, 8);
|
||||
|
||||
return String.fromCharCode(octal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an escape sequence or line continuation.
|
||||
* @param {TextReader} reader The reader should be positioned on the backslash.
|
||||
* @returns {string} A string of zero, one or two code units.
|
||||
*/
|
||||
function readEscapeSequenceOrLineContinuation(reader) {
|
||||
const char = reader.read(1);
|
||||
|
||||
reader.advance(2);
|
||||
const unitChar = SIMPLE_ESCAPE_SEQUENCES[char];
|
||||
|
||||
if (unitChar) {
|
||||
return unitChar;
|
||||
}
|
||||
switch (char) {
|
||||
case "x":
|
||||
return readHexSequence(reader, 2);
|
||||
case "u":
|
||||
return readUnicodeSequence(reader);
|
||||
case "\r":
|
||||
if (reader.read() === "\n") {
|
||||
reader.advance(1);
|
||||
}
|
||||
|
||||
// fallthrough
|
||||
case "\n":
|
||||
case "\u2028":
|
||||
case "\u2029":
|
||||
return "";
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
return readOctalSequence(reader, 3);
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
return readOctalSequence(reader, 2);
|
||||
default:
|
||||
return char;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an escape sequence or line continuation and generates the respective `CodeUnit` elements.
|
||||
* @param {TextReader} reader The reader should be positioned on the backslash.
|
||||
* @returns {Generator<CodeUnit>} Zero, one or two `CodeUnit` elements.
|
||||
*/
|
||||
function* mapEscapeSequenceOrLineContinuation(reader) {
|
||||
const start = reader.pos;
|
||||
const str = readEscapeSequenceOrLineContinuation(reader);
|
||||
const end = reader.pos;
|
||||
const source = reader.source.slice(start, end);
|
||||
|
||||
switch (str.length) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
yield new CodeUnit(start, source);
|
||||
break;
|
||||
default:
|
||||
yield new CodeUnit(start, source);
|
||||
yield new CodeUnit(start, source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string literal.
|
||||
* @param {string} source The string literal to parse, including the delimiting quotes.
|
||||
* @returns {CodeUnit[]} A list of code units produced by the string literal.
|
||||
*/
|
||||
function parseStringLiteral(source) {
|
||||
const reader = new TextReader(source);
|
||||
const quote = reader.read();
|
||||
|
||||
reader.advance(1);
|
||||
const codeUnits = [];
|
||||
|
||||
for (;;) {
|
||||
const char = reader.read();
|
||||
|
||||
if (char === quote) {
|
||||
break;
|
||||
}
|
||||
if (char === "\\") {
|
||||
codeUnits.push(...mapEscapeSequenceOrLineContinuation(reader));
|
||||
} else {
|
||||
codeUnits.push(new CodeUnit(reader.pos, char));
|
||||
reader.advance(1);
|
||||
}
|
||||
}
|
||||
return codeUnits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a template token.
|
||||
* @param {string} source The template token to parse, including the delimiting sequences `` ` ``, `${` and `}`.
|
||||
* @returns {CodeUnit[]} A list of code units produced by the template token.
|
||||
*/
|
||||
function parseTemplateToken(source) {
|
||||
const reader = new TextReader(source);
|
||||
|
||||
reader.advance(1);
|
||||
const codeUnits = [];
|
||||
|
||||
for (;;) {
|
||||
const char = reader.read();
|
||||
|
||||
if (char === "`" || (char === "$" && reader.read(1) === "{")) {
|
||||
break;
|
||||
}
|
||||
if (char === "\\") {
|
||||
codeUnits.push(...mapEscapeSequenceOrLineContinuation(reader));
|
||||
} else {
|
||||
let unitSource;
|
||||
|
||||
if (char === "\r" && reader.read(1) === "\n") {
|
||||
unitSource = "\r\n";
|
||||
} else {
|
||||
unitSource = char;
|
||||
}
|
||||
codeUnits.push(new CodeUnit(reader.pos, unitSource));
|
||||
reader.advance(unitSource.length);
|
||||
}
|
||||
}
|
||||
return codeUnits;
|
||||
}
|
||||
|
||||
module.exports = { parseStringLiteral, parseTemplateToken };
|
||||
@@ -0,0 +1,12 @@
|
||||
"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.es2025_promise = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
exports.es2025_promise = {
|
||||
libs: [],
|
||||
variables: [['PromiseConstructor', base_config_1.TYPE]],
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import { MessagePort } from 'node:worker_threads';
|
||||
import { R as RequiredProperty } from '../../types-Cxp8y2TL.js';
|
||||
|
||||
type ScopedImport = (specifier: string, parent: string) => Promise<any>;
|
||||
|
||||
type TsconfigOptions = false | string;
|
||||
type InitializationOptions = {
|
||||
namespace?: string;
|
||||
port?: MessagePort;
|
||||
tsconfig?: TsconfigOptions;
|
||||
};
|
||||
type RegisterOptions = {
|
||||
namespace?: string;
|
||||
onImport?: (url: string) => void;
|
||||
tsconfig?: TsconfigOptions;
|
||||
};
|
||||
type Unregister = () => Promise<void>;
|
||||
type NamespacedUnregister = Unregister & {
|
||||
import: ScopedImport;
|
||||
unregister: Unregister;
|
||||
};
|
||||
type Register = {
|
||||
(options: RequiredProperty<RegisterOptions, 'namespace'>): NamespacedUnregister;
|
||||
(options?: RegisterOptions): Unregister;
|
||||
};
|
||||
declare const register: Register;
|
||||
|
||||
type Options = {
|
||||
parentURL: string;
|
||||
onImport?: (url: string) => void;
|
||||
tsconfig?: TsconfigOptions;
|
||||
};
|
||||
declare const tsImport: (specifier: string, options: string | Options) => Promise<any>;
|
||||
|
||||
export { type InitializationOptions, type NamespacedUnregister, type Register, type RegisterOptions, type ScopedImport, type Unregister, register, tsImport };
|
||||
@@ -0,0 +1,326 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
/// <reference lib="es2015.symbol" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
/**
|
||||
* A method that determines if a constructor object recognizes an object as one of the
|
||||
* constructor’s instances. Called by the semantics of the instanceof operator.
|
||||
*/
|
||||
readonly hasInstance: unique symbol;
|
||||
|
||||
/**
|
||||
* A Boolean value that if true indicates that an object should flatten to its array elements
|
||||
* by Array.prototype.concat.
|
||||
*/
|
||||
readonly isConcatSpreadable: unique symbol;
|
||||
|
||||
/**
|
||||
* A regular expression method that matches the regular expression against a string. Called
|
||||
* by the String.prototype.match method.
|
||||
*/
|
||||
readonly match: unique symbol;
|
||||
|
||||
/**
|
||||
* A regular expression method that replaces matched substrings of a string. Called by the
|
||||
* String.prototype.replace method.
|
||||
*/
|
||||
readonly replace: unique symbol;
|
||||
|
||||
/**
|
||||
* A regular expression method that returns the index within a string that matches the
|
||||
* regular expression. Called by the String.prototype.search method.
|
||||
*/
|
||||
readonly search: unique symbol;
|
||||
|
||||
/**
|
||||
* A function valued property that is the constructor function that is used to create
|
||||
* derived objects.
|
||||
*/
|
||||
readonly species: unique symbol;
|
||||
|
||||
/**
|
||||
* A regular expression method that splits a string at the indices that match the regular
|
||||
* expression. Called by the String.prototype.split method.
|
||||
*/
|
||||
readonly split: unique symbol;
|
||||
|
||||
/**
|
||||
* A method that converts an object to a corresponding primitive value.
|
||||
* Called by the ToPrimitive abstract operation.
|
||||
*/
|
||||
readonly toPrimitive: unique symbol;
|
||||
|
||||
/**
|
||||
* A String value that is used in the creation of the default string description of an object.
|
||||
* Called by the built-in method Object.prototype.toString.
|
||||
*/
|
||||
readonly toStringTag: unique symbol;
|
||||
|
||||
/**
|
||||
* An Object whose truthy properties are properties that are excluded from the 'with'
|
||||
* environment bindings of the associated objects.
|
||||
*/
|
||||
readonly unscopables: unique symbol;
|
||||
}
|
||||
|
||||
interface Symbol {
|
||||
/**
|
||||
* Converts a Symbol object to a symbol.
|
||||
*/
|
||||
[Symbol.toPrimitive](hint: string): symbol;
|
||||
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Is an object whose properties have the value 'true'
|
||||
* when they will be absent when used in a 'with' statement.
|
||||
*/
|
||||
readonly [Symbol.unscopables]: {
|
||||
[K in keyof any[]]?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface ReadonlyArray<T> {
|
||||
/**
|
||||
* Is an object whose properties have the value 'true'
|
||||
* when they will be absent when used in a 'with' statement.
|
||||
*/
|
||||
readonly [Symbol.unscopables]: {
|
||||
[K in keyof readonly any[]]?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface Date {
|
||||
/**
|
||||
* Converts a Date object to a string.
|
||||
*/
|
||||
[Symbol.toPrimitive](hint: "default"): string;
|
||||
/**
|
||||
* Converts a Date object to a string.
|
||||
*/
|
||||
[Symbol.toPrimitive](hint: "string"): string;
|
||||
/**
|
||||
* Converts a Date object to a number.
|
||||
*/
|
||||
[Symbol.toPrimitive](hint: "number"): number;
|
||||
/**
|
||||
* Converts a Date object to a string or number.
|
||||
*
|
||||
* @param hint The strings "number", "string", or "default" to specify what primitive to return.
|
||||
*
|
||||
* @throws {TypeError} If 'hint' was given something other than "number", "string", or "default".
|
||||
* @returns A number if 'hint' was "number", a string if 'hint' was "string" or "default".
|
||||
*/
|
||||
[Symbol.toPrimitive](hint: string): string | number;
|
||||
}
|
||||
|
||||
interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakMap<K extends WeakKey, V> {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface WeakSet<T extends WeakKey> {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface JSON {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Function {
|
||||
/**
|
||||
* Determines whether the given value inherits from this function if this function was used
|
||||
* as a constructor function.
|
||||
*
|
||||
* A constructor function can control which objects are recognized as its instances by
|
||||
* 'instanceof' by overriding this method.
|
||||
*/
|
||||
[Symbol.hasInstance](value: any): boolean;
|
||||
}
|
||||
|
||||
interface GeneratorFunction {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Math {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Promise<T> {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
readonly [Symbol.species]: PromiseConstructor;
|
||||
}
|
||||
|
||||
interface RegExp {
|
||||
/**
|
||||
* Matches a string with this regular expression, and returns an array containing the results of
|
||||
* that search.
|
||||
* @param string A string to search within.
|
||||
*/
|
||||
[Symbol.match](string: string): RegExpMatchArray | null;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using this regular expression.
|
||||
* @param string A String object or string literal whose contents matching against
|
||||
* this regular expression will be replaced
|
||||
* @param replaceValue A String object or string literal containing the text to replace for every
|
||||
* successful match of this regular expression.
|
||||
*/
|
||||
[Symbol.replace](string: string, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using this regular expression.
|
||||
* @param string A String object or string literal whose contents matching against
|
||||
* this regular expression will be replaced
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
|
||||
/**
|
||||
* Finds the position beginning first substring match in a regular expression search
|
||||
* using this regular expression.
|
||||
*
|
||||
* @param string The string to search within.
|
||||
*/
|
||||
[Symbol.search](string: string): number;
|
||||
|
||||
/**
|
||||
* Returns an array of substrings that were delimited by strings in the original input that
|
||||
* match against this regular expression.
|
||||
*
|
||||
* If the regular expression contains capturing parentheses, then each time this
|
||||
* regular expression matches, the results (including any undefined results) of the
|
||||
* capturing parentheses are spliced.
|
||||
*
|
||||
* @param string string value to split
|
||||
* @param limit if not undefined, the output array is truncated so that it contains no more
|
||||
* than 'limit' elements.
|
||||
*/
|
||||
[Symbol.split](string: string, limit?: number): string[];
|
||||
}
|
||||
|
||||
interface RegExpConstructor {
|
||||
readonly [Symbol.species]: RegExpConstructor;
|
||||
}
|
||||
|
||||
interface String {
|
||||
/**
|
||||
* Matches a string or an object that supports being matched against, and returns an array
|
||||
* containing the results of that search, or null if no matches are found.
|
||||
* @param matcher An object that supports being matched against.
|
||||
*/
|
||||
match(matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null;
|
||||
|
||||
/**
|
||||
* Passes a string and {@linkcode replaceValue} to the `[Symbol.replace]` method on {@linkcode searchValue}. This method is expected to implement its own replacement algorithm.
|
||||
* @param searchValue An object that supports searching for and replacing matches within a string.
|
||||
* @param replaceValue The replacement text.
|
||||
*/
|
||||
replace(searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using an object that supports replacement within a string.
|
||||
* @param searchValue A object can search for and replace matches within a string.
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
replace(searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
|
||||
/**
|
||||
* Finds the first substring match in a regular expression search.
|
||||
* @param searcher An object which supports searching within a string.
|
||||
*/
|
||||
search(searcher: { [Symbol.search](string: string): number; }): number;
|
||||
|
||||
/**
|
||||
* Split a string into substrings using the specified separator and return them as an array.
|
||||
* @param splitter An object that can split a string.
|
||||
* @param limit A value used to limit the number of elements returned in the array.
|
||||
*/
|
||||
split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[];
|
||||
}
|
||||
|
||||
interface ArrayBuffer {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface DataView {
|
||||
readonly [Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
interface Int8Array {
|
||||
readonly [Symbol.toStringTag]: "Int8Array";
|
||||
}
|
||||
|
||||
interface Uint8Array {
|
||||
readonly [Symbol.toStringTag]: "Uint8Array";
|
||||
}
|
||||
|
||||
interface Uint8ClampedArray {
|
||||
readonly [Symbol.toStringTag]: "Uint8ClampedArray";
|
||||
}
|
||||
|
||||
interface Int16Array {
|
||||
readonly [Symbol.toStringTag]: "Int16Array";
|
||||
}
|
||||
|
||||
interface Uint16Array {
|
||||
readonly [Symbol.toStringTag]: "Uint16Array";
|
||||
}
|
||||
|
||||
interface Int32Array {
|
||||
readonly [Symbol.toStringTag]: "Int32Array";
|
||||
}
|
||||
|
||||
interface Uint32Array {
|
||||
readonly [Symbol.toStringTag]: "Uint32Array";
|
||||
}
|
||||
|
||||
interface Float32Array {
|
||||
readonly [Symbol.toStringTag]: "Float32Array";
|
||||
}
|
||||
|
||||
interface Float64Array {
|
||||
readonly [Symbol.toStringTag]: "Float64Array";
|
||||
}
|
||||
|
||||
interface ArrayConstructor {
|
||||
readonly [Symbol.species]: ArrayConstructor;
|
||||
}
|
||||
interface MapConstructor {
|
||||
readonly [Symbol.species]: MapConstructor;
|
||||
}
|
||||
interface SetConstructor {
|
||||
readonly [Symbol.species]: SetConstructor;
|
||||
}
|
||||
interface ArrayBufferConstructor {
|
||||
readonly [Symbol.species]: ArrayBufferConstructor;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import crypto from 'crypto'
|
||||
|
||||
import { urlAlphabet } from './url-alphabet/index.js'
|
||||
|
||||
const POOL_SIZE_MULTIPLIER = 128
|
||||
let pool, poolOffset
|
||||
|
||||
let fillPool = bytes => {
|
||||
if (bytes < 0) throw new RangeError('Wrong ID size')
|
||||
try {
|
||||
if (!pool || pool.length < bytes) {
|
||||
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
|
||||
crypto.randomFillSync(pool)
|
||||
poolOffset = 0
|
||||
} else if (poolOffset + bytes > pool.length) {
|
||||
crypto.randomFillSync(pool)
|
||||
poolOffset = 0
|
||||
}
|
||||
} catch (e) {
|
||||
pool = undefined
|
||||
throw e
|
||||
}
|
||||
poolOffset += bytes
|
||||
}
|
||||
|
||||
let random = bytes => {
|
||||
fillPool((bytes |= 0))
|
||||
return pool.subarray(poolOffset - bytes, poolOffset)
|
||||
}
|
||||
|
||||
let customRandom = (alphabet, defaultSize, getRandom) => {
|
||||
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
||||
|
||||
|
||||
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
||||
|
||||
return (size = defaultSize) => {
|
||||
if (size <= 0) return ''
|
||||
let id = ''
|
||||
while (true) {
|
||||
let bytes = getRandom(step)
|
||||
let i = step
|
||||
while (i--) {
|
||||
id += alphabet[bytes[i] & mask] || ''
|
||||
if (id.length === size) return id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let customAlphabet = (alphabet, size = 21) =>
|
||||
customRandom(alphabet, size, random)
|
||||
|
||||
let nanoid = (size = 21) => {
|
||||
fillPool((size |= 0))
|
||||
let id = ''
|
||||
for (let i = poolOffset - size; i < poolOffset; i++) {
|
||||
id += urlAlphabet[pool[i] & 63]
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @fileoverview Rule to flag the generator functions that does not have yield.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
docs: {
|
||||
description: "Require generator functions to contain `yield`",
|
||||
recommended: true,
|
||||
url: "https://eslint.org/docs/latest/rules/require-yield",
|
||||
},
|
||||
|
||||
schema: [],
|
||||
|
||||
messages: {
|
||||
missingYield: "This generator function does not have 'yield'.",
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const stack = [];
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
/**
|
||||
* If the node is a generator function, start counting `yield` keywords.
|
||||
* @param {Node} node A function node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function beginChecking(node) {
|
||||
if (node.generator) {
|
||||
stack.push(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the node is a generator function, end counting `yield` keywords, then
|
||||
* reports result.
|
||||
* @param {Node} node A function node to check.
|
||||
* @returns {void}
|
||||
*/
|
||||
function endChecking(node) {
|
||||
if (!node.generator) {
|
||||
return;
|
||||
}
|
||||
|
||||
const countYield = stack.pop();
|
||||
|
||||
if (countYield === 0 && node.body.body.length > 0) {
|
||||
context.report({
|
||||
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
||||
messageId: "missingYield",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
FunctionDeclaration: beginChecking,
|
||||
"FunctionDeclaration:exit": endChecking,
|
||||
FunctionExpression: beginChecking,
|
||||
"FunctionExpression:exit": endChecking,
|
||||
|
||||
// Increases the count of `yield` keyword.
|
||||
YieldExpression() {
|
||||
if (stack.length > 0) {
|
||||
stack[stack.length - 1] += 1;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ripemd160.d.ts","sourceRoot":"","sources":["../src/ripemd160.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,IAAI,UAAU,EAAE,SAAS,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAC/E,+DAA+D;AAC/D,eAAO,MAAM,SAAS,EAAE,OAAO,UAAuB,CAAC;AACvD,+DAA+D;AAC/D,eAAO,MAAM,SAAS,EAAE,OAAO,UAAuB,CAAC"}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @fileoverview Types for the plugin-kit package.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Imports
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
import type {
|
||||
RuleDefinition,
|
||||
RuleDefinitionTypeOptions,
|
||||
RuleVisitor,
|
||||
} from "@eslint/core";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Exports
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Defaults for non-language-related `RuleDefinition` options.
|
||||
*/
|
||||
export interface CustomRuleTypeDefinitions {
|
||||
RuleOptions: unknown[];
|
||||
MessageIds: string;
|
||||
ExtRuleDocs: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper type to define language specific specializations of the `RuleDefinition` type.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* type YourRuleDefinition<
|
||||
* Options extends Partial<CustomRuleTypeDefinitions> = {},
|
||||
* > = CustomRuleDefinitionType<
|
||||
* {
|
||||
* LangOptions: YourLanguageOptions;
|
||||
* Code: YourSourceCode;
|
||||
* Visitor: YourRuleVisitor;
|
||||
* Node: YourNode;
|
||||
* },
|
||||
* Options
|
||||
* >;
|
||||
* ```
|
||||
*/
|
||||
export type CustomRuleDefinitionType<
|
||||
LanguageSpecificOptions extends Omit<
|
||||
RuleDefinitionTypeOptions,
|
||||
keyof CustomRuleTypeDefinitions
|
||||
>,
|
||||
Options extends Partial<CustomRuleTypeDefinitions>,
|
||||
> = RuleDefinition<
|
||||
// Language specific type options (non-configurable)
|
||||
LanguageSpecificOptions &
|
||||
Required<
|
||||
// Rule specific type options (custom)
|
||||
Options &
|
||||
// Rule specific type options (defaults)
|
||||
Omit<CustomRuleTypeDefinitions, keyof Options>
|
||||
>
|
||||
>;
|
||||
|
||||
/**
|
||||
* Adds matching `:exit` selector properties for each key of a `RuleVisitor`.
|
||||
*/
|
||||
export type CustomRuleVisitorWithExit<RuleVisitorType extends RuleVisitor> = {
|
||||
[Key in keyof RuleVisitorType as
|
||||
| Key
|
||||
| `${Key & string}:exit`]: RuleVisitorType[Key];
|
||||
};
|
||||
|
||||
/**
|
||||
* A map of names to string values, or `null` when no value is provided.
|
||||
*/
|
||||
export type StringConfig = Record<string, string | null>;
|
||||
|
||||
/**
|
||||
* A map of names to boolean flags.
|
||||
*/
|
||||
export type BooleanConfig = Record<string, boolean>;
|
||||
@@ -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.es2020_full = void 0;
|
||||
const dom_1 = require("./dom");
|
||||
const dom_asynciterable_1 = require("./dom.asynciterable");
|
||||
const dom_iterable_1 = require("./dom.iterable");
|
||||
const es2020_1 = require("./es2020");
|
||||
const scripthost_1 = require("./scripthost");
|
||||
const webworker_importscripts_1 = require("./webworker.importscripts");
|
||||
exports.es2020_full = {
|
||||
libs: [
|
||||
es2020_1.es2020,
|
||||
dom_1.dom,
|
||||
webworker_importscripts_1.webworker_importscripts,
|
||||
scripthost_1.scripthost,
|
||||
dom_iterable_1.dom_iterable,
|
||||
dom_asynciterable_1.dom_asynciterable,
|
||||
],
|
||||
variables: [],
|
||||
};
|
||||
Reference in New Issue
Block a user